How can I implement a custom jqGrid delete button? - javascript

I have added a delete button for each row into my jqGrid. Now I need to add functionality to those buttons. Each button has to delete the row which it is in and remove data from the server. How can I do this? Here is my code so far:
var lastsel;
jQuery(document).ready(function () {
jQuery("#list").jqGrid({
url: '#Url.Action("Category1List")',
datatype: 'json',
mtype: 'GET',
colNames: ['Navn', 'Slet'],
colModel: [
{ name: 'Navn', index: 'Navn', width: 50,edittype: 'text', align: 'center', editable: true , key: true },
{ name: 'act', index: 'act', width: 75, sortable: false}],
gridComplete: function () {
var ids = jQuery("#list").jqGrid('getDataIDs');
for (var i = 0; i < ids.length; i++) {
var cl = ids[i];
be = "<input style='height:22px;width:90px;' type='button' value='Slet' onclick=\"jQuery('#list').deleteRow('" + cl + "');\" />";
jQuery("#list").jqGrid('setRowData', ids[i], { act: be });
}
},
onSelectRow: function (id) {
if (id && id !== lastsel) {
jQuery('#list').jqGrid('restoreRow', lastsel);
jQuery('#list').jqGrid('editRow', id, true);
lastsel = id;
}
},
editurl: '#Url.Action("GridSave")',
rowNum: 50000,
rowList: [5, 10, 20, 50],
pager: '#page',
sortname: 'Id',
sortorder: "desc",
viewrecords: true,
height: "500px"
});
});

You can use delGridRow method fore example. To do this you can just replace in your code jQuery('#list').deleteRow( to jQuery('#list').jqGrid('delGridRow',
You can consider to use formatter:'actions': see here, here and here. One more way to implement custom buttons you will find here.
UPDATED: To send additional information during Delete operation you can use delData parameter of delGridRow method:
be = "... onclick=\"jQuery('#list').deleteRow('" + cl +
",{delData:{Navn:'"+ jQuery("#list").jqGrid('getCell',cl,'Navn')+ "'});\" />";
The expression jQuery("#list").jqGrid('getCell',cl,'Navn') will get the value from the 'Navn' column and {delData:{Navn:'NavnValue'} will add Navn=NavnValue parameter to the data send to the server.
UPDATED 2: Your main problem was that you used in the demo project another version of the code as you posted in your question. Your demo has
... onclick=\"jQuery('#list').jqGrid('delGridRow','" + rows + "',
instead of
... onclick=\"jQuery('#list').jqGrid('delGridRow','" + cl + "',
which is the first important error. The rows variable you set as var rows = jQuery("#list").jqGrid('getGridParam','selrow'); inside of gridComplete. At the time no row is selected, rows = null and you place onclick=\"jQuery('#list').jqGrid('delGridRow','null' in for all your buttons.
The next important problem: you should rename
public ActionResult deleteRow(String ProductId)
to
public ActionResult deleteRow(String id)
or use prmNames: {id: 'ProductId'} as additional jqGrid parameter.
Other common problems:
You should modify _Layout.cshtml file. You should remove <script src="#Url.Content("~/Scripts/jquery-1.5.1.min.js")" type="text/javascript"></script> because you include another version of the jQuery (jquery-1.5.2.min.js) in the Index.cshtml
You should close <table id="list"> (add ) in the Index.cshtml.
If you want to have pager in the grid (you used jQuery("#list").jqGrid('navGrid', "#page", ...) you should 1) add <div id="page"></div> in the Index.cshtml and add parameter pager: '#page' to the jqGrid.
You have to clean the HTML markup which you use. For example you should remove </div> from the end of Index.cshtml. One more </div> at the end of #RenderSection("Main", required: false)</div> (in the _Layout.cshtml file) should be also removed.
To see the pager in the correct width you should include in the _Layout.cshtml file the following fix
<style type="text/css">input.ui-pg-input { width: auto; }</style>
You should include at least jQuery UI CSS and ui.jqgrid.css for example in the _Layout.cshtml file:
I would recommend you to replace jquery-1.5.2.min.js to jquery-1.6.2.min.js. The last version of vsdoc files you can always load from here. In the same way the last version (currently 1.8.16) of jQuery UI is also recommended.
I would recommend you to download the VS2010 demo project which I created for the answer and use it as the template for your project. You can easy change the code to use Razor.

try
$("#classOfYourButton").click(function(e){
e.stopPropagation();
$(this).closest("tr").remove();
});

Related

DataTables - Sorting not working after content update

I'm using DataTables (version 1.10.18) and I'm updating rows and its content via jQuery.
My table is initalized with this code:
$(".summary").append(tableContent);
var otable = $('.summary').DataTable({
initComplete: function () {
this.api().columns([0, 1, 2, 3]).every(function () {
var column = this;
var select = $('<select><option value=""></option></select>')
.appendTo($(column.footer()).empty())
.on('change', function () {
var val = $.fn.dataTable.util.escapeRegex(
$(this).val()
);
column
.search(val ? '^' + val + '$' : '', true, false)
.draw();
});
column.data().unique().sort().each(function (d, j) {
select.append('<option value="' + d + '">' + d + '</option>')
});
});
},
"pageLength": records_per_page,
"language": {
"url": "//cdn.datatables.net/plug-ins/1.10.16/i18n/Italian.json"
},
"order": [[0, 'desc']],
"ordering": true,
"scrollX": true,
"scrollY":"50vh",
"searching":false,
"info":false,
"paging": false
});
Then I've an input field that searches in a SharePoint list (via Rest API). So I make an AJAX call, I get the response from SharePoint web service and I prepare HTML code with new data (some data returned from web services needs to be modified). Finally I update the table content using this code:
var otable = $('.summary).DataTable();
otable.clear().draw();
$(".dataTables_scrollBody>.summary").append(newContent);
otable.rows().invalidate().draw();
newContent is something like:
newContent = "<tbody><tr><td>content</td><td>content</td></tr></tbody>";
Content is updating correctly and sorting arrows are visible in the table header, they are also changing their own active status (desc or asc) but content is not sorted.
I've tried a lot of solutions found online but no one is working for me. In the content update section I'm also adding rows using .append() method.
Is there a way to fix this?
i would suggest, instead of appending the row, you should use the https://datatables.net/reference/api/row.add() add method which is exposed by datatable api. This will automatically apply all the initial settings to new added row.

Kendo Grid: how to get the selected item from a Combobox cell template when using with Angular

I have a Kendo grid which I am using within Angular, and have a field with a combo box, that has the editor set to the following function...
function comboCellTemplate(container, options) {
var input = $('<input name="' + options.field + '" />')
input.appendTo(container)
var combobox = input.kendoComboBox({
autoBind: true,
filter: "contains",
placeholder: "select...",
suggest: true,
dataTextField: "description",
dataValueField: "code",
dataSource: data,
});
And data is a list of simple json objects...
[
{code: 'code1', description: 'desc1'}
{code: 'code2', description: 'desc2'}
[
Each field in the grid data is bound to the same objects (ie with a code and description field)
I a previous post, to get sorting and filtering working I need to bind a field to the display field...
{
field: "Category.description",
title: "Category",
editor: comboCellTemplate,
template: "#=Category.description#"
},
When I do this, the combo box seems to set the field of the grid to the code.
How can I get this to set the grid data to the whole data object (ie the {code, description})
I have tried adding a on - change handler to do this
input.on('change', function () {
var val = input.val();
//var dataItem = input.dataItem();
options.model.set(options.field, val + 'xx');
});
but can't see how to get the "selected Item" from the combo
I don't seem to be able to find this in the help (in particular when using Angular)
Any help here would be greatly appreciated.
regards, Peter
I think you can simply add a change handler to the editor and set it from there:
function comboCellTemplate(container, options) {
var input = $('<input name="' + options.field + '" />')
input.appendTo(container)
var combobox = input.kendoComboBox({
autoBind: true,
filter: "contains",
placeholder: "select...",
suggest: true,
dataTextField: "description",
dataValueField: "code",
dataSource: data,
change: function () {
options.model.set(options.field, this.dataItem());
}
});
}
Ok, I think I have got to the bottom of this (after lots of diving through the doco)
I could get everything to work after I discovered that you can give a column a "magical" compare function.
So using this, my field can go back to binding to the whole json object ..
and add the sortable as follows...
{
field: "Category",
title: "Category",
editor: comboCellTemplate,
template: "#=Category.description#",
sortable:{
compare: function (a, b){
return a.Category.description.localeCompare(b.Category.description);
}
},
Now everything works exactly as I expect, and I don't need to do anything extra in the combobox. I hope this ("simple when you know how") tip can save someone else all the time it took me to find it.

changing data of select2 with x-editable without re-setting source option

How to keep the source of option values updated in x-editable
without re-initialising the editable element with source.
Here is the sandbox : http://jsfiddle.net/wQysh/322/
HTML
<p>X-editable (dev)</p>
<div>
<button id="controller">Add</button>
</div>
<div>
<button id="controller1">Remove</button>
</div>
<div>
<button id="controller2">Update</button>
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
<div style="margin: 50px">
</div>
JS :
$.fn.editable.defaults.mode = 'inline';
var count = 4, sources = [];
for(var i = 1; i <= count; i++){
sources.push({ id : i, text : String(i) })
}
var getSource = function() {
//i want this function must be called whenever available options is rendred. to ensure i used JSON.parse
return JSON.parse(JSON.stringify(sources));
};
$('#controller2').click(function(e){
count++;
sources[2].text = String(count);
//to verify live changes, if a new record updated in sources and used instantly
$('#username').editable('setValue', [1, count]); $('#username2').editable('setValue', count);
});
$('#controller').click(function(e){
count++;
sources.push( {id : count, text :String(count) });
//to verify live changes, what if a new record added in sources and used instantly
$('#username').editable('setValue', [1, count]); $('#username2').editable('setValue', count);
});
$('#controller1').click(function(e){
count++;
var a = sources.pop();
//to verify live changes by selecting value that is not present in the list. It should escape those, print the rest all if available in list
$('#username').editable('setValue', [1, a.id]); $('#username2').editable('setValue', a.id);
});
$('#username').editable({ //to keep track of selected values in multi select
type: 'select2',
url: '/post',
autotext : 'always',
value : [1,2],
source : getSource,
emptytext: 'None',
select2: {
multiple : true
}
});
$('#username2').editable({ //to keep track of selected values in single select
type: 'select2',
url: '/post',
autotext : 'always',
value : 2,
source : getSource,
emptytext: 'None',
select2: {
multiple : false
}
});
$('#username3').editable({ //to keep track of available values in multi select
type: 'select2',
url: '/post',
autotext : 'always',
value : null,
source : getSource,
emptytext: 'None',
select2: {
multiple : true
}
});
$('#username4').editable({ //to keep track of available values in single select
type: 'select2',
url: '/post',
autotext : 'always',
value : null,
source : getSource,
emptytext: 'None',
select2: {
multiple : false
}
});
//ajax emulation. Type "err" to see error message
$.mockjax({
url: '/post',
responseTime: 400,
response: function(settings) {
if(settings.data.value == 'err') {
this.status = 500;
this.responseText = 'Validation error!';
} else {
this.responseText = '';
}
}
});
Requirement :
Whenever i add new item in sources, if item is not selected then it should be updated in available options otherwise if selected then view should have updated value at element.
Whenever i update an item in sources, if item is not selected then it should be updated in available options otherwise if selected then view should have updated value at element.
Whenever i delete an item in sources, if item is not selected then it should be removed from the available options otherwise if selected then view should have "None" value (if single select) and rest element values (if multi select) at element.
Not allowed:
to reinit the widget
to reinit the source option
I hope this is possible. But struggling to get the result.
EDIT2 : code did not worked when i used JSON.parse over stringified 'sources' Problem is still unresolved. New fiddle : http://jsfiddle.net/wQysh/322/
(EDIT1 was misleading this question so removed EDIT1)
EDIT3 : so far i am able to achieve this http://jsfiddle.net/wQysh/324/
Here problem is that previous selected values are not rendered, so can't remove the items if selected previously in multi-select
EDIT4: not completely solved, http://jsfiddle.net/wQysh/339/. After add or update the available option does change but after setting that new record, does not reflect in html element after submit.
the answer is to use a custom display function
here is the updated fiddle. http://jsfiddle.net/wQysh/357/
Every time we 'setValue' to editable or on close event editable's 'display' function is called.
in display function existing values is checked by this function
$.fn.editableutils.itemsByValue
where the third parameter accepts the idKey. If we do not provide third parameter while calling this function, it by default takes 'value' as idKey. and 'value' as idKey should not be used when we are using to load array data. ref : http://ivaynberg.github.io/select2/#data_array.
I added display function in which third parameter is 'id'.
and i got the desired result

Showing serial number in jqgrid

I want to show serial number as first column in jqgrid.since, database records doesn't has contigous 'ids', I can't use it.
Is there any simple way to accomplish this?
Update:
sample code:
$(document).ready(function()
{
$("#list").jqGrid(
{
url:'<%=Url.class_variable_get(:##baseurl) %>/address_books/show.json',
datatype:'json',
mtype:'get',
colNames:['Id','Name','Email Id','Number'],
colModel:[
{name:'address_book_id',index:'address_book_id',sorttype:'int',sortable:true,width:100},
{name:'name',index:'name',sortable:true,width:300},
{name:'email',index:'email',sortable:true,width:265},
{name:'number',index:'number',sorttype:'int',sortable:true,width:300},
],
pager:$('#pager'),
emptyrecords: "No Records to display",
pginput:true,
pgbuttons:true,
rowNum:10,
rowList:[5,10,20,30],
viewrecords:true,
sortorder: "desc",
//multiselect:true,
loadonce:true,
gridview:false,
sortname:'name',
caption: " Contacts List",
jsonReader: {
repeatitems : false,
cell:"",
id: "0"
},
height: 80
});
$("#list").jqGrid('navGrid','#pager',{edit:false,add:false,del:false,search:true},{multipleSearch:true});
});
This question/answer should contain information on how to redraw the jqgrid based on redefined table data: jqGrid add new column
Regarding the addition of a you might add a time stamp to each of the records, or even the value of a counter; something like:
var recordsSet = [];
$.each(databaseRecords, function(i, record) {
record.idx = Date.now();
record._id = i;
recordSet.push(record);
});
/* code to populate or redraw using update recordSet array jqgrid here */
You shoud then be able to assign either the _id field or the idx field (sample property names only) to the index property of your column models in the call to jqgrid.

Saving dynamically generated jqgrid columns

I have a jqgrid with generated columns like this (in a ASP.NET MVC 3 project). They use inline editing :
#foreach (var template in Model.TemplateList.Where(m => m.Type == 2))
{
<text>
{ name: 'A'+'#template.ID', index: 'A'+'#template.ID', width: 40, align: 'left',
editable: true,
editoptions: { dataEvents: [{ type: 'keyup', fn: function (e) {
var $tr = $(e.target).closest("tr.jqgrow"), rowId = $tr.attr("id");
var nextRow = parseInt(rowId, 10) + 1;
var total = parseInt(e.target.value, 10);
if (isNaN(total)) {
total = 0;
}
ChangeValue('A'+'#template.ID', total, $tr);
}}]}},
</text>
}
The columns are generated and work well, until I try to save them. I'm trying to give the value to the controller, but it doesn't seem to work. I already tried to give the same name to all column to get them in an array :
... name: 'templateColumns', index: 'A'+'#template.ID', width: 40, align: 'left', ...
and in the controller :
public ActionResult SaveRow(string[] templateColumns)
but it didn't work (I only got the value of the last column)
I think you can not have same names for all the columns, check the link i gave u in comments. Now if you give one column name as ''A'+'#template.ID'' and lets suppose it is getting rendered like A1, A2 then in your controller you should accept something like this only.
public ActionResult SaveRow(string A1, string A2)
Your column name and parameters in controller should be same.

Categories

Resources