I am using multi-select grid functionality in my application and it is working as i expected. But the issue is i need to get all the selected records across the pagination in external javascript function. Below is my code,
function createCommodity(){
$.ajax({
url : 'commoditycategory.do?method=listCommodity' + '&random='
+ Math.random(),
type : "POST",
async : false,
success : function(data) {
$("#list2").jqGrid('GridUnload');
var newdata = jQuery.parseJSON(data);
var wWidth = $(window).width();
var dWidth = wWidth * 0.7;
var wHeight = $(window).height();
var dHeight = wHeight * 0.5, idsOfSelectedRows = [];
jQuery("#list2").jqGrid({
data : newdata,
datatype : "local",
colNames : [ "id", "Commodity Code",
"Commodity Description", "Commodity Category" ],
colModel : [
{
name : 'id',
index : 'id',
hidden : true,
editable : true
},
{
name : 'commodityCode',
index : 'commodityCode',
align : "center",
editable : true,
editrules : {
required : true
}
},
{
name : 'commodityDesc',
index : 'commodityDesc',
align : "center",
editable : true,
editrules : {
required : true
}
},
{
name : 'commodityCategoryId',
index : 'commodityCategoryId',
align : "center",
// hidden : true,
editable : true,
edittype : "select",
editoptions : {
dataUrl : 'commoditycategory.do?method=parentCategory'
+ '&random=' + Math.random()
},
editrules : {
edithidden : true,
required : true
// custom : true
}
} ],
pager : "#pager2",
rowNum : 10,
rowList : [ 10, 20, 50 ],
height : "230",
width : dWidth,
onSelectRow: function (id, isSelected) {
var p = this.p, item = p.data[p._index[id]], i = $.inArray(id, idsOfSelectedRows);
item.cb = isSelected;
if (!isSelected && i >= 0) {
idsOfSelectedRows.splice(i,1); // remove id from the list
} else if (i < 0) {
idsOfSelectedRows.push(id);
}
},
loadComplete: function () {
var p = this.p, data = p.data, item, $this = $(this), index = p._index, rowid, i, selCount;
for (i = 0, selCount = idsOfSelectedRows.length; i < selCount; i++) {
rowid = idsOfSelectedRows[i];
item = data[index[rowid]];
if ('cb' in item && item.cb) {
$this.jqGrid('setSelection', rowid, false);
}
}
},
multiselect : true,
cmTemplate : {
title : false
}
});
$grid = $("#list2"),
$("#cb_" + $grid[0].id).hide();
$("#jqgh_" + $grid[0].id + "_cb").addClass("ui-jqgrid-sortable");
cbColModel = $grid.jqGrid('getColProp', 'cb');
cbColModel.sortable = true;
cbColModel.sorttype = function (value, item) {
return typeof (item.cb) === "boolean" && item.cb ? 1 : 0;
};
}
});
}
Till now its working great. Its holding correct rows which are selected across pagination.
And My external JS function where i need to get the selected rowids include pagination is,
function updateCommodity() {
var grid = jQuery("#list2");
var ids = grid.jqGrid('getGridParam', 'selarrrow'); // This only returns selected records in current page.
if (ids.length > 0) {
var html = "<table id='commodityTable' class='main-table' width='100%' border='0' style='border:none;border-collapse:collapse;float: none;'><thead><td class='header'>Commodity Code</td><td class='header'>Commodity</td><td class='header'>Action</td></thead><tbody>";
for ( var i = 0, il = ids.length; i < il; i++) {
var commodityCode = grid.jqGrid('getCell', ids[i],
'commodityCode');
var commodityDesc = grid.jqGrid('getCell', ids[i],
'commodityDesc');
html = html
+ "<tr class='even' id='row" + i + "'><td><input type='text' name='commodityCode' id='geographicState"+i+"' class='main-text-box' readonly='readonly' value='" + commodityCode + "'></td>";
html = html
+ "<td><input type='text' name='commodityDesc' id='commodityDesc"+i+"' class='main-text-box' readonly='readonly' value='" + commodityDesc + "'></td>";
html = html
+ "<td><a style='cursor: pointer;' onclick='deleteRow(\"commodityTable\",\"row"
+ i + "\");' >Delete</a></td></tr>";
}
html = html + "</tbody></table>";
$("#commodityArea").html(html);
}
}
Update I have fiddled the issue for providing more clarity about the issue.
First of all I want remind that you use the code which I posted in the answer.
I see that the solution of your problem is very easy. The list of options of jqGrid can be easy extended. If you just include new property in the list of options
...
data : newdata,
datatype : "local",
idsOfSelectedRows: [],
...
you will don't need more define the variable idsOfSelectedRows (see the line var dHeight = wHeight * 0.5, idsOfSelectedRows = []; of you code). To access new option you can use
var ids = grid.jqGrid('getGridParam', 'idsOfSelectedRows');
instead of var ids = grid.jqGrid('getGridParam', 'selarrrow');. To make the code of onSelectRow and loadComplete callbacks working with idsOfSelectedRows as jqGrid option you should just modify the first line of the callbacks from
var p = this.p, ...
to
var p = this.p, idsOfSelectedRows = p.idsOfSelectedRows, ...
It's all.
UPDATED: See http://jsfiddle.net/OlegKi/s2JQB/4/ as the fixed demo.
Related
I am trying to display data in a jQuery DataTable which has column level filter at the top, fixed height and scroller enabled. I am able to display the column level filter at the top and have it working. But, as soon as I set the height (scrollY property), the column level filters at the top disappear.
Fiddler: https://jsfiddle.net/8f63kmeo/6/
HTML:
<table id="CustomFilterOnTop" class="display nowrap" width="100%"></table>
JS
var Report4Component = (function () {
function Report4Component() {
//contorls
this.customFilterOnTopControl = "CustomFilterOnTop"; //table id
//data table object
this.customFilterOnTopGrid = null;
}
Report4Component.prototype.ShowGrid = function () {
var instance = this;
//create the datatable object
instance.customFilterOnTopGrid = $('#' + instance.customFilterOnTopControl).DataTable({
columns: [
{ data: "Description", title: "Desc" },
{ data: "Status", title: "Status" },
{ data: "Count", title: "Count" }
],
"paging": true,
//scrollY: "30vh",
//deferRender: true,
//scroller: true,
dom: '<"top"Bf<"clear">>rt <"bottom"<"Notes">ilp<"clear">>',
buttons: [
{
text: 'Load All',
action: function (e, dt, node, config) {
instance.ShowData(10000);
}
}
]
});
//now, add a second row in header which will hold controls for filtering.
$('#' + instance.customFilterOnTopControl + ' thead').append('<tr role="row" id="FilterRow">' +
'<th>Desc</th>' +
'<th>Status</th>' +
'<th>Count</th>' +
'</tr>');
$('#' + instance.customFilterOnTopControl + ' thead tr#FilterRow th').each(function () {
var title = $('#' + instance.customFilterOnTopControl + ' thead th').eq($(this).index()).text();
$(this).html('<input type="text" onclick="StopPropagation(event);" placeholder="Search ' + title + '" class="form-control" />');
});
$("div.Notes").html('<div class="alert alert-warning">This is a notes section part of the table dom.</div>');
};
Report4Component.prototype.BindEvents = function () {
var instance = this;
$("#CustomFilterOnTop thead input").on('keyup change', function () {
instance.customFilterOnTopGrid
.column($(this).parent().index() + ':visible')
.search(this.value)
.draw();
});
};
Report4Component.prototype.ShowData = function (limit) {
if (limit === void 0) { limit = 100; }
var instance = this;
instance.customFilterOnTopGrid.clear(); //latest api function
var recordList = [];
for (var i = 1; i <= limit; i++) {
var record = {};
record.Description = "This is a test description of record " + i;
record.Status = "Some status " + i;
record.Count = i;
recordList.push(record);
}
instance.customFilterOnTopGrid.rows.add(recordList);
instance.customFilterOnTopGrid.draw();
};
return Report4Component;
}());
$(function () {
var report4Component = new Report4Component();
report4Component.ShowGrid();
report4Component.BindEvents();
report4Component.ShowData();
});
function StopPropagation(evt) {
if (evt.stopPropagation !== undefined) {
evt.stopPropagation();
}
else {
evt.cancelBubble = true;
}
}
Current Status
When the following properties are commented,
//scrollY: "30vh",
//deferRender: true,
//scroller: true,
the table appears with the column level filters on top as shown below,
Issue:
When the above properties are enabled, the column level filter disappears,
You can use the fiddler to see this behavior.
Expectation:
I want to have a DataTable with column level filter on top, fixed height and scroller enabled. What am I missing? Any help / suggestion is appreciated.
You need to use table().header() API function to access thead element instead of referencing it directly. When Scroller or FixedHeader extensions are used thead element appears outside of your table in a separate element.
See updated jsFiddle for code and demonstration.
getting error when retrieving the datas from the row using an id and displaying it in the textfield in next page..and another error is all the rows are getting deleted when passing id for a specific row..
Here is the coding:
var data = [];
var db = Titanium.Database.open('trip');
db.execute('CREATE TABLE IF NOT EXISTS newtrip (id INTEGER PRIMARY KEY AUTOINCREMENT, triplabel TEXT,tripname TEXT,destination TEXT,fromdate TEXT,todate TEXT)');
//db.execute('INSERT INTO newtrip(triplabel,tripname,destination,fromdate,todate) VALUES(?,?,?,?,?)',"British museum","mytrip","london","12-10-2014","12-12-2014");
//db.execute('DELETE FROM newtrip');
var resultrows = db.execute('SELECT destination,fromdate,todate FROM newtrip');
while (resultrows.isValidRow()) {
//var res=
var row = Ti.UI.createTableViewRow({
height : Ti.UI.SIZE,
rightImage : '/images/right1.png',
layout : 'absolute'
});
var tripnamelabel = Ti.UI.createLabel({
//text : 'Buckingham Palace',
text : resultrows.fieldByName('destination'),
color : theme_style,
font : {
fontSize : '16dp',
fontWeight : 'bold'
},
top : '10dp',
left : '10dp',
//right:'30dp'
});
var gettablecount = resultrows.rowCount;
for (var i = 0; i < gettablecount; i++) {
var data_edit = [];
var imgedit = Ti.UI.createButton({
backgroundImage : '/images/list_edit.png',
// left:'200dp',
top : '20dp',
width : wb,
height : hb,
// bottom:10,
right : '20dp',
onClick : "edit",
rowid : resultrows.fieldByName('id')
});
if (resultrows.isValidRow()) {
imgedit.addEventListener('click', function(e) {
var db = Titanium.Database.open('trip');
if (e.source.onClick == "edit") {
var x = db.execute('SELECT * FROM newtrip WHERE id=' + rowid);
//alert(x);
var createnewWindowback = require('ui/apppage5');
//the name of the url you wish to move
new createnewWindowback(e.source.rowid).open();
win.close();
}
resultrows.close();
db.close();
});
}
}
for (var i = 0; i < gettablecount; i++) {
var imgdelete = Ti.UI.createButton({
backgroundImage : '/images/delete_ic.png',
// left:'240dp',
top : '20dp',
width : wb,
height : hb,
//bottom:'20dp',
right : '60dp',
onClick : "delete",
rowid : resultrows.fieldByName('id')
});
imgdelete.addEventListener('click', function(e) {
var db = Titanium.Database.open('trip');
if (e.source.onClick == "delete") {
var x = db.execute('DELETE FROM newtrip WHERE id=' + rowid);
alert("you have just clicked the delete button");
}
resultrows.next();
db.close();
});
}
var fromdate = Ti.UI.createLabel({
//text : '10.11.2014',
text : resultrows.fieldByName('fromdate'),
color : 'Black',
font : {
fontSize : '13dp',
fontWeight : 'bold'
},
top : '40dp',
left : '10dp',
right : '10dp',
bottom : '20dp'
});
var dash = Ti.UI.createLabel({
text : '-',
color : 'Black',
font : {
fontSize : '15dp',
fontWeight : 'bold'
},
top : '40dp',
left : '80dp',
right : '10dp',
bottom : '20dp'
});
var todate = Ti.UI.createLabel({
text : resultrows.fieldByName('todate'),
color : 'Black',
font : {
fontSize : '13dp',
fontWeight : 'bold'
},
top : '40dp',
left : '90dp',
right : '10dp',
bottom : '20dp'
});
row.add(tripnamelabel);
row.add(imgedit);
row.add(imgdelete);
row.add(fromdate);
row.add(dash);
row.add(todate);
row.className = 'control';
data.push(row);
resultrows.next();
}
resultrows.close();
db.close();
triplistview.setData(data);
I think you not able to fetch data according to id field because you fetch the data in resultrows variable as :
var resultrows = db.execute('SELECT destination,fromdate,todate FROM newtrip');
So here you do not fetch the id column. But you use it at :
rowid : resultrows.fieldByName('id') // in : var imgedit
Hence rowid for var imgedit would be null/undefined. You should modify your SELECT query as :
var resultrows = db.execute('SELECT id,destination,fromdate,todate FROM newtrip');
Edit : Under click listener of imgedit you have :
var x = db.execute('SELECT * FROM newtrip WHERE id=' + rowid);
But there is no variable rowid defined, hence error is thrown. Make following changes ( rowid changed to e.source.rowid) :
var x = db.execute('SELECT * FROM newtrip WHERE id=' + e.source.rowid);
Hope it helps.
I'm trying to when I press button (Get Value) to set the size of checkboxes to text. I make the variable (numAll) global, and convert toString, but still not working. any idea to solve the solution?
Demo
Jquery:
$(function () {
// Click function to add a card
var $div = $('<div />').addClass('sortable-div');
$('<label>Title</label><br/>').appendTo($div);
$('<input/>', {
"type": "text",
"class": "ctb"
}).appendTo($div);
$('<input/>', {
"type": "text",
"class": "date"
}).appendTo($div);
$('<input/>', {
"type": "text",
"class": "Cbox"
}).appendTo($div);
var cnt = 0,
$currentTarget;
$('#AddCardBtn').click(function () {
var $newDiv = $div.clone(true);
cnt++;
$newDiv.prop("id", "div" + cnt);
$newDiv.data('checkboxes', []);
$('#userAddedCard').append($newDiv);
// alert($('#userAddedCard').find("div.sortable-div").length);
});
$("#Getbtn").on("click", function () {
var val = $("#customTextBox").val();
$currentTarget.find(".ctb").val(val);
$currentTarget.find(".date").val($("#datepicker").val());
var Cboxval = numAll;
var st = console.toString(Cboxval);
$currentTarget.find(".Cbox").val(st);
$currentTarget.data('checkboxes', $('#modalDialog').data('checkboxes')); /* Copy checkbox data to card */
//$('#modalDialog').dialog("close");
});
var numAll;
function updateProgress() {
var numAll = $('input[type="checkbox"]').length;
var numChecked = $('input[type="checkbox"]:checked').length;
if (numAll > 0) {
var perc = (numChecked / numAll) * 100;
$("#progressbar").progressbar("value", perc)
.children('.ui-progressbar-value')
.html(perc.toPrecision(3) + '%')
.css("display", "block");
}
}
You should use .toString() method on a Number Object:
var st = Cboxval.toString();
Otherwise I can't find where are you defining the numAll variable, so I had to replace
var Cboxval = numAll;
with:
var Cboxval = numAll === undefined ? 0 : numAll;
in order to be able to perform mys tests.
Here you have an updated version of your JS fiddle.
I am using flot charts. I want to plot chart which is updated per second and also want to add the feature of turning off and on the data series.
I am able to make it work but has problems which I did not expect, like color of one series change when other series is turned off; other is when I update the array of data series the charts seems to move but it removes element from the right,at the same time the new value is plotted on the right hand side ...
var d1 = [] ;
var d2 = [] ;
var d3 = [] ;
$(function(){
{%for reading in readings%}
var time_stamp = parseFloat({{reading['timestamp']}} + 19800.00) * 1000
var A = parseFloat({{reading['values']['A']}}) ;
var V = parseFloat({{reading['values']['VLN']}}) - 50 ;
var W = parseFloat({{reading['values']['W']}}) / 1000 ;
d1.push([time_stamp,A]);
d2.push([time_stamp,V]);
d3.push([time_stamp,W]);
{%endfor%}
var datasets = {
"current":{
label : "A",
data : d1
},
"voltage":{
label : "V",
data : d2
},
"power":{
label : "W",
data : d3
},
}
var i = 0;
$.each(datasets, function(key, val) {
val.color = i;
++i;
});
// insert checkboxes
var choiceContainer = $("#choices");
$.each(datasets, function(key, val) {
choiceContainer.append("<br/><input type='checkbox' name='" + key +
"' checked='checked' id='id" + key + "'></input>" +
"<label for='id" + key + "'>"
+ val.label + "</label>");
});
choiceContainer.find("input").click(plotAccordingToChoices);
function plotAccordingToChoices() {
var data = [];
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key]) {
data.push(datasets[key]);
}
});
if (data.length > 0) {
$.plot("#placeholder", data, {
series: {
shadowSize: 0,
lines: {
show: true
},
},
yaxis: {
min: 0
},
xaxis: {
tickDecimals: 0,
mode:"time"
}
});
}
setTimeout(getNextDataset,1000);
}
plotAccordingToChoices();
});
function getNextDataset()
{
$.ajax({url : '/newdata' , success:function(result){
reading =JSON.parse(result);
var time_stamp = (parseFloat(reading.timestamp) + 19800.00) * 1000
var A = parseFloat(reading.values.A) ;
var W = parseFloat(reading.values.W) / 1000 ;
var V = parseFloat(reading.values.VLN) - 50 ;
d1.shift();d2.shift();d3.shift();
d1.push([time_stamp,A]);
d2.push([time_stamp,V]);
d3.push([time_stamp,W]);
var datasets = {
"current":{
label : "A",
data : d1
},
"voltage":{
label : "V",
data : d2
},
"power":{
label : "W",
data : d3
},
}
var data = [] ;
var choiceContainer = $("#choices");
choiceContainer.find("input:checked").each(function () {
var key = $(this).attr("name");
if (key && datasets[key]) {
data.push(datasets[key]);
}
});
if (data.length > 0) {
$.plot("#placeholder", data, {
series: {
shadowSize: 0,
lines: {
show: true
},
points:{
show:false
},
},
yaxis: {
min: 0
},
xaxis: {
tickDecimals: 0,
mode:"time"
}
});
}
}
});
setTimeout(getNextDataset,1000) ;
}
`
I am making use of code available in flot charts examples.Where am I going wrong ??
Thank you ?
Problem 1 : Color updating every time a checkbox was checked or unchecked
Reason: Every time the checkbox click event was triggered,some how the color used to get updated
Solution : Removed setTimeout(getNextDataset,1000); call from the function plotAccordingToChoices()
Problem 2: The data elements are removed from the right instead of left.
Reason : (Very dumb) Data was coming in descending order and I was using pushing data in that order only.So latest point was at location 0 of the array and oldest point was at location n-1.And I was removing (n-1)th point.
Solution : Replaced push in the beginning with unshift().Did the magic :P
in My Jqgrid i have a column with delete links, everything works perfect, except that delete confirmation box pops up at top left corner all the time. i want to have the confirmation box in center of the jqgrid, not in top left corner.
{ name: 'act', index: 'act', width: 150, align: 'center', sortable: false}],
gridComplete: function () {
var rows = jQuery("#list").jqGrid('getGridParam','selrow');
var ids = jQuery("#list").jqGrid('getDataIDs');
var gr = jQuery('#list'); gr.setGridHeight("auto", true);
for (var i = 0; i < ids.length; i++) {
var cl = ids[i];
be = "<a href='#' style='height:25px;width:120px;' type='button' value='Slet' onclick=\"jQuery('#list').jqGrid('delGridRow','" + cl + "',{reloadAfterSubmit:false, url:'#Url.Action("deleteRow")'}); return false;\">Slet </>";
jQuery("#list").jqGrid('setRowData', ids[i], { act: be });
}
},
UPDATE
be = "<a href='#' style='height:25px;width:120px;' type='button' value='Slet' onclick=\"jQuery('#list').jqGrid('delGridRow','" + cl + "', myDelParameters); return false;\">Slet </>";
code for my Global variable:
myDelParameters = {reloadAfterSubmit:false, url:'#Url.Action("deleteRow")', beforeShowForm: function(form) {
// "editmodlist"
var dlgDiv = jQuery("#list").jqGrid("#delmodlist" + grid[0].id);
var parentDiv = dlgDiv.parent(); // div#gbox_list
var dlgWidth = dlgDiv.width();
var parentWidth = parentDiv.width();
var dlgHeight = dlgDiv.height();
var parentHeight = parentDiv.height();
// TODO: change parentWidth and parentHeight in case of the grid
// is larger as the browser window
dlgDiv[0].style.top = Math.round((parentHeight-dlgHeight)/2) + "px";
dlgDiv[0].style.left = Math.round((parentWidth-dlgWidth)/2) + "px";
}};
You set already some parameters of the delGridRow method (see {reloadAfterSubmit:false, url:... in your code).
My suggestion that you use afterShowForm in the list of delGridRow parameters. The implementation of the afterShowForm could be like in the old answer, but with the usage of "#delmodlist" ("#delmod" + grid[0].id, where var grid = $("#list")) instead of $("#editmod" + grid[0].id).
Another more short form of the implementation could be with respect of jQuery UI Position:
afterShowForm = function ($form) {
$form.closest('div.ui-jqdialog').position({
my: "center",
of: $("#list").closest('div.ui-jqgrid')
});
}
In the demo I use such function for all Add/Edit and Delete forms.
UPDATED: It seems to me that you have implementation problems. I made one more demo which you can easy modify to what you want. I don't set any editurl, so if you press "Delete" button the error will be displayed. Moreover the HTML fragment which you try to place in the 'act' column is a combination of <a> and <button> settings. Because I don't know what you wanted I placed just <a> in the 'act' column. I hope now you can easy modify my demo to make your program working.
Here is the schema of the code from my demo which you can use:
<script type="text/javascript">
//<![CDATA[
var myDelParameters = {
reloadAfterSubmit: false,
//url:'#Url.Action("deleteRow")',
afterShowForm: function ($form) {
'use strict';
$form.closest('div.ui-jqdialog').position({
my: "center",
of: $("#list").closest('div.ui-jqgrid')
});
}
};
$(document).ready(function () {
var grid = $("#list"),
centerForm = function ($form) {
$form.closest('div.ui-jqdialog').position({
my: "center",
of: grid.closest('div.ui-jqgrid')
});
},
getColumnIndexByName = function (mygrid, columnName) {
var cm = mygrid.jqGrid('getGridParam', 'colModel'), i = 0, l = cm.length;
for (; i < l; i += 1) {
if (cm[i].name === columnName) {
return i; // return the index
}
}
return -1;
};
grid.jqGrid({
colModel: [
...
{name: 'action', index: 'action', width: 70, align: 'center', sortable: false},
...
],
...
loadComplete: function () {
var iCol = getColumnIndexByName($(this), 'action'), iRow, row,
rows = this.rows,
cRows = rows.length;
for (iRow = 0; iRow < cRows; iRow += 1) {
row = rows[iRow];
if ($.inArray('jqgrow', row.className.split(' ')) > 0) {
$(row.cells[iCol]).html("<a href='#' style='height:25px;width:120px;' onclick=\"jQuery('#list').jqGrid('delGridRow','" +
row.id + "',myDelParameters); return false;\">Del</>");
}
}
});
});
//]]>
</script>
for centering the jqdialog and display near the row selected
.ui-jqdialog{position:fixed; left:415px;}
This is working perfect for my requirement.
Thank You