Selectize load function is not showing options in html - javascript

Usecase
There are a total of 200000 records exist in my database, if i load all the option in one time the page is not loading at all, it is saying maximum transaction time crossed (i felt like its the worst approach).
I thought of loading the selectize options based on keyword search, i will show the 50 records close to the search keyword.
I implemented the search in backend(Serverside), it is returning the data correctly to the client but i'm not finding a way to show them as options in html.
Please find my code below:
$scope.$selectUser = $('#selectUser').selectize({
valueField: 'sys_id',
labelField: 'name',
maxItems: c.data.maxteam,
placeholder:"Enter names or select below",
create: false,
load: function (query, callback) {
if (!query.length) return callback();
$scope.data.funcName = 'getUsers';
$scope.data.searchQuery = query;
$scope.data.kudosTo = [];
//Server call happens here
c.server.update().then(function(){
//Search data coming fine in this variable
var results = c.data.activeUsers;
//??? AT this step i'm not what to do to appear the data as selectize options and select from them ??
callback(results);
});
},
render: {
option: function (item, escape) {
return '<div class="option">' +
'<div class="text">' +
'<span class="name">' + escape(item.name) +"<i class='fa fa-circle circleFont'></i>"+ escape(item.user_name) + '</span>' +
'</div>' +
'</div>';
}
},
});
$scope.selectizeControlUser = $scope.$selectUser[0].selectize;
<div class="form-group text-left clearfix">
<select class="form-control" id="selectUser" multiple></select>
</div>
Search data coming fine in client code:
Issue: Selectize options are not showing in the HTML view
Expected results: Options should come like below image

I figure it out myself.
Options are appending to the options but just not showing in the view.
I added searchField and it started working fine as expected.
searchField: ['name', 'email', 'user_name'],

Related

Use multiselect with dynamically generated select

I am trying to use the multiselect plugin I found on here:
How to use Checkbox inside Select Option
The question above is for a <select> with hard coded <options>.
The <select> I am using generates <options> using jQuery and PHP with this function:
function initializeSelect($select, uri, adapt){
$.getJSON( uri, function( data ) {
$select.empty().append($('<option>'));
$.each(data, function(index, item) {
var model = adapt(item);
var $option = $('<option>');
$option.get(0).selected = model.selected;
$option.attr('value', model.value)
.text(model.text)
.appendTo($select);
});
});
};
initializeSelect($('#salesrep'), 'process/getSalesReps.php', function (item) {
return {
value: item.final_sales_rep,
text: item.final_sales_rep
}
});
I have used the above function several times in different projects, as it successfully creates all of the options brought in by the PHP process. Unless requested, I will not show the code for the process. Just know I am indeed retrieving a group of names and displaying them in the dropdown.
Right beneath the function above is where I call the multiselect feature:
$('select[multiple]').multiselect();
$('#salesrep').multiselect({
columns: 1,
placeholder: 'Select Reps'
});
The HTML for the select is as follows:
<select class="form-control" name="salesrep[]" multiple id="salesrep"></select>
Using all of the above, the output looks like this:
Upon inspecting the element, I can see all of the sales reps names. This tells me that the initializeSelect function is working properly.
Therefore I think the issue must have something to do with the multiselect.
Ajax calls are asynchronous. You call multiselect() before the ajax call has had time to complete and therefore the option list is still empty at the point you call the multiselect() function.
Either move the $('#salesrep').multiselect({.. bit to inside the getJSON method or call the multiselect refresh function after the option list has been populated as I am doing here. (Untested.)
function initializeSelect($select, uri, adapt){
$.getJSON( uri, function( data ) {
$select.empty().append($('<option>'));
$.each(data, function(index, item) {
var model = adapt(item);
var $option = $('<option>');
$option.get(0).selected = model.selected;
$option.attr('value', model.value)
.text(model.text)
.appendTo($select);
});
//now that the ajax has completed you can refresh the multiselect:
$select.multiselect('refresh');
});
};
initializeSelect($('#salesrep'), 'process/getSalesReps.php', function (item) {
return {
value: item.final_sales_rep,
text: item.final_sales_rep
}
});
$('select[multiple]').multiselect();
$('#salesrep').multiselect({
columns: 1,
placeholder: 'Select Reps'
});

jQuery 'change' doesn't show most up-to-date data

I have a jQuery change function that populates a dropdown list of Titles from the user selection of a Site dropdown list
$("#SiteID").on("change", function() {
var titleUrl = '#Url.Content("~/")' + "Form/GetTitles";
var ddlsource = "#SiteID";
$.getJSON(titleUrl, { SiteID: $(ddlsource).val() }, function(data) {
var items = "";
$("#TitleID").empty();
$.each(data, function(i, title) {
items +=
"<option value='" + title.value + "'>" + title.text + "</option>";
});
$("#TitleID").html(items);
});
});
The controller returns JSON object that populates another dropdown list.
public JsonResult GetTitles(int siteId)
{
IEnumerable<Title> titleList;
titleList = repository.Titles
.Where(o => o.SiteID == siteId)
.OrderBy(o => o.Name);
return Json(new SelectList(titleList, "TitleID", "Name"));
}
The markup is:
<select id="SiteID" asp-for="SiteID" asp-items="#Model.SiteList" value="#Model.Site.SiteID" class="form-control"></select>
<select id="TitleID"></select>
The problem is that the controller method is only touched on the FIRST time a selection is made. For example,
The first time SITE 1 is selected, the controller method will return the updated list of Titles corresponding to SITE 1
If SITE 2 is selected from the dropdown, the controller will return the updated list of Titles corresponding to SITE 2
The user adds/deletes Titles in the database corresponding to SITE 1
User returns to the form and selects SITE 1 from the dropdown. The list still shows the results from step 1 above, not the updates from step 3
If I stop debugging and restart, the selection will now show the updates from step 3.
Similar behavior described in jQuery .change() only fires on the first change but I'm hoping for a better solution than to stop using jQuery id's
The JSON response is:
[{"disabled":false,"group":null,"selected":false,"text":"Title2","value":"2"},{"disabled":false,"group":null,"selected":false,"text":"Title3","value":"1002"},{"disabled":false,"group":null,"selected":false,"text":"Title4","value":"2004"},{"disabled":false,"group":null,"selected":false,"text":"Title5","value":"3"},{"disabled":false,"group":null,"selected":false,"text":"Title6","value":"9004"}]
The issue was that the JSON result was being read from cache as #KevinB pointed out. This was fixed by adding the following line within the change function
$.ajaxSetup({ cache: false });

KendoUI Grid Cell Template with promise

I have to use templates to translate my grid's cells values.
For some reasons, the function I'm calling to translate is returning a promise.
I found the following topic related to my issue
Asynchronous cell template
I'm using the angular method with
ng-bind-html
$scope.lookUpEventNameAsync = function(data) {
refData.events().fetch(function() {
var eData = refData.events().data();
var refEvent = eData.find(function(re, i, a) {
return re.code === data.eventCode;
});
$("#async_tse_" + data.key).html(refEvent.name);
});
return $sce.trustAsHtml("<div id='async_tse_" + data.key + "'> </div>");
};
$scope.gridTimesheetColumns = [
{
field: "eventCode",
title: "Event",
template: "<span ng-bind-html='lookUpEventNameAsync(dataItem)'> </span>"
},
....
I made a similar thing to adapt it with the code I have and it's working.
But the problem now is that it's calling $scope.lookUpEventNameAsync several times and never stop calling it which is freezing the screen and make the app unusable.
Do you have an idea why and how can I prevent it ?
I needed a one way data binding like the following :
$scope.gridTimesheetColumns = [
{
field: "eventCode",
title: "Event",
template: "<span ng-bind-html='::lookUpEventNameAsync(dataItem)'> </span>"
},

Telerik Kendo dropdownlist remove item

I have a kendo dropdownlist which options looks like the following:
$scope.addressDropdownOptions = {
dataSource: $scope.customerAddress,
dataTextField: "Address.PrId",
dataValueField: "PrId",
headerTemplate: '<div style="width:100%;">' +
'<span style="padding-left:5px; font-weight:bold;">City</span>' +
'<span style="padding-left:129px; font-weight:bold;">Address</span>' +
'<span style="padding-left:107px; font-weight:bold;">Note</span>' +
'</div>',
valueTemplate: '<span>{{dataItem.Address.City}} </span>' +
'<span>{{dataItem.Address.Street}}</span>',
template: '<div style="width:100%;">' +
'<div class="customerDropDown">{{dataItem.Address.City}}</div>' +
'<div class="customerDropDown">{{dataItem.Address.Street}}</div>' +
'<div class="customerDropDown">{{dataItem.Address.Note}}</div> </div>',
};
The user has the option to select one, and then hit a button, which is supposed to remove the selected item from the dropdownlist.
So I'm doing the following:
$scope.customerAddress.splice(i, 1);
Now the selected item is not an option anymore in the dropdown, BUT - the valueTemplate is still showing the removed item. I'd like that to be the first index of $scope.customerAddress.
Another problem is that the first option in the new list, can not be selected. When I click it, the valueTemplate still results in the previously removed item.
Can anyone help me?
If you remove item directly from the source object (in your case, $scope.customerAddress), the dropDownList won't be aware of that change. If you want to remove an item, it has to be done using the dataSource's remove function:
var ddl = $("#color").data("kendoDropDownList");
var oldData = ddl.dataSource.data();
ddl.dataSource.remove(oldData[0]); //remove first item

Modifying Replicated EditorTemplates with Javascript

I have an Editor Template which contains a table row with (among other stuff) a dropdown/combobox to select a currency. This edit template is shown many times on the same View and it's possible for a user to add these rows as many times as he wants.
I want changes on a row's dropdown to reflect in an EditorFor (the currency's rate) on the same row, so I've added a onchange html parameter:
<td>
#*#Html.LabelFor(model => model.Currency)*#
#Html.DropDownListFor(model => model.Currency, new SelectList(Model.CurrencyList, "Code", "Code"), new { onchange = "updateCurrency(this)" })
#Html.ValidationMessageFor(model => model.Currency)
</td>
My javascript function makes an ajax call to retrieve the rate for the selected currency:
function updateCurrency(elem) {
alert("Currency changed!")
$.ajax({
type: "GET",
url: "Currency?code=" + elem.value,
success: function (msg) {
// The Rate field's Id:
var RateId = "#Html.ClientIdFor(model=>model.Rate)" // // Halp, problem is here!
document.getElementById(RateId).value = msg;
}
});
}
My problem is that
var RateId = "#Html.ClientIdFor(model=>model.Rate)"
has that Html helper which is server-side code. So when i view the page's source code, the javascript code is replicated (once for each row) and all the var RateId = "#Html.ClientIdFor(model=>model.Rate)" are pointing to the most recently added column's EditorFor.
Probably my way of attempting to solve the problem is wrong, but how can I get my javascript code to update the desired field (i.e. the field in the same row as the changed dropdown list).
I believe that one of the problems is that I have the javasript on the Editor Template, but how could I access stuff like document.getElementById(RateId).value = msg; if I did it like that?
Thanks in advance :)
Figured it out. Hoping it helps somebody:
In my view:
#Html.DropDownListFor(model => model.Currency, new SelectList(Model.CurrencyList, "Code", "Code"), new { #onchange = "updateCurrency(this, " + #Html.IdFor(m => m.Rate) + ", " + #Html.IdFor(m => m.Amount) + ", " + #Html.IdFor(m => m.Total) + ")" })
In a separate JavaScript file:
function updateCurrency(elem, RateId, AmountId, TotalId) {
var cell = elem.parentNode // to get the <td> where the dropdown was
var index = rowindex(cell) // get the row number
// Request the currency's rate:
$.ajax({
blah blah blah .........
(RateId[index - 1]).value = 'retreived value'; // Set the rate field value.
});
}
Seems to be working so far.

Categories