I'm using the materialize autocomplete plugin to create multiple tags input with autocomplete. Plugin works fine, yet only with data passed as an array defined in advance. If data is passed from ajax call, plugin does not show dropdown with options as if there were no results. There are results in fact, they are cached (using cache option) and are shown as dropdown only after re-typing search phrase.
To sum up, autocomplete plugin does not wait for the ajax to complete its request and deliver data and that is why dropdown is not shown at first try.
Is there any way to get this plugin to show suggestions in dropdown once these are retrieved trough ajax call?
Plugin initialization:
autocomplete = $('#multipleInput').materialize_autocomplete({
cacheable: true,
throttling: true,
multiple: {
enable: true,
maxSize : 5
},
appender: {
el: '.ac-users'
},
dropdown: {
el: '#multipleDropdown'
},
getData: function (value, callback) {
callback(value,getAjaxDropdowValuesAutocomplete(value));
}
});
Function to get values from DB:
function getAjaxDropdowValuesAutocomplete(value){
var returnArray = [],
dataArray,
innerObject = {},
postParamsObj = {"search" : value};
$.ajax({
type: "POST",
url: '/search-elements',
data: postParamsObj,
success: function( msg ) {
dataArray = msg['data'];
for(var i = 0;i < dataArray.length; i++){
innerObject = {};
innerObject["id"] = dataArray[i][0];
innerObject["text"] = dataArray[i][1] + " " + dataArray[i][2];
returnArray.push(innerObject);
}
// returnArray format [{ 'id': '1', 'text': 'Johnny Bravo' }]
},
error : function(msg){
}
});
return returnArray;
}
You could try initializing the autocomplete during the success callback of the ajax request instead of the other way around. That way you're sure to have the data before it tries to start binding the autocomplete events. e.g.
function getAjaxDropdowValuesAutocomplete(value) {
var returnArray = [],
dataArray,
innerObject = {},
postParamsObj = {"search": value};
$.ajax({
type: "POST",
url: '/search-elements',
data: postParamsObj,
success: function (msg) {
dataArray = msg['data'];
for (var i = 0; i < dataArray.length; i++) {
innerObject = {};
innerObject["id"] = dataArray[i][0];
innerObject["text"] = dataArray[i][1] + " " + dataArray[i][2];
returnArray.push(innerObject);
}
// returnArray format [{ 'id': '1', 'text': 'Johnny Bravo' }]
autocomplete = $('#multipleInput').materialize_autocomplete({
cacheable: true,
throttling: true,
multiple: {
enable: true,
maxSize: 5
},
appender: {
el: '.ac-users'
},
dropdown: {
el: '#multipleDropdown'
},
getData: returnArray
});
},
error: function (msg) {
}
});
return returnArray;
}
Related
I have the below custom button added to my navigation pager, but i want it to look at what i multi selected and send it to the JQGrid's editurl for processing which is a ASHX.CS page
But i can't make sense of the documentation when it comes to custom button
I can get it call a local function with onClickButton: customButtonClicked but it doesn't send the data like the EDIT button does
In the end what i want to do it select multiple rows and press a button on the navbar and approve all the selected records
// add first custom button
$('#jQGrid').navButtonAdd('#jQGridPager',
{
buttonicon: "ui-icon-mail-closed",
title: "Send Mail",
caption: "Send Mail",
position: "last",
editData: {
WrkId: function () {
var sel_id = $('#jQGrid').jqGrid('getGridParam', 'selarrrow');
var value = "";
for (var a = 0; a < sel_id.length; a++) {
value = value + $('#jQGrid').jqGrid('getCell', sel_id[a], 'wrkid') + ',';
}
return value;
},
CurrentUser: function () {
return '<% =System.Web.HttpContext.Current.User.Identity.Name %>';
}
},
afterSubmit: function (response, postdata) {
if (response.responseText == "") {
$("#jQGrid").trigger("reloadGrid", [{ current: true }]);
return [false, response.responseText]
}
else {
$(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')
return [true, response.responseText]
}
}
}
);
using a few different words (how to manually post data to server json) i was able to find a snippet of an ajax code that made more sense (i'm sure i came across this before but as someone who has no jquery experience i didn't recognize it)
but the below sends to the C# handler page the data in a JSON string that was processable, had to use dynamic to read it in but it worked, couldn't get it to not return an error even though there was no error, so i used the complete: instead of success: and then called the trigger to reload the JQGrid
Final Code:
$('#jQGrid').navButtonAdd('#jQGridPager',
{
buttonicon: "ui-icon-check",
title: "Approve all selected entries",
caption: "Approve",
position: "last",
onClickButton: function () {
var sel_id = $('#jQGrid').jqGrid('getGridParam', 'selarrrow');
var value = "";
for (var a = 0; a < sel_id.length; a++) {
value = value + $('#jQGrid').jqGrid('getCell', sel_id[a], 'wrkid') + ',';
};
$.ajax({
type: "POST",
url: "AdministrationHandler.ashx?oper=approve",
data: JSON.stringify({
WrkId: value,
CurrentUser: "<% =System.Web.HttpContext.Current.User.Identity.Name %>"
}),
dataType: "json",
contentType: "application/json; charsset=utf-8",
complete: function (xhr, x) {
if (xhr.responseText.toUpperCase().indexOf("SUCCESS") >= 0) {
alert('Success!\n' + xhr.responseText);
}
else {
alert('Failed!\n' + xhr.responseText + '\n' + x);
};
$("#jQGrid").jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid');
}
})
}
});
C# Code
try
{
String postData = new System.IO.StreamReader(context.Request.InputStream).ReadToEnd();
var data = JsonConvert.DeserializeObject<dynamic>(postData);
Approve(data.WrkId.ToString(), data.CurrentUser.ToString());
strResponse = "Employee records successfully approved";
}
catch
{
strResponse = "Employee records not approved";
}
context.Response.Write(strResponse);
I have a select2 list which having huge data. So, basically on scrolling we're populating data through pagination( adding 10 records on each scroll). In Select2, version 3.4.8, its working fine and able to load data through asp.net web method. Below is the code
$("#ddlEntity").select2({
width: 200,
dropdownAutoWidth: true,
loadMorePadding: 200
initSelection: function (element, callback) {
var data = { id: ID, text: Value };
callback(data);
},
query: timedelayfunction(function (query) {
var res = AjaxRequest( URL , 'GetOnDemandWebMethod', { searchFilter : query.term, pageCounter: query.page, uid:$('#uid').val() });
var data = { more: (res.d[0] != undefined ? res.d[0].MoreStatus : false), results: [] }, i;
for (i = 0; i < res.d.length; i++) {
data.results.push({ id: res.d[i].ID, text: res.d[i].Value });
}
query.callback(data);
}, 200)
});
After moving Select2, version 4.0.3, same functionality is breaking. Can anyone help on this.
Thanks in Advance.
Finally, I've resolved it at my end and after tweaking web method response as JSON serialised array string and select2 v4 with data portion as json string worked for me.
for others it would be simple as like below code
$('#ddlEntity').select2({
width: 200,
allowClear: true,
placeholder: {
id: -1,
text: "Select any."
},
ajax: {
type:"POST",
url: '',
contentType: "application/json; charset=utf-8",
async: false,
dataType: 'json',
data: function (params) {
return "{'searchFilter':'" + (params.term || "") + "','searchPage':'" + (params.page || 1) + "'}";
},
processResults: function (res, params) {
var jsonData = JSON.parse(res.d);
params.page = params.page || 1;
var data = { more: (jsonData[0] != undefined ? jsonData[0].MoreStatus : false), results: [] }, i;
for (i = 0; i < jsonData.length; i++) {
data.results.push({ id: jsonData[i].ID, text: jsonData[i].Value });
}
return {
results: data.results,
pagination: {
more: data.more
}
};
}
}
});
i have been trying to fix this, what i want to do is:
I have a datasource who gets data from server, when i go to server, i get the list of items, then i have to search the item i have to select (This item could be in any page), after i have the item and the page where the item is located (assuming each page has 30 items), then i call LINQ expression to skip the required ammount of data and take 30. Finally i return this list to the client side.
When data arrives to client i need to "auto-select" the selected item and change the page to locate the user in the right page where the selected item is located. I have the new page, skip, selected value and everything in the client side again.
What do you suggest to me to change the page into the kendo grid datasource without call a new refresh and go to the server again?
This is how the datasource looks like:
return new kendo.data.DataSource({
serverPaging: true,
transport: {
read: {
url: URLController.Current().getURL('MyURL'),
contentType: 'application/json',
accepts: 'application/json',
type: 'POST'
},
parameterMap: function(data, type) {
if (data) {
return JSON.stringify(
{
data: jsonData,
pageSize: data.pageSize,
skip: data.skip,
take: data.take
});
}
}
},
schema: {
data: function (data) {
var dropDownData = JSON.parse(data);
gridElement.attr('data-model', JSON.stringify({ data: data }));
return dropDownData.Data;
},
total: function (data) {
var dropDownData = JSON.parse(data);
return dropDownData.total;
},
model: {
id: 'ID'
}
},
pageable: true,
pageSize: 30,
error: function(e) {
alert('Error ' + e);
}
});
When the grid data is bounded i have to change the page to current page number and then select the current item.
grid.one('dataBound', function (e) {
var currentGridElement = this.element;
var currentModel = currentGridElement.attr('data-model');
var currentJsonData = parseDropDownDataJSONString(currentModel).data;
var gridDataSource = this.dataSource;
var selection = gridDataSource.get(currentJsonData.selectedValue);
if (selection != undefined) {
var row = currentGridElement.find('tbody>tr[data-uid=' + selection.uid + ']');
if (row != undefined) {
currentGridElement.attr('data-closeByChange', false);
gridDataSource.page(currentJsonData.pageNumber);
this.select(row);
dexonDropDownGrid.combobox().text(selection.DISPLAY);
}
}
var aaaa = 0;
});
This is how my databound event listener looks like, when i try to set the page it calls again the server and i got more delay to load the right data.
Is there any way to solve this?
Thanks
Have the same problem.
There is how I fix that(not the best solution ever, but it works):
var forcedPageChange = false;
var cachedResult;
var dataSource = new kendo.data.DataSource({
transport: {
read: function (options) {
if (forcedPageChange) { // prevent data request after manual page change
forcedPageChange = false;
options.success(cachedResult);
cachedResult = null;
return;
}
gridDataProvider.getData() // promise of data
.then(function (result) {
// check if current page number was changed
if ($scope.gridConfig.dataSource.page() !== result.pageNumber ||
$scope.gridConfig.dataSource.pageSize() !== result.rowsPerPage) {
cachedResult = _.clone(result);
forcedPageChange = true;
options.page = result.pageNumber;
options.pageSize = result.rowsPerPage;
$scope.gridConfig.dataSource.query(options);
}
options.success(result);
}, function () {
options.error();
});
}
},
schema: {
data: function (response) {
return response.items;
},
total: function (response) {
return response.totalCount;
}
},
//...
serverPaging: true,
serverSorting: true,
serverFiltering: true
});
I found that dataSource.page(newPageNumber) doesn't work in this situation. It just drop page number to 1.
This solution works, but I still have a bug with missing sorting icon after dataSource.query(options)...
I am using select2 plugin to load remote data. I am using an aspx page which returns JSON data and same is assigned to select2 plugin. After user selects some value from the select2 textbox, i am forcing page to postback. After the postback i am using following code to reload to set the text in the select2 textbox.
var data = { "PatientID": "XYX", "Email": "testing#gmail.com" };
$('#e6').select2('val', '123');
But system is throwing following error: cannot call val() if initSelection() is not defined
Even if I define init, I am not able to set the value. I am using following code. Please help me set the value on the select2 textbox after the postback.
$(document).ready(function () {
$("#e6").select2({
placeholder: "Search for a movie",
minimumInputLength: 1,
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: "data.aspx",
dataType: 'json',
quietMillis: 1000,
data: function (term, page) {
return {
name: term
};
},
initSelection: function (element, callback) {
var data = { "PatientID": "XYX", "Email": "testing#gmail.com" };
callback(data);
},
results: function (data) {
var results = [];
$.each(data, function (index, item) {
results.push({
id: item['Email'],
text: item['PatientID']
});
});
return {
results: results
};
},
},
});
});
window.onload = function () {
var data = { "PatientID": "XYX", "Email": "testing#gmail.com" };
//When this is called system is throwing error
//This code is required to show the value in select2 textbox after the post back
$('#e6').select2('val', data);
}
$(document).ready(function () {
$("#e6").on("select2-selecting", function (e) {
//alert("selecting val=" + e.val + " choice=" + JSON.stringify(e.choice));
var id = document.getElementById('<%= savebtn.ClientID %>');
document.getElementById('<%= hdnFld.ClientID %>').value = e.val;
id.value = e.val;
//causes post back
id.click();
});
});
There is a mistake with your script. I had the same problem and I saw your question. After I read the API docs of Select2 I realised my error.
You should place the initSelection at the same level as ajax. e.g.
$("#e6").select2({
placeholder: "Search for a movie",
minimumInputLength: 1,
initSelection: function (element, callback) {
var data = { "PatientID": "XYX", "Email": "testing#gmail.com" };
callback(data);
},
ajax: { // instead of writing the function to execute the request we use Select2's convenient helper
url: "data.aspx",
dataType: 'json',
quietMillis: 1000,
data: function (term, page) {
return {
name: term
};
},
results: function (data) {
var results = [];
$.each(data, function (index, item) {
results.push({
id: item['Email'],
text: item['PatientID']
});
});
return {
results: results
};
},
},
});
this is related to my previous question about jqgrid. im doing now a search button that would search my inputed text from the server and display those data (if there is) in the jqgrid. Now, what i did is i create a global variable that stores the filters. Here's my javascript code for my searching and displaying:
filter = ''; //this is my global variable for storing filters
$('#btnsearchCode').click(function(){
var row_data = '';
var par = {
"SessionID": $.cookie("ID"),
"dataType": "data",
"filters":[{
"name":"code",
"comparison":"starts_with",
"value":$('#searchCode').val(),
}],
"recordLimit":50,
"recordOffset":0,
"rowDataAsObjects":false,
"queryRowCount":true,
"sort_descending_fields":"main_account_group_desc"
}
filter="[{'name':'main_account_group_code','comparison':'starts_with','value':$('#searchCode').val()}]";
$('#list1').setGridParam({
url:'json.php?path=' + encodeURI('data/view') + '&json=' + encodeURI(JSON.stringify(par)),
datatype: Settings.ajaxDataType,
});
$('#list1').trigger('reloadGrid');
$.ajax({
type: 'GET',
url: 'json.php?' + $.param({path:'data/view',json:JSON.stringify(par)}),
dataType: Settings.ajaxDataType,
success: function(data) {
if ('error' in data){
showMessage('ERROR: ' + data["error"]["msg"]);
}
else{
if ( (JSON.stringify(data.result.main.row)) <= 0){
alert('code not found');
}
else{
var root=[];
$.each(data['result']['main']['rowdata'], function(rowIndex, rowDataValue) {
var row = {};
$.each(rowDataValue, function(columnIndex, rowArrayValue) {
var fldName = data['result']['main']['metadata']['fields'][columnIndex].name;
row[fldName] = rowArrayValue;
});
root[rowIndex] = row;
row_data += JSON.stringify(root[rowIndex]) + '\r\n';
});
}
alert(row_data); //this alerts all the data that starts with the inputed text...
}
}
});
}
i observed that the code always enter this (i am planning this code to use with my other tables) so i put the filter here:
$.extend(jQuery.jgrid.defaults, {
datatype: 'json',
serializeGridData: function(postData) {
var jsonParams = {
'SessionID': $.cookie("ID"),
'dataType': 'data',
'filters': filter,
'recordLimit': postData.rows,
'recordOffset': postData.rows * (postData.page - 1),
'rowDataAsObjects': false,
'queryRowCount': true,
'sort_fields': postData.sidx
};
return 'json=' + JSON.stringify(jsonParams);
},
loadError: function(xhr, msg, e) {
showMessage('HTTP error: ' + JSON.stringify(msg) + '.');
},
});
now, my question is, why is it that that it displayed an error message "Server Error: Parameter 'dataType' is not specified"? I already declared dataType in my code like above but it seems that its not reading it. Is there anybody here who can help me in this on how to show the searched data on the grid?(a function is a good help)
I modified your code based on the information from both of your questions. As the result the code will be about the following:
var myGrid = $("#list1");
myGrid.jqGrid({
datatype: 'local',
url: 'json.php',
postData: {
path: 'data/view'
},
jsonReader: {
root: function(obj) {
var root = [], fields;
if (obj.hasOwnProperty('error')) {
alert(obj.error['class'] + ' error: ' + obj.error.msg);
} else {
fields = obj.result.main.metadata.fields;
$.each(obj.result.main.rowdata, function(rowIndex, rowDataValue) {
var row = {};
$.each(rowDataValue, function(columnIndex, rowArrayValue) {
row[fields[columnIndex].name] = rowArrayValue;
});
root.push(row);
});
}
return root;
},
page: "result.main.page",
total: "result.main.pageCount",
records: "result.main.rows",
repeatitems: false,
id: "0"
},
serializeGridData: function(postData) {
var filter = JSON.stringify([
{
name:'main_account_group_code',
comparison:'starts_with',
value:$('#searchCode').val()
}
]);
var jsonParams = {
SessionID: $.cookie("ID"),
dataType: 'data',
filters: filter,
recordLimit: postData.rows,
recordOffset: postData.rows * (postData.page - 1),
rowDataAsObjects: false,
queryRowCount: true,
sort_descending_fields:'main_account_group_desc',
sort_fields: postData.sidx
};
return $.extend({},postData,{json:JSON.stringify(jsonParams)});
},
loadError: function(xhr, msg, e) {
alert('HTTP error: ' + JSON.stringify(msg) + '.');
},
colNames:['Code', 'Description','Type'],
colModel:[
{name:'code'},
{name:'desc'},
{name:'type'}
],
rowNum:10,
viewrecords: true,
rowList:[10,50,100],
pager: '#tblDataPager1',
sortname: 'desc',
sortorder: 'desc',
loadonce:false,
height: 250,
caption: "Main Account"
});
$("#btnsearchCode").click(function() {
myGrid.setGridParam({datatype:'json',page:1}).trigger("reloadGrid");
});
You can see the code live here.
The code uses datatype:'local' at the beginning (at the 4th line), so you will have no requests to the server if the "Search" button is clicked. The serializeGridData the data from the postData parameter of serializeGridData will be combined with the postData parameter of jqGrid (the parameter "&path="+encodeURIComponent('data/view') will be appended). Additionally all standard jqGrid parameters will continue to be sent, and the new json parameter with your custom information will additionally be sent.
By the way, if you want rename some standard parameters used in the URL like the usage of recordLimit instead of rows you can use prmNames parameter in the form.
prmNames: { rows: "recordLimit" }