Skip to content

Commit 3114665

Browse files
committed
finished coupling chips and autocomplete
1 parent cd32e16 commit 3114665

File tree

7 files changed

+141
-38
lines changed

7 files changed

+141
-38
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ Bolded styling surrounded by emojis indicates a breaking change.
1414
- changed events to callbacks
1515
- Added max chips option
1616

17+
- Autocomplete
18+
- rewritten with classes
19+
- Added updateData method
20+
1721
## v0.100.1 (July 21st)
1822
- Fixed bug where modal triggers could not contain child elements
1923
- Fixed bug with right alignment option for dropdown

Gruntfile.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,7 @@ module.exports = function(grunt) {
308308
"toasts.js",
309309
"sidenav.js",
310310
"scrollspy.js",
311-
"/autocomplete.js",
311+
"autocomplete.js",
312312
"forms.js",
313313
"slider.js",
314314
"cards.js",

jade/page-contents/chips_content.html

+4-4
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,16 @@ <h4>Tags</h4>
4747
<div id="basic" class="section scrollspy">
4848
<h4>Javascript Plugin Usage</h4>
4949
<p class="caption">To add tags, just enter your tag text and press enter. You can delete them by clicking on the close icon or by using your delete button.</p>
50-
<div class="chips"></div>
50+
<div class="chips"><input></div>
5151
<br>
5252
<p class="caption">Set initial tags.</p>
53-
<div class="chips chips-initial"></div>
53+
<div class="chips chips-initial"><input></div>
5454
<br>
5555
<p class="caption">Use placeholders and override hint texts.</p>
56-
<div class="chips chips-placeholder"></div>
56+
<div class="chips chips-placeholder"><input></div>
5757
<br>
5858
<p class="caption">Use autocomplete with chips.</p>
59-
<div class="chips chips-autocomplete"></div>
59+
<div class="chips chips-autocomplete"><input></div>
6060
</div>
6161

6262
<div id="properties" class="section scrollspy">

js/autocomplete.js

+71-22
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,12 @@
4646
this.options = $.extend({}, Autocomplete.defaults, options);
4747

4848
// Setup
49+
this.isOpen = false;
4950
this.count = 0;
5051
this.activeIndex = -1;
5152
this.oldVal;
5253
this.$inputField = this.$el.closest('.input-field');
5354
this.$active = $();
54-
console.log(this.$inputField);
5555
this._setupDropdown();
5656

5757
this._setupEventHandlers();
@@ -81,6 +81,7 @@
8181
*/
8282
destroy() {
8383
this._removeEventHandlers();
84+
this._removeDropdown();
8485
this.el.M_Autocomplete = undefined;
8586
}
8687

@@ -128,6 +129,13 @@
128129
this.$inputField.append(this.container);
129130
}
130131

132+
/**
133+
* Remove dropdown
134+
*/
135+
_removeDropdown() {
136+
this.container.parentNode.removeChild(this.container);
137+
}
138+
131139
/**
132140
* Handle Input Blur
133141
*/
@@ -140,6 +148,12 @@
140148
* @param {Event} e
141149
*/
142150
_handleInputKeyupAndFocus(e) {
151+
console.log(e.type);
152+
if (e.type === 'keyup') {
153+
console.log("SET KEYDUP");
154+
Autocomplete._keydown = false;
155+
}
156+
143157
this.count = 0;
144158
let val = this.el.value.toLowerCase();
145159

@@ -155,26 +169,8 @@
155169
this._removeAutocomplete();
156170

157171
if (val.length >= this.options.minLength) {
158-
for (let key in this.options.data) {
159-
if (this.options.data.hasOwnProperty(key) &&
160-
key.toLowerCase().indexOf(val) !== -1) {
161-
// Break if past limit
162-
if (this.count >= this.options.limit) {
163-
break;
164-
}
165-
166-
let $autocompleteOption = $('<li></li>');
167-
if (!!this.options.data[key]) {
168-
$autocompleteOption.append('<img src="'+ this.options.data[key] +'" class="right circle"><span>'+ key +'</span>');
169-
} else {
170-
$autocompleteOption.append('<span>'+ key +'</span>');
171-
}
172-
173-
$(this.container).append($autocompleteOption);
174-
this._highlight(val, $autocompleteOption);
175-
this.count++;
176-
}
177-
}
172+
this.isOpen = true;
173+
this._renderDropdown(this.options.data, val);
178174
}
179175
}
180176

@@ -187,6 +183,9 @@
187183
* @param {Event} e
188184
*/
189185
_handleInputKeydown(e) {
186+
console.log("SET KEYDOWN");
187+
Autocomplete._keydown = true;
188+
190189
// Arrow keys and enter key usage
191190
let keyCode = e.keyCode,
192191
liElement,
@@ -265,6 +264,7 @@
265264
$(this.container).empty();
266265
this._resetCurrentElement();
267266
this.oldVal = null;
267+
this.isOpen = false;
268268
}
269269

270270
/**
@@ -279,11 +279,60 @@
279279

280280
// Handle onAutocomplete callback.
281281
if (typeof(this.options.onAutocomplete) === 'function') {
282-
this.options.onAutocomplete.call(this, this.$el, text);
282+
this.options.onAutocomplete.call(this, text);
283+
}
284+
}
285+
286+
/**
287+
* Render dropdown content
288+
* @param {Object} data data set
289+
* @param {String} val current input value
290+
*/
291+
_renderDropdown(data, val) {
292+
this._removeAutocomplete();
293+
294+
for (let key in data) {
295+
if (data.hasOwnProperty(key) &&
296+
key.toLowerCase().indexOf(val) !== -1) {
297+
// Break if past limit
298+
if (this.count >= this.options.limit) {
299+
break;
300+
}
301+
302+
let $autocompleteOption = $('<li></li>');
303+
if (!!data[key]) {
304+
$autocompleteOption.append('<img src="'+ data[key] +'" class="right circle"><span>'+ key +'</span>');
305+
} else {
306+
$autocompleteOption.append('<span>'+ key +'</span>');
307+
}
308+
309+
$(this.container).append($autocompleteOption);
310+
this._highlight(val, $autocompleteOption);
311+
this.count++;
312+
}
313+
}
314+
}
315+
316+
/**
317+
* Update Data
318+
* @param {Object} data
319+
*/
320+
updateData(data) {
321+
let val = this.el.value.toLowerCase();
322+
this.options.data = data;
323+
324+
if (this.isOpen) {
325+
this._renderDropdown(data, val);
283326
}
284327
}
285328
}
286329

330+
/**
331+
* @static
332+
* @memberof Autocomplete
333+
*/
334+
Autocomplete._keydown = false;
335+
287336
Materialize.Autocomplete = Autocomplete;
288337

289338
jQuery.fn.autocomplete = function(methodOrOptions) {

js/chips.js

+55-3
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,12 @@
5151
*/
5252
this.options = $.extend({}, Chips.defaults, options);
5353

54-
// this.$el.empty();
55-
this.$el.addClass('chips');
54+
this.$el.addClass('chips input-field');
5655
this.chipsData = [];
5756
this.$chips = $();
5857
this.$input = this.$el.find('input');
5958
this.$input.addClass('input');
59+
this.hasAutocomplete = Object.keys(this.options.autocompleteOptions).length > 0;
6060

6161
// Set input id
6262
if (!this.$input.attr('id')) {
@@ -69,6 +69,12 @@
6969
this._renderChips(this.chipsData);
7070
}
7171

72+
console.log(this.hasAutocomplete);
73+
if (this.hasAutocomplete) {
74+
this._setupAutocomplete();
75+
}
76+
77+
this._setPlaceholder();
7278
// this._createLabel();
7379
this._setupEventHandlers();
7480
}
@@ -114,11 +120,15 @@
114120
_setupEventHandlers() {
115121
this._handleChipClickBound = this._handleChipClick.bind(this);
116122
this._handleInputKeydownBound = this._handleInputKeydown.bind(this);
123+
this._handleInputFocusBound = this._handleInputFocus.bind(this);
124+
this._handleInputBlurBound = this._handleInputBlur.bind(this);
117125

118126
this.el.addEventListener('click', this._handleChipClickBound);
119127
document.addEventListener('keydown', Chips._handleChipsKeydown);
120128
document.addEventListener('keyup', Chips._handleChipsKeyup);
121129
this.el.addEventListener('blur', Chips._handleChipsBlur, true);
130+
this.$input[0].addEventListener('focus', this._handleInputFocusBound);
131+
this.$input[0].addEventListener('blur', this._handleInputBlurBound);
122132
this.$input[0].addEventListener('keydown', this._handleInputKeydownBound);
123133
}
124134

@@ -130,6 +140,8 @@
130140
document.removeEventListener('keydown', Chips._handleChipsKeydown);
131141
document.removeEventListener('keyup', Chips._handleChipsKeyup);
132142
this.el.removeEventListener('blur', Chips._handleChipsBlur, true);
143+
this.$input[0].removeEventListener('focus', this._handleInputFocusBound);
144+
this.$input[0].removeEventListener('blur', this._handleInputBlurBound);
133145
this.$input[0].removeEventListener('keydown', this._handleInputKeydownBound);
134146
}
135147

@@ -153,6 +165,10 @@
153165
// select chip
154166
this.selectChip(index);
155167
}
168+
169+
// Default handle click to focus on input
170+
} else {
171+
this.$input[0].focus();
156172
}
157173
}
158174

@@ -236,6 +252,20 @@
236252
}
237253
}
238254

255+
/**
256+
* Handle Input Focus
257+
*/
258+
_handleInputFocus() {
259+
this.$el.addClass('focus');
260+
}
261+
262+
/**
263+
* Handle Input Blur
264+
*/
265+
_handleInputBlur() {
266+
this.$el.removeClass('focus');
267+
}
268+
239269
/**
240270
* Handle Input Keydown
241271
* @param {Event} e
@@ -246,6 +276,14 @@
246276
console.log(e.keyCode, e.which, this.$input[0].value, this.chipsData);
247277
// enter
248278
if (e.keyCode === 13) {
279+
// Override enter if autocompleting.
280+
console.log(this.hasAutocomplete, this.autocomplete, Materialize.Autocomplete._keydown);
281+
if (this.hasAutocomplete &&
282+
this.autocomplete &&
283+
this.autocomplete.isOpen) {
284+
return;
285+
}
286+
249287
e.preventDefault();
250288
this.addChip({tag: this.$input[0].value});
251289
this.$input[0].value = '';
@@ -302,6 +340,20 @@
302340
this.$el.append(this.$input);
303341
}
304342

343+
/**
344+
* Setup Autocomplete
345+
*/
346+
_setupAutocomplete() {
347+
this.options.autocompleteOptions.onAutocomplete = (val) => {
348+
this.addChip({tag: val});
349+
this.$input[0].value = '';
350+
this.$input[0].focus();
351+
};
352+
353+
this.autocomplete = Materialize.Autocomplete.init(this.$input, this.options.autocompleteOptions)[0];
354+
console.log(this.autocomplete);
355+
}
356+
305357
/**
306358
* Render Chips
307359
*/
@@ -765,7 +817,7 @@
765817
// Handle removal of static chips.
766818
$(document).on('click', '.chip .close', function() {
767819
let $chips = $(this).closest('.chips');
768-
if (!$chips.length || $chips[0].M_Chips) {
820+
if ($chips.length && $chips[0].M_Chips) {
769821
return;
770822
}
771823
$(this).closest('.chip').remove();

js/init.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@
198198
}
199199

200200
// Chips
201-
$('.chips').material_chip();
202-
$('.chips-initial').material_chip({
201+
$('.chips').chips();
202+
$('.chips-initial').chips({
203203
readOnly: true,
204204
data: [{
205205
tag: 'Apple',
@@ -209,11 +209,11 @@
209209
tag: 'Google',
210210
}]
211211
});
212-
$('.chips-placeholder').material_chip({
212+
$('.chips-placeholder').chips({
213213
placeholder: 'Enter a tag',
214214
secondaryPlaceholder: '+Tag',
215215
});
216-
$('.chips-autocomplete').material_chip({
216+
$('.chips-autocomplete').chips({
217217
autocompleteOptions: {
218218
data: {
219219
'Apple': null,

tests/spec/autocomplete/autocompleteSpec.js

+2-4
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ describe("Autocomplete Plugin", function () {
3434
"Google": 'http://placehold.it/250x250'
3535
}
3636
});
37-
37+
3838
var $autocompleteEl = $parent.find('.autocomplete-content');
39-
var autocompleteEvents = $._data($normal[0], 'events');
40-
39+
4140
expect($autocompleteEl.length).toEqual(1, 'Should dynamically generate autocomplete structure.');
42-
expect(autocompleteEvents.keyup.length).toEqual(1, 'Should only bind 1 keyup handler on input');
4341
done();
4442
}, 400);
4543
});

0 commit comments

Comments
 (0)