From 9a52e622b4b99000448f839dc608276525341f9e Mon Sep 17 00:00:00 2001 From: Method-es Date: Mon, 25 May 2015 13:24:17 -0600 Subject: [PATCH 01/51] Update jquery.emojipicker.js --- js/jquery.emojipicker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 93dd88b..feefc5a 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -206,8 +206,8 @@ } // Update section - this.$picker.find('section').hide(); - this.$picker.find('section.' + section).show(); + this.$picker.find('section').addClass('hidden');//.hide(); + this.$picker.find('section.' + section).removeClass('hidden');//.show(); }, pickerClicked: function(e) { From e2473e647f668af234a8c504a28b8d98c0078c0c Mon Sep 17 00:00:00 2001 From: Method-es Date: Wed, 27 May 2015 12:01:21 -0600 Subject: [PATCH 02/51] Added position support (left/right) Reduced use of wrapper when not needed Added resize event to reposition --- demo.html | 26 +++++++--- js/jquery.emojipicker.js | 103 +++++++++++++++++++++++---------------- 2 files changed, 78 insertions(+), 51 deletions(-) diff --git a/demo.html b/demo.html index 64ed16c..34990a4 100644 --- a/demo.html +++ b/demo.html @@ -13,20 +13,26 @@ diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index ab8abfb..f107c9e 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -207,6 +207,9 @@ var emojiUnicode = toUnicode(findEmoji(emojiShortcode).unicode); insertAtCaret(this.element, emojiUnicode); + + // trigger change event on input + $(this.element).trigger("keyup"); }, emojiCategoryClicked: function(e) { @@ -347,8 +350,6 @@ inputField.focus(); inputField.value += myValue; } - // trigger change event on input - $(inputField).trigger("change"); } function toUnicode(code) { From 5d95aa0058237f1d8b00d57110afe3f6be9ef188 Mon Sep 17 00:00:00 2001 From: Brian McManus Date: Wed, 9 Dec 2015 09:06:48 -0800 Subject: [PATCH 05/51] Use normal for loop instead of for/in For/in, at least in our environment, winds up iterating over the object's prototype methods such as `_super` and `nextObject`. These result in a _bunch_ of `class="emoji-undefined"` elements being added to the UI which makes the sections scroll way farther than needed. Switching for/in to a normal for loop because these are just arrays so why bother with for/in and hasOwnProperty? --- js/jquery.emojipicker.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index f107c9e..ca9630e 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -115,7 +115,7 @@ }, listen: function() { - // If the button is being used, wrapper has not been set, + // If the button is being used, wrapper has not been set, // and will not need a listener if (this.settings.button){ // Clicking on the picker icon @@ -140,16 +140,16 @@ }, updatePosition: function() { - + /* Process: - 1. Find the nearest positioned element by crawling up the ancestors, record it's offset + 1. Find the nearest positioned element by crawling up the ancestors, record it's offset 2. Find the bottom left or right of the input element, record this (Account for position setting of left or right) 3. Find the difference between the two, as this will become our new position 4. Magic. N.B. The removed code had a reference to top/bottom positioning, but I don't see the use case for this.. - */ - + */ + // Step 1 // Luckily jquery already does this... var positionedParent = this.$picker.offsetParent(); @@ -207,7 +207,7 @@ var emojiUnicode = toUnicode(findEmoji(emojiShortcode).unicode); insertAtCaret(this.element, emojiUnicode); - + // trigger change event on input $(this.element).trigger("keyup"); }, @@ -294,7 +294,8 @@ nodes.push('
'); nodes.push('
'); } nodes.push(''); - for (var i in categories) { + for (var i = 0; i < categories_length; i++) { nodes.push('
'); - for (var j in items[ categories[i].name ] ) { + var category_length = items[ categories[i].name ].length; + for (var j = 0; j < category_length; j++) { var emoji = items[ categories[i].name ][ j ]; nodes.push('
'); } From 91a1b3d60cfe391beda5c1e6ebea3020c1b86acb Mon Sep 17 00:00:00 2001 From: Pawel Szymczykowski Date: Wed, 9 Dec 2015 10:58:25 -0800 Subject: [PATCH 06/51] Adding grunt-cli --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 4c23bd9..ca91f0b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,6 @@ "name": "jquery-emoji-picker", "version": "0.1.1", "description": "Add an emoji picker to any text field", - "repository": { "type": "git", "url": "https://github.com/wedgies/jquery-emoji-picker.git" @@ -20,6 +19,7 @@ "homepage": "https://github.com/wedgies/jquery-emoji-picker", "devDependencies": { "grunt": "^0.4.5", - "grunt-bump": "^0.3.0" + "grunt-bump": "^0.3.0", + "grunt-cli": "^0.1.13" } } From 2bf45c735701f86d856637a2ca43be12f95a4411 Mon Sep 17 00:00:00 2001 From: Pawel Szymczykowski Date: Wed, 9 Dec 2015 10:58:28 -0800 Subject: [PATCH 07/51] Release v0.1.2 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 299be2f..b0c7965 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-emoji-picker", - "version": "0.1.1", + "version": "0.1.2", "homepage": "https://github.com/wedgies/jquery-emoji-picker", "authors": [ "Wedgies, Inc" diff --git a/package.json b/package.json index ca91f0b..bc7f8ec 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery-emoji-picker", - "version": "0.1.1", + "version": "0.1.2", "description": "Add an emoji picker to any text field", "repository": { "type": "git", From 1b81d6a2c123b5b35b86256a8cfebae8554d4475 Mon Sep 17 00:00:00 2001 From: Pawel Szymczykowski Date: Wed, 9 Dec 2015 10:58:41 -0800 Subject: [PATCH 08/51] Release v0.1.3 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index b0c7965..97b6cae 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-emoji-picker", - "version": "0.1.2", + "version": "0.1.3", "homepage": "https://github.com/wedgies/jquery-emoji-picker", "authors": [ "Wedgies, Inc" diff --git a/package.json b/package.json index bc7f8ec..1ed241e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery-emoji-picker", - "version": "0.1.2", + "version": "0.1.3", "description": "Add an emoji picker to any text field", "repository": { "type": "git", From 6d0c86086fe4180e24ecfc9669ac8fa3f2c4b792 Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Tue, 29 Dec 2015 15:29:07 -0800 Subject: [PATCH 09/51] Adds a recently used tab/section to the picker. --- js/jquery.emojipicker.js | 58 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index ca9630e..8c66a8e 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -8,11 +8,12 @@ fadeTime: 100, iconColor: 'black', iconBackgroundColor: '#eee', + recentCount: 28, container: 'body', button: true }; - var MIN_WIDTH = 200, + var MIN_WIDTH = 300, MAX_WIDTH = 600, MIN_HEIGHT = 100, MAX_HEIGHT = 350, @@ -131,6 +132,10 @@ this.$picker.find('nav .tab') .click( $.proxy(this.emojiCategoryClicked, this) ); + // Click event for recent tab + this.$picker.find('nav div[data-tab=recent]') + .click( $.proxy(this.emojiRecentClicked, this) ); + this.$picker.click( $.proxy(this.pickerClicked, this) ); $(document.body).click( $.proxy(this.clickOutside, this) ); @@ -207,6 +212,7 @@ var emojiUnicode = toUnicode(findEmoji(emojiShortcode).unicode); insertAtCaret(this.element, emojiUnicode); + addToLocalStorage(emojiShortcode); // trigger change event on input $(this.element).trigger("keyup"); @@ -230,6 +236,15 @@ this.$picker.find('section.' + section).removeClass('hidden');//.show(); }, + emojiRecentClicked: function(e) { + $('section.recent').empty(); + + var recentlyUsedEmojis = JSON.parse(localStorage.emojis); + for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { + $('section.recent').append('
'); + } + }, + pickerClicked: function(e) { e.stopPropagation(); }, @@ -284,6 +299,7 @@ 'undefined': 'thing' } var items = {}; + var localStorageSupport = (typeof(Storage) !== 'undefined') ? true : false; // Re-Sort Emoji table $.each($.fn.emojiPicker.emojis, function(i, emoji) { @@ -294,10 +310,17 @@ nodes.push('
'); nodes.push(''); + + // Recent Section, if localstorage support + if (localStorageSupport) { + nodes.push('
'); + + var recentlyUsedEmojis = JSON.parse(localStorage.emojis); + for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { + nodes.push('
'); + } + nodes.push('
'); + } + for (var i = 0; i < categories_length; i++) { nodes.push('
'); var category_length = items[ categories[i].name ].length; for (var j = 0; j < category_length; j++) { @@ -361,6 +396,23 @@ return String.fromCodePoint.apply(null, codes); } + function addToLocalStorage(emoji) { + var recentlyUsedEmojis = JSON.parse(localStorage.emojis); + + // If already in recently used, move to front + var index = recentlyUsedEmojis.indexOf(emoji); + if (index > -1) { + recentlyUsedEmojis.splice(index, 1); + } + recentlyUsedEmojis.push(emoji); + + if (recentlyUsedEmojis.length > defaults.recentCount) { + recentlyUsedEmojis.shift(); + } + + localStorage.emojis = JSON.stringify(recentlyUsedEmojis); + } + if (!String.fromCodePoint) { // ES6 Unicode Shims 0.1 , © 2012 Steven Levithan http://slevithan.com/ , MIT License String.fromCodePoint = function fromCodePoint () { From bdcf26c78a46465d2e9ef45228471d4e359f4dca Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Tue, 29 Dec 2015 15:52:36 -0800 Subject: [PATCH 10/51] Hover state for emojis, nicer tab styling. --- css/jquery.emojipicker.css | 13 ++++++++----- js/jquery.emojipicker.js | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index 0eb74f7..6c289e9 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -11,10 +11,13 @@ .emojiPicker span.emoji {width:1.3em; height:1.3em; display:inline-block; position:relative; overflow:hidden; text-indent:-9999px; vertical-align:middle;} .emojiPicker .hidden {display:none;} -.emojiPicker nav {position:relative; z-index:0; background-color:#f2f2f2; border-top-left-radius:4px; border-top-right-radius:4px;} -.emojiPicker nav div.tab {display:inline-block; margin:2% 1% 0 1%; padding:2% 2% 1% 2%; border-top-left-radius:4px; border-top-right-radius:4px; cursor:pointer;} -.emojiPicker nav div.tab.active {background-color:#fff; box-shadow:0 0 3px #ccc;} +.emojiPicker nav {display:flex; position:relative; z-index:0; background-color:#f2f2f2; border-top-left-radius:4px; border-top-right-radius:4px; border-bottom:1px solid #ddd;} +.emojiPicker nav div.tab {position:relative; flex-grow:1; top:1px; display:inline-block; margin:2% 0 0 0; padding:2% 2% 1% 2%; text-align:center; border-top-left-radius:4px; border-top-right-radius:4px; cursor:pointer;} +.emojiPicker nav div.tab.active {background-color:#fff; box-shadow:0 0 3px #ccc; border:1px solid #ddd; border-bottom:none;} +.emojiPicker nav div.tab:first-of-type {margin-left:2%;} -.emojiPicker section {overflow:scroll; position:relative; z-index:10; background:#fff;} -.emojiPicker section div {width:40px; float:left; margin:3%;} +.emojiPicker section {overflow:scroll; position:relative; padding-top:1%; z-index:10; background:#fff;} +.emojiPicker section div {width:40px; float:left; margin:1%;} .emojiPicker section div:hover {cursor:pointer;} +.emojiPicker section em {display:inline-block; padding:2%; border-radius:4px;} +.emojiPicker section em:hover {background-color:#eee;} diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 8c66a8e..c067820 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -241,7 +241,7 @@ var recentlyUsedEmojis = JSON.parse(localStorage.emojis); for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { - $('section.recent').append('
'); + $('section.recent').append('
'); } }, @@ -335,7 +335,7 @@ var recentlyUsedEmojis = JSON.parse(localStorage.emojis); for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { - nodes.push('
'); + nodes.push('
'); } nodes.push('
'); } @@ -348,7 +348,7 @@ var category_length = items[ categories[i].name ].length; for (var j = 0; j < category_length; j++) { var emoji = items[ categories[i].name ][ j ]; - nodes.push('
'); + nodes.push('
'); } nodes.push('
'); } From 136d6e961763812c203acd0d938359a9609163a7 Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Tue, 29 Dec 2015 16:20:47 -0800 Subject: [PATCH 11/51] Added sexy hover state for emojis, added shortcode section to bottom of picker. --- css/jquery.emojipicker.css | 4 ++++ js/jquery.emojipicker.js | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index 6c289e9..1879942 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -21,3 +21,7 @@ .emojiPicker section div:hover {cursor:pointer;} .emojiPicker section em {display:inline-block; padding:2%; border-radius:4px;} .emojiPicker section em:hover {background-color:#eee;} + +.emojiPicker .shortcode {height:40px; background:#eee; border-top:1px solid #ddd; vertical-align:middle;} +.emojiPicker .shortcode .emoji {position:relative; top:4px; left:8px; width:1.9em; height:1.9em; margin-right:20px;} +.emojiPicker .shortcode em {position:relative; top:-5px; font-family:Helvetica, Arial, sans-serif; color:#555; font-size:12px; font-weight:900; font-style:normal;} diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index c067820..457a389 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -128,6 +128,12 @@ this.$picker.find('section div') .click( $.proxy(this.emojiClicked, this) ); + // Hover event for emoji + this.$picker.find('section em') + .mouseover( $.proxy(this.emojiMouseover, this) ); + this.$picker.find('section em') + .mouseout( $.proxy(this.emojiMouseout, this) ); + // Click event for active tab this.$picker.find('nav .tab') .click( $.proxy(this.emojiCategoryClicked, this) ); @@ -218,6 +224,15 @@ $(this.element).trigger("keyup"); }, + emojiMouseover: function(e) { + var emojiShortcode = $(e.target).parent().find('.emoji').attr('class').split('emoji-')[1]; + $(e.target).parents('.emojiPicker').find('.shortcode').html('
' + emojiShortcode + ''); + }, + + emojiMouseout: function(e) { + $(e.target).parents('.emojiPicker').find('.shortcode').empty(); + }, + emojiCategoryClicked: function(e) { var section = ''; @@ -352,6 +367,12 @@ } nodes.push(''); } + + // Shortcode + nodes.push('
'); + + + nodes.push(''); return nodes.join("\n"); } From 2aa5ecc678dfb2899833c73ac737a7ae88fc1fc0 Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Tue, 29 Dec 2015 17:48:47 -0800 Subject: [PATCH 12/51] Adds search feature. --- css/jquery.emojipicker.css | 14 +++++++++--- js/jquery.emojipicker.js | 46 ++++++++++++++++++++++++++++++++++---- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index 1879942..b84acb2 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -6,12 +6,12 @@ .emojiPickerIconWrap .yellow {background:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iMjc2Ljg5MXB4IiBoZWlnaHQ9IjI3Ni44OTFweCIgdmlld0JveD0iMCAwIDI3Ni44OTEgMjc2Ljg5MSIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjc2Ljg5MSAyNzYuODkxIg0KCSB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxjaXJjbGUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRUJDMjAwIiBzdHJva2Utd2lkdGg9IjExIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGN4PSIxMzguNDQ1IiBjeT0iMTM4LjQ0NSIgcj0iMTMyLjk0NSIvPg0KPGNpcmNsZSBmaWxsPSIjRUJDMjAwIiBjeD0iNjguMTIiIGN5PSIxMjUuMzk1IiByPSIxNi41MDciLz4NCjxjaXJjbGUgZmlsbD0iI0VCQzIwMCIgY3g9IjIwOC42MTciIGN5PSIxMjUuMzk1IiByPSIxNi41MDgiLz4NCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0VCQzIwMCIgc3Ryb2tlLXdpZHRoPSIxMyIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGQ9Ik02OC4xMiwxODIuMDM0DQoJYzAsMCw2OS43OTMsNzAuNzA0LDE0MC40OTgsMCIvPg0KPC9zdmc+DQo=') center center no-repeat; background-size:60%;} .emojiPickerIconWrap .grey, .emojiPickerIconWrap .gray {background:url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhLS0gR2VuZXJhdG9yOiBBZG9iZSBJbGx1c3RyYXRvciAxNi4wLjAsIFNWRyBFeHBvcnQgUGx1Zy1JbiAuIFNWRyBWZXJzaW9uOiA2LjAwIEJ1aWxkIDApICAtLT4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4Ig0KCSB3aWR0aD0iMjc2Ljg5MXB4IiBoZWlnaHQ9IjI3Ni44OTFweCIgdmlld0JveD0iMCAwIDI3Ni44OTEgMjc2Ljg5MSIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgMjc2Ljg5MSAyNzYuODkxIg0KCSB4bWw6c3BhY2U9InByZXNlcnZlIj4NCjxjaXJjbGUgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjRUJDMjAwIiBzdHJva2Utd2lkdGg9IjExIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGN4PSIxMzguNDQ1IiBjeT0iMTM4LjQ0NSIgcj0iMTMyLjk0NSIvPg0KPGNpcmNsZSBmaWxsPSIjRUJDMjAwIiBjeD0iNjguMTIiIGN5PSIxMjUuMzk1IiByPSIxNi41MDciLz4NCjxjaXJjbGUgZmlsbD0iI0VCQzIwMCIgY3g9IjIwOC42MTciIGN5PSIxMjUuMzk1IiByPSIxNi41MDgiLz4NCjxwYXRoIGZpbGw9Im5vbmUiIHN0cm9rZT0iI0VCQzIwMCIgc3Ryb2tlLXdpZHRoPSIxMyIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiIGQ9Ik02OC4xMiwxODIuMDM0DQoJYzAsMCw2OS43OTMsNzAuNzA0LDE0MC40OTgsMCIvPg0KPC9zdmc+DQo=') center center no-repeat; background-size:60%;} -.emojiPicker {display:none; position:absolute; outline:none; border:none; box-shadow:0 0 7px #555; border-top-left-radius:4px; border-top-right-radius:4px;} +.emojiPicker {display:none; position:absolute; outline:none; border:none; box-shadow:0 0 7px #555; border-top-left-radius:4px; border-top-right-radius:4px; font-family:Helvetica, Arial, sans-serif; } .emojiPicker div.emoji {width:1.3em; height:1.3em; position:relative; display:inline-block;} .emojiPicker span.emoji {width:1.3em; height:1.3em; display:inline-block; position:relative; overflow:hidden; text-indent:-9999px; vertical-align:middle;} .emojiPicker .hidden {display:none;} -.emojiPicker nav {display:flex; position:relative; z-index:0; background-color:#f2f2f2; border-top-left-radius:4px; border-top-right-radius:4px; border-bottom:1px solid #ddd;} +.emojiPicker nav {display:flex; position:relative; z-index:0; background-color:#eee; border-top-left-radius:4px; border-top-right-radius:4px; border-bottom:1px solid #ddd;} .emojiPicker nav div.tab {position:relative; flex-grow:1; top:1px; display:inline-block; margin:2% 0 0 0; padding:2% 2% 1% 2%; text-align:center; border-top-left-radius:4px; border-top-right-radius:4px; cursor:pointer;} .emojiPicker nav div.tab.active {background-color:#fff; box-shadow:0 0 3px #ccc; border:1px solid #ddd; border-bottom:none;} .emojiPicker nav div.tab:first-of-type {margin-left:2%;} @@ -21,7 +21,15 @@ .emojiPicker section div:hover {cursor:pointer;} .emojiPicker section em {display:inline-block; padding:2%; border-radius:4px;} .emojiPicker section em:hover {background-color:#eee;} +.emojiPicker section.recent .search {width:95%; padding:0 1%;} +.emojiPicker section.recent .search input { display:block; width:94%; height:20px; padding:1% 3%; font-size:12px; border:1px solid #ddd; border-radius:4px;} +.emojiPicker section.recent h1 {clear:both; margin:0; padding:2%; color:#444; font-size:14px;} + +.emojiPicker section.recent .recentEmojis {width:98%;} +.emojiPicker section.recent .searchEmojis {width:98%; display:none;} + +.emojiPicker section.recent .wrap {width:100%;} .emojiPicker .shortcode {height:40px; background:#eee; border-top:1px solid #ddd; vertical-align:middle;} .emojiPicker .shortcode .emoji {position:relative; top:4px; left:8px; width:1.9em; height:1.9em; margin-right:20px;} -.emojiPicker .shortcode em {position:relative; top:-5px; font-family:Helvetica, Arial, sans-serif; color:#555; font-size:12px; font-weight:900; font-style:normal;} +.emojiPicker .shortcode em {position:relative; top:-5px; color:#444; font-size:12px; font-weight:900; font-style:normal;} diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 457a389..c90b50e 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -144,6 +144,10 @@ this.$picker.click( $.proxy(this.pickerClicked, this) ); + // Key events for search + this.$picker.find('section.recent .search input') + .keyup( $.proxy(this.searchCharEntered, this) ); + $(document.body).click( $.proxy(this.clickOutside, this) ); // Resize events forces a reposition, which may or may not actually be required @@ -208,6 +212,9 @@ iconClicked : function(e) { if ( this.$picker.is(':hidden') ) { this.show(); + if( this.$picker.find('.search input').length > 0 ) { + this.$picker.find('.search input').focus(); + } } else { this.hide(); } @@ -252,7 +259,8 @@ }, emojiRecentClicked: function(e) { - $('section.recent').empty(); + console.log('asdlfkjalskdjf'); + $('section.recent').find('.emoji').remove(); var recentlyUsedEmojis = JSON.parse(localStorage.emojis); for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { @@ -268,8 +276,34 @@ if ( this.active ) { this.hide(); } - } + }, + searchCharEntered: function(e) { + var searchTerm = $(e.target).val(); + var recentSection = $(e.target).parents('section.recent'); + var searchEmojis = recentSection.find('.searchEmojis'); + var recentEmojis = recentSection.find('.recentEmojis'); + + if (searchTerm.length > 0) { + recentEmojis.hide(); + searchEmojis.show(); + + var results = []; + var searchEmojiWrap = searchEmojis.find('.wrap'); + searchEmojiWrap.empty(); + + $.each($.fn.emojiPicker.emojis, function(i, emoji) { + var shortcode = emoji.shortcode; + if ( shortcode.indexOf(searchTerm) > -1 ) { + results.push('
'); + } + }); + searchEmojiWrap.html(results.join('')); + } else { + recentEmojis.show(); + searchEmojis.hide(); + } + } }); $.fn[ pluginName ] = function ( options ) { @@ -347,11 +381,17 @@ // Recent Section, if localstorage support if (localStorageSupport) { nodes.push('
'); + nodes.push(''); + nodes.push('

Recently Used

'); var recentlyUsedEmojis = JSON.parse(localStorage.emojis); for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { nodes.push('
'); } + nodes.push('
'); + + nodes.push('

Search Results

') + nodes.push('
'); } @@ -371,8 +411,6 @@ // Shortcode nodes.push('
'); - - nodes.push(''); return nodes.join("\n"); } From 6ac780c3afd2c5efaabaa304c57023370df08153 Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Mon, 4 Jan 2016 10:38:13 -0800 Subject: [PATCH 13/51] Implemented scroll functionality instead of separate tabs for sections. :frog: --- css/jquery.emojipicker.css | 20 +++++----- js/jquery.emojipicker.js | 78 ++++++++++++++++++++++---------------- 2 files changed, 55 insertions(+), 43 deletions(-) diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index b84acb2..9dd673e 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -16,19 +16,17 @@ .emojiPicker nav div.tab.active {background-color:#fff; box-shadow:0 0 3px #ccc; border:1px solid #ddd; border-bottom:none;} .emojiPicker nav div.tab:first-of-type {margin-left:2%;} -.emojiPicker section {overflow:scroll; position:relative; padding-top:1%; z-index:10; background:#fff;} -.emojiPicker section div {width:40px; float:left; margin:1%;} -.emojiPicker section div:hover {cursor:pointer;} -.emojiPicker section em {display:inline-block; padding:2%; border-radius:4px;} +.emojiPicker .sections {overflow:scroll; position:relative; background:#fff; z-index:10;} +.emojiPicker section {width:100%; padding-top:1%;} +.emojiPicker section h1 {clear:both; margin:0; padding:2%; color:#444; font-size:14px;} +.emojiPicker section em {float:left; display:inline-block; padding:2%; border-radius:4px;} .emojiPicker section em:hover {background-color:#eee;} -.emojiPicker section.recent .search {width:95%; padding:0 1%;} -.emojiPicker section.recent .search input { display:block; width:94%; height:20px; padding:1% 3%; font-size:12px; border:1px solid #ddd; border-radius:4px;} -.emojiPicker section.recent h1 {clear:both; margin:0; padding:2%; color:#444; font-size:14px;} +.emojiPicker section em div {width:40px; margin:1%;} +.emojiPicker section em div:hover {cursor:pointer;} -.emojiPicker section.recent .recentEmojis {width:98%;} -.emojiPicker section.recent .searchEmojis {width:98%; display:none;} - -.emojiPicker section.recent .wrap {width:100%;} +.emojiPicker section .wrap {width:100%;} +.emojiPicker section.search .wrap {padding-top:1%;} +.emojiPicker section.search input {display:block; width:90%; height:20px; margin:2%; padding:1% 3%; font-size:12px; border:1px solid #ddd; border-radius:4px;} .emojiPicker .shortcode {height:40px; background:#eee; border-top:1px solid #ddd; vertical-align:middle;} .emojiPicker .shortcode .emoji {position:relative; top:4px; left:8px; width:1.9em; height:1.9em; margin-right:20px;} diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index c90b50e..e3e7bdf 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -8,7 +8,7 @@ fadeTime: 100, iconColor: 'black', iconBackgroundColor: '#eee', - recentCount: 28, + recentCount: 36, container: 'body', button: true }; @@ -19,6 +19,8 @@ MAX_HEIGHT = 350, MAX_ICON_HEIGHT = 50; + var prevSectionPosition = 0; + function Plugin( element, options ) { this.element = element; @@ -105,7 +107,7 @@ .css('z-index',10000); // Picker height - this.$picker.find('section') + this.$picker.find('.sections') .height(parseInt(this.settings.height) - 40); // 40 is height of the tabs // Tab size based on width @@ -125,7 +127,7 @@ } // Click event for emoji - this.$picker.find('section div') + this.$picker.find('section em') .click( $.proxy(this.emojiClicked, this) ); // Hover event for emoji @@ -145,7 +147,7 @@ this.$picker.click( $.proxy(this.pickerClicked, this) ); // Key events for search - this.$picker.find('section.recent .search input') + this.$picker.find('section.search input') .keyup( $.proxy(this.searchCharEntered, this) ); $(document.body).click( $.proxy(this.clickOutside, this) ); @@ -221,7 +223,7 @@ }, emojiClicked: function(e) { - var emojiShortcode = $(e.target).attr('class').split('emoji-')[1]; + var emojiShortcode = $(e.target).parent().find('.emoji').attr('class').split('emoji-')[1]; var emojiUnicode = toUnicode(findEmoji(emojiShortcode).unicode); insertAtCaret(this.element, emojiUnicode); @@ -248,24 +250,34 @@ if ($(e.target).parent().hasClass('tab')) { section = $(e.target).parent().attr('data-tab'); $(e.target).parent('.tab').addClass('active'); - } else { + } + else { section = $(e.target).attr('data-tab'); $(e.target).addClass('active'); } - // Update section - this.$picker.find('section').addClass('hidden');//.hide(); - this.$picker.find('section.' + section).removeClass('hidden');//.show(); + // Scroll to section + var scrollHeight = $('.sections')[0].scrollHeight; + var scrollTo = this.$picker.find('section.' + section + ' h1').position().top; + + if (scrollTo == 0) return; // Already on the active section + $('.sections').animate({ + scrollTop: scrollTo + prevSectionPosition + }, 250); + + prevSectionPosition = scrollTo + prevSectionPosition; }, emojiRecentClicked: function(e) { - console.log('asdlfkjalskdjf'); - $('section.recent').find('.emoji').remove(); + var emojiWrap = $('section.recent .recentEmojis .wrap'); + emojiWrap.find('em').remove(); var recentlyUsedEmojis = JSON.parse(localStorage.emojis); + var emojiMarkup = []; for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { - $('section.recent').append('
'); + emojiMarkup.push('
'); } + emojiWrap.append(emojiMarkup.join('')); }, pickerClicked: function(e) { @@ -280,17 +292,17 @@ searchCharEntered: function(e) { var searchTerm = $(e.target).val(); - var recentSection = $(e.target).parents('section.recent'); - var searchEmojis = recentSection.find('.searchEmojis'); - var recentEmojis = recentSection.find('.recentEmojis'); + var searchEmojis = $(e.target).parents('.sections').find('section.search'); + var searchEmojiWrap = searchEmojis.find('.wrap'); + var sections = $(e.target).parents('.sections').find('section'); if (searchTerm.length > 0) { - recentEmojis.hide(); + sections.hide(); searchEmojis.show(); + searchEmojiWrap.show(); var results = []; - var searchEmojiWrap = searchEmojis.find('.wrap'); - searchEmojiWrap.empty(); + searchEmojiWrap.find('em').remove(); $.each($.fn.emojiPicker.emojis, function(i, emoji) { var shortcode = emoji.shortcode; @@ -298,10 +310,10 @@ results.push('
'); } }); - searchEmojiWrap.html(results.join('')); + searchEmojiWrap.append(results.join('')); } else { - recentEmojis.show(); - searchEmojis.hide(); + sections.show(); + searchEmojiWrap.hide(); } } }); @@ -377,29 +389,30 @@ '">'); } nodes.push(''); + nodes.push('
'); + + // Search + nodes.push(''); // Recent Section, if localstorage support if (localStorageSupport) { + var recentlyUsedEmojis = JSON.parse(localStorage.emojis); nodes.push('
'); - nodes.push(''); - nodes.push('

Recently Used

'); + nodes.push('

Recently Used

'); - var recentlyUsedEmojis = JSON.parse(localStorage.emojis); for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { nodes.push('
'); } - nodes.push('
'); - - nodes.push('

Search Results

') - + nodes.push('
'); nodes.push('
'); } for (var i = 0; i < categories_length; i++) { - nodes.push('
'); + nodes.push('
'); + nodes.push('

' + categories[i].name + '

'); var category_length = items[ categories[i].name ].length; for (var j = 0; j < category_length; j++) { var emoji = items[ categories[i].name ][ j ]; @@ -407,6 +420,7 @@ } nodes.push('
'); } + nodes.push('
'); // Shortcode nodes.push('
'); From 563d2fa3e7ba9b617132d30c30a3f6d8bf6dd731 Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Mon, 4 Jan 2016 10:40:56 -0800 Subject: [PATCH 14/51] Style for category names until proper taxonomy is built out. :turtle: --- css/jquery.emojipicker.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index 9dd673e..6773326 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -18,7 +18,7 @@ .emojiPicker .sections {overflow:scroll; position:relative; background:#fff; z-index:10;} .emojiPicker section {width:100%; padding-top:1%;} -.emojiPicker section h1 {clear:both; margin:0; padding:2%; color:#444; font-size:14px;} +.emojiPicker section h1 {clear:both; margin:0; padding:2%; color:#444; font-size:14px; text-transform:capitalize;} .emojiPicker section em {float:left; display:inline-block; padding:2%; border-radius:4px;} .emojiPicker section em:hover {background-color:#eee;} .emojiPicker section em div {width:40px; margin:1%;} From 83811a631f0bec54057825d14c813d470cb75be6 Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Mon, 4 Jan 2016 12:24:12 -0800 Subject: [PATCH 15/51] Updated documentation. --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c9ee9fa..f4a67e7 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,11 @@ The color of the smiley image that appears on the picker button. Acceptable valu ### iconBackgroundColor (string) ### The background color of the picker button. Any hex value is acceptable. Defaults to '#eee' if no iconBackgroundColor is specified. +### recentCount (int) ### +The number of emojis that should show in the 'Recently Used' section. Defaults to 36 if no recentCount is specified. + +Note: 'Recently Used' will only show for the user if their browser supports HTML5 Local Storage. + ### button (boolean) ### Whether to show the emoji button on the input or not. Defaults to true. If you hide the button, you will probably need to trigger the emoji entry manually (see below). @@ -120,8 +125,8 @@ The jQuery Emoji Picker was developed by the team at [Wedgies](http://www.wedgie Wedgies is a digital survey platform that gives media, journalists and brands in-line survey capabilities inside social media, their website, and their apps — where they can collect millions of opinions from their readers and users. Wedgies is the leading social survey platform that enables publishers to collect survey respondents directly within social media streams. -Wedgies, a darling of Tony Hsieh’s Las Vegas’ Vegas Tech Fund, is backed by an all-star list of investors including Greycroft, Advancit Capital, MESA Ventures, Knight Foundation, kbs+ Ventures, Battle Born Ventures, Twilio, 500 Startups and SV Angel. +Wedgies is backed by an all-star list of investors including Vegas Tech Fund, Greycroft, Advancit Capital, MESA Ventures, Knight Foundation, kbs+ Ventures, Battle Born Ventures, Twilio, 500 Startups and SV Angel. -Wedgies founding team consists of top talent in developer tools and community management with experience that includes Zappos.com, Overstock.com, and Backcountry.com. +Wedgies' founding team consists of top talent in developer tools and community management with experience that includes Zappos.com, Overstock.com, and Backcountry.com. [![Built with Wedgies](https://d3v9r9uda02hel.cloudfront.net/production/1.55.17/img/built-with-wedgies.png)](http://wedgies.com) From f782cd0c34d88b57ad17cdc615ae110c70337bd7 Mon Sep 17 00:00:00 2001 From: Zach K Date: Tue, 5 Jan 2016 15:35:36 -0800 Subject: [PATCH 16/51] Fix json parse errors when localstorage is empty. --- js/jquery.emojipicker.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index e3e7bdf..86ee061 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -250,7 +250,7 @@ if ($(e.target).parent().hasClass('tab')) { section = $(e.target).parent().attr('data-tab'); $(e.target).parent('.tab').addClass('active'); - } + } else { section = $(e.target).attr('data-tab'); $(e.target).addClass('active'); @@ -305,7 +305,7 @@ searchEmojiWrap.find('em').remove(); $.each($.fn.emojiPicker.emojis, function(i, emoji) { - var shortcode = emoji.shortcode; + var shortcode = emoji.shortcode; if ( shortcode.indexOf(searchTerm) > -1 ) { results.push('
'); } @@ -398,7 +398,7 @@ nodes.push(''); // Recent Section, if localstorage support - if (localStorageSupport) { + if (localStorageSupport && localStorage.emojis) { var recentlyUsedEmojis = JSON.parse(localStorage.emojis); nodes.push('
'); nodes.push('

Recently Used

'); @@ -470,7 +470,10 @@ } function addToLocalStorage(emoji) { - var recentlyUsedEmojis = JSON.parse(localStorage.emojis); + var recentlyUsedEmojis = []; + if (localStorage.emojis) { + recentlyUsedEmojis = JSON.parse(localStorage.emojis); + } // If already in recently used, move to front var index = recentlyUsedEmojis.indexOf(emoji); From 150181e4234d87f57960c8267c68746e9d4268d8 Mon Sep 17 00:00:00 2001 From: Zach K Date: Tue, 5 Jan 2016 16:00:31 -0800 Subject: [PATCH 17/51] Scroll scroll scroll and scroll some more! :scroll: --- js/jquery.emojipicker.js | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 86ee061..1a081fc 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -19,8 +19,6 @@ MAX_HEIGHT = 350, MAX_ICON_HEIGHT = 50; - var prevSectionPosition = 0; - function Plugin( element, options ) { this.element = element; @@ -256,16 +254,21 @@ $(e.target).addClass('active'); } - // Scroll to section - var scrollHeight = $('.sections')[0].scrollHeight; - var scrollTo = this.$picker.find('section.' + section + ' h1').position().top; + var $section = this.$picker.find('section.' + section); + + var heightOfSectionsHidden = $section.parent().scrollTop(); + var heightOfSectionToPageTop = $section.offset().top; + var heightOfSectionsToPageTop = $section.parent().offset().top; + var heightOfH1Tag = 28; + + var scrollDistance = heightOfSectionsHidden + + heightOfSectionToPageTop + - heightOfSectionsToPageTop + - heightOfH1Tag; - if (scrollTo == 0) return; // Already on the active section $('.sections').animate({ - scrollTop: scrollTo + prevSectionPosition + scrollTop: scrollDistance }, 250); - - prevSectionPosition = scrollTo + prevSectionPosition; }, emojiRecentClicked: function(e) { From 25cd1491711a6d3d307667ae8f0bef39eef9517a Mon Sep 17 00:00:00 2001 From: Zach K Date: Tue, 5 Jan 2016 16:21:31 -0800 Subject: [PATCH 18/51] Fix position issue causing awkward height calculations. --- css/jquery.emojipicker.css | 2 +- js/jquery.emojipicker.js | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index 6773326..4b56675 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -19,7 +19,7 @@ .emojiPicker .sections {overflow:scroll; position:relative; background:#fff; z-index:10;} .emojiPicker section {width:100%; padding-top:1%;} .emojiPicker section h1 {clear:both; margin:0; padding:2%; color:#444; font-size:14px; text-transform:capitalize;} -.emojiPicker section em {float:left; display:inline-block; padding:2%; border-radius:4px;} +.emojiPicker section em {display:inline-block; padding:2%; border-radius:4px;} .emojiPicker section em:hover {background-color:#eee;} .emojiPicker section em div {width:40px; margin:1%;} .emojiPicker section em div:hover {cursor:pointer;} diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 1a081fc..0194f35 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -259,12 +259,10 @@ var heightOfSectionsHidden = $section.parent().scrollTop(); var heightOfSectionToPageTop = $section.offset().top; var heightOfSectionsToPageTop = $section.parent().offset().top; - var heightOfH1Tag = 28; var scrollDistance = heightOfSectionsHidden + heightOfSectionToPageTop - - heightOfSectionsToPageTop - - heightOfH1Tag; + - heightOfSectionsToPageTop; $('.sections').animate({ scrollTop: scrollDistance From fe38e3b61e4e06ceb2e011e10a156aff44cc9733 Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Tue, 5 Jan 2016 16:23:52 -0800 Subject: [PATCH 19/51] Added custom icons to picker tabs. --- css/jquery.emojipicker.css | 13 ++++++++++++- demo.html | 6 +++--- js/jquery.emojipicker.js | 21 +++++++++++---------- js/jquery.emojipicker.tw.js | 26 +++++++++++++------------- 4 files changed, 39 insertions(+), 27 deletions(-) diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index 6773326..4f8a5ac 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -16,9 +16,20 @@ .emojiPicker nav div.tab.active {background-color:#fff; box-shadow:0 0 3px #ccc; border:1px solid #ddd; border-bottom:none;} .emojiPicker nav div.tab:first-of-type {margin-left:2%;} +.emojiPicker nav div.tab .emoji-tab-recent {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} +.emojiPicker nav div.tab .emoji-tab-emotion {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} +.emojiPicker nav div.tab .emoji-tab-nature {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} +.emojiPicker nav div.tab .emoji-tab-food {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} +.emojiPicker nav div.tab .emoji-tab-sport {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} +.emojiPicker nav div.tab .emoji-tab-travel {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} +.emojiPicker nav div.tab .emoji-tab-object {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} +.emojiPicker nav div.tab .emoji-tab-symbol {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} +.emojiPicker nav div.tab .emoji-tab-flag {background:url('data:image/svg+xml;utf8, ') center center no-repeat;} + + .emojiPicker .sections {overflow:scroll; position:relative; background:#fff; z-index:10;} .emojiPicker section {width:100%; padding-top:1%;} -.emojiPicker section h1 {clear:both; margin:0; padding:2%; color:#444; font-size:14px; text-transform:capitalize;} +.emojiPicker section h1 {clear:both; margin:0; padding:2%; color:#444; font-size:14px; text-transform: capitalize;} .emojiPicker section em {float:left; display:inline-block; padding:2%; border-radius:4px;} .emojiPicker section em:hover {background-color:#eee;} .emojiPicker section em div {width:40px; margin:1%;} diff --git a/demo.html b/demo.html index c3f7482..cf9d599 100644 --- a/demo.html +++ b/demo.html @@ -7,8 +7,8 @@ - - + + - - + + - + + ``` -The jQuery Emoji Picker has 3 icon sets to choose from - Apple, Twitter, and Google icons. The Apple icons are used by default. To instead use Twitter or Google icons, replace: +The jQuery Emoji Picker has 3 icon sets to choose from - Apple, Twitter, and Google icons. The Apple icons are used by default. To instead use Twitter or Google icons, replace the stylesheet: ```html - ``` with either Google: ```html - ``` or Twitter: ```html - ``` Initialize the jQuery Emoji Picker by calling `emojiPicker` on an input element with optional parameters, described below: @@ -63,7 +60,7 @@ Initialize the jQuery Emoji Picker by calling `emojiPicker` on an input element ```javascript $('.question').emojiPicker({ height: '300px', - width: '450px' + width: '450px' }); ``` From 5f9af3c57204730615b904dc2b7bda6eaf37db7b Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Thu, 7 Jan 2016 20:29:15 -0800 Subject: [PATCH 31/51] Adds hover event to tabs and displays category title. :sunflower: --- css/jquery.emojipicker.css | 3 ++ js/jquery.emojipicker.js | 56 +++++++++++++++++++++++++++----------- 2 files changed, 43 insertions(+), 16 deletions(-) diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index 0cd811a..554846e 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -13,6 +13,7 @@ .emojiPicker nav {display:flex; position:relative; z-index:0; background-color:#eee; border-top-left-radius:4px; border-top-right-radius:4px; border-bottom:1px solid #ddd;} .emojiPicker nav div.tab {position:relative; flex-grow:1; top:1px; display:inline-block; margin:2% 0 0 0; padding:2% 2% 1% 2%; text-align:center; border:1px solid #eee; border-top-left-radius:4px; border-top-right-radius:4px; cursor:pointer;} +.emojiPicker nav div.tab:hover {background-color:#ddd;} .emojiPicker nav div.tab.active {background-color:#fff; box-shadow:0 0 3px #ccc; border:1px solid #ddd; border-bottom:none;} .emojiPicker nav div.tab:first-of-type {margin-left:1%;} .emojiPicker nav div.tab:last-of-type {margin-right:1%;} @@ -43,3 +44,5 @@ .emojiPicker .shortcode {height:40px; background:#eee; border-top:1px solid #ddd; vertical-align:middle;} .emojiPicker .shortcode .emoji {position:relative; top:4px; left:8px; width:1.9em; height:1.9em; margin-right:20px;} .emojiPicker .shortcode em {position:relative; top:-5px; color:#444; font-size:12px; font-weight:900; font-style:normal;} +.emojiPicker .shortcode em.tabTitle {position:relative; top:10px; left:8px; font-size:14px;} +.emojiPicker .shortcode em.tabTitle .count {font-size:12px; font-weight:500;} diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 43771f8..d429fc0 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -20,6 +20,17 @@ MAX_HEIGHT = 350, MAX_ICON_HEIGHT = 50; + var categories = [ + { name: 'people', label: 'People' }, + { name: 'nature', label: 'Nature' }, + { name: 'food', label: 'Food' }, + { name: 'activity', label: 'Activities' }, + { name: 'travel', label: 'Travel & Places' }, + { name: 'object', label: 'Objects' }, + { name: 'symbol', label: 'Symbols' }, + { name: 'flag', label: 'Flags' } + ]; + function Plugin( element, options ) { this.element = element; @@ -134,7 +145,9 @@ // Click event for active tab this.$picker.find('nav .tab') - .click( $.proxy(this.emojiCategoryClicked, this) ); + .click( $.proxy(this.emojiCategoryClicked, this) ) + .mouseover( $.proxy(this.emojiTabMouseover, this) ) + .mouseout( $.proxy(this.emojiMouseout, this) ); // Scroll event for active tab this.$picker.find('.sections') @@ -275,6 +288,26 @@ }, + emojiTabMouseover: function(e) { + var section = ''; + if ($(e.target).parent().hasClass('tab')) { + section = $(e.target).parent().attr('data-tab'); + } + else { + section = $(e.target).attr('data-tab'); + } + + var categoryTitle = ''; + for (var i = 0; i < categories.length; i++) { + if (categories[i].name == section) { categoryTitle = categories[i].label; } + } + if (categoryTitle == '') { categoryTitle = 'Recently Used'; } + + var categoryCount = $('section.' + section).attr('data-count'); + var categoryHtml = '' + categoryTitle + ' (' + categoryCount + ' emojis)'; + $(e.target).parents('.emojiPicker').find('.shortcode').html(categoryHtml); + }, + emojiScroll: function(e) { var sections = $('section'); $.each(sections, function(key, value) { @@ -365,16 +398,6 @@ function getPickerHTML() { var nodes = []; - var categories = [ - { name: 'people', label: 'People' }, - { name: 'nature', label: 'Nature' }, - { name: 'food', label: 'Food' }, - { name: 'activity', label: 'Activity' }, - { name: 'travel', label: 'Travel & Places' }, - { name: 'object', label: 'Objects' }, - { name: 'symbol', label: 'Symbols' }, - { name: 'flag', label: 'Flags' } - ]; var aliases = { 'undefined': 'object' } @@ -396,7 +419,7 @@ nodes.push('
'); } - // Emoji categories + // Emoji category tabs var categories_length = categories.length; for (var i = 0; i < categories_length; i++) { nodes.push('
'); + nodes.push('
'); nodes.push('

Recently Used

'); for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { @@ -428,10 +451,11 @@ nodes.push('
'); } + // Emoji sections for (var i = 0; i < categories_length; i++) { - nodes.push('
'); - nodes.push('

' + categories[i].label + '

'); var category_length = items[ categories[i].name ].length; + nodes.push('
'); + nodes.push('

' + categories[i].label + '

'); for (var j = 0; j < category_length; j++) { var emoji = items[ categories[i].name ][ j ]; nodes.push(''); @@ -440,7 +464,7 @@ } nodes.push('
'); - // Shortcode + // Shortcode section nodes.push('
'); nodes.push('
'); From 7975e043c4da6b5222901c505c28b6ce162d90cf Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Fri, 8 Jan 2016 16:18:58 -0800 Subject: [PATCH 32/51] Emoji of the day for blank shortcode field. Hover style for tabs. :doughnut: --- README.md | 2 +- css/jquery.emojipicker.css | 5 +++++ js/jquery.emojipicker.js | 28 +++++++++++++++++++++++----- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 141b75d..e4fa034 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ $('.question').emojiPicker({ ## Parameters ## ### width (int) ### -The width of the picker in pixels. Must be between 200-600px. Defaults to 200px if no width is specified. +The width of the picker in pixels. Must be between 280-600px. Defaults to 280px if no width is specified. ### height (int) ### The height of the picker in pixels. Must be between 100-350px. Defaults to 250px if no height is specified. diff --git a/css/jquery.emojipicker.css b/css/jquery.emojipicker.css index 554846e..cb3e1cf 100644 --- a/css/jquery.emojipicker.css +++ b/css/jquery.emojipicker.css @@ -42,7 +42,12 @@ .emojiPicker section.search input {display:block; width:96%; height:28px; margin:2%; padding:1%; font-size:12px; border:1px solid #ddd; border-radius:4px;} .emojiPicker .shortcode {height:40px; background:#eee; border-top:1px solid #ddd; vertical-align:middle;} +.emojiPicker .shortcode .info {display:none;} .emojiPicker .shortcode .emoji {position:relative; top:4px; left:8px; width:1.9em; height:1.9em; margin-right:20px;} .emojiPicker .shortcode em {position:relative; top:-5px; color:#444; font-size:12px; font-weight:900; font-style:normal;} .emojiPicker .shortcode em.tabTitle {position:relative; top:10px; left:8px; font-size:14px;} .emojiPicker .shortcode em.tabTitle .count {font-size:12px; font-weight:500;} +.emojiPicker .shortcode .random .tabTitle {color:#7d7d7d; font-size:12px;} +.emojiPicker .shortcode .eod {float:right; padding:8px 10px 0 0; max-width:200px;} +.emojiPicker .shortcode .eod .emoji {top:-10px; left:0; margin-right:10px;} +.emojiPicker .shortcode .eod .emojiName {max-width:70%; padding:5px 0 0 0; font-size:10px; font-weight:normal;} diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index d429fc0..4f83367 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -159,6 +159,8 @@ this.$picker.find('section.search input') .on('keyup search', $.proxy(this.searchCharEntered, this) ); + // Shortcode hover + this.$picker.find('.shortcode').mouseover(function(e) { e.stopPropagation(); }); $(document.body).click( $.proxy(this.clickOutside, this) ); @@ -246,11 +248,15 @@ emojiMouseover: function(e) { var emojiShortcode = $(e.target).parent().find('.emoji').attr('class').split('emoji-')[1]; - $(e.target).parents('.emojiPicker').find('.shortcode').html('
' + emojiShortcode + ''); + var $shortcode = $(e.target).parents('.emojiPicker').find('.shortcode'); + $shortcode.find('.random').hide(); + $shortcode.find('.info').show().html('
' + emojiShortcode + ''); }, emojiMouseout: function(e) { - $(e.target).parents('.emojiPicker').find('.shortcode').empty(); + $(e.target).parents('.emojiPicker').find('.shortcode .info').empty().hide(); + $(e.target).parents('.emojiPicker').find('.shortcode .random').show(); + }, emojiCategoryClicked: function(e) { @@ -285,7 +291,6 @@ }, 250, function() { that.$picker.find('.sections').on('scroll', $.proxy(that.emojiScroll, that) ); // Enable scroll event }); - }, emojiTabMouseover: function(e) { @@ -305,7 +310,10 @@ var categoryCount = $('section.' + section).attr('data-count'); var categoryHtml = '' + categoryTitle + ' (' + categoryCount + ' emojis)'; - $(e.target).parents('.emojiPicker').find('.shortcode').html(categoryHtml); + + var $shortcode = $(e.target).parents('.emojiPicker').find('.shortcode'); + $shortcode.find('.random').hide(); + $shortcode.find('.info').show().html(categoryHtml); }, emojiScroll: function(e) { @@ -465,12 +473,22 @@ nodes.push('
'); // Shortcode section - nodes.push('
'); + nodes.push('
'); + nodes.push('' + generateEmojiOfDay() + ''); + nodes.push('
'); nodes.push('
'); return nodes.join("\n"); } + function generateEmojiOfDay() { + var emojis = $.fn.emojiPicker.emojis; + var i = Math.floor(Math.random() * (364 - 0) + 0); + var emoji = emojis[i]; + console.log(emoji.name); + return 'Daily Emoji: ' + emoji.name + ''; + } + function findEmoji(emojiShortcode) { var emojis = $.fn.emojiPicker.emojis; for (var i = 0; i < emojis.length; i++) { From d9f2b6537b704cc37bfd2d806b0a81de030dc68f Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Fri, 8 Jan 2016 18:00:40 -0800 Subject: [PATCH 33/51] Fix for when Recently Used doesn't appear to start. :octopus: --- js/jquery.emojipicker.js | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 4f83367..fd19d94 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -256,7 +256,6 @@ emojiMouseout: function(e) { $(e.target).parents('.emojiPicker').find('.shortcode .info').empty().hide(); $(e.target).parents('.emojiPicker').find('.shortcode .random').show(); - }, emojiCategoryClicked: function(e) { @@ -448,9 +447,18 @@ nodes.push('
'); // Recent Section, if localstorage support - if (localStorageSupport && localStorage.emojis) { - var recentlyUsedEmojis = JSON.parse(localStorage.emojis); - nodes.push('
'); + if (localStorageSupport) { + var recentlyUsedEmojis = []; + var recentlyUsedCount = 0; + var displayRecentlyUsed = ' style="display:none;"'; + + if (localStorage.emojis) { + recentlyUsedEmojis = JSON.parse(localStorage.emojis); + recentlyUsedCount = recentlyUsedEmojis.length; + displayRecentlyUsed = ' style="display:block;"'; + } + + nodes.push('
'); nodes.push('

Recently Used

'); for (var i = recentlyUsedEmojis.length-1; i > -1 ; i--) { @@ -485,7 +493,6 @@ var emojis = $.fn.emojiPicker.emojis; var i = Math.floor(Math.random() * (364 - 0) + 0); var emoji = emojis[i]; - console.log(emoji.name); return 'Daily Emoji: ' + emoji.name + ''; } @@ -552,12 +559,29 @@ function updateRecentlyUsed(emoji) { var recentlyUsedEmojis = JSON.parse(localStorage.emojis); var emojis = []; + var recent = $('section.recent'); for (var i = recentlyUsedEmojis.length-1; i >= 0; i--) { emojis.push(''); } + // Fix height as emojis are added + var prevHeight = recent.outerHeight(); $('section.recent .wrap').html(emojis.join('')); + var currentScrollTop = $('.sections').scrollTop(); + var newHeight = recent.outerHeight(); + var newScrollToHeight = 0; + + if (!$('section.recent').is(':visible')) { + recent.show(); + newScrollToHeight = newHeight; + } else if (prevHeight != newHeight) { + newScrollToHeight = newHeight - prevHeight; + } + + $('.sections').animate({ + scrollTop: currentScrollTop + newScrollToHeight + }, 0); } if (!String.fromCodePoint) { From 046a7f0df277f73b13507a0adb54f66c113bf08c Mon Sep 17 00:00:00 2001 From: Pawel Szymczykowski Date: Wed, 13 Jan 2016 10:21:30 -0800 Subject: [PATCH 34/51] Random is more descriptive than Daily --- js/jquery.emojipicker.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index fd19d94..4433584 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -306,10 +306,10 @@ if (categories[i].name == section) { categoryTitle = categories[i].label; } } if (categoryTitle == '') { categoryTitle = 'Recently Used'; } - + var categoryCount = $('section.' + section).attr('data-count'); var categoryHtml = '' + categoryTitle + ' (' + categoryCount + ' emojis)'; - + var $shortcode = $(e.target).parents('.emojiPicker').find('.shortcode'); $shortcode.find('.random').hide(); $shortcode.find('.info').show().html(categoryHtml); @@ -457,7 +457,7 @@ recentlyUsedCount = recentlyUsedEmojis.length; displayRecentlyUsed = ' style="display:block;"'; } - + nodes.push('
'); nodes.push('

Recently Used

'); @@ -489,11 +489,11 @@ return nodes.join("\n"); } - function generateEmojiOfDay() { + function generateEmojiOfDay() { var emojis = $.fn.emojiPicker.emojis; var i = Math.floor(Math.random() * (364 - 0) + 0); var emoji = emojis[i]; - return 'Daily Emoji: ' + emoji.name + ''; + return 'Random Emoji: ' + emoji.name + ''; } function findEmoji(emojiShortcode) { @@ -572,7 +572,7 @@ var newHeight = recent.outerHeight(); var newScrollToHeight = 0; - if (!$('section.recent').is(':visible')) { + if (!$('section.recent').is(':visible')) { recent.show(); newScrollToHeight = newHeight; } else if (prevHeight != newHeight) { From 7a91c5f744ab60c10f85200db580759ad8879986 Mon Sep 17 00:00:00 2001 From: Pawel Szymczykowski Date: Wed, 13 Jan 2016 10:21:53 -0800 Subject: [PATCH 35/51] Release v0.2.0 --- bower.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bower.json b/bower.json index 97b6cae..13ca167 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "jquery-emoji-picker", - "version": "0.1.3", + "version": "0.2.0", "homepage": "https://github.com/wedgies/jquery-emoji-picker", "authors": [ "Wedgies, Inc" diff --git a/package.json b/package.json index 1ed241e..a705d91 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "jquery-emoji-picker", - "version": "0.1.3", + "version": "0.2.0", "description": "Add an emoji picker to any text field", "repository": { "type": "git", From 16ba6311bc1e55938b05f53bcbb192d19656e479 Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Mon, 25 Jan 2016 16:47:10 -0800 Subject: [PATCH 36/51] Return better name of plugin instance. :frog: --- js/jquery.emojipicker.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 4433584..0bfef86 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -31,7 +31,7 @@ { name: 'flag', label: 'Flags' } ]; - function Plugin( element, options ) { + function EmojiPicker( element, options ) { this.element = element; this.$el = $(element); @@ -71,7 +71,7 @@ } - $.extend(Plugin.prototype, { + $.extend(EmojiPicker.prototype, { init: function() { this.active = false; @@ -395,7 +395,7 @@ this.each(function() { // Don't attach to the same element twice if ( !$.data( this, pluginName ) ) { - $.data( this, pluginName, new Plugin( this, options ) ); + $.data( this, pluginName, new EmojiPicker( this, options ) ); } }); return this; From 048e90002bfb98f7d0d6ef1d6456e1400e4c084a Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Mon, 25 Jan 2016 17:37:29 -0800 Subject: [PATCH 37/51] Adds onShow/onHide handlers. :tropical_drink: --- README.md | 22 ++++++++++++++++++++++ js/jquery.emojipicker.js | 10 ++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e4fa034..ea8b91a 100644 --- a/README.md +++ b/README.md @@ -89,6 +89,28 @@ Note: 'Recently Used' will only show for the user if their browser supports HTML ### button (boolean) ### Whether to show the emoji button on the input or not. Defaults to true. If you hide the button, you will probably need to trigger the emoji entry manually (see below). +### onShow (function) ### +Triggered once the emoji picker appears. `picker` (Object), `settings` (Object), and `isActive` (boolean) are returned. Example usage: + +```javascript +$('#question').emojiPicker({ + onShow: function(picker, settings, isActive) { + ... + } +}); +``` + +### onHide (function) ### +Triggered once the emoji picker disappears. `picker` (Object), `settings` (Object), and `isActive` (boolean) are returned. Example usage: + +```javascript +$('#question').emojiPicker({ + onHide: function(picker, settings, isActive) { + ... + } +}); +``` + ## Triggering Emoji Picker Manually ## To trigger the button manually, you can call a jQuery function on the same element you bound it to. diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 0bfef86..096d36a 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -208,6 +208,9 @@ hide: function() { this.$picker.hide(this.settings.fadeTime, 'linear', function() { this.active = false; + if (this.settings.onHide) { + this.settings.onHide(this.$picker); + } }.bind(this)); }, @@ -216,6 +219,9 @@ this.updatePosition(); this.$picker.show(this.settings.fadeTime, 'linear', function() { this.active = true; + if (this.settings.onShow) { + this.settings.onShow(this.$picker); + } }.bind(this)); }, @@ -223,7 +229,7 @@ * EVENTS * ************/ - iconClicked : function(e) { + iconClicked : function() { if ( this.$picker.is(':hidden') ) { this.show(); if( this.$picker.find('.search input').length > 0 ) { @@ -493,7 +499,7 @@ var emojis = $.fn.emojiPicker.emojis; var i = Math.floor(Math.random() * (364 - 0) + 0); var emoji = emojis[i]; - return 'Random Emoji: ' + emoji.name + ''; + return 'Daily Emoji: ' + emoji.name + ''; } function findEmoji(emojiShortcode) { From 43c3cda36d882ac062e7af2a789884260f7575aa Mon Sep 17 00:00:00 2001 From: Jen Wilhelm Date: Mon, 25 Jan 2016 17:39:24 -0800 Subject: [PATCH 38/51] Includes extra parameters. :sake: --- js/jquery.emojipicker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/js/jquery.emojipicker.js b/js/jquery.emojipicker.js index 096d36a..b73ec6e 100644 --- a/js/jquery.emojipicker.js +++ b/js/jquery.emojipicker.js @@ -209,7 +209,7 @@ this.$picker.hide(this.settings.fadeTime, 'linear', function() { this.active = false; if (this.settings.onHide) { - this.settings.onHide(this.$picker); + this.settings.onHide( this.$picker, this.settings, this.active ); } }.bind(this)); }, @@ -220,7 +220,7 @@ this.$picker.show(this.settings.fadeTime, 'linear', function() { this.active = true; if (this.settings.onShow) { - this.settings.onShow(this.$picker); + this.settings.onShow( this.$picker, this.settings, this.active ); } }.bind(this)); }, From 0fdb982e8044862398db0b2d73127488eb8f720b Mon Sep 17 00:00:00 2001 From: childish gambino Date: Thu, 28 Jan 2016 15:15:42 -0800 Subject: [PATCH 39/51] emojiPicker('destroy') --- README.md | 14 +++++++++++++- demo.html | 30 +++++++++++++++++++++--------- js/jquery.emojipicker.js | 16 +++++++++++++++- 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ea8b91a..18249c4 100644 --- a/README.md +++ b/README.md @@ -82,7 +82,7 @@ The color of the smiley image that appears on the picker button. Acceptable valu The background color of the picker button. Any hex value is acceptable. Defaults to '#eee' if no iconBackgroundColor is specified. ### recentCount (int) ### -The number of emojis that should show in the 'Recently Used' section. Defaults to 36 if no recentCount is specified. +The number of emojis that should show in the 'Recently Used' section. Defaults to 36 if no recentCount is specified. Note: 'Recently Used' will only show for the user if their browser supports HTML5 Local Storage. @@ -121,6 +121,18 @@ $('#question').emojiPicker('toggle'); You can see an example of this in the [demo](http://wedgies.github.io/jquery-emoji-picker/demo.html). +## Destroying the Emoji Picker ## + +To remove the the emoji picker html and event listeners, simply call the emoji picker function with the `destroy` option: + +```javascript +$('#question').emojiPicker('destroy'); +``` + +An example of this can be found in the [demo](http://wedgies.github.io/jquery-emoji-picker/demo.html). + + + ## Notes ## jQuery Emoji Picker is disabled for mobile devices, which already support the emoji keyboard. diff --git a/demo.html b/demo.html index 72966f6..bd2a17f 100644 --- a/demo.html +++ b/demo.html @@ -13,12 +13,6 @@