DataTables not paginating - using ajax - ajax

I'm using DataTables to display data returned from an ajax call. DataTables returns the data, but without dividing it into pages and at the bottom, it says, "Showing 0 to 0 of 0 entries (filtered from NaN total entries)" and the buttons at the bottom say, "Previous 1 2 3 4 5 ... NaN Next". So something isn't right, but I'm not sure what.
The data is returned from a PHP page with a sql call in this format:
[{hospital_name: "Advanced Surgical", raw_description: "Removal of breast lesion",…},…]
[0 … 99]
0: {hospital_name: "Advanced Surgical", raw_description: "Removal of breast lesion",…}
full_payer_name: "Aetna Auto: Medical OP"
hospital_name: "Advanced Surgical"
plan_type: "Commercial"
price: "$2,968.40"
raw_description: "Removal of breast lesion"
...(136 records in the same format as 0 above)
Here is my DataTables call:
$('#results').DataTable( {
"processing": true,
"serverSide": true,
searching: false,
"ajax": {
"url": "./php/getDataForCode.php",
"type": "POST",
"data": {code: $code}, //a variable that I pass to the query
"dataSrc": ""
},
columns: [
{ title: "Hospital", data: "hospital_name" },
{ title: "Description", data: "raw_description" },
{ title: "Insurer", data: "full_payer_name" },
{ title: "Insurer type", data: "plan_type"},
{ title: "You Pay", data: "price" }
]
} );
Can anyone tell me what I'm doing wrong to parse the data?

In your case, if you do not have an excessively large volume of data, you do not need to use serverSide: true. Set it to false, or just remove it entirely (the default is false).
The server-side approach is intended for those cases where DataTables and your browser will not be able to handle the entire data set via a single Ajax fetch - for example, if there is too much data for reasonable performance.
On the other hand, using Ajax in a DataTable is a separate option. Using Ajax is one common way to populate your table (whether or not you use server-side processing). You can see links to examples on this "Data Sources" page.

Related

Kendo grid adding another data source as object to model on save

So I’m working on learning Kendo in an effort to push our employer closer towards purchasing a few licenses for our new web development agenda.
I have an Core2 API set up and functioning on an internal web server and am attempting to use that to create an administration page for another application.
What would cause this (described below) to occur and what's the best way to handle it or what I'm attempting?
Setting up the grid and displays is done but having a problem getting data back to the API, correctly.
It seems to be an odd problem related to having drop down lists as the data source for 2 fields.
When the page first loads, the model matches that as defined in the data source schema.
schema: {
model: {
id: "id",
fields: {
projectName: { validation: { required: true, max: 150 } },
projectDescr: { validation: { required: true, max: 500 } },
projectOwner: { validation: { required: true, max: 125 } },
projectCoder: {type:"number", required:true, validation: { required: true }, from:"projectCoder"},
projectCoderNavigation: { from: "projectCoderNavigation", nullable:false},
projectEstHours: {type: "number", validation: {min: 0}},
statusId: { validation: { required: true }, from:"statusId"},
statusReason: { validation: { max: 125 },from:"statusReason" }
}
}
Kendo grid columns
columns: [
{field: "projectName", title: "Project Name"},
{field: "projectDescr", title: "Description", editor: descrEditor},
{field: "projectOwner", title: "Project Owner"},
{field: "projectCoder", title: "Programmer", editor: programmerDDL, template:"#= projectCoderNavigation.adName#" },
{field: "statusId", title:"Status", editor: statusDDL, template:"#= statusReason#"},
{field: "projectEstHours", title: "Estimated Hours"}
Model data returned from server (chrome dev tools). Here it matches above model, with the exception that the projectCoderNavigation property also includes projectTime, Tasks, and a repeat of projects.
When I click the add new record button, the model data is updated with blank data correctly.
However once I hit save, the model changes and a new object “adName” is added and matches the data source for the drop down list used for selection.
The projectCoder remains 0, projectCoderNavigation remains null, and the other fields are updated.
And of course, POST fails due to invalid model state.
EDIT
This is the function to populate the DDL editor.
function programmerDDL(container, options) {
// var input = $("<input/>");
//input.attr("projectCoderNavigation.adName",options.field);
// input.append(container);
$('<input type="text" class="k-input k-textbox" name="adName"/>')
.appendTo(container)
.kendoDropDownList({
autoBind: false,
//valuePrimitive: true,
dataTextField: "adName",
dataValueField: "id",
dataSource: usersListDs,
text: "Select someone"
});
}
This is assigning the editor to the dropdown.
{field: "projectCoder", title: "Programmer", editor: programmerDDL,
template:"#= projectCoderNavigation.adName#" },
Note:
I have managed to work it out so that I assign the projectCoder via the parameter map, but still have the empty projectCoderNavigation property and the unwanted "adName" object in the options.models.
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
console.log("model: "+options.models);
if (operation === "create") {
options.models[0].projectCoder = options.models[0].adName.id;
}
console.log(options.models);
console.log(kendo.stringify(options.models));
return options.models;
}
}
EDIT 2
So I've progressed to where I can verify the request is reaching the API and will probably close this question, but I'll provide more information first.
When save is clicked, the API receives the POST request. However, the data from the payload isn't used by the method.
The response is HTTP code 500, as the model was null and the insert failed due to foreign key constraints.
The INSERT statement conflicted with the FOREIGN KEY constraint
"FK_att_projects_att_Users". The conflict occurred in database
"ASSIST_TimeTracking", table "dbo.att_users", column 'id'. The
statement has been terminated.

jqgrid data comes as undefined while grouping

I am using free jqgrid.I am using following code as a simple example.Data comes out be correct without grouping but with grouping it is unable to capture data(placeid) not shown in the row.I understand that on grouping, rowObject does not have placeid but how do I go about resolving the issue.
jsfiddle link: http://jsfiddle.net/johnnash03/6jhqgxw8/5/
var rows = [{
"place": "Kerala",
"placeid": "61",
"code": "kc10",
}]
var cols = ["place","code"];
$("#grid").jqGrid({
datatype: "local",
height: 250,
colNames: cols,
colModel: [{
name: 'place',
}, {
name: 'code',
formatter: function( cellvalue, options, rowObject ) {
return rowObject['placeid']
}
}]
});
for(var i=0;i<rows.length;i++)
$("#grid").jqGrid('addRowData',i+1,rows[i]);
// Data comes correct on commenting following line.
$("#grid").jqGrid( 'groupingGroupBy', 'place');
The main problem in your demo is the usage of the property placeid, which isn't in any columns of the grid. You fills additionally the grid using addRowData method called in the loop. It's the slowest way to fill the grid, which I know. The most important in your case is that the internal data of the grid will be filled only with place, code and id properties. No placeid property will be saved locally. Thus one don't see it during the later groping the grid.
One can solves the problem by usage additionalProperties option, which specify the names of additional properties of input items, which needed be saved in the local data. Adding
additionalProperties: ["placeid"]
option solves the issue. See the modified demo http://jsfiddle.net/OlegKi/6jhqgxw8/8/
I'd strictly recommend you to modify the code to about the following:
var rows = [{
"place": "Kerala",
"placeid": "61",
"code": "kc10",
}];
$("#grid").jqGrid({
data: rows,
colModel: [
{ name: "place" },
{ name: "code",
formatter: function (cellvalue, options) {
return options.rowData.placeid;
}
}
],
grouping: true,
groupingView : {
groupField : ["place"]
},
localReader: { id: "placeid" }
});
Where one can add optionally additionalProperties: ["placeid"] too. See http://jsfiddle.net/OlegKi/6jhqgxw8/9/.
The above code create, fills and group the data at once. It uses localReader: { id: "placeid" } additionally to inform that placeid property has the rowid information (the unique values used as the values of id property of the rows: <tr> elements) instead of default id property.

How to pre-load an array via ajax and use it for select2?

My general problem is that I want to have a Javascript variable which I then use with select2, to prepare the options for a select multiple. I have a fairly large array (7000 objects) and just want to store that once in a variable rather than constantly polling the server with search terms. Here is what I got.
The HTML is simply:
<input type="hidden" id="group_a" multiple="multiple" placeholder="Select at least two treatments">
Now, when I write the variable directly everything works as expected:
var treatments = [{id: 1, text: "you"}, {id: 2, text: "me"}];
$("#group_a").select2({
data: treatments,
minimumInputLength: 1,
multiple: true,
closeOnSelect: false,
width: "660px"
});
However, when I use ajax to load the array things get weird. My code to do that:
$.ajax({
url: '/funny/url',
}).done(function(data) {
treatments = data.choices;
});
I tend to get the following error unless I use the debugger to step through the code, then it works as expected. So could this somehow be a timing issue?
uncaught exception: query function not defined for Select2 group_a
My complete javascript looks like below and I've also prepared a fiddle which shows the same error.
$(document).ready(function() {
var treatments;
$.ajax({
url: '/funny/url',
}).done(function(data) {
treatments = data.choices;
});
$("#group_a").select2({
data: treatments,
minimumInputLength: 1,
multiple: true,
closeOnSelect: false,
width: "960px"
});
});
The ajax call is asynchronous, so at the time you are instrumenting the Select2 control, treatments is still undefined.
You could do the following:
$(document).ready(function() {
$.ajax({
url: '/funny/url',
}).done(function(data) {
$("#group_a").select2({
data: data.choices,
minimumInputLength: 1,
multiple: true,
closeOnSelect: false,
width: "960px"
});
});
});
jsfiddle
Better yet though, I would do the following.
Initially set treatments to an empty array, and use a function for the data option so if treatments is changed, the changes will be picked up by the Select2 control. That way, you can instrument the Select2 control right away, and then update treatments with the data returned by the ajax call. Additionally, you could initially disable the Select2 control, and then enable it when the ajax call returns.
$(document).ready(function() {
var treatments = [];
$.ajax({
url: '/funny/url',
}).done(function(data) {
treatments = data.choices;
$("#group_a").select2('enable', true);
});
$("#group_a").select2({
data: function() { return { results: treatments }; },
minimumInputLength: 1,
multiple: true,
closeOnSelect: false,
width: "960px"
}).select2('enable', false);
});
jsfiddle
The third option would be to keep your original code, but make the ajax call synchronous. I recommend not doing that though. When you make an ajax call synchronous, you lock up the entire browser.
Here is my solution. Thanks to #John S for the initial approach, but I couldn't get the select2 formatter to parse my array. Select2 box would tell me 'no results found.' I ended up running a for loop through my array and writing out the :id, :text hashes.
Starting with my json ajax call is an array of string 'terms':
// localhost:3000/search/typeahead_terms_all.json
[
"Super Term",
"cool term",
"killer term",
"awesome term",
"try term",
"param term",
"try name",
"Academic Year",
"grade average",
"Hello Term",
"Academic Calendar",
"kinda cool term",
"My Term",
]
Then the javascript:
$(document).ready(function() {
var term_names_array = [];
$.ajax({
url: '/search/typeahead_terms_all',
}).done(function(data) {
// Here I iterate through my array of strings and write out the hash select2 needs
for (index = 0; index < data.length; ++index) {
term_names_array.push({ id: index, text: data[index] });
}
$('.report_term_input').select2('enable', true);
});
$('.report_term_input').select2({
dataType: 'json',
data: term_names_array,
multiple: true,
width: "500px"
});
});

Setting Value programmatically in KendoUI multiselect

I have my KendoUI MultiSelect widget initialized like this:
$("#" + key).kendoMultiSelect({
placeholder: placeholder,
dataTextField: dataText,
dataValueField: dataValue,
filter: "contains",
autoBind: false,
dataSource: {
type: "jsonp",
transport: {
read: {
url: urlValue
}
},
error: function(e) {
console.log(e);
}
},
value: GetSavedJSONObject(key),
//value: [
//{ Name: "Chang", Id: 2 },
// { Name: "Uncle Bob's Organic Dried Pears", Id: 7 }
//],
select: removeMark,
change: multiselect_checkForChanges,
autoClose: isAutoClose
});
where GetSavedJSONObject(key) is an array of objects like this:
[Object { Id=1, Name="AA"}, Object { Id=2, Name="BB"}]
The issue I'm facing is when the page loads, I can see "AA" and "BB" in the multiselect widget and no call is made to the url. However, when I attempt to add more items to the widget, there are none to be added because the widget thinks the only items available are the items I specified in the "value" field of the widget during initialization.
In the Server Filtering demo, you will see that the example sets the value of the widget just like I did but when you try to add more items to the widget, then a call is made to the url for more data and the widget opens.
I'm sure this is user error but I just need some pointers on what to try next in order to get the widget to display the rest of the data.
EDIT:
When I made GetSavedJSONObject(key) return an array of the Ids so
[1,2,3]
I was able to click on the widget to get the rest of the data. However, the desired outcome is being able to set the values of the widget (because I have the Id/Name pairs) without having to make the call to the datasource and being able to click on the widget to fetch the rest of the data)
Keeping my array of Objects and setting the serverFiltering: true attribute fixed the issue. Hope this saves someone else time. sigh

How to pass page size, filters and sort parameters to back- end in Kendo UI Grid?

I am trying to use Kendo UI grid with remote data source, but cannot understand how to pass page size, filters and sort parameters to the ASP.Net aspx page that return a json string for grid's data source. Telerik's documentation on Kendo UI is bad because they have no examples on using server-side technologies with Kendo UI. If someone knows this please let me know?
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "json",
transport: {
read: "GetProducts.aspx"
},
schema: {
model: {
fields: {
ProductId: { type: "number" },
ProductName: { type: "string" },
CategoryName: { type: "string" },
IncludeProduct : { type: "boolean" }
}
}
},
pageSize: 10,
serverPaging: true,
serverFiltering: true,
serverSorting: true
},
In GetProducts.aspx page, I create a json string in page load event and send it back to browser. I am using ASP.Net Webforms.
The parameters are passed automatically in the server request. You need to look at the requests being made (ie Firebug addon for FireFox) to see them all but some of them are skip, take, filter[logic],sort[i][dir], sort[i][field] etc.
If your page number is 3 and your page size is 100 then the skip value passed would be 200 and the take would be 100.
To modify these to pass under different names you would need to use the parameterMap Kendo provides but I don't have experience with that.
I don't have familiarity with ASP.Net Web Forms to know for sure but I wrote this after a basic google search so you can get the basic idea for pulling the parameter.
protected void Page_Load(object sender, EventArgs e)
{
string skip = Request.QueryString["skip"];
}

Resources