Use data source from a function (dynamic datasource) - Select2 v4 - javascript

In the previous versions one can easily get this done by:
someDynamicData=function(){
//return some data...
}
$("#lga").select2({
width: '100%',
allowClear: false, placeholder: "--- please select ---",
data: function () {
return {results: someDynamicData, text: 'name'};
}
});
I this dosen't work with the new select2 v4. How do I achieve this in the new select2 v4.

For anyone that might be stocked as much as I am with select2 v4. I got a workaroud. Please note that I am some javascript guru and there might be some better way around this issue. For the time being this is rocking:
Case study: I have a chained select options which share from a list JSON Objects: here I am show only Subject and Level example just to keep it simple. When a Subject is selected I what to initialize the Level data source from the selected Subject's data source
function getDynamicData(){
return [
{"code": "ACC", "name": "ACCOUNTING", "levels": [
{"id": 3, "name": "SS 1", "description": "Senior Secondary School 1", "type": "Standard", "resultTemplates": []},
....
]}
....
];
}
$.fn.select2.amd.require(['select2/data/array', 'select2/utils'],
function (ArrayData, Utils) {
function CustomData($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
}
Utils.Extend(CustomData, ArrayData);
CustomData.prototype.query = function (params, callback) {
subjects = getDynamicData();
$.map(subjects, function (d) {//Required only when the object do not have either id/text
d.id = d.code;
d.text = d.name;
return d;
});
callback({results: subjects});
};
$("#subjects").select2({
width: '100%',
dataAdapter: CustomData
});
}
);
This works fine but then I realized that I am repeating many things hence it is time for cleanup
//Added this function to a javascript file on my template (shared across pages)
function initMySelect2(myQuery, mySelector, props) {
$.fn.select2.amd.require(['select2/data/array', 'select2/utils'],
function (ArrayData, Utils) {
function CustomData($element, options) {
CustomData.__super__.constructor.call(this, $element, options);
}
Utils.Extend(CustomData, ArrayData);
CustomData.prototype.query = myQuery;//Pass the query function as a parameter
$(mySelector).select2(props(CustomData));//Initialise the select2 with the custom data
}
);
}
//Used this to initialize select2
initMySelect2(function (params, callback) {
callback({results: getDynamicData()});
},
"#subjects",
function (myCustomData) {
return {
width: '100%',
placeholder: '---please select subjects ---',
dataAdapter: myCustomData
};
}
);
Reference https://select2.github.io/announcements-4.0.html
I hope this will help someone out there.

Related

Execute javascript code delivered via PHP using AJAX

I have been stumped on this for about 2 hours now.
My problem is that I need to load an array from a MySQL database using PHP and Ajax, and use the array in JavaScript.
I got that part working fine however the part where it references "onClick" and contains a function to run does not work. It provides numerous errors which say the exact same thing.
Uncaught RangeError: Maximum call stack size exceeded
at buttons.<computed>.onClick (app.js:1281)
The example of the array is the following:
[
{
"text": "Lost to Competitor",
"onClick": "closeOpportunity(\"Lost to Competitor\", el, stages)"
},
{
"text": "No Budget \/ Lost Funding",
"onClick": "closeOpportunity(\"No Budget \/ Lost Funding\", el, stages)"
},
{
"text": "No Decision \/ Non-responsive",
"onClick": "closeOpportunity(\"No Decision \/ Non-responsive\", el, stages)"
},
{
"text": "Price",
"onClick": "closeOpportunity(\"Price\", el, stages)"
},
{
"text": "Other",
"onClick": "closeOpportunity(\"Other\", el, stages)"
},
{
"text": "Won via Another Opportunity",
"onClick": "closeOpportunity(\"Won via Another Opportunity\", el, stages)"
}
]
My code for loading the array is the following:
function closeOpportunity(name, el, stages) {
$$("#opportunity_loss_reason2").text(name);
$$("#closedType").text("Closed Lost");
$$("#convertToProject").hide();
$$("#lostReasonLI").show();
upStepper(el, stages);
}
var stages = [
"enquiry",
"qualification",
"proposal",
"negotiation",
"closed"
];
var buttons = [];
app.request.json('scripts/lostButtonsArray.php', function (data) {
buttons = data;
console.log(buttons);
});
buttons.forEach((v, i) => {
console.log(v['onClick']);
buttons[i]['onClick'] = function() { window.eval.call(window, v['onClick'])(el, stages); };
});
app.dialog.create({
title: 'ECOM',
text: 'Why was the opportunity lost?',
cssClass: 'custom-dialog',
closeByBackdropClick: 'true',
buttons: buttons,
verticalButtons: true,
}).open();
I have already tried using regular eval() and loading the code directly without any sort of helper (eval, window.eval).
I will be happy to provide more information to help solve this problem if I haven't provided enough information.
Found the solution.
I was trying to load "name" instead of "text"
Working function
app.request.json('scripts/lostButtonsArray.php', function (data) {
buttons = data;
buttons.forEach((v, i) => {
buttons[i]['onClick'] = function() { eval('closeOpportunity')(v['text'], el, stages); };
});
});

Selectize render method is not called and my options are not rendering

I'm using selectize.js for remote search and get options against that search for my select input.
I've seen example code in their demo
<script type="application/javascript">
$(function () {
$('#workers_paid').selectize({
placeholder: "No worker Is selected",
valueField: "name",
labelfield : "name",
searchField: 'name',
render: {
option: function (item,escape) {
console.log(item);
}
},
onLoad : function (data) {
}
,
load: function (query, callback) {
alert(query);
let data = JSON.parse('{"users" : [{"user_name": "Humza"},{"user_name": "Humza"},{"user_name": "Humza"},{"user_name": "Humza"},{"user_name": "Humza"},{"user_name": "Humza"}]}');
callback(data.users);
}
});
});
</script>
This is my code that i've written for loading a static data but still render is not logging any data in console .... Onload function is also working just render is not calling anything or any options is not being created.
Sorry for bad english and thanks in advance

AutoComplete with Key-Value in grid, showing key when focus

I am using paramquery grid component in which I am trying to use autocomplete.
Column Model for branch:
{ title: "Branch", dataIndx: "branchId", width: 150,
filter: { type: "select",
condition: 'equal',
prepend: { '': '--All--' },
listeners: ['change'],
valueIndx: "branchId",
labelIndx: "branchName",
options: branchList,
},
editor: {
type: "textbox",
init: autoCompleteEditor
//type: function (ui) { return dropdowneditor(this, ui); }
},
render: function (ui) {
for (var i = 0; i < branchList.length; i++) {
var option = branchList[i];
if (option.branchId == ui.rowData.branchId) {
return option.branchName;
}
}
}
}
autoCompleteEditorMethod:
var autoCompleteEditor = function (ui) {
var $inp = ui.$cell.find("input");
//initialize the editor
$inp.autocomplete({
source: function(request, response) {
var rows = imAutocompleteJSONParse(branchList);// this method converting my JSON object into Value and label format.
return response(rows);
},
selectItem: { on: true }, //custom option
highlightText: { on: true }, //custom option
minLength: 0,
select: function(event, ui) {
event.preventDefault();
$(this).val(ui.item.label);
},
focus: function(event, ui) {
event.preventDefault();
$("#search").val(ui.item.label);
}
}).focus(function () {
//open the autocomplete upon focus
$(this).autocomplete("search", "");
});
}
I get branch id into my grid and I have branchList JSON which have branch id & branch Name. Inside grid my render function showing branchName on UI.
But when I click on searchable dropdown I'm getting branch id.
Below snapshot may explain my issue properly.
Summary of issue: I am getting branch id in Grid. With help of render method I am able to show branch name on grid. but when I click on textbox I getting branch id.
http://jsfiddle.net/v4zx8tjc/4/
Like blackmiaool suggests in his comment, this question would be easier to answer with a live demo using something like JSFiddle.
Based on what I can see in your question, which isn't that much, there are a few areas I would take a second look at.
The Source function in JQuery.autoComplete. Where is branchList coming from? I don't see it declared anywhere and why are you not using the 'request' param?
Not sure what your custom properties are doing but it might be a good idea to verify those are not interfering with the results.
Edit 1: Looking back at the code you posted I think I see where your branchList variable is coming from. It would be very helpful to see your imAutocompleteJSONParse() method because I believe that may be where things are breaking down.

Algolia template if no hits are returned

I've implemented my own Algolia PoC based of https://www.algolia.com/doc/search/auto-complete and I'm now struggling with a specific use case: how can I handle a search which does not return any hits?
Here is my code:
I've been able to identify and detect when/where no hits are returned, but I can't do anything beside just using a console.log(). I tried to get a custom return_msg but I can't call the function.
I also tried to do some tweak under suggestion: function(suggestion) but this function is never called if no hits are returned.
I also did not found any documentation about this "Templates" section on https://github.com/algolia/autocomplete.js
$('#q').autocomplete({ hint: false }, [
{
source: function(q, cb) {
index.search(q,
{ hitsPerPage: 10 },
function(error, content) {
if (error) {
cb([]);
return;
}
if (content.nbHits == 0)
{ return_msg = '<h5> Sorry, no result </h5>';
// DO something here
console.log(return_msg);
// console.log return "Sorry, no result"
}
cb(content.hits, content);
});
},
displayKey: 'game',
templates: {
suggestion: function(suggestion) {
return_msg = '<h5> '+ suggestion.MY_ATTRIBUTE + '</h5>'
return return_msg;
}
}
}
]).on('autocomplete:selected', function(event, suggestion, dataset) {
window.location = (suggestion.url);
});
Any pointers would be greatly appreciated =)
Using the templates option of your dataset you can specify the template to use when there are no results:
source: autocomplete.sources.hits(indexObj, { hitsPerPage: 2 }),
templates: {
suggestion: // ...
header: // ...
footer: // ...
empty: function(options) {
return '<div>My empty message</div>';
}
}
Full documentation here.

FuelUX datagrid not loading (using example)

I'm new to FuelUX so I was trying to get this to work, based on the example provided:
require(['jquery','data.js', 'datasource.js', 'fuelux/all'], function ($, sampleData, StaticDataSource) {
var dataSource = new StaticDataSource({
columns: [{property:"memberid",label:"LidId",sortable:true},{property:"name",label:"Naam",sortable:true},{property:"age",label:"Leeftijd",sortable:true}],
data: sampleData.memberdata,
delay: 250
});
$('#MyGrid').datagrid({
dataSource: dataSource,
stretchHeight: true
});
});
});
With this as the data:
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(factory);
} else {
root.sampleData = factory();
}
}(this, function () {
return {
"memberdata": [{
"memberid": 103,
"name": "Laurens Natzijl",
"age": "25"
}, {
"memberid": 104,
"name": "Sandra Snoek",
"age": "25"
}, {
"memberid": 105,
"name": "Jacob Kort",
"age": "25"
}, {
"memberid": 106,
"name": "Erik Blokker",
"age": "25"
}, {
"memberid": 107,
"name": "Jacco Ruigewaard",
"age":"25"
},{ /* etc */ }]
}
}));
I've got no console errors, no missing includes. Everthing works just fine - it even looks like it's loading. Except nothing shows up in the datagrid but '0 items'.
Any suggestions? I think I did everything the example provided...
EDIT: 14:33 (Amsterdam)
There seems to be a difference when I put this in console:
My page:
require(['jquery','data.js','datasource.js', 'fuelux/all'], function ($, sampleData, StaticDataSource) {
var dataSource = new StaticDataSource({
columns: [{property:"memberid",label:"LidId",sortable:true},{property:"name",label:"Naam",sortable:true},{property:"age",label:"Leeftijd",sortable:true}],
data: sampleData.memberdata,
delay: 250
});
console.debug(dataSource);
});
1st row in console:
function localRequire(deps, callback, errback) { /* etc */ }
2nd row in console:
StaticDataSource {_formatter: undefined, _columns: Array[3], _delay: 250, _data: Array[25], columns: function…}
FuelUX Example:
require(['jquery', 'sample/data', 'sample/datasource', 'sample/datasourceTree', 'fuelux/all'], function ($, sampleData, StaticDataSource, DataSourceTree) {
var dataSource = new StaticDataSource({
columns: [{property: 'toponymName',label: 'Name',sortable: true}, {property: 'countrycode',label: 'Country',sortable: true}, {property: 'population',label: 'Population',sortable: true}, {property: 'fcodeName',label: 'Type',sortable: true}],
data: sampleData.geonames,
delay: 250
});
console.debug(dataSource);
});
1st row in console:
StaticDataSource {_formatter: undefined, _columns: Array[4], _delay: 250, _data: Array[146], columns: function…}
2nd row in console:
function (deps, callback, errback, relMap) { /* etc */ }
Maybe this will help you help me :)
I didn't see all of the information I needed to provide a finite answer. The real magic is the datasource.js file (which you had not provided).
I thought an easier way of demonstrating all the necessary pieces would be to put together a JSFiddle showing your data in use and all the pieces that were necessary.
Link to JSFiddle of Fuel UX Datagrid sample with your data
Adam Alexander, the author of the tool, also has written a valuable example of using the dataGrid DailyJS Fuel UX DataGrid
// DataSource Constructor
var StaticDataSource = function( options ) {
this._columns = options.columns;
this._formatter = options.formatter;
this._data = options.data;
this._delay = options.delay;
};
StaticDataSource.prototype = {
columns: function() {
return this._columns
},
data: function( options, callback ) {
var self = this;
var data = $.extend(true, [], self._data);
// SEARCHING
if (options.search) {
data = _.filter(data, function (item) {
for (var prop in item) {
if (!item.hasOwnProperty(prop)) continue;
if (~item[prop].toString().toLowerCase().indexOf(options.search.toLowerCase())) return true;
}
return false;
});
}
var count = data.length;
// SORTING
if (options.sortProperty) {
data = _.sortBy(data, options.sortProperty);
if (options.sortDirection === 'desc') data.reverse();
}
// PAGING
var startIndex = options.pageIndex * options.pageSize;
var endIndex = startIndex + options.pageSize;
var end = (endIndex > count) ? count : endIndex;
var pages = Math.ceil(count / options.pageSize);
var page = options.pageIndex + 1;
var start = startIndex + 1;
data = data.slice(startIndex, endIndex);
if (self._formatter) self._formatter(data);
callback({ data: data, start: 0, end: 0, count: 0, pages: 0, page: 0 });
}
};
If you were to provide your markup and what your "datasource.js" file contains, I may be able to help you further.
I think the demonstration provides much information on any pieces you may not have understood.
Adding on to creatovisguru's answer:
In his JSFiddle example, pagination is broken. To fix it, change the following line:
callback({ data: data, start: start, end: end, count: count, pages: pages, page: page });
I had the exact same issue, when tried to integrate with Django. The issue I believe is on this line :
require(['jquery','data.js','datasource.js', 'fuelux/all'], function ($, sampleData, StaticDataSource) {
I was not able to specify file extension, my IDE (pycharm), would mark "red", when used "data.js", so it needs to stay without an extension, such as "sample/data"
What I end up doing to make it work, is downloading the full fuelux directory from github in /var/www/html on a plain Apache setup ( no django, to avoid URL.py issues for static files ) and everything works using their example. Here are the steps to get you started :
cd /var/www/html
git clone https://github.com/ExactTarget/fuelux.git
and you will end up with fuelux in /var/www/html/fuelux/
in your browser, navigate to : http://foo.com/fuelux/index.html ( assuming your default document root is /var/www/html )
good luck!

Categories