Why can't I choose value from select2? - javascript

All data is shown and correct but I can't select any value from select2 dropdown.
What is wrong with my code?
jQuery(document).ready(function() {
jQuery('#basic').select2({
minimumInputLength: 0,
multiple: false,
query:function(options) {
var result = ymaps.suggest(options.term).then(function (items) {
var data = [];
var output = {
results : [],
more : null
};
for (var index = 0; index < items.length; ++index) {
console.log(items[index]);
data.push({
id: index,
text: items[index]['displayName'],
})
}
output.results = data;
output.more = true;
console.log(output);
options.callback(output);
});
}
});
jQuery('#basic').on('select2:select', function () {
console.log('on select: ' + jQuery(this).val());});
}

After doing R&D on select2 I found that query method is deprecated (See https://select2.org/configuration/options-api) so try to use ajax method.
Also there is one more issue when I opened the debugger I found that other select2 drop down (I mean select2 used on https://select2.org/) is adding options under drop down but in your case your select box is empty.
I would suggest try asking on their community https://forums.select2.org/

Related

updating the array that is being passed to highcharts in meteor app

I'm using meteor to build a dashboard that uses highcharts to build the charts. Current set up is as follows. The page loads to show a drop down menu. When the user clicks the drop down menu, the client.js queries the database based on the selection, pushes the results to a few global arrays followed by a blaze.render of the template which has the chart. The chart uses the global variables as the series data and the xAxis categories. Problem is that when the user selects a different option from the drop down, the arrays should get updated and the chart re-rendered. But I noticed that the array does not get populated with new values. Instead new values get appended to the array.
Code below:
Template.districtDropdown.events({
'change #selectDistrict' : function(event, template){
// productValues2.length = 0;
// productUsage2.length = 0;
// productFidelity2.length = 0;
// productNames2.length = 0;
event.preventDefault();
var selectedValue = template.$("#selectDistrict").val();
console.log("You Selected " + selectedValue);
var filter = {
find: {
'School District' : selectedValue
}
};
$(filter).ready(function() {
Meteor.subscribe('aggByDistrict', filter, function() {
productUsage2 = [], productValues2 = [], productFidelity2 = [];
productNames2 = _.uniq(CombinedData.find().map( function(doc) { return doc.Product; }));
for(var i = 0; i < productNames2.length; i++) {
productValues2.push(CombinedData.find({'Product' : productNames2[i]}).count());
productUsage2.push(CombinedData.find({'Product' : productNames2[i], 'Usage' : {$gt:0}}).count());
productFidelity2.push(CombinedData.find({'Product' : productNames2[i], 'Fidelity' :1 }).count());
};
console.log(productNames2, productUsage2, productValues2, productFidelity2);
// Renders the highchart that shows the various aggs for selected district
Blaze.render(Template.LicensesDistributedByDistrict, $("#LicensesByDistrictCharts")[0]);
});
});
}
});
If I were to uncomment the productValues2.length = 0 then the chart gets empty arrays.
I know this is probably a a horrible implementation, but I'm trying to learn how to use meteor / highcharts.
It's appending the values because you're not clearing out its existing values.
// productValues2.length = 0;
// productUsage2.length = 0;
// productFidelity2.length = 0;
// productNames2.length = 0;
The code above clears the arrays
Okay, I think I figured out the answer. With the code posted by me earlier, the client side minimongo is populated by the subscribe command when the client makes the first choice from the drop down menu. When the client makes a second choice from the drop down, the server uses the new filter, and published the new documents to the already live collection on the client side minimongodb. To fix this, I modified the code by adding a .stop() at the end, after the chart has been rendered. This stops / clears the client side collection, and the whole process starts again when the client selects a second option from the drop down. Fixed code below:
//Handle the selection event from district dropdowns
Template.districtDropdown.events({
'change #selectDistrict' : function(event, template){
event.preventDefault();
var selectedValue = $(event.target).val();
var filter = {
find: {
'School District' : selectedValue
}
};
// console.log(filter);
$(filter).ready(function() {
var filteredCollection = Meteor.subscribe('aggByDistrict', filter, function() {
productNames2 = [], productUsage2 = [], productValues2 = [], productFidelity2 = [];
console.log(productNames2, productUsage2, productValues2, productFidelity2);
productNames2.length = 0, productUsage2.length = 0, productValues2.length = 0, productFidelity2 .length = 0;
productNames2 = _.uniq(CombinedData.find().map( function(doc) { return doc.Product; }));
for(var i = 0; i < productNames2.length; i++) {
// productValues2 = CombinedData.find({'Product' : productNames2[i]}).map()
productValues2.push(CombinedData.find({'Product' : productNames2[i]}).count());
productUsage2.push(CombinedData.find({'Product' : productNames2[i], 'Usage' : {$gt:0}}).count());
productFidelity2.push(CombinedData.find({'Product' : productNames2[i], 'Fidelity' :1 }).count());
};
console.log(productNames2, productUsage2, productValues2, productFidelity2);
// Renders the highchart that shows the various aggs for selected district
Blaze.render(Template.LicensesDistributedByDistrict, $("#LicensesByDistrictCharts")[0]);
filteredCollection.stop();
});
});
}
});

Angular Check All button

I have a handful of simple checkbox lists that I need to create for an application. I built a "Check All" button for my initial test and it worked beautifully. But, when I changed the code to fetch a subset of the list via a Node call, the list still appeared as expected, but the Check All functionality no longer did. In my initial test, the list was just an array of objects with "description" and "value" but after inserting Node into the middle, the objects also had a $$hashkey property. I'm not sure if this is the source of the problem, but if someone could take a look and tell me what's wrong, I'd appreciate it.
My HTML looks like this:
<div class="row">
<div class="col-md-3" id="semRushApiList_None">
<input type="checkbox" value="semRushCheckAll_None" name="semRushCheckAll_None" ng-click="toggleSemRushApiTypes_None()" /><strong>Check All</strong>
<div ng-repeat="apiCall in semRushApiTypes_None">
<input type="checkbox" name="selectedSemRushApiTypes_None[]" value="{{apiCall.apiName}}" ng-checked="selectedSemRushApiTypes_None.indexOf(apiCall) > -1" ng-click="toggleSemRushApiSelection_None(apiCall)" /> {{apiCall.description}}
</div>
</div>
</div>
My angular js looks like this:
$scope.semRushCheckAll_None = false;
$scope.semRushApiTypes_None = [];
fetchApiTypesByCategory("none").then(function(types){
$scope.semRushApiTypes_None = types;
});
$scope.selectedSemRushApiTypes_None = [];
$scope.toggleSemRushApiTypes_None = function() {
$scope.semRushCheckAll_None = !$scope.semRushCheckAll_None;
if ($scope.semRushCheckAll_None) {
$scope.selectedSemRushApiTypes_None = angular.copy($scope.semRushApiTypes_None);
} else {
$scope.selectedSemRushApiTypes_None = [];
}
};
$scope.toggleSemRushApiSelection_None = function(apiCall) {
var idx = $scope.selectedSemRushApiTypes_None.indexOf(apiCall);
if (idx > -1) {
$scope.selectedSemRushApiTypes_None.splice(idx, 1);
} else {
$scope.selectedSemRushApiTypes_None.push(apiCall);
console.log(JSON.stringify($scope.selectedSemRushApiTypes_None));
}
};
function fetchApiTypesByCategory(category) {
var deferred = $q.defer();
$http.get(rootApiUrl + "/fetchSemRushApiTypesByCategory?category=" + category).then(function(response) {
deferred.resolve(response.data);
}, function(response){
deferred.reject("Error: " + response.data);
});
return deferred.promise;
}
The node call looks like this:
server.route({
method:"GET",
path:"/fetchSemRushApiTypesByCategory",
handler:function(request,reply){
var q = Qs.parse(request.query);
return reply(factory.createApiTypeList(q["category"])).code(200);
}
});
and the factory looks like this:
exports.createApiTypeList = function(category) {
var result = [];
for (var i = 0; i < semRushApiJson.length; i++) {
if (semRushApiJson[i].category === category) {
var description = semRushApiJson[i].description;
var apiName = "";
for (var p = 0; p < semRushApiJson[i].params.length; p++) {
if (semRushApiJson[i].params[p].key == "type") {
apiName = semRushApiJson[i].params[p].value;
break;
}
}
result.push({
"description": description,
"apiName": apiName
});
}
}
return result;
};
Some simple console.log statements have proven that things are being populated as expected, with the exception of the $$hashkey property on the objects coming out of the Node call.
When I check the checkboxes individually, the selected array is populated with a value that doesn't have the $$hashkey and when I check the check all, the selected list gets all of the appropriate values including the $$hashkey, but the checkboxes do not get updated on the UI like they did before I moved the populating of the list to a Node call.
Can anyone tell me what I'm doing wrong here?
V

Get object id on drop with fullCalendar

I am using the fullCalendar plugin to show a calendar with the different events and elements in. Some of then are draggable and therefore possible to alter the date etc. which I need to update in the database as well. But I'm getting stuck because I can't seem to find a way to get that id of the object that is being moved.
I have the code that takes the data out of DB and renders it in the calendar like this:
$scope.temp = [];
$scope.academy = [];
$http.get(api.getUrl('academy', user.id)).success(function (response) {
$scope.temp = response;
for (var j = 0; j < response.length; j++) {
$scope.academy.push({
id: $scope.temp[j].id,
title: $scope.temp[j].name,
start: new Date($scope.temp[j].date).getTime(),
className: 'bg-info bg',
editable: true,
location: $scope.temp[j].location,
info: $scope.temp[j].description
})
if($scope.academy[j].start < $scope.time ) {
$scope.academy[j].className= 'bg-success bg'
}
if(0 < $scope.academy[j].start-$scope.time && $scope.academy[j].start-$scope.time < 172800000) {
$scope.academy[j].className= 'bg-danger bg'
alert('Remember '+$scope.academy[j].title);
}
$('.calendar').fullCalendar('renderEvent',{
id: $scope.academy[j].id,
title: $scope.academy[j].title,
start: $scope.academy[j].start,
className: $scope.academy[j].className,
editable: true,
location: $scope.academy[j].location,
info: $scope.academy[j].info
}, true)
}
});
I then have a onDrop function that is being activated whenever a drop happens. I can verify that with a simple alert().
/* alert on Drop */
$scope.alertOnDrop = function(){
alert($('.calendar').fullCalendar('clientEvents'));
};
This obviously returns an alert with all the objects on the calendar, and if I add a specific id I get that specific object as [object Object]. But I need to get the object and id of whatever object is being dropped on the calendar and I could really use some inputs on how I can achieve that?
alertOnDrop gives you the element as the first argument of your anon function.
$scope.alertOnDrop = function(e){
alert(e.id);
};

Knockout.js computed array property

I've a KnockoutViewModel ViewData this has an array of Items. These items are read from a server with $post.
Now this items have each an id and a link field. the id can be changed in the ui via a combobox. When the id changed, i want to update the link.
For this i re-assigned the id property to be observable and create the link property as computed.
As a result the computed event is raised. But i don't know how to reference the link field correctly. using the item reference, i always get the latest element which was processed in the the for loop.
$.post(url,
function (data, status) {
for (var index = 0; index < data.length; ++index) {
item.Id = ko.observable(data[index].Id);
item.Link = ko.computed(function () {
return url.replace(urlTemplate, item.Id());;
});
}
self.items(data);
});
}
I also tried to create a ItemModel to represent the item and convert each server element to a new ItemModel,but then i see for each entry the data of the last item.
what am i doing wrong ?
$.post(url,
function (data, status) {
var items = $.map(data, function (item) { return new ItemModel(item) });
self.items(items);
});
Try creating a new item object for each in the in the for loop. Something like this,
self.items = ko.observableArray();
for (var index = 0; index < data.length; ++index) {
var item = {
Id: ko.observable(data[index].Id),
Link: ko.computed(function () {
return url.replace(urlTemplate, data[index].Id);
});
};
self.items.push(item);
}

How to serialize delete data with jqGrid, multiselection, and Spring?

Currently, I have an overridden delGridRow call that looks like this (credit to Krams and his Spring tutorial):
var row = $('#grid').jqGrid('getGridParam','selrow');
$('#grid').jqGrid( 'delGridRow', row,
{ url:'deleteRequirement.html',
recreateForm: true,
beforeShowForm: function(form) {
//Change title
$(".delmsg").replaceWith('<span style="white-space: pre;">' +
'Delete selected record?' + '</span>');
//hide arrows
$('#pData').hide();
$('#nData').hide();
},
reloadAfterSubmit:true,
closeAfterDelete: true,
serializeDelData: function (postdata) {
var rowdata = $('#grid').getRowData(postdata.id);
// append postdata with any information
return {id: postdata.id, oper: postdata.oper, reqID: rowdata.reqID};
},
afterSubmit : function(response, postdata)
{
var result = eval('(' + response.responseText + ')');
var errors = "";
if (result.success == false) {
for (var i = 0; i < result.message.length; i++) {
errors += result.message[i] + "<br/>";
}
} else {
$('#msgbox').text('Entry has been deleted successfully');
$('#msgbox').dialog(
{ title: 'Success',
modal: true,
buttons: {"Ok": function() {
$(this).dialog("close");
}
}
});
}
// only used for adding new records
var newId = null;
return [result.success, errors, newId];
}
});
else {
$('#msgbox').text('You must select a record first!');
$('#msgbox').dialog(
{ title: 'Error',
modal: true,
buttons: {"Ok": function() {
$(this).dialog("close");}
}
});
}
In order to add support for multiselection deletes, I changed the "selrow" first line to this:
var rowList = jQuery("#grid").getGridParam('selarrrow');
After this, things start getting sketchy fast. The spec says that the default delGridRow can accept an array of inputs records to delete. I made the following change to attempt to get the new 'rowList' variable to get used:
$('#grid').jqGrid( 'delGridRow', rowList, ...
I'm still hitting my deleteRequirement.html URL in my Spring controller, but only the last records appears to make it. I'm guessing the problem is in the postdata preparation in the serializeDelData section, but I haven't found the correct way to prepare this postdata with the list of records instead of the single record.
Any suggestions/insight would be appreciated.
Thanks all.
I don't use Spring myself, but some parts of your code seams be strange for me.
First of all the you can use two forms of the first parameter of delGridRow (row in your code). It can be either the comma-separated list of ids or an array of ids. If you use array of ids then jqGrid convert it to the comma-separated format by rowids = rowids.join();. As the result the format of postdata.id inside of serializeDelData can be also the comma-separated list of ids.
So if you need to support delete of multiple rows you should
modify the code of serializeDelData to send in reqID property also the list of the reqID. The corresponding code can be
serializeDelData: function (postdata) {
var ids = postdata.id.split(','), i, l = ids.length, reqIDList = [];
for (i = 0; i < l; i++) {
reqIDList.push($(this).jqGrid("getCell", ids[i], "reqID"));
}
return {id: postdata.id, oper: postdata.oper, reqID: reqIDList.join()};
}
modify your server code to support both id and reqID in comma-separated form.
Inside of afterSubmit callback you you the lines
// only used for adding new records
var newId = null;
return [result.success, errors, newId];
You can modify the lines to the following
return [result.success, errors];
because only the first two elements of the array returned by afterSubmit callback will be used.

Categories

Resources