I've implemented a JQGrid table with loadonce:true like this :
jQuery("#list").jqGrid({
datatype: 'jsonstring',
datastr : maVarJSON,
colNames:['AA','BB', 'CC','DD','EE','FF'],
colModel :[
{name:'invid', index:'invid', align:'center'},
{name:'invdate', index:'invdate'},
{name:'amount', index:'amount', align:'right'},
{name:'tax', index:'tax', align:'right'},
{name:'total', index:'total', align:'right'},
{name:'note', index:'note'}
],
pager: jQuery('#pager'),
rowNum: 50,
rowList: [50, 100],
caption: '',
height: 470,
width: 1000,
loadonce: true
});
jQuery("#list").jqGrid('filterToolbar',{afterSearch: function(){
var rowsFiltered = jQuery("#list").getRowData();
}});
My problem is :
I have 500 rows in maVarJSON. I see 50 rows and 10 pages. I decide to filter my column AA. Only 100 rows accept this filter. So, I see 50 rows and 2 pages.
I would get the 100 rows data. (The method jQuery("#list").getRowData() give me only the 50 first rows data.)
Thanks
You will push only the searched for rows across all pages to the obj.items object:
var obj = new Object();
var numpages = jQuery(id).getGridParam('lastpage');
obj.items = new Array();
var realname = id.split("_");
realname = "input_jqGridPager_" + realname[1];
var curpage = jQuery('#'+realname);
curpage = curpage.children('input');
curpage = curpage[0].value;
for (var i = 1; i <= numpages; i++)
{
jQuery(id).trigger("reloadGrid",[{page:i}]);
selRowIds = jQuery(id).jqGrid ('getRowData');
obj.count = selRowIds.length;
for(elem in selRowIds) {
obj.items.push(selRowIds[elem]);
}
}
jQuery(id).trigger("reloadGrid",[{page:curpage}]);
The method getRowData get the data from the current page only. If you need get all the grid data you can use getGridParam to get 'data' parameters and get all grid data. I don't really understand what you want to do with the data inside of afterSearch callback. The goal of filterToolbar to display the data for the user and not to get you JavaScript interface to filter some JavaScript data.
By the way you can remove caption: '' option which is default, remove loadonce: true which will be ignored for local data inclusive datatype: 'jsonstring' and replace pager: jQuery('#pager') option to pager: '#pager'. If you would use pager: jQuery('#pager') jqGrid will have to convert it to pager: '#pager' itself internally.
Related
I have a datatable that shows mock json data retrieved from a text file. I have removed the first column as it contains the id and it isn't ideal to display the id on the table. I appended a buy button on each row on the first column only. However, when I sort the table the button disappears and the original first column data also appears.
JavScript:
$(document).ready(function() {
$.getJSON('/apps/mchp/clientlibs/clientlib-site/components/parametrictable/data.txt', function(json) {
var data = json.data;
var $thead = $('#parametrictable').find('thead');
var tr = $("<tr>");
$thead.append(tr);
var columns = [];
var obj = Object.keys(data[0]);
console.log(data[0])
var button = '<div class="left-btn"><i class="download fas fa-file-download"></i></div><div class="right-btn"><div class="input-group"><div class="input-group-area"><input type="text" value="100"></div><div class="input-group-icon">BUY</div></div></div>';
$.each(data[0], function(name, value) {
var column = {
"data": name,
"title":name
};
$('tr').find('th:first-child',).remove();
columns.push(column);
});
for (i=1; i<obj.length; i++) {
$(".dropdown-content").append('<li><input type="checkbox" class="dropcheck" data-column="'+i+'"/>'+obj[i]+'</li>');
}
var table= $('#tableId').DataTable({
data: data,
columns: columns,
columnDefs: [ {
orderable: true,
className: 'select-checkbox',
targets: 1
} ],
select: {
style: 'multi',
selector: 'td:first-child'
},
order: [[ 1, 'asc' ]]
});
$('tr').find('th:first-child').remove();
$('tr').find('td:first-child').remove();
$('tr').find('td:first-child').append(button);
$('tr').on('change', function(e){
e.preventDefault();
console.log('change!');
});
$('input[type=checkbox]').on( 'change', function (e) {
e.preventDefault();
var column = table.column( $(this).attr('data-column') );
column.visible( ! column.visible() );
} );
$('.show-all').on( 'click', function (e) {
e.preventDefault();
var obj = Object.keys(data[0])
for (i=1; i<obj.length; i++) {
var col = table.columns([i]);
if (col.visible().join(', ') == 'false') {
col.visible(true);
$(".dropcheck").prop("checked", false);
}
}
} );
});
})
First, it is not a good practice to hide datatable columns by .remove(), datatables have a built-in code for that by columnDefs refer:
https://datatables.net/examples/basic_init/hidden_columns.html
Second, that is not the right way to append data/html in datatable columns, use rowCallback function for datatable, see:
columnDefs: [
{
"targets": [ 0 ],
"visible": false,
"searchable": false
},
],
rowCallback: function(row, data, index) {
if($('td:eq(1)', row).find('.download').length == 0)
{
$('td:eq(1)', row).append(button);
}
},
When using datatable sort or search or any datatable actions it always refreshes the table therefore, any initialization before the action will be disregarded unless executed again.
I'm working on a system of medical transportation. Every day I have around 700 trips, so the table is pretty large.
I want the app, after the user adds a trip, the screen is positioned in the newly added trip. (scroll) ,for the user to corroborate the trip successfully added (not my idea, my client wants it that way) . For this, I am sending to the page by parameter the ID of the new trip added.
I'm using a function "fnFindCellRowIndexes" that i found on datatables page, but i can't make it work. The column i wait to search in is index 1.
Here's my code:
<script type="text/javascript">
$(document).ready(function() {
var table = $('#tabla').DataTable({
"deferRender": true,
"language": {
"url": "include/DataTables/Spanish.json"
},
"paging": false,
"ordering": false,
"info": false,
"searching": true,
"columnDefs": [
{
"targets": [ 0 ],
"visible": false,
"searchable": true
},
{
"targets": [ 1 ],
"visible": false,
"searchable": false
}
],
"stateSave": true
});
var index = table.fnFindCellRowIndexes( '<?=$idNuevo?>', 1 );
alert(index);
jQuery.fn.dataTableExt.oApi.fnFindCellRowIndexes = function ( oSettings, sSearch, iColumn )
{
var
i,iLen, j, jLen, val,
aOut = [], aData,
columns = oSettings.aoColumns;
for ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )
{
aData = oSettings.aoData[i]._aData;
if ( iColumn === undefined )
{
for ( j=0, jLen=columns.length ; j<jLen ; j++ )
{
val = this.fnGetData(i, j);
if ( val == sSearch )
{
aOut.push( i );
}
}
}
else if (this.fnGetData(i, iColumn) == sSearch )
{
aOut.push( i );
}
}
return aOut;
};
</script>
I'm getting error "fnFindCellRowIndexes is not a function"
Can anyone help me? if anyone has any idea to do it in a better way, suggestions are accepted.
Declare fnFindCellRowIndexes before you instantiate your dataTable!
You must instantiate with dataTable(). fnFindCellRowIndexes is an oldschool none-API plugin. As far as I can see in your code, you should not have problems with that. If you still want to use the new API, you can always use table.api().<api-functions>
The PHP variable does not magically echo itself out (no offense :-) - you forget to actually print it :
var index = table.fnFindCellRowIndexes( '<? echo $idNuevo ?>', 1 );
Remember that fnFindCellRowIndexes is an equal / == search. If you search for 1 in column #1 it only return columns that hold the value 1 and nothing more, not rows holding 10, 101, 1.1 etc.
I have following code for jQuery DataTables:
Contact.DataTable = $('#otable').DataTable( {
"ajax": {
"url" : '/Contact/' + Contact.id,
"dataSrc": function(check) {
return check.data;
},
},
"responsive": true,
"columns": [
{ "data": "id"},
{ "data": "category", "sClass": "category" },
{ "data": "name", "sClass": "name" },
{ "data": "lname" },
{
"render": function ( data, type, method, meta ) {
return Contact.saveContact(method);
}
},
]
} );
Datatable - dropdown - inline edit:
$('#otable tbody').on('click', '.category', function () { //second column
var row = this.parentElement;
if(!$('#otable').hasClass("editing")){
$('#otable').addClass("editing");
var data = Contact.DataTable.row(row).data();
var $row = $(row);
var thiscategory = $row.find("td:nth-child(2)");
var thiscategoryText = thiscategory.text();
thiscategory.empty().append($("<select></select>",{
"id":"category" + data[0],
"class":"in_edit"
}).append(function(){
var options = [];
$.each(Categories, function(key, value){
options.push($("<option></option>",{
"text":value,
"value":value
}))
})
return options;
}));
$("#category" + data[0]).val(thiscategoryText)
}
})
;
For changing values in dropdown
$('#otable tbody').on("change", ".in_edit", function(){ //Inline editing
var val = $(this).val();
$(this).parent("td").empty().text(val);
$('#otable').removeClass("editing");
});
Below code for saving new values(after inline edit) while clicking save:
$('#divsave').on("click", ".saveContact", function() {
var data = Contact.DataTable.row($(this).closest('tr')).data();
// Here I have to get new values after inline editing - but getting old values
});
My problem is : while clicking edit, in 'data', I am getting old values in the row of datatable, not the modified value after inline edit
datatable view - 1:
datatable - dropdown in column:
datatable after inline editing:
What I need: Save modified row while clicking 'save' image - currently it saves older value before inline editing(datatable view - 1)
When using dataTables it is generally a very bad idea to manipulate the DOM <table> or any content by "hand" - you should always go through the dataTables API.
Thats why you are getting "old values" - you have manipulated the content of the <table>, or so it seems - dataTables are not aware of those changes.
In a perfect world you should refactor the setup completely (i.e to use the API) but I guess you can solve the issue by using invalidate() on the row being changed in order to refresh the dataTables internals :
$('#otable tbody').on("change", ".in_edit", function(){ //Inline editing
var val = $(this).val();
$(this).parent("td").empty().text(val);
//add this line to refresh the dataTables internals
Contact.DataTable.row($(this).parent("tr")).invalidate();
//
$('#otable').removeClass("editing");
});
I am trying to display a result det data on a table and a chart together. For exampIe: A user gives a value as an input and a query has to be made to the server to filter the table based on the user input and give nbacj the result set.
I am implementing a filter on the table and then bind the filtered result set to the table. I write the below code which works fine.
var oModel = new sap.ui.model.odata.ODataModel( "../TEST_ODATA.xsodata",false);
oTable.setModel(oModel);
var oFilter=new sap.ui.model.Filter("SUPPLIERID",sap.ui.model.FilterOperator.EQ,oInput1.getValue());
oTable.getBinding("rows").filter(oFilter);
var NumberOfRows = oTable.getBinding("rows").iLength;
oTable.setTitle("Title1" + "(" + NumberOfRows + ")");
oTable.placeAt("content");
Now I need to bind ofilter to a chart too and I write the following code which does not work.
var oDataset = new sap.viz.ui5.data.FlattenedDataset({
dimensions : [{axis : 1, name : 'SUPPLIERID', value : "{SUPPLIERID}"},{axis : 2, name : 'MATERIALNUMBER', value : "{MATERIALNUMBER}"}],
measures : [{name : 'Result', value : '{Result}'}],
data : {
path : "/service_path"
}});
var oStackChart = new sap.viz.ui5.StackedColumn({
width : "80%",
height : "400px",
plotArea : {'colorPalette' : d3.scale.category20().range()},
title : {visible : true,text : 'Title2'},
dataset : oDataset});
oStackChart.setModel(oModel);
var oFilter=new sap.ui.model.Filter("SUPPLIERID",sap.ui.model.FilterOperator.EQ,oInput1.getValue());
oStackChart.getBinding("rows").filter(oFilter);
oStackChart.placeAt("content");
Can anyone suggest the change in my code to do so. Kindly help.
Thanks
You can add the filters to the FlattenedDataset like:
var oDataset = new FlattenedDataset({ // required by "sap/viz/ui5/data/FlattenedDataset"
dimensions: aDimensions,
measures: aMeasures,
data: {
path: sEntity,
filters: [ oFilter ],
parameters: {
select: 'ProductID,UnitPrice,Quantity'
}
}
});
Note I used parameters to reduce the columns returned.
!SOLVED!
I want to automatically create charts with users and their time spent on pages of a website.
I have a file - "log.xml" where I keep information with users (customers), visited pages, dates and their time spent; and after I "get" this Xml file with Ajax, I want to parse it and create with values "extracted" charts with JqPlot.
My problem is that I can't loop through more than just one customer and it don't build chart for the single customer.
If I remove the code block with initialization of variable plot I can loop through all my customers from Xml.
Please, if someone can tell me what is wrong, and how to create charts for all customers...
Here is the code of the file "log.xml":
<?xml version="1.0"?>
<log>
<customer id="14" name="Florin Virdol">
<page name="/mobilestore/index.php">
<date_ts on="2011-12-02" timeSpent="205"/>
</page>
<page name="/mobilestore/products_all.php">
<date_ts on="2011-12-02" timeSpent="15"/>
</page>
</customer>
<customer id="0" name="guest">
<page name="/mobilestore/services.php">
<date_ts on="2011-12-02" timeSpent="50"/>
</page>
</customer>
</log>
Here is the javascript code of the "operations":
$(document).ready(function()
{
//read from xml
$.ajax({
type: "GET",
url: "log.xml",
dataType: "xml",
success: parseXml
});
});//ready
//parse xml
function parseXml(xml) {
var i = 0;
$(xml).find("customer").each(function() {
$('<div class = "jqplot graph" id = "chart' + i + '"></div>').appendTo('#content');
var customerName = $(this).attr("name");
var line_inside = []; // declare as array
$(this).find("page").each(function() {
var pageName = $(this).attr("name");
$(this).find("date_ts").each(function() {
var timeSpent_ = $(this).attr("timeSpent");//if mai multe timespent, sa faca totalul, else singuru; timespent
line_inside.push([pageName,timeSpent_]); //do not string cat, push onto array
});
});
var line = '[' + line_inside + ']';
//--------jqplot----!!! if i remove this block, will loop through customers------------
var plot = $.jqplot('chart' + i, [line_inside],
{
title: customerName,
series:[{renderer:$.jqplot.BarRenderer}],
axes: {
xaxis: {
renderer: $.jqplot.CategoryAxisRenderer,
label: 'Web Page',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: { labelPosition:'middle', angle: -30 }
},
yaxis: {
autoscale:true,
label: 'Total Time Spent',
labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
tickRenderer: $.jqplot.CanvasAxisTickRenderer,
tickOptions: { labelPosition:'middle', angle: -30 }
}
}
});
//-------jqplot----!!! if i remove this block, will loop through customers------------
i++;
});//find customer
}//parse xml
SOLUTION: made modifications that Mark suggested, and it works.
(now, above code works!)
You are passing strings that look like arrays and not actual arrays to jqplot.
Try:
var line_inside = []; // declare as array
$(this).find("page").each(function() {
var pageName = $(this).attr("name");
$(this).find("date_ts").each(function() {
var timeSpent_ = $(this).attr("timeSpent");//if mai multe timespent, sa faca totalul, else singuru; timespent
line_inside.push([pageName,timeSpent_]); //do not string cat, push onto array
});
});
alert(line_inside); // this is an array of arrays
var plot = $.jqplot('chart' + i, [line_inside],
Since you want a different plot for each customer, you need to make plot a local var to your inline function: "var plot" not just "plot" -- same goes for "line". You are assigning a global scope variable and overwriting it each time, currently.