Tooltip C3JS - Add a row in the table - tooltip

I'm trying to add a footer on the table displayed in the tooltip. Inside this row I would like to show a particular data loaded from a json file.
Chart:
<script>
var scene;
$.getJSON('assets/json/chartc3.json', function (data) {
scene = data;
var chart = c3.generate({
bindto: '#chartc3',
data:
{
json: scene,
keys:
{
x: 'round',
value: ['Marketable', 'Total Requested Capacity', 'Your Bid'],
},
types: {
Marketable: 'area'
},
colors: {
Marketable: '#A09FA2',
'Total Requested Capacity': '#272E80',
'Your Bid': '#8EBF60'
}
},
axis:
{
x: {
tick:
{
culling:
{
max: 10
}
},
type: 'category'
},
y:
{
min: 0,
padding: {
bottom: 0
},
tick:
{
values: [[0], [d3.max(d3.values(scene))]],
format: function (d) { return d3.format(',f')(d) + ' kWh/h' }
//or format: function (d) { return '$' + d; }
}
}
},
tooltip: {
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
var $$ = this, config = $$.config, CLASS = $$.CLASS,
titleFormat = config.tooltip_format_title || defaultTitleFormat,
nameFormat = config.tooltip_format_name || function (name) { return name; },
valueFormat = config.tooltip_format_value || defaultValueFormat,
text, i, title, value, name, bgcolor;
// You can access all of data like this:
for (i = 0; i < d.length; i++) {
if (!(d[i] && (d[i].value || d[i].value === 0))) { continue; }
// ADD
if (d[i].name === 'data2') { continue; }
if (!text) {
title = 'MY TOOLTIP'
text = "<table class='" + CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
}
name = nameFormat(d[i].name);
value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
text += "<tr class='" + CLASS.tooltipName + "-" + d[i].id + "'>";
text += "<td class='name'><span style='background-color:" + bgcolor + "; border-radius: 5px;'></span>" + name + "</td>";
text += "<td class='value'>" + value + "</td>";
text += "</tr>";
}
**var surchargedata;
$.getJSON('assets/json/surcharge.json', function(data)
{
console.log("Prima"+text);
surchargedata=data;
text += "<tr class='" + CLASS.tooltipName + "-Surcharge" + "'>";
text += "<td class='name'>" + surchargedata[i].Surcharge+ "</td>";
text += "<td class='value'>" + surchargedata[i].Surcharge+ "</td>";
text += "</tr></table>";
console.log(text);
})**
return text;
}
}
});
});
</script>
I printed the log and the table seems generated well but if you have a look at the tooltip :
I can't see the last row.
Here the log for the table generated:
<table class='c3-tooltip'>
<tr>
<th colspan='2'>MY TOOLTIP</th>
</tr>
<tr class='c3-tooltip-name-Marketable'>
<td class='name'><span style='background-color:#A09FA2; border-radius: 5px;'>
</span>Marketable
</td>
<td class='value'>5,220,593 kWh/h</td>
</tr>
<tr class='c3-tooltip-name-Total Requested Capacity'>
<td class='name'><span style='background-color:#272E80; border-radius: 5px;'>
</span>Total Requested Capacity
</td>
<td class='value'>16,449,051 kWh/h</td>
</tr>
<tr class='c3-tooltip-name-Your Bid'>
<td class='name'>
<span style='background-color:#8EBF60; border-radius: 5px;'>
</span>Your Bid
</td>
<td class='value'>100,000 kWh/h
</td>
</tr>
<tr class='c3-tooltip-name-Surcharge'>
<td class='name'>50.38</td>
<td class='value'>50.38</td>
</tr>
</table>

You are loading the surcharge data using $.getJSON when you generate your tooltip. And your surcharge line is added to the text that you are generating for the tooltip in the callback. By this time, the actual tooltip function has returned with whatever text was generated before the $.getJSON call.
The easiest way to fix this would be to load your surcharge data first by moving your surcharge $.getJSON to wrap around your original script.
Here is the updated script.
<script>
var surchargedata;
$.getJSON('assets/json/surcharge.json', function (data) {
surchargedata = data;
var scene;
$.getJSON('assets/json/chartc3.json', function (data) {
scene = data;
var chart = c3.generate({
bindto: '#chartc3',
data:
{
json: scene,
keys:
{
x: 'round',
value: ['Marketable', 'Total Requested Capacity', 'Your Bid'],
},
types: {
Marketable: 'area'
},
colors: {
Marketable: '#A09FA2',
'Total Requested Capacity': '#272E80',
'Your Bid': '#8EBF60'
}
},
axis:
{
x: {
tick:
{
culling:
{
max: 10
}
},
type: 'category'
},
y:
{
min: 0,
padding: {
bottom: 0
},
tick:
{
values: [[0], [d3.max(d3.values(scene))]],
format: function (d) { return d3.format(',f')(d) + ' kWh/h' }
//or format: function (d) { return '$' + d; }
}
}
},
tooltip: {
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
var $$ = this, config = $$.config, CLASS = $$.CLASS,
titleFormat = config.tooltip_format_title || defaultTitleFormat,
nameFormat = config.tooltip_format_name || function (name) { return name; },
valueFormat = config.tooltip_format_value || defaultValueFormat,
text, i, title, value, name, bgcolor;
console.log(JSON.stringify(d))
// You can access all of data like this:
for (i = 0; i < d.length; i++) {
if (!(d[i] && (d[i].value || d[i].value === 0))) { continue; }
// ADD
if (d[i].name === 'data2') { continue; }
if (!text) {
title = 'MY TOOLTIP'
text = "<table class='" + CLASS.tooltip + "'>" + (title || title === 0 ? "<tr><th colspan='2'>" + title + "</th></tr>" : "");
}
name = nameFormat(d[i].name);
value = valueFormat(d[i].value, d[i].ratio, d[i].id, d[i].index);
bgcolor = $$.levelColor ? $$.levelColor(d[i].value) : color(d[i].id);
text += "<tr class='" + CLASS.tooltipName + "-" + d[i].id + "'>";
text += "<td class='name'><span style='background-color:" + bgcolor + "; border-radius: 5px;'></span>" + name + "</td>";
text += "<td class='value'>" + value + "</td>";
text += "</tr>";
}
console.log("Prima" + text);
text += "<tr class='" + CLASS.tooltipName + "-Surcharge" + "'>";
text += "<td class='name'>" + surchargedata[i].Surcharge + "</td>";
text += "<td class='value'>" + surchargedata[i].Surcharge + "</td>";
text += "</tr></table>";
console.log(text);
return text;
}
}
});
});
})
</script>

Related

Select2 - missing text on tags (in template)

Following this example:
https://select2.org/data-sources/ajax
Select2 v4.0.13
how do i style the missing text to show up?
// -- - --- - -SELECT2 ------------------
// https://select2.org/data-sources/ajax
function select2CommonSearch(selector, url, placeholder){
$(selector).select2({
ajax: {
url: url,
dataType: 'json',
delay: 200,
data: function (params) {
return {
q: params.term, // search term
};
},
processResults: function (data) {
return {
results: data,
}
},
},
placeholder: placeholder,
allowClear: true,
// minimumInputLength: 1,
templateResult: select2formatSearchResults,
templateSelection: select2formatSearchResultsSelection
});
}
function select2formatSearchResults (repo) {
if (repo.loading) {
return repo.text;
}
var $container = $(
"<div class='select2-result-repository clearfix'>" +
// "<div class='select2-result-repository__avatar'><img src='" + repo.first_name + "' /></div>" +
// "<div class='select2-result-repository__meta'>" + repo.name +
"<div class='select2-result-repository__title'>"+ repo.name +"</div>" +
// "<div class='select2-result-repository__description'></div>" +
// "<div class='select2-result-repository__statistics'>" +
// "<div class='select2-result-repository__forks'><i class='fa fa-flash'></i> </div>" +
// "<div class='select2-result-repository__stargazers'><i class='fa fa-star'></i> </div>" +
// "<div class='select2-result-repository__watchers'><i class='fa fa-eye'></i> </div>" +
// "</div>" +
"</div>" +
"</div>"
);
$container.find(".select2-result-repository__title").text(repo.first_name);
// $container.find(".select2-result-repository__description").text(repo.first_name);
// $container.find(".select2-result-repository__forks").append(repo.first_name + " Forks");
// $container.find(".select2-result-repository__stargazers").append(repo.first_name + " Stars");
// $container.find(".select2-result-repository__watchers").append(repo.first_name + " Watchers");
return $container;
}
function select2formatSearchResultsSelection (repo) {
return repo.text;
}
It works fine for regular items.

How to create autocomplete form with MaterializeCss?

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

Uncaught TypeError: Property 'min' of object #<Object> is not a function

I'm trying to make use of the knockout slider binderhalders that RP Niemeyer has posted a few times. Unfortunately while trying to use it I receive the error within the title.
(function($){
ko.bindingHandlers.slider = {
init: function (element, valueAccessor, allBindingsAccessor) {
var options = allBindingsAccessor().sliderOptions || {};
var sliderValues = ko.utils.unwrapObservable(valueAccessor());
if(sliderValues.min !== undefined) {
options.range = true;
}
options.slide = function(e, ui) {
if(sliderValues.min) {
// Errors here
sliderValues.min(ui.values[0]);
sliderValues.max(ui.values[1]);
} else {
sliderValues.value(ui.value);
}
};
ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
$(element).slider("destroy");
});
$(element).slider(options);
},
update: function (element, valueAccessor) {
var sliderValues = ko.toJS(valueAccessor());
if(sliderValues.min !== undefined) {
$(element).slider("values", [sliderValues.min, sliderValues.max]);
} else {
$(element).slider("value", sliderValues.value);
}
}
};
this.range = {
'cook': function(kitchen, name, label, recipe){
var food = new this.viewModel(kitchen);
food.name = name;
food.label = label;
food.total(recipe.numberOfResults);
food.criteriaMin = recipe.minValue;
food.criteriaMax = recipe.maxValue;
return food;
},
'viewModel': function(kitchen){
var self = this;
this.name = '';
this.label = '';
this.total = window.ko.observable();
this.criteriaMin = ko.observable(0);
this.criteriaMax = ko.observable(100);
this.loading = window.ko.observable(false);
this.template = '';
this.getSelection = function(){
return null;
};
this.setSelection = function(){
};
},
'template': '<th class="idc-td-criteria" scope="row" data-bind="text:label"></th>' +
'<td class="idc-td-value idc-td-slider">' +
' <label for="AmountMin" class="hiddenText">Amount Min</label>' +
' <input type="text" data-default="0" data-maxdecimal="2" class="idc-textinput idc-sliderinput" maxlength="6" data-bind="value: criteriaMin || \'0.00\'">' +
' <span class="slider" data-bind="slider: { min: criteriaMin, max: criteriaMax }, sliderOptions: {min: 0, max: 100, step: 1}"></span>' +
' <label for="AmountMax" class="hiddenText">Amount Max</label>' +
' <input type="text" data-default="10" data-maxdecimal="2" class="idc-textinput idc-sliderinput" maxlength="6" data-bind="value: criteriaMax || \'10.00\'">' +
'</td>' +
'<td class="idc-td-results" data-bind="text:total"></td>' +
'<td class="idc-td-remove">' +
' <a href="#">' +
' <img src="images/column_delete.png" alt="Delete criteria [criteria name]" role="button" />' +
' </a>' +
'</td>'
};
}).call(window.idmsScreener.chefs, jQuery);
I've tried to change it from sliderValues.min() to sliderValues.min = ui.values[0]; However by changing that I can't seem to get the values back correctly. I also tried changing the min and max values of the slider options so that they are not statically set but that throws a completely different error. Any help on solving this would be greatly appreciated.
Was able to resolve this. Determined that I was setting my min and max criteria in correctly. I was doing assignment using an equals sign which was overriding the observable.

Dynamic append of option into select is not working

DDL is not refreshing with new set of options
$("#selectid").live('change', function () {
if ($('option:selected', $(this)).text() == '--Next 50--') {
var currentFifty = (parseInt($(this).val()) - 1);
var upperFifty = parseInt(currentFifty + 50);
var cOptions = '';
for (var i = currentFifty; i < upperFifty; i++) {
if (collection[i].ID != null && collection[i].ID != "undefined") {
cOptions = cOptions + "<option value=" + collection[i].ID + ">" + collection[i].Text + "</option>";
}
}
alert($(this).html());
$(this).append(cOptions);
$(this).append($("<option></option>").val((upperFifty + 1)).html("--Next 50--"));
var allhtml = ($(this).html());
$(this).trigger('refresh');
}
});

Dependent dropdownlist jqgrid

I need to load a dropdownlist dependent using jqgrid. Here's part of my code (I'm using MVC)
{ name: 'parIDUnidadMedida', index: 'parIDUnidadMedida', width: 80, align: 'center', editable: true, edittype: "select",
editrules: { required: true },
editoptions: {
multiple: false,
size: 1,
dataUrl: '#Url.Content("~/")' + 'CertificadoGarantiaExtendidaOpciones/ListarUnidadesMedida/',
buildSelect: function (data) {
var response = jQuery.parseJSON(data);
var s = '<select>';
if (response && response.length) {
for (var i = 0, l = response.length; i < l; i++) {
var ri = response[i];
s += '<option value="' + ri.Value + '">' + ri.Text + '</option>';
}
}
return s + "</select>";
},
dataEvents: [{
type: 'change',
fn: function (e) {
var varIDUnidadMedida = e.currentTarget.value;
newOptions = '';
var arrPlazos = $.ajax({
url: '#Url.Content("~/")' + 'CertificadoGarantiaExtendidaOpciones/ListarPlazos/' + varIDUnidadMedida,
async: false
}).responseText;
var response = jQuery.parseJSON(arrPlazos);
for (var i = 0; i < response.length; i++) {
newOptions += '<option value="' + response[i].Value + '">' + response[i].Text + '</option>';
}
$('parPlazo').html(newOptions);
}
}]
}
},
{ name: 'parPlazo', index: 'parPlazo', width: 80, align: 'center', editable: true, edittype: "select",
editrules: { required: true },
editoptions: {
multiple: false,
size: 1
}
},
As you can see if the parIDUnidadMedida select control change then parPlazo must be updated...
Can you help me?? I don't know how to solve it.
Regards.
Ok... after looking for an answer I got it..
You see I made some minor fixes, but the main reason because it didn't work was because I've never loaded the second dropdownlist (parPlazo). So the select parPlazo didn't have id or name. Obviously it coudl never be reached
Here's the code. I hope this helps you.
Regards
{ name: 'parIDUnidadMedida', index: 'parIDUnidadMedida', width: 80, align: 'center', editable: true, edittype: "select",
editrules: { required: true },
editoptions: {
multiple: false,
size: 1,
dataUrl: '#Url.Content("~/")' + 'CertificadoGarantiaExtendidaOpciones/ListarUnidadesMedida/',
buildSelect: function (data) {
var response = jQuery.parseJSON(data);
var s = '<select>';
if (response && response.length) {
for (var i = 0, l = response.length; i < l; i++) {
var ri = response[i];
s += '<option value="' + ri.Value + '">' + ri.Text + '</option>';
}
}
return s + "</select>";
},
dataEvents: [{
type: 'change',
fn: function (e) {
var varIDUnidadMedida = e.currentTarget.value;
$.ajax({
url: '#Url.Content("~/")' + 'CertificadoGarantiaExtendidaOpciones/ListarPlazos/' + varIDUnidadMedida,
type: 'GET',
success: function (PlazosJson) {
var plazos = eval(PlazosJson);
var plazosHtml = "";
$(plazos).each(function (i, option) {
plazosHtml += '<option value="' + option.Value + '">' + option.Text + '</option>';
});
// Poblar los datos
if ($(e.target).is('.FormElement')) {
// En caso de se formulario de edicion, aƱadir
var form = $(e.target).closest('form.FormGrid');
$("select#parPlazo.FormElement", form[0]).html(plazosHtml);
} else {
// Edicion de una linea
var row = $(e.target).closest('tr.jqgrow');
var rowId = row.attr('id');
var rowId = jQuery("#grid").jqGrid('getGridParam', 'selrow');
jQuery("select#" + rowId + "_parPlazo").append(plazosHtml);
}
}
});
}
}]
}
},
{ name: 'parPlazo', index: 'parPlazo', width: 80, align: 'center', editable: true, edittype: "select",
editrules: { required: true },
editoptions: {
multiple: false,
size: 1,
dataUrl: '#Url.Content("~/")' + 'CertificadoGarantiaExtendidaOpciones/ListarPlazos/1',
buildSelect: function (data) {
var response = jQuery.parseJSON(data);
var s = '<select>';
if (response && response.length) {
for (var i = 0, l = response.length; i < l; i++) {
var ri = response[i];
s += '<option value="' + ri.Value + '">' + ri.Text + '</option>';
}
}
return s + "</select>";
}
}
},

Resources