JQgrid on sorting data changes for ID column - javascript

I am using JQgrid to display data, data in grid is added row by row. also i am using "local" data type to enable sorting on client side.
i am having 'id'in colmodel which stores database Id. at first time data is loaded properly
but when i click on header for sorting data content of 'id' column changes to 1,2 ...
please help..
my code
var pageNumber=0,
previouslySelectedId,
numberOfRecords;
var numberOfPages,sortingFlag=false;
$(function() {
$("#supplierCommodityList").jqGrid({
datatype: "local",
colNames:['ID','Supplier','Commodity','Unit','Cost Per Unit','Start Date','End Date'],
colModel:[
{name:'id',index:'id',hidden:true},
{name:'supplier.name',index:'supplier.name',sorttype:"string",formatter:wrapToLinkFormatter},
{name:'coProductSpecification.name',index:'coProductSpecification.name',sorttype:"string",sortable:true},
{name:'unit',index:'unit',sorttype:"string"},
{name:'expense',index:'expense',sorttype:"int"},
{name:'startDateStr',index:'startDate',formatter:dateFormatter},
{name:'endDateStr',index:'endDate',formatter:dateFormatter}
],
pager: '#supplierCommodityPager', //require id pagination, contains id for pagination div.
viewrecords: true,
multiselect: false, // to enable multiselect (chack box)
caption: "Supplier Commodity", //to show title on top
width: 920,
height:600,
viewrecords: true,
loadonce: true, // to enable sorting on client side
sortable: true, //to enable sorting
onPaging:paginationEvent, //pagination
onSortCol:sortingEvent,
gridComplete:gridCompleteFunction,
editurl: "clientArray"
}).navGrid('#supplierCommodityList',{edit:false,add:false,del:false});
attach_events(pagiantion_control_classes,'supplierCommodityList','supplierCommodityPager',get_supplier_commodity_details);
sortingEvent.gridId='supplierCommodityList'; //Id of grid
sortingEvent.pagerId='supplierCommodityPager';//Id of Pager
get_supplier_commodity_details(0);
});
/**
* method to get data .
*/
var get_supplier_commodity_details=function(requestedPage){
if(typeof requestedPage == 'undefined')
requestedPage=0;
var rurl='supplierCommodity/false';
$.ajax({
url: rurl+'/'+requestedPage,
processData:false,
type: 'GET',
success: function(data, textStatus, jqXHR){
render_supplier_commodity_details(data,requestedPage);
}
});
};
/**
* method used to render data in grid, row by row
*
*/
var render_supplier_commodity_details=function(data,pageNo){
numberOfRecords=data.numberOfRecords;
var numberOfPages=data.totalPages;
var noOfRecordPerPage=0;
console.debug(data);
$.each(data.supplierCommodityList,function(i,row){
$("#supplierCommodityList").jqGrid('addRowData',row.id,row);
noOfRecordPerPage+=1;
});
//alert(noOfRecordPerPage);
$("#supplierCommodityList").setGridParam({rowNum:numberOfRecords});
//jQuery("#supplierCommodityList").trigger("reloadGrid"); // to avoid total no of pages to be shown as 0.
$('span#sp_1_supplierCommodityPager').text(data.totalPages); //shows total pages
$('input.ui-pg-input').val(pageNo+1);
$("#supplierCommodityList").setGridParam({rowNum:numberOfRecords});
if(numberOfPages==1){
$('#supplierCommodityPager .ui-paging-info').text('View '+ 1 +' - '+ noOfRecordPerPage+ ' of '+noOfRecordPerPage);
}else if(numberOfPages==(parseInt(pageNo)+1)){
var minrecord=numberOfRecords-noOfRecordPerPage+1;
var maxrecord=numberOfRecords;
$('#supplierCommodityPager .ui-paging-info').text('View '+ minrecord +' - '+ maxrecord+ ' of '+numberOfRecords);
}else if(numberOfPages!=1){
var minrecord=(noOfRecordPerPage*pageNo)+1;
var maxrecord=noOfRecordPerPage*(pageNo+1)>numberOfRecords?noOfRecordPerPage :noOfRecordPerPage*(pageNo+1);
$('#supplierCommodityPager .ui-paging-info').text('View '+minrecord +' - '+ maxrecord+ ' of '+data.numberOfRecords);
}
};
/**
* method handling sorting of column
*/
sortingEvent=function(index,iCol,sortorder){//index=col. name, icol=index of column,sortorder=asc or desc
// console.debug(index+ iCol+sortorder+" satrt");
sortingFlag=true; //flag required in gridCompleteFunction to change Text in Pager.
numberOfPages=$('span#sp_1_'+sortingEvent.pagerId).text();
var pageNumber=$('#'+sortingEvent.pagerId+' .ui-pg-input').val();
if(iCol== 6 || iCol==7){
var obj=$("#"+sortingEvent.gridId).jqGrid('getRowData');
console.debug(obj);
compareDate.sortorder=sortorder=='asc'?1:-1; //for acending order directly return 1 if 1st element<2nd element
compareDate.sortingField=(iCol==6)?'startDateStr':'endDateStr';
obj.sort(compareDate);
console.debug(obj);
var gridObj = jQuery("#"+sortingEvent.gridId);
var textOnPager=$('#'+sortingEvent.pagerId+' .ui-paging-info').text();
gridObj.clearGridData();
$.each(obj,function(i,row){
$("#"+sortingEvent.gridId).jqGrid('addRowData',row.id,row); //appends data row by row to grid
});
$('#'+sortingEvent.pagerId+' .ui-paging-info').text(textOnPager);
$('span#sp_1_'+sortingEvent.pagerId).text(numberOfPages); //shows total pages
$('#'+sortingEvent.pagerId+' .ui-pg-input').val(pageNumber);
return 'stop';
}
};
/**
* method called when we click on link for updating Headline
*/
clickMethod=function(id){
if(id!=null && typeof id != 'undefined')
window.location = "/kiss/portal/yoadmintool/supplierCommodity/supplierCommodityDetail/"+id+"/";
else
window.location = "/kiss/portal/yoadmintool/supplierCommodityList";
};
/*
* method which gets called on pagination.
*/
var paginationEvent=function(pgButton){
pageNumber=$('#supplierCommodityPager .ui-pg-input').val();
var gridObj = jQuery("#supplierCommodityList");
gridObj.clearGridData();
get_supplier_commodity_details(pageNumber-1);
};
gridCompleteFunction=function(){
var noOfRecordPerPage=jQuery("#supplierCommodityList").jqGrid('getGridParam', 'records');
if(sortingFlag){
if(numberOfPages==1){
$('#supplierCommodityPager .ui-paging-info').text('View '+ 1 +' - '+ noOfRecordPerPage+ ' of '+noOfRecordPerPage);
}else if(numberOfPages==(parseInt(pageNumber)+1)){
var minrecord=numberOfRecords-noOfRecordPerPage+1;
var maxrecord=numberOfRecords;
$('#supplierCommodityPager .ui-paging-info').text('View '+ minrecord +' - '+ maxrecord+ ' of '+numberOfRecords);
}else if(numberOfPages==0){
}else if(numberOfPages!=1){
var minrecord=(noOfRecordPerPage*pageNumber)+1;
var maxrecord=noOfRecordPerPage*(parseInt(pageNumber))>numberOfRecords?noOfRecordPerPage :noOfRecordPerPage*(parseInt(pageNumber));
$('#supplierCommodityPager .ui-paging-info').text('View '+minrecord +' - '+ maxrecord+ ' of '+numberOfRecords);
}
}
sortingFlag=false;
$('.ui-state-disabled.ui-pg-button').removeClass('ui-state-disabled').addClass('ui-state-enabled');//to enable pager button
};
/**
* method to wrap discription to link for updation purpose
*/
wrapToLinkFormatter=function(cellvalue, options, rowObject){
var link=""+cellvalue+"";
return link;
};

I have seen the jsfiddle demo many times and I am wonder where is the origin of it. The problem is that the demo is really bad template. It contains many small errors and shows the worst way to fill jqGrid with local data. Please never use the template for your real code.
The error which is in your current code is the following: you choosed id as the name of the first column. The id property will be used to save the rowid (the id of <tr> elements of the grid). On the one side you use id: 48803 and id: 48769. On the other side you use $("#grid").jqGrid('addRowData', i + 1, mydata[i]);. So the id will be set to i + 1 (1 and 2). So the values 48803 and 48769 will be placed in the grid, but the id properties of internal data parameter will be overwritten to 1 and 2 values. If you would change the code to $("#grid").jqGrid('addRowData', data[i][0], mydata[i]); the problem will be solved.
Nevertheless I strictly recommend you to rewrite the code. You should first fill the mydata and then create the grid with data: mydata abd gridview: true options. You should additionally fix the sorttype to corresponds the data which you use. I recommend you additionally to use height: "auto" instead of height: 250 and include pager. The current code will just display first 20 rows of the data (rowNum has default value 20) and the user will be not able to see the next page.

Related

Selectize load function is not showing options in html

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'],

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 });

Return and refresh select option value on closest tr

I have the below sample code:
<table id='myTable'>
<tr>
<td>Id</td>
<td>Status</td>
<td>Summary</td>
</tr>
</table>
//Sample document ready function
$(document).ready(function(){
$('#myTable').dataTable({
"aoColumnDefs": [
{
"aTargets":[1],
"createdCell": function (td, cellData, rowData, row, col){
if(cellData === 'ordered')
$(td).css('background-color', '#5cb85c');
if(cellData === 'not_ordered')
$(td).css('background-color', '#d9534f');
if(cellData === 'shipped')
$(td).css('background-color', '#f0ad4e');
}
},
{
"aTarget": [2],
"render": function(data, type, full, meta){
if(type === 'display' && data == null) {
data = "enter field summary";
return '<input type="text"' + data +'>';
}
else
return '<input type="text"' + data + '>';
}
}
]
});
//With this function, i want to change the background-color of select field per option selected.However, the val() is returning "undefined"
$('#myTable').on('change',function(){
var optionField = $(this).closest('tr').find('option:selected').val();
if(optionField === 'ordered')
$(this).css({'background-color':'#696969'});
else if(optionField === 'notOrdered')
$(this).css({'background-color':'#e7e7e7'});
else(optionField === 'shipped')
$(this).css({'background-color':'#326f3a'});
}
$('table').on('click', 'input[type="submit"]', function(e)){
var url = 'hiddenAPI.com';
$.ajax({
url: url,
type: "POST",
async: true,
data: {
id: idField,
status: statusField,
summary: summaryField
},
dataType: "json",
success: function (data){
$('#responseField').html('Order ' + idField + ', summary has been posted to the database successfully');
$('#myTable').ajax.reload(); //<- table not refreshing here
},
});
});
});
With the above code, I want to change the background color everytime a select option is selected (determined per value in the code above), also after every post to the database, I want to refresh the whole datatable with the new JSON data. So far the API provided on the datatable site (table.ajax.reload()) isn't working.
Two questions,
1.) With my code above, how can I change the background color of a specific column in datatable after select option is selected?
2.) How do I refresh datatable after every post to the database without having to refresh the entire window/page?
In here:
$(this).css({background-color':'#696969'});
else if(optionField === 'notOrdered')
$(this).css({background-color':'#e7e7e7'});
else(optionField === 'shipped')
$(this).css({background-color':'#326f3a'});
}
the "background-color" string is missing an extra ' at the start
edit: sorry, only fixed a syntax error
After playing around, I ended up fixing this myself.
1.) to refresh ajax data, I ended up calling another ajax call (from another primary function) inside the done function.
2.) to click and return the closest selected option in a table row, I ended up first creating an on click function on the table, and then nested another function for the select on change, then used $(this).closest('tr).find('select').val().

How to pass selected value as extra parameter to ajax call

my coding part
$("#demo-input").tokenInput("data/autosuggest-search-city.php",
{
searchDelay: 2000,
minChars: 3,
tokenLimit: 10
});
I want to send the selected values as extra parameter to "data/autosuggest-search-city.php".
For example,
Initially I search and select one value from list
then again searching, this time I want to send the 1st selected value to server.
How to do this?
TokenInput plugin doesn't support that natively.
You can however make a simple workaround to update "AJAX url" whenever a token is added or removed from selection.
Use onAdd and onDelete callbacks to trigger "AJAX url" changes;
Get selected tokens using selector.tokenInput("get") method;
Set the new "AJAX url" by updating .data("settings").url of the element;
// cache the original url:
var token_url = "data/autosuggest-search-city.php";
$("#demo-input").tokenInput(token_url, {
searchDelay : 2000,
minChars : 3,
tokenLimit : 10,
onAdd : function(){
urlChange.call(this);
},
onDelete : function(){
urlChange.call(this);
}
});
function urlChange(){
var tokens = '', token_list = $(this).tokenInput("get");
// proceed if any token/s are selected:
if(token_list.length){
// loop through the selected tokens (if more than one is selected)
$.each(token_list, function(i, token){
// use token "id" (or "name" if you wish) and separate them with comma:
tokens += token.id + ',';
});
// update url:
$(this).data("settings").url = token_url + '?selected_tokens='+tokens.replace(/,+$/,'');
}else{
// leave original url if no tokens are selected:
$(this).data("settings").url = token_url;
}
};

Liferay Alloy UI - Clearing cache of dependent AutoCompleteList

I need to have two dependent AutoCompleteList in my Liferay portlet page. When I select some value from first AutoCompleteList then based on it's selected value I need to change the second AutoCompleteList source data. Based on information available, I have done coding and it is working fine except one issue.
When I select item in first AutoCompleteList then second AutoCompleteList gets populated with certain values based on my first list's selected item. Then if I change my selection again in first list, second AutoCompleteList gets updated with new possible values. But it appends the new possible values in the existing list or can say keep caching of data from both cases. But I need to show only possible values in list based on current selection of first list. For example, for selected value 1 in first list, if initially it was showing [A, B] in second list, after changing selection in first list from 1 to 2, it is showing [[A,B]+[C,D]].
Below here is part of that code. I tried setting "enableCache: 'false' " in second AutoComepleteList but not working.
<aui:script>
AUI().use('autocomplete-list','aui-base','aui-io-request','autocomplete-filters','autocomplete-highlighters',
function (A)
{
A.io.request('<%=getUrl %>',{
dataType: 'json',
method: 'GET',
on: {
success: function() {
new A.AutoCompleteList(
{
allowBrowserAutocomplete: 'false',
activateFirstItem: 'true',
inputNode: '#<portlet:namespace />name',
resultTextLocator: 'name',
render: 'true',
resultHighlighter: 'phraseMatch',
resultFilters:['phraseMatch'],
source:this.get('responseData'),
on: {
select: function(event) {
var result = event.result.raw;
A.one('#<portlet:namespace/>pk').val(result.id)
}
},
})
}}
});
});
</aui:script>
<aui:input id="pk" name="pk" label="Primary Id"
onChange='<%= renderResponse.getNamespace() + "fetchDisplayValues();"%
/>
Liferay.provide(
window,
'<portlet:namespace />fetchDisplayValues',
function() {
var A = AUI();
var pk = A.one("#<portlet:namespace/>pk");
var id = pk.get("value");
var url = '<%=getValues %>';
url = url+"&<portlet:namespace/>id="+id;
var datasource = new A.io.request(url,{
dataType: 'json',
method: 'GET',
on: {
success: function(){
var data = this.get('responseData');
new A.AutoCompleteList(
{
allowBrowserAutocomplete: 'false',
enableCache: 'false',
activateFirstItem: 'true',
inputNode: '#<portlet:namespace />displayName',
resultTextLocator: 'name',
render: 'true',
resultHighlighter: 'phraseMatch',
resultFilters:['phraseMatch'],
source:this.get('responseData'),
on: {
select: function(event) {
var result = event.result.raw;
A.one('#<portlet:namespace/>displayId').val(result.id);
}
},
})
}
}
});
})
</aui:script>
Please help me to resolve this issue. Thanks in advance.

Categories