How to create autocomplete form with MaterializeCss? - jquery-select2

I am looking for autocomplete form for MaterializeCss, any plugins for this? i has try to use select2 but that's css not looks good

Materialize is an awesome library, I was able to get it to work.
$('document').ready(function() {
var input_selector = 'input[type=text], input[type=password], input[type=email], input[type=url], input[type=tel], input[type=number], input[type=search], textarea';
/**************************
* Auto complete plugin *
*************************/
$(input_selector).each(function() {
var $input = $(this);
if ($input.hasClass('autocomplete')) {
var $array = $input.data('array'),
$inputDiv = $input.closest('.input-field'); // Div to append on
// Check if "data-array" isn't empty
if ($array !== '') {
// Create html element
var $html = '<ul class="autocomplete-content hide">';
for (var i = 0; i < $array.length; i++) {
// If path and class aren't empty add image to auto complete else create normal element
if ($array[i]['path'] !== '' && $array[i]['path'] !== undefined && $array[i]['path'] !== null && $array[i]['class'] !== undefined && $array[i]['class'] !== '') {
$html += '<li class="autocomplete-option"><img src="' + $array[i]['path'] + '" class="' + $array[i]['class'] + '"><span>' + $array[i]['value'] + '</span></li>';
} else {
$html += '<li class="autocomplete-option"><span>' + $array[i]['value'] + '</span></li>';
}
}
$html += '</ul>';
$inputDiv.append($html); // Set ul in body
// End create html element
function highlight(string) {
$('.autocomplete-content li').each(function() {
var matchStart = $(this).text().toLowerCase().indexOf("" + string.toLowerCase() + ""),
matchEnd = matchStart + string.length - 1,
beforeMatch = $(this).text().slice(0, matchStart),
matchText = $(this).text().slice(matchStart, matchEnd + 1),
afterMatch = $(this).text().slice(matchEnd + 1);
$(this).html("<span>" + beforeMatch + "<span class='highlight'>" + matchText + "</span>" + afterMatch + "</span>");
});
}
// Perform search
$(document).on('keyup', $input, function() {
var $val = $input.val().trim(),
$select = $('.autocomplete-content');
// Check if the input isn't empty
$select.css('width',$input.width());
if ($val != '') {
$select.children('li').addClass('hide');
$select.children('li').filter(function() {
$select.removeClass('hide'); // Show results
// If text needs to highlighted
if ($input.hasClass('highlight-matching')) {
highlight($val);
}
var check = true;
for (var i in $val) {
if ($val[i].toLowerCase() !== $(this).text().toLowerCase()[i])
check = false;
};
return check ? $(this).text().toLowerCase().indexOf($val.toLowerCase()) !== -1 : false;
}).removeClass('hide');
} else {
$select.children('li').addClass('hide');
}
});
// Set input value
$('.autocomplete-option').click(function() {
$input.val($(this).text().trim());
$('.autocomplete-option').addClass('hide');
});
} else {
return false;
}
}
});
});
.autocomplete-content {
position: absolute;
background: #383838;
margin-top: -.9rem;
}
.autocomplete-content li {
clear: both;
color: rgba(0, 0, 0, 0.87);
cursor: pointer;
line-height: 0;
width: 100%;
text-align: left;
text-transform: none;
padding: 10px;
}
.autocomplete-content li > span {
color: #ffa726;
font-size: .9rem;
padding: 1.2rem;
display: block;
}
.autocomplete-content li > span .highlight {
color: #000000;
}
.autocomplete-content li img {
height: 52px;
width: 52px;
padding: 5px;
margin: 0 15px;
}
.autocomplete-content li:hover {
background: #eee;
cursor: pointer;
}
.autocomplete-content > li:hover {
background: #292929;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="row">
<div class="input-field col s12">
<label class="active">State</label>
<input type="text" id="autocompleteState" class="autocomplete inputFields">
</div>
</div>
<script>
var stateData = [{
value: "Alabama"
}, {
value: "Alaska"
}, {
value: "Arizona"
}, {
value: "Arkansas"
}, {
value: "California"
}, {
value: "Colorado"
}, {
value: "Connecticut"
}, {
value: "District of Columbia"
}, {
value: "Delaware"
}, {
value: "Florida"
}, {
value: "Georgia"
}, {
value: "Hawaii"
}, {
value: "Idaho"
}, {
value: "Illinois"
}, {
value: "Indiana"
}, {
value: "Iowa"
}, {
value: "Kansas"
}, {
value: "Kentucky"
}, {
value: "Louisiana"
}, {
value: "Maine"
}, ];
$('#autocompleteState').data('array', stateData);
</script>
Hope this helps people who are new to this just like me.:)

UPDATED 1/09/2016:
Autocomplete is already available officially:
http://materializecss.com/forms.html#autocomplete
I was looking for exactly the same and I think We have been lucky. They added the autocomplete recently, (not yet in the documentation). But you can see the info here https://github.com/SuperDJ/materialize/commit/3648f74542e41c3b3be4596870b7485f6ebdf176#diff-e4535828acef79852aa104417c16fe3dR157
and the code:
https://github.com/SuperDJ/materialize/blob/master/bin/materialize.css
https://github.com/SuperDJ/materialize/blob/master/bin/materialize.js

(function (root, factory) {
if(typeof module === 'object' && module.exports) {
module.exports = factory(require('jquery'));
} else if(typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else {
factory(root.jQuery);
}
}(this, function ($) {
var template = function (text) {
var matcher = new RegExp('<%=([\\s\\S]+?)%>|<%([\\s\\S]+?)%>|$', 'g');
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
var escapeChar = function(match) {
return '\\' + escapes[match];
};
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, interpolate, evaluate, offset) {
source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
index = offset + match.length;
if (match == "<% item.value %>")
interpolate = " item.value ";
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
return match;
});
source += "';\n";
source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + 'return __p;\n';
var render;
try {
render = new Function('obj', source);
} catch (e) {
e.source = source;
throw e;
}
var _template = function(data) {
return render.call(this, data);
};
_template.source = 'function(obj){\n' + source + '}';
return _template;
};
var Autocomplete = function (el, options) {
this.options = $.extend(true, {}, Autocomplete.defaults, options);
this.$el = $(el);
this.$wrapper = this.$el.parent();
this.compiled = {};
this.$dropdown = null;
this.$appender = null;
this.$hidden = null;
this.resultCache = {};
this.value = '';
this.initialize();
};
Autocomplete.defaults = {
cacheable: true,
limit: 10,
multiple: {
enable: false,
maxSize: 4,
onExist: function (item) {
Materialize.toast('Tag: ' + item.text + '(' + item.id + ') is already added!', 2000);
},
onExceed: function (maxSize, item) {
Materialize.toast('Can\'t add over ' + maxSize + ' tags!', 2000);
},
onAppend: function (item) {
var self = this;
self.$el.removeClass('active');
self.$el.click();
},
onRemove: function (item) {
var self = this;
self.$el.removeClass('active');
self.$el.click();
}
},
hidden: {
enable: true,
el: '',
inputName: '',
required: false
},
appender: {
el: '',
tagName: 'ul',
className: 'ac-appender',
tagTemplate: '<div class="chip" data-id="<%= item.id %>" data-value="<% item.value %> data-text="<% item.text %>" "><%= item.text %>(<%= item.id %>)<i class="material-icons close">close</i></div>'
},
dropdown: {
el: '',
tagName: 'ul',
className: 'ac-dropdown',
itemTemplate: '<li class="ac-item" data-id="<%= item.id %>" data-value="<% item.value %>" data-text="<%= item.text %>" ><%= item.text %></li>',
noItem: ''
},
handlers: {
'setValue': '.ac-dropdown .ac-item',
'.ac-appender .ac-tag .close': 'remove'
},
getData: function (value, callback) {
callback(value, []);
},
onSelect: function (item) { },
onRemove: function (item) { alert('delete'); },
ignoreCase: true,
throttling: true,
showListOnFocus: false,
minLength:0
};
Autocomplete.prototype = {
constructor: Autocomplete,
initialize: function () {
var self = this;
var timer;
var fetching = false;
function getItemsHtml (list) {
var itemsHtml = '';
if (!list.length) {
return self.options.dropdown.noItem;
}
list.forEach(function (item, idx) {
if (idx >= self.options.limit) {
return false;
}
itemsHtml += self.compiled.item({ 'item': item});
});
return itemsHtml;
}
function handleList (value, list) {
var itemsHtml = getItemsHtml(list);
var currentValue = self.$el.val();
if (self.options.ignoreCase) {
currentValue = currentValue.toUpperCase();
}
if (self.options.cacheable && !self.resultCache.hasOwnProperty(value)) {
self.resultCache[value] = list;
}
if (value !== currentValue) {
return false;
}
if(itemsHtml) {
self.$dropdown.html(itemsHtml);
self.$dropdown.show();
} else {
self.$dropdown.hide();
}
}
self.value = self.options.multiple.enable ? [] : '';
self.compiled.tag = template(self.options.appender.tagTemplate);
self.compiled.item = template(self.options.dropdown.itemTemplate);
self.render();
if (self.options.showListOnFocus) {
self.$el.on('focus', function (e) {
if (self.options.throttling) {
clearTimeout(timer);
timer = setTimeout(function () {
self.options.getData('', handleList);
}, 200);
return true;
}
// self.$dropdown.show();
});
}
self.$el.on('input', function (e) {
var $t = $(this);
var value = $t.val();
if (!value) {
self.$dropdown.hide();
return false;
}
if (self.options.ignoreCase) {
value = value.toUpperCase();
}
if (self.resultCache.hasOwnProperty(value) && self.resultCache[value]) {
handleList(value, self.resultCache[value]);
return true;
}
if (self.options.showListOnFocus || self.options.minLength <= value.length) {
if (self.options.throttling) {
clearTimeout(timer);
timer = setTimeout(function () {
self.options.getData(value, handleList);
}, 200);
return true;
}
self.options.getData(value, handleList);
}
});
self.$el.on('keydown', function (e) {
var $t = $(this);
var keyCode = e.keyCode;
var $items, $hover;
// BACKSPACE KEY
if (keyCode == '8' && !$t.val()) {
if (!self.options.multiple.enable) {
return true;
}
if (!self.value.length) {
return true;
}
var lastItem = self.value[self.value.length - 1];
self.remove(lastItem);
return false;
}
// UP DOWN ARROW KEY
if (keyCode == '38' || keyCode == '40') {
$items = self.$dropdown.find('[data-id]');
if (!$items.size()) {
return false;
}
$hover = $items.filter('.ac-hover');
if (!$hover.size()) {
$items.removeClass('ac-hover');
$items.eq(keyCode == '40' ? 0 : -1).addClass('ac-hover');
} else {
var index = $hover.index();
$items.removeClass('ac-hover');
$items.eq(keyCode == '40' ? (index + 1) % $items.size() : index - 1).addClass('ac-hover');
}
return false;
}
// ENTER KEY CODE
if (keyCode == '13') {
$items = self.$dropdown.find('[data-id]');
if (!$items.size()) {
return false;
}
$hover = $items.filter('.ac-hover');
if (!$hover.size()) {
return false;
}
self.setValue({
id: $hover.data('id'),
text: $hover.data('text'),
value: $hover.data('value')
});
return false;
}
});
self.$dropdown.on('click', '[data-id]', function (e) {
var $t = $(this);
var item = {
id: $t.data('id'),
text: $t.data('text'),
value : $t.data('value')
};
self.setValue(item);
});
self.$appender.on('click', '[data-id] .close', function (e) {
var $t = $(this);
var $li = $t.closest('[data-id');
var item = {
id: $li.data('id'),
text: $li.data('text'),
value:$t.data('value')
};
self.remove(item);
});
},
render: function () {
var self = this;
if (self.options.dropdown.el) {
self.$dropdown = $(self.options.dropdown.el);
} else {
self.$dropdown = $(document.createElement(self.options.dropdown.tagName));
self.$dropdown.insertAfter(self.$el);
}
self.$dropdown.addClass(self.options.dropdown.className);
if (self.options.appender.el) {
self.$appender = $(self.options.appender.el);
} else {
self.$appender = $(document.createElement(self.options.appender.tagName));
self.$appender.insertBefore(self.$el);
}
if (self.options.hidden.enable) {
if (self.options.hidden.el) {
self.$hidden = $(self.options.hidden.el);
} else {
self.$hidden = $('<input type="hidden" class="validate" />');
self.$wrapper.append(self.$hidden);
}
if (self.options.hidden.inputName) {
self.$el.attr('name', self.options.hidden.inputName);
}
if (self.options.hidden.required) {
self.$hidden.attr('required', 'required');
}
}
self.$appender.addClass(self.options.appender.className);
},
setValue: function (item) {
var self = this;
if (self.options.multiple.enable) {
self.append(item);
} else {
self.select(item);
}
},
append: function (item) {
var self = this;
var $tag = self.compiled.tag({ 'item': item });
if (self.value.some(function (selectedItem) {
return selectedItem.id === item.id;
})) {
if ('function' === typeof self.options.multiple.onExist) {
self.options.multiple.onExist.call(this, item);
}
return false;
}
if (self.value.length >= self.options.multiple.maxSize) {
if ('function' === typeof self.options.multiple.onExceed) {
self.options.multiple.onExceed.call(this, self.options.multiple.maxSize);
}
return false;
}
self.value.push(item);
self.$appender.append($tag);
var valueStr = self.value.map(function (selectedItem) {
return selectedItem.id;
}).join(',');
if (self.options.hidden.enable) {
self.$hidden.val(valueStr);
}
self.$el.val('');
self.$el.data('value', valueStr);
self.$dropdown.html('').hide();
if ('function' === typeof self.options.multiple.onAppend) {
self.options.multiple.onAppend.call(self, item);
}
},
remove: function (item) {
var self = this;
self.$appender.find('[data-id="' + item.id + '"]').remove();
self.value = self.value.filter(function (selectedItem) {
return selectedItem.id !== item.id;
});
var valueStr = self.value.map(function (selectedItem) {
return selectedItem.id;
}).join(',');
if (self.options.hidden.enable) {
self.$hidden.val(valueStr);
self.$el.data('value', valueStr);
}
self.$dropdown.html('').hide();
if ('function' === typeof self.options.multiple.onRemove) {
self.options.multiple.onRemove.call(self, item);
}
self.options.onRemove(item);
},
select: function (item) {
var self = this;
self.value = item.text;
self.$el.val(item.text);
self.$el.data('value', item.id);
self.$dropdown.html('').hide();
if (self.options.hidden.enable) {
self.$hidden.val(item.id);
}
self.options.onSelect(item);
}
};
$.fn.materialize_autocomplete = function (options) {
var el = this;
var $el = $(el).eq(0);
var instance = $el.data('autocomplete');
if (instance && arguments.length) {
return instance;
}
var autocomplete = new Autocomplete(el, options);
$el.data('autocomplete', autocomplete);
$el.dropdown();
return autocomplete;
};
}));
down load this js and save inside your js folder jquery.materialize-autocomplete.js and u can over ride onSelect,minLength,showListOnFocus

Visit the link for demo https://ampersandacademy.com/demo/autocomplete/
you can easily achieve the autocomplete functionality using the Devberidge plugin.
Get Devbridge plugin using https://github.com/devbridge/jQuery-Autocomplete
<script type="text/javascript">
$(document).ready(function() {
$("#country").devbridgeAutocomplete({
//lookup: countries,
serviceUrl:"getCountry.php", //tell the script where to send requests
type:'POST',
//callback just to show it's working
onSelect: function (suggestion) {
// $('#selection').html('You selected: ' + suggestion.value + ', ' + suggestion.data);
},
showNoSuggestionNotice: true,
noSuggestionNotice: 'Sorry, no matching results',
});
});
Here the getCountry.php file returns the JSON data. For more info visit https://ampersandacademy.com/tutorials/materialize-css/materialize-css-framework-ajax-autocomplete-example-using-php

According to the commit done by SuperDJ (https://goo.gl/0Mbrtg), I didn't manage to get it works...
Here is the code :
<div class="row">
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<input type="text" id="autocomplete" class="autocomplete highlight-matching" data-array='[{"value": "example","path": "","class": ""},{"value": "example 2","path": "","class": ""},{"value": "test","path": "","class": ""}]'>
<label for="autocomplete">Autocomplete</label>
</div>
</div>
</div>
</div>
Here is a codepen test :
http://codepen.io/anthonyvialleton/pen/BjPjKM
Need some help to get this work.

As per, here.
You just need to do this simple thing (From the example there only):
HTML:
<div class="row">
<div class="col s12">
<div class="row">
<div class="input-field col s12">
<i class="material-icons prefix">textsms</i>
<input type="text" id="autocomplete-input" class="autocomplete">
<label for="autocomplete-input">Autocomplete</label>
</div>
</div>
</div>
JS:
$('input.autocomplete').autocomplete({
data: {
"Apple": null,
"Microsoft": null,
"Google": null
}
});

(function (root, factory) {
if(typeof module === 'object' && module.exports) {
module.exports = factory(require('jquery'));
} else if(typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else {
factory(root.jQuery);
}
}(this, function ($) {
var template = function (text) {
var matcher = new RegExp('<%=([\\s\\S]+?)%>|<%([\\s\\S]+?)%>|$', 'g');
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;
var escapeChar = function(match) {
return '\\' + escapes[match];
};
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, interpolate, evaluate, offset) {
source += text.slice(index, offset).replace(escapeRegExp, escapeChar);
index = offset + match.length;
if (match == "<% item.value %>")
interpolate = " item.value ";
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
} else if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
return match;
});
source += "';\n";
source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + 'return __p;\n';
var render;
try {
render = new Function('obj', source);
} catch (e) {
e.source = source;
throw e;
}
var _template = function(data) {
return render.call(this, data);
};
_template.source = 'function(obj){\n' + source + '}';
return _template;
};
var Autocomplete = function (el, options) {
this.options = $.extend(true, {}, Autocomplete.defaults, options);
this.$el = $(el);
this.$wrapper = this.$el.parent();
this.compiled = {};
this.$dropdown = null;
this.$appender = null;
this.$hidden = null;
this.resultCache = {};
this.value = '';
this.initialize();
};
Autocomplete.defaults = {
cacheable: true,
limit: 10,
multiple: {
enable: false,
maxSize: 4,
onExist: function (item) {
Materialize.toast('Tag: ' + item.text + '(' + item.id + ') is already added!', 2000);
},
onExceed: function (maxSize, item) {
Materialize.toast('Can\'t add over ' + maxSize + ' tags!', 2000);
},
onAppend: function (item) {
var self = this;
self.$el.removeClass('active');
self.$el.click();
},
onRemove: function (item) {
var self = this;
self.$el.removeClass('active');
self.$el.click();
}
},
hidden: {
enable: true,
el: '',
inputName: '',
required: false
},
appender: {
el: '',
tagName: 'ul',
className: 'ac-appender',
tagTemplate: '<div class="chip" data-id="<%= item.id %>" data-value="<% item.value %> data-text="<% item.text %>" "><%= item.text %>(<%= item.id %>)<i class="material-icons close">close</i></div>'
},
dropdown: {
el: '',
tagName: 'ul',
className: 'ac-dropdown',
itemTemplate: '<li class="ac-item" data-id="<%= item.id %>" data-value="<% item.value %>" data-text="<%= item.text %>" ><%= item.text %></li>',
noItem: ''
},
handlers: {
'setValue': '.ac-dropdown .ac-item',
'.ac-appender .ac-tag .close': 'remove'
},
getData: function (value, callback) {
callback(value, []);
},
onSelect: function (item) { },
onRemove: function (item) { alert('delete'); },
ignoreCase: true,
throttling: true,
showListOnFocus: false,
minLength:0
};
Autocomplete.prototype = {
constructor: Autocomplete,
initialize: function () {
var self = this;
var timer;
var fetching = false;
function getItemsHtml (list) {
var itemsHtml = '';
if (!list.length) {
return self.options.dropdown.noItem;
}
list.forEach(function (item, idx) {
if (idx >= self.options.limit) {
return false;
}
itemsHtml += self.compiled.item({ 'item': item});
});
return itemsHtml;
}
function handleList (value, list) {
var itemsHtml = getItemsHtml(list);
var currentValue = self.$el.val();
if (self.options.ignoreCase) {
currentValue = currentValue.toUpperCase();
}
if (self.options.cacheable && !self.resultCache.hasOwnProperty(value)) {
self.resultCache[value] = list;
}
if (value !== currentValue) {
return false;
}
if(itemsHtml) {
self.$dropdown.html(itemsHtml);
self.$dropdown.show();
} else {
self.$dropdown.hide();
}
}
self.value = self.options.multiple.enable ? [] : '';
self.compiled.tag = template(self.options.appender.tagTemplate);
self.compiled.item = template(self.options.dropdown.itemTemplate);
self.render();
if (self.options.showListOnFocus) {
self.$el.on('focus', function (e) {
if (self.options.throttling) {
clearTimeout(timer);
timer = setTimeout(function () {
self.options.getData('', handleList);
}, 200);
return true;
}
// self.$dropdown.show();
});
}
self.$el.on('input', function (e) {
var $t = $(this);
var value = $t.val();
if (!value) {
self.$dropdown.hide();
return false;
}
if (self.options.ignoreCase) {
value = value.toUpperCase();
}
if (self.resultCache.hasOwnProperty(value) && self.resultCache[value]) {
handleList(value, self.resultCache[value]);
return true;
}
if (self.options.showListOnFocus || self.options.minLength <= value.length) {
if (self.options.throttling) {
clearTimeout(timer);
timer = setTimeout(function () {
self.options.getData(value, handleList);
}, 200);
return true;
}
self.options.getData(value, handleList);
}
});
self.$el.on('keydown', function (e) {
var $t = $(this);
var keyCode = e.keyCode;
var $items, $hover;
// BACKSPACE KEY
if (keyCode == '8' && !$t.val()) {
if (!self.options.multiple.enable) {
return true;
}
if (!self.value.length) {
return true;
}
var lastItem = self.value[self.value.length - 1];
self.remove(lastItem);
return false;
}
// UP DOWN ARROW KEY
if (keyCode == '38' || keyCode == '40') {
$items = self.$dropdown.find('[data-id]');
if (!$items.size()) {
return false;
}
$hover = $items.filter('.ac-hover');
if (!$hover.size()) {
$items.removeClass('ac-hover');
$items.eq(keyCode == '40' ? 0 : -1).addClass('ac-hover');
} else {
var index = $hover.index();
$items.removeClass('ac-hover');
$items.eq(keyCode == '40' ? (index + 1) % $items.size() : index - 1).addClass('ac-hover');
}
return false;
}
// ENTER KEY CODE
if (keyCode == '13') {
$items = self.$dropdown.find('[data-id]');
if (!$items.size()) {
return false;
}
$hover = $items.filter('.ac-hover');
if (!$hover.size()) {
return false;
}
self.setValue({
id: $hover.data('id'),
text: $hover.data('text'),
value: $hover.data('value')
});
return false;
}
});
self.$dropdown.on('click', '[data-id]', function (e) {
var $t = $(this);
var item = {
id: $t.data('id'),
text: $t.data('text'),
value : $t.data('value')
};
self.setValue(item);
});
self.$appender.on('click', '[data-id] .close', function (e) {
var $t = $(this);
var $li = $t.closest('[data-id');
var item = {
id: $li.data('id'),
text: $li.data('text'),
value:$t.data('value')
};
self.remove(item);
});
},
render: function () {
var self = this;
if (self.options.dropdown.el) {
self.$dropdown = $(self.options.dropdown.el);
} else {
self.$dropdown = $(document.createElement(self.options.dropdown.tagName));
self.$dropdown.insertAfter(self.$el);
}
self.$dropdown.addClass(self.options.dropdown.className);
if (self.options.appender.el) {
self.$appender = $(self.options.appender.el);
} else {
self.$appender = $(document.createElement(self.options.appender.tagName));
self.$appender.insertBefore(self.$el);
}
if (self.options.hidden.enable) {
if (self.options.hidden.el) {
self.$hidden = $(self.options.hidden.el);
} else {
self.$hidden = $('<input type="hidden" class="validate" />');
self.$wrapper.append(self.$hidden);
}
if (self.options.hidden.inputName) {
self.$el.attr('name', self.options.hidden.inputName);
}
if (self.options.hidden.required) {
self.$hidden.attr('required', 'required');
}
}
self.$appender.addClass(self.options.appender.className);
},
setValue: function (item) {
var self = this;
if (self.options.multiple.enable) {
self.append(item);
} else {
self.select(item);
}
},
append: function (item) {
var self = this;
var $tag = self.compiled.tag({ 'item': item });
if (self.value.some(function (selectedItem) {
return selectedItem.id === item.id;
})) {
if ('function' === typeof self.options.multiple.onExist) {
self.options.multiple.onExist.call(this, item);
}
return false;
}
if (self.value.length >= self.options.multiple.maxSize) {
if ('function' === typeof self.options.multiple.onExceed) {
self.options.multiple.onExceed.call(this, self.options.multiple.maxSize);
}
return false;
}
self.value.push(item);
self.$appender.append($tag);
var valueStr = self.value.map(function (selectedItem) {
return selectedItem.id;
}).join(',');
if (self.options.hidden.enable) {
self.$hidden.val(valueStr);
}
self.$el.val('');
self.$el.data('value', valueStr);
self.$dropdown.html('').hide();
if ('function' === typeof self.options.multiple.onAppend) {
self.options.multiple.onAppend.call(self, item);
}
},
remove: function (item) {
var self = this;
self.$appender.find('[data-id="' + item.id + '"]').remove();
self.value = self.value.filter(function (selectedItem) {
return selectedItem.id !== item.id;
});
var valueStr = self.value.map(function (selectedItem) {
return selectedItem.id;
}).join(',');
if (self.options.hidden.enable) {
self.$hidden.val(valueStr);
self.$el.data('value', valueStr);
}
self.$dropdown.html('').hide();
if ('function' === typeof self.options.multiple.onRemove) {
self.options.multiple.onRemove.call(self, item);
}
self.options.onRemove(item);
},
select: function (item) {
var self = this;
self.value = item.text;
self.$el.val(item.text);
self.$el.data('value', item.id);
self.$dropdown.html('').hide();
if (self.options.hidden.enable) {
self.$hidden.val(item.id);
}
self.options.onSelect(item);
}
};
$.fn.materialize_autocomplete = function (options) {
var el = this;
var $el = $(el).eq(0);
var instance = $el.data('autocomplete');
if (instance && arguments.length) {
return instance;
}
var autocomplete = new Autocomplete(el, options);
$el.data('autocomplete', autocomplete);
$el.dropdown();
return autocomplete;
};
}));
You can use the above .js file and you can over ride
Onselect
showListOnFocus: false,
minLength:2
according to your requirement and it will work.

Just write the Initialisation script inside $(document).ready(function(){});
i.e.
$(document).ready(function(){
$('input.autocomplete').autocomplete({
data: {
"Apple": null,
"Microsoft": null,
"Google": null
}
});
});

As mentioned above, autocomplete has been added the the materialize framework but it is still pretty limited. I'm waiting for a solution that supports values (ex Ids) icons and text.
Re: https://github.com/Dogfalo/materialize/issues/4086

Related

jQuery UI Widget Factory, modify start, drag, stop of Draggable

I am working to extend the Draggable widget by adding guides to the draggable element.
Example Fiddle: https://jsfiddle.net/Twisty/0mgrqy48/181/
JavaScript
$(function() {
$.widget("custom.guidedDrag", $.ui.draggable, {
options: {
autoShowGuides: true,
guideWidth: "1px",
guideStyle: "dashed",
guideColor: "#55f",
guideSides: ["top", "left"]
},
_create: function() {
this._makeGuides();
return this._super();
},
_makeGuides: function() {
var target = this.options.appendTo;
if (target == "parent") {
target = this.element.parent();
}
var self = this;
$.each(self.options.guideSides, function(i, side) {
var styles = {};
styles['border-' + side + '-width'] = self.options.guideWidth;
styles['border-' + side + '-style'] = self.options.guideStyle;
styles['border-' + side + '-color'] = self.options.guideColor;
styles.position = "absolute";
styles.top = 0;
styles.left = 0;
if (side == "top" || side == "bottom") {
styles.width = "100%";
styles.height = "";
$("<div>", {
class: "ui-draggable-guide-horizontal-" + side,
"data-elem-rel": self.uuid
}).css(styles).appendTo(target);
} else {
styles.width = "";
styles.height = "100%";
$("<div>", {
class: "ui-draggable-guide-vertical-" + side,
"data-elem-rel": self.uuid
}).css(styles).appendTo(target);
}
console.log("Guide Created for " + self.uuid + " on " + side + " side.");
});
},
_showGuides: function() {
if (this.options.autoShowGuides) {
this._moveGuides();
$("div[class*='ui-draggable-guide-'][data-elem-rel='" + this.uuid + "']").show();
}
},
_hideGuides: function() {
if (this.options.autoShowGuides) {
$("div[class*='ui-draggable-guide-'][data-elem-rel='" + this.uuid + "']").hide();
}
},
_moveGuides: function() {
var guides = $("div[class*='ui-draggable-guide-'][data-elem-rel='" + this.uuid + "']");
var t = this.element.position().top,
l = this.element.position().left,
b = t + this.element.outerHeight(),
r = l + this.element.outerWidth();
$(".ui-draggable-guide-horizontal-top", guides).css("top", t + "px");
$(".ui-draggable-guide-horizontal-left", guides).css("left", l + "px");
$(".ui-draggable-guide-horizontal-bottom", guides).css("top", b + "px");
$(".ui-draggable-guide-horizontal-right", guides).css("left", r + "px");
},
start: function(event, ui) {
console.log("Drag Start");
this._showGuides();
return this._super();
},
drag: function(event, ui) {
self._moveGuides();
return this._super();
},
stop: function(event, ui) {
console.log("Stop Drag");
self._hideGuides();
return this._super();
},
_destroy: function() {
$("div[class*='ui-draggable-guide-'][data-elem-rel='" + this.uuid + "']").remove();
return this._super()
}
});
$(".draggable").guidedDrag({
guideSides: ["top", "right"],
scroll: false
});
});
Currently, the guides are created and appear where expected. When I drag the element, the start event should be triggered and move the guides to the element (and unhide them later).
In console, I see the following, after running and dragging the element:
Guide Created for 0 on top side.
Guide Created for 0 on right side.
So I can tell that _create is running but start and stop do not seem to fire.
I have also tried to use .on() to bind to dragstart with no change. Example:
_create: function() {
this._makeGuides();
var self = this;
this.element.on("dragstart", function(event, ui){
console.log("Drag Start");
self._moveGuides();
});
return this._super();
}
Based on documentation, I should just be able to call the same widget and use _super().
To make the parent's methods available, the widget factory provides two methods - _super() and _superApply().
This never seems to work.
To resolve this, I have to make use of the _mouseStart, _mouseDrag, and _mouseStop event callbacks.
Example: https://jsfiddle.net/Twisty/0mgrqy48/245/
JavaScript
$(function() {
$.widget("app.guidedDrag", $.ui.draggable, {
options: {
autoShowGuides: true,
guideWidth: "1px",
guideStyle: "dashed",
guideColor: "#55f",
guideSides: ["top", "left"]
},
_create: function() {
this._makeGuides();
this._super();
},
_guideElems: {},
_makeGuides: function() {
var target = this.options.appendTo;
switch (target) {
case "parent":
target = this.element.parent();
break;
case "window":
target = $(window);
break;
case "document":
target = $(document);
break;
default:
target = $(target);
}
var self = this;
$.each(self.options.guideSides, function(i, side) {
var styles = {};
styles['border-' + side + '-width'] = self.options.guideWidth;
styles['border-' + side + '-style'] = self.options.guideStyle;
styles['border-' + side + '-color'] = self.options.guideColor;
styles.position = "absolute";
styles.top = 0;
styles.left = 0;
if (self.options.autoShowGuides) {
styles.display = "none";
}
if (side == "top" || side == "bottom") {
styles.width = "100%";
self._guideElems[side] = $("<div>", {
class: "ui-draggable-guide-horizontal-" + side,
}).data("ui-draggable-rel", self.uuid).css(styles).appendTo(target);
} else {
styles.height = "100%";
self._guideElems[side] = $("<div>", {
class: "ui-draggable-guide-vertical-" + side,
}).data("ui-draggable-rel", self.uuid).css(styles).appendTo(target);
}
console.log("Guide Created for " + self.uuid + " on " + side + " side.");
});
},
_showGuides: function() {
if (this.options.autoShowGuides) {
this._moveGuides();
$.each(this._guideElems, function(i, g) {
g.show();
});
}
},
_hideGuides: function() {
if (this.options.autoShowGuides) {
$.each(this._guideElems, function(i, g) {
g.hide();
});
}
},
_moveGuides: function() {
var t = this.element.position().top,
l = this.element.position().left,
b = t + this.element.outerHeight(),
r = l + this.element.outerWidth();
$.each(this._guideElems, function(i, g) {
if (g.hasClass("ui-draggable-guide-horizontal-top")) {
g.css("top", t + "px");
}
if (g.hasClass("ui-draggable-guide-horizontal-bottom")) {
g.css("top", b + "px");
}
if (g.hasClass("ui-draggable-guide-vertical-left")) {
g.css("left", l + "px");
}
if (g.hasClass("ui-draggable-guide-vertical-right")) {
g.css("left", r + "px");
}
});
},
_mouseStart: function(event) {
this._moveGuides();
this._showGuides();
this._super(event);
},
_mouseDrag: function(event) {
this._moveGuides();
return this._super(event);
},
_mouseStop: function(event) {
this._hideGuides();
return this._super(event);
},
_destroy: function(event) {
$(this._guideElems).remove();
return this._super(event);
}
});
$(".draggable").guidedDrag({
guideSides: ["top", "right"],
scroll: false
});
});

React Select chained options based on another dropdown selected value

Using React Select Async what are the best practices to chain options.
What I mean: I have 3 dropdowns the first one is populated from default with option values and the next 2 dropdowns are disabled.
Selecting the first dropdown value should populate the second dropdown options based on it's value and so on with the next dropdown.
so what I've been trying
import React from "react";
import Select from "react-select";
import AsyncSelect from "react-select/async";
import classnames from "classnames";
import Requests from "../services/requests";
const filterOptions = (inputValue, options) => {
return options.filter(i =>
i.label.toLowerCase().includes(inputValue.toLowerCase())
);
};
class FieldsRenderer extends React.Component {
constructor(props) {
super(props);
this.state = {
fields: props.fields,
containerClass: props.containerClass,
stepSnapshot: null,
selectOptions: {}
};
this.props.fields.map( (f) => {
if(f.type === 'select' && typeof f.dependsOn !== 'undefined') {
this.state.selectOptions[f.name] = null;
}
})
}
static getDerivedStateFromProps(nextProps, prevState) {
if (nextProps.fields !== prevState.fields) {
return {
fields: nextProps.fields,
containerClass: nextProps.containerClass
};
}
return null;
}
componentDidUpdate(prevProps, nextProps) {
if (prevProps !== this.props) {
this.setState({
fields: nextProps.fields,
containerClass: nextProps.containerClass
});
this.props.fields.map(f => {
if (typeof f.dependsOn != "undefined") {
this.state.selectOptions[f.name] = null;
}
});
}
}
handleInputChange = (index, e) => {
console.log(e.target.value);
console.log(index);
};
handleSelectChange = (selectedOption, item) => {
this.setState({
stepSnapshot: {
[item.name]: {
value: selectedOption.value,
label: selectedOption.label
}
}
});
let childField = this.props.fields.filter(t => {
if (t.type === "select" && typeof t.dependsOn !== "undefined") {
return t.dependsOn === item.name;
}
});
if (childField) {
this.loadChildOptions(childField[0], selectedOption);
}
};
//load child slect options
loadChildOptions(target, parentValue) {
Requests.get(
process.env.REACT_APP_API_BASE_URL +
target.source +
"/" +
parentValue.value,
(status, data) => {
//data will be set but will be shown just the previous state
this.state.selectOptions[target.name] = data;
}
);
}
render() {
let containerClass = "";
let fields = this.state.fields.map((field, i) => {
const fieldType = field.type;
let fieldStyle;
if (
typeof this.state.containerClass !== "undefined" &&
this.state.containerClass !== ""
) {
containerClass = this.state.containerClass;
}
if (typeof field.width !== "undefined" && field.width !== "") {
fieldStyle = {
width: "calc(" + field.width + " - 5px)"
};
}
switch (fieldType) {
case "select": {
const selectCustomStyles = {
control: (base, state) => ({
...base,
boxShadow: state.isFocused ? 0 : 0,
borderWidth: 2,
height: 45,
borderColor: state.isFocused ? "#707070" : base.borderColor,
"&:hover": {
borderColor: state.isFocused ? "#707070" : base.borderColor
}
}),
option: (provided, state) => ({
...provided,
backgroundColor: state.isSelected ? "#46B428" : "initial"
})
};
if (
typeof field.async !== "undefined" &&
typeof field.dependsOn === "undefined"
) {
return (
<div key={i} className={"field-wrapper"}>
<AsyncSelect
loadOptions={(inputValue, callback) => {
Requests.get(
process.env.REACT_APP_API_BASE_URL + field.source,
(status, data) => {
callback(data);
}
);
}}
styles={selectCustomStyles}
defaultOptions
name={field.name}
placeholder={field.label}
onChange={this.handleSelectChange}
/>
</div>
);
} else if(typeof field.dependsOn !== "undefined") {
return(<div key={i} className={"field-wrapper"}>
<AsyncSelect
styles={selectCustomStyles}
placeholder={field.label}
defaultOptions={this.state.selectOptions[field.name]}
loadOptions={this.state.selectOptions[field.name]}
/>
</div>)
} else {
const disabled =
typeof field.dependsOn !== "undefined" && field.dependsOn !== ""
? this.state.selectOptions[field.name] != null
? false
: true
: false;
return (
<div key={i} className={"field-wrapper"}>
<Select
styles={selectCustomStyles}
placeholder={field.label}
//isLoading={this.state.selectOptions[field.name].length ? true : false}
isDisabled={disabled}
name={field.name}
options={this.state.selectOptions[field.name]}
/>
</div>
);
}
}
case "input":
{
let suffix;
let inputAppendClass;
if (typeof field.suffix !== "undefined" && field.suffix !== "") {
inputAppendClass = "input-has-append";
suffix = <span className={"input-append"}>{field.suffix}</span>;
}
return (
<div
key={i}
className={classnames("field-wrapper input", inputAppendClass)}
style={fieldStyle}
>
<input
placeholder={field.label}
type="text"
className={"input-field"}
onChange={event => this.handleInputChange(field.name, event)}
/>
{suffix}
</div>
);
}
break;
case "checkbox":
{
containerClass = "checkbox-fields";
let radios = field.options.map((option, b) => {
return (
<div key={i + b} className={"field-wrapper checkbox-button"}>
<input
placeholder={option.label}
id={option.name + "_" + i + b}
type={"checkbox"}
className={"input-field"}
/>
<label htmlFor={option.name + "_" + i + b}>
<div className={"label-name"}>{option.label}</div>
<span className={"info-icon"}></span>
<div className={"hint"}>{option.hint}</div>
</label>
</div>
);
});
return radios;
}
break;
case "radio":
{
let radios = field.options.map((option, k) => {
return (
<div key={i + k} className={"field-wrapper radio-button"}>
<input
name={option.name}
id={option.name + "_" + i + k}
placeholder={option.label}
type={"radio"}
className={"input-field"}
/>
<label htmlFor={option.name + "_" + i + k}>
<div className={"label-name"}>{option.label}</div>
<div className={"hint"}>{option.hint}</div>
</label>
</div>
);
});
return radios;
}
break;
default:
break;
}
});
return (
<div className={classnames("fields-group", containerClass)}>{fields}</div>
);
}
}
export default FieldsRenderer;
For example I has react-select Async field. I use for manage form formik. At first you create field:
<AsyncSelect
name="first"
...
onChange={(name, value) => {
// you can write what you want but here small example what I do for other
// two fields
setFieldValue('second', null);
setFieldValue('third', null);
return setFieldValue(name, value);
}}
/>
And second field:
<AsyncSelect
name="second"
key={!!values.first && !!values.first.id ? values.first.id : null}
...
onChange={(name, value) => {
setFieldValue('third', null);
return setFieldValue(name, value);
}}
/>
There is i give key and change key value on changes first field. Because if you don't do it second field don't know when first field changes value. And if you give uniq changeable key second can load from remote data which depends from first field.
And third field:
<AsyncSelect
name="third"
key={!!values.third && !!values.third.id ? values.third.id : null}
...
onChange={setFieldValue}
/>
This is easy way to manage depended three or more fields. I think this you understand this logic.

change color of ui-state-highlight to red color in datepicker

here was my code
var dates = #Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewData["ph"]));
$('#StartDate').datepicker({
format: 'dd-M-yyyy',
autoclose: true,
beforeShowDay: function (date) {
for (var i = 0; i < dates.length; i++) {
if (new Date(dates[i]).toString() == date.toString()) {
return [true, 'ui-state-highlight'];
}
}
return [true];
}
});
i had the date 18th was outlined in yellow.
how can i change it into red solid?
You could do this via CSS:
.ui-state-highlight {
border-color: red;
}
An example:
var dtNow = new Date();
function addDays(d) {
return d * 86400000;
}
function showMyDate(d) {
return d.getDate() + (d.getMonth() + 1) + d.getFullYear();
}
var dates = [
new Date(dtNow.getTime() + addDays(5)),
new Date(dtNow.getTime() + addDays(10)),
new Date(dtNow.getTime() + addDays(12)),
];
$(function() {
$("#datepicker").datepicker({
format: 'dd-M-yyyy',
autoclose: true,
beforeShowDay: function(date) {
var status = [];
$.each(dates, function(key, myDate) {
if (showMyDate(myDate) === showMyDate(date)) {
status = [true, 'ui-state-highlight highlight-red', ''];
} else {
status = [true, '', ''];
}
});
return status;
}
});
});
In this example, I have added two classes: ui-state-highlight and highlight-red. This way I can directly change just the ones that need to be red.
CSS
td.ui-state-highlight.highlight-red {
border-color: red;
}
Working Example: https://jsfiddle.net/Twisty/6fapkykr/

Add a additional <li> tag to the end of rails3-jquery-autocomplete plugin

I'm trying to add an addition tag to the end of the autocomplete list.
$('#address ul.ui-autocomplete').append("<li>Add Venue</li>");
I'm trying to figure out where I can place the code above to add the extra li to the autocomplete list.
Any help will be deeply appreciated.
This is the rails3-jquery-autocomplete file.
source: function( request, response ) {
$.getJSON( $(e).attr('data-autocomplete'), {
term: extractLast( request.term )
}, function() {
$(arguments[0]).each(function(i, el) {
var obj = {};
obj[el.id] = el;
$(e).data(obj);
});
response.apply(null, arguments);
});
},
open: function() {
// when appending the result list to another element, we need to cancel the "position: relative;" css.
if (append_to){
$(append_to + ' ul.ui-autocomplete').css('position', 'static');
}
},
search: function() {
// custom minLength
var minLength = $(e).attr('min_length') || 2;
var term = extractLast( this.value );
if ( term.length < minLength ) {
return false;
}
},
focus: function() {
// prevent value inserted on focus
return false;
},
select: function( event, ui ) {
var terms = split( this.value );
// remove the current input
terms.pop();
// add the selected item
terms.push( ui.item.value );
// add placeholder to get the comma-and-space at the end
if (e.delimiter != null) {
terms.push( "" );
this.value = terms.join( e.delimiter );
} else {
this.value = terms.join("");
if ($(this).attr('data-id-element')) {
$($(this).attr('data-id-element')).val(ui.item.id);
}
if ($(this).attr('data-update-elements')) {
var data = $(this).data(ui.item.id.toString());
var update_elements = $.parseJSON($(this).attr("data-update-elements"));
for (var key in update_elements) {
$(update_elements[key]).val(data[key]);
}
}
}
var remember_string = this.value;
$(this).bind('keyup.clearId', function(){
if($(this).val().trim() != remember_string.trim()){
$($(this).attr('data-id-element')).val("");
$(this).unbind('keyup.clearId');
}
});
$(this).trigger('railsAutocomplete.select');
return false;
}
});
}
Solved it with this.
$('#address').bind('autocompleteopen', function(event,data){
$('<li id="ac-add-venue">Add venue</li>').appendTo('ul.ui-autocomplete');
});

jQuery Mobile Slider / Carousel

I need to make a jQuery "Carousel" pretty similar to the one in this page: http://m.henrys.com/
There are plenty of "carousel" jQuery plugins, but how can I bind a carousel next/prev page action to the "swipe" mobile phone/tablet gesture?
Either you use a JQM plugin for that (I've seen some available), or you add your own touch event management and manually call the next/prev on your chosen plugin.
For example,
$(document).swiperight(function(){
jqPlugin.goPrev();
});
$(document).swipeleft(function(){
jqPlugin.goNext();
});
More details on JQM events can be found in their documentation
Here is code of their jQuery carousel plugin
(function ($) {
$.fn.slideCarousel = function (options) {
var options = jQuery.extend({
duration: 500,
current_slide: 0,
counter_slide: false,
structure_counter_parent: "<div class='slider-counter'></div>",
structure_counter_el: "<span></span>",
counter_slide_number: false,
btn_next: false,
btn_prev: false,
slide_switch: false,
slide_timer: 10000
}, options);
return this.each(function () {
var elem = this;
var slides = $(elem).children();
var slide_last = slides.length - 1;
var img_list = $(elem).find('img');
var current_slide = options.current_slide;
var current_slide_counter = options.current_slide;
var width_elem;
var nav_version = navigator.appVersion;
var permit_next = true;
var css_transitions;
var css_transform;
var _timer;
var transit_timer;
var agent = null;
var orient_change = true;
var link_counter;
$(elem).closest("*[data-role='page']").bind('pageshow', setup);
$(window).bind('resize orientationchange', function () {
if (!permit_next) {
orient_change = false;
return;
}
size_change();
});
function size_change() {
size_slider();
fix_slider();
return false;
}
if (css_supports('transition')) {
css_transitions = true;
if (agent === null) {
agent = GetAgent();
}
var agent_low = agent.replace(/^[a-zA-Z]/, function (value) {
return value.toLowerCase();
});
slides.bind(agent_low + 'TransitionEnd transitionend', TransitionEnd);
}
if (css_supports('transform')) {
if (agent === null) {
agent = GetAgent();
}
if (agent == 'Webkit') {
if (nav_version.indexOf('BlackBerry') == -1 || nav_version.indexOf('Version/7') == -1) {
if (nav_version.indexOf('Android') == -1 || $(elem).closest("*[data-role='page']").find('select').length == 0) {
css_transform = true;
slides.css(agent + 'Transform', 'translate3d(0px,0px,0px)');
}
}
}
}
if (nav_version.indexOf('Android 2.1') != -1) {
if (document.getElementsByTagName('iframe').length > 0) {
$(elem).closest("*[data-role='page']").bind('pagebeforehide', function () {
$(this).nextAll("[data-role='page']").bind('pagebeforeshow', function () {
window.location.reload();
});
});
}
}
function css_supports(css_prop) {
var div = document.createElement('div'),
vendors = 'Khtml Ms O Moz Webkit'.split(' '),
len = vendors.length;
if (css_prop in div.style) return true;
css_prop = css_prop.replace(/^[a-z]/, function (val) {
return val.toUpperCase();
});
while (len--) {
if (vendors[len] + css_prop in div.style) {
agent = vendors[len];
return true;
}
}
return false;
}
function GetAgent() {
$.browser.chrome = /chrome/.test(navigator.userAgent.toLowerCase());
if ($.browser.chrome) return "Moz";
if ($.browser.mozilla) return "Moz";
if ($.browser.opera) return "O";
if ($.browser.safari) return "Webkit";
if ($.browser.msie) return "Ms";
}
function setup() {
if (agent == 'Webkit') {
if (img_list.length > 0) img();
}
loadEnd();
}
function img() {
var call_back = 0;
var error_back = 0;
img_list.each(function () {
$(this).bind('error', function () {
error_back++;
img_event(call_back + error_back);
});
$(this).bind('load', function () {
call_back++;
img_event(call_back + error_back);
});
});
}
function img_event(event_back) {
if (event_back == img_list.length) {
loadEnd();
}
}
function loadEnd() {
addClass();
size_slider();
fix_slider();
};
function addClass() {
var i = 0;
slides.each(function () {
$(this).addClass('slide-item-' + i);
i++;
})
}
function size_slider() {
var height = 0;
offTransition();
width_elem = $(elem).width();
slides.css('width', width_elem);
slides.each(function () {
if ($(this).outerHeight() > height) height = $(this).outerHeight();
});
$(elem).css('height', height);
}
function fix_slider() {
offTransition();
if (css_transform) {
slides.not('.slide-item-' + current_slide).css(agent + 'Transform', 'translate3d' + '(' + width_elem + 'px,0,0)');
slides.filter('.slide-item-' + current_slide).css(agent + 'Transform', 'translate3d(0,0,0)');
return;
}
slides.not('.slide-item-' + current_slide).css('left', width_elem);
slides.filter('.slide-item-' + current_slide).css('left', 0);
}
if (options.counter_slide) {
$(elem).after(options.structure_counter_parent);
link_counter = $(elem).next();
slides.each(function () {
link_counter.append(options.structure_counter_el);
});
if (options.counter_slide_number) {
var i = 1;
link_counter.find("*:empty").each(function () {
$(this).text(i);
i++;
})
}
}
addCheck();
function slideCounter() {
link_counter.children().removeClass('current');
link_counter.children().eq(current_slide).addClass('current');
}
function addCheck() {
if (options.counter_slide) slideCounter();
if (options.slide_switch) onTimer();
}
function onTimer() {
_timer = setTimeout(function () {
slideNext();
}, options.slide_timer)
}
function offTransition() {
if (css_transitions) {
slides.css('transition-property', 'none')
.css(agent + 'TransitionProperty', 'none');
}
}
function TransitionEnd() {
if (!orient_change) {
size_change();
orient_change = true;
}
permit_next = true;
}
$(elem).bind('swipeleft', slideNext);
if (options.btn_next) {
$(options.btn_next).bind('tap', slideNext);
};
$(elem).bind('swiperight', slidePrev);
if (options.btn_prev) {
$(options.btn_prev).bind('tap', slidePrev);
};
function checkDevice() {
if (true) {
$(document).scrollTop($(document).scrollTop() + 1);
}
}
function preparation_next() {
var current_slide_;
offTransition();
if (current_slide > slide_last) current_slide_ = 0;
else current_slide_ = current_slide;
if (css_transform) {
slides.filter('.slide-item-' + current_slide_).css(agent + 'Transform', 'translate3d' + '(' + width_elem + 'px,0,0)');
return;
}
slides.filter('.slide-item-' + current_slide_).css('left', width_elem);
}
function preparation_prev() {
var current_slide_;
offTransition();
if (current_slide < 0) current_slide_ = slide_last;
else current_slide_ = current_slide;
if (css_transform) {
slides.filter('.slide-item-' + current_slide_).css(agent + 'Transform', 'translate3d' + '(' + (-width_elem) + 'px,0,0)');
return;
}
slides.filter('.slide-item-' + current_slide_).css('left', -width_elem);
}
function slideNext(event) {
if (event) event.stopPropagation();
if (!permit_next) return;
if (options.slide_switch) clearTimeout(_timer);
current_slide++;
preparation_next();
slideToggle('next');
}
function slidePrev(event) {
if (event) event.stopPropagation();
if (!permit_next) return;
if (options.slide_switch) clearTimeout(_timer);
current_slide--;
preparation_prev();
slideToggle('prev');
}
function slideToggle(direct) {
if (css_transitions) {
if (transit_timer) return;
transit_timer = setTimeout(function () {
slides.css('transition', 'all ' + options.duration + 'ms')
.css(agent + 'Transition', 'all ' + options.duration + 'ms');
setTimeout(function () {
if (direct == 'next') {
if (css_transform) {
slides.filter('.slide-item-' + (current_slide - 1)).css(agent + 'Transform', 'translate3d' + '(' + (-width_elem) + 'px,0,0)');
if (current_slide > slide_last) current_slide = 0;
slides.filter('.slide-item-' + current_slide).css(agent + 'Transform', 'translate3d(0,0,0)');
}
else {
slides.filter('.slide-item-' + (current_slide - 1)).css('left', -width_elem);
if (current_slide > slide_last) current_slide = 0;
slides.filter('.slide-item-' + current_slide).css('left', 0);
}
}
else if (direct == 'prev') {
if (css_transform) {
slides.filter('.slide-item-' + (current_slide + 1)).css(agent + 'Transform', 'translate3d' + '(' + width_elem + 'px,0,0)');
if (current_slide < 0) current_slide = slide_last;
slides.filter('.slide-item-' + current_slide).css(agent + 'Transform', 'translate3d(0,0,0)');
}
else {
slides.filter('.slide-item-' + (current_slide + 1)).css('left', width_elem);
if (current_slide < 0) current_slide = slide_last;
slides.filter('.slide-item-' + current_slide).css('left', 0);
}
}
addCheck();
transit_timer = false;
}, 1);
}, 20);
}
else {
if (direct == 'next') {
slides.filter('.slide-item-' + (current_slide - 1)).animate({ left: -width_elem }, options.duration);
if (current_slide > slide_last) current_slide = 0;
slides.filter('.slide-item-' + current_slide).animate({ left: 0 }, options.duration, TransitionEnd);
}
else if (direct == 'prev') {
slides.filter('.slide-item-' + (current_slide + 1)).animate({ left: width_elem }, options.duration);
if (current_slide < 0) current_slide = slide_last;
slides.filter('.slide-item-' + current_slide).animate({ left: 0 }, options.duration, TransitionEnd);
}
addCheck();
}
if (options.duration > 1) permit_next = false;
}
});
};
})(jQuery);

Resources