Remove row from Kendo UI Grid with jQuery - javascript

I am using a Kendo UI grid and for deleting a row I am using a custom button with bootstrap that when I click on it, with ajax I call a web api method to remove that row and if it is successfully deleted that row removes it from the DOM. (I'm not using the command destroy of kendo)
The problem I have is that if I try to filter that row that was removed, it appears again in the grid and it seems that it was not removed at all.
This is my Kendo UI grid:
var table = $("#grid").kendoGrid({
dataSource: {
transport: {
read: {
url: "/api/customers",
dataType: "json"
}
},
pageSize: 10
},
height: 550,
filterable: true,
sortable: true,
pageable: {
refresh: true,
pageSizes: true,
buttonCount: 5
},
columns: [{
template: "<a href='' class='btn-link glyphicon glyphicon-remove js-delete' title='Delete' data-customer-id= #: Id #></a>",
field: "Id",
title: " ",
filterable: false,
sortable: false,
width: 50,
attributes: {
style: "text-align: center"
}
}, {
field: "Name",
title: "Name",
width: 100,
}, {
field: "LastName",
title: "LastName",
width: 100,
}, {
field: "Email",
title: "Email",
width: 150
}]
});
And this is my jQuery code for deleting a row:
$("#grid").on("click", ".js-delete", function () {
var button = $(this);
if (confirm("Are you sure you want to delete this customer?")) {
$.ajax({
url: "/api/customers/" + button.attr("data-customer-id"),
method: "DELETE",
success: function () {
button.parents("tr").remove(); //This part is removing the row but when i filtered it still there.
}
});
}
});
I know that in jQuery DataTables when can do something like this:
table.row(button.parents("tr")).remove().draw();
How can i do something like this with Kendo UI using jQuery?

Don't ever play with a Kendo's widget DOM. Always use it's methods instead.
Using Grid's removeRow():
$("#grid").on("click", "button.remove", function() {
var $tr = $(this).closest("tr"),
grid = $("#grid").data("kendoGrid");
grid.removeRow($tr);
});
Demo
Using DataSource's remove():
$("#grid").on("click", "button.remove", function() {
var $tr = $(this).closest("tr"),
grid = $("#grid").data("kendoGrid"),
dataItem = grid.dataItem($tr);
grid.dataSource.remove(dataItem);
});
Demo

My usage was a little different. I have a custom delete button, so I needed to delete by ID, not UID.
You should be able to match on any field value instead of ID.
var grid = $("#grid").data("kendoGrid");
var dataItem = grid.dataSource.get(ID);
var row = grid.tbody.find("tr[data-uid='" + dataItem.uid + "']");
grid.removeRow(row);
We were trying to prevent messing with the controller, and this calls the existing delete function.

The removed row will be present in the kendo ui till you push changes to server.
To remove the row entirely you need to use
grid.saveChanges()
So the code below will remove row from server as well from ui
const row = $(e.target).closest('tr')[0];
const grid = $(e.target).closest('#grid').data("kendoGrid");
grid.removeRow(row);
grid.saveChanges() //comment out if you need to remove only from ui

Related

Datatable activate single cell editing onclick

I was unable to utilize the jQuery datatable plugin here:
https://editor.datatables.net/examples/inline-editing/simple
I kept getting an error, so I just dropped it and decided to do it myself.
Starting with the datatable:
$.ajax({
url: 'api/searchVoyageInfo.php',
type: 'POST',
data: '',
dataType: 'html',
success: function(data, textStatus, jqXHR){
var jsonObject = JSON.parse(data);
var table = $('#example1').DataTable({
"data": jsonObject,
"columns": [{
{ "data": "COLUMN1" },
{
"data": "COLUMN2",
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol)
{
$(nTd).html("<a href='#' class='checkBound'>"+oData.COLUMN2+"</a>
<input type='text' class='editbound'
id='editbound' data-uid='"+oData.VOYID+"'
data-editbound='"+oData.COLUMN2+"' value='"+oData.BOUND+"
display: none;' />");
}
},
{ "data": "COLUMN3" },
// few more columns
}],
"iDisplayLength": 50,
"paging": true,
"bDestroy": true,
"autoWidth": true,
"dom": 'Bfrtip',
"buttons": [
// some extend buttons
]
});
},
error: function(// some stuff){
// do some other stuff
// this part is not important
}
});
Within COLUMN2, you should see a class 'checkBound' which is visible when the page loads. There is also an input class 'editbound' which is not visible.
Here is the function that is supposed to hide class 'checkBound' and then display class 'editbound':
$('#example1').on('click', 'tr > td > a.checkBound', function(e)
{
e.preventDefault();
var $dataTable = $('#example1').DataTable();
var tr = $(this).closest('tr');
var data = $dataTable.rows().data();
var rowData = data[tr.index()];
$('.checkBound').hide();
$('.editbound').show();
});
Using the above, when the page is finished loading, the datatable is displayed with no problem.
Upon clicking one of the cells with class 'checkBound' to display the input class 'editbound', the input does display itself, but it also displays every other cell in the column.
Before click:
After click:
As you can see, the first cell in the BOUND column is the cell that was clicked. But when clicked, the rest of the cells were activated. I want to prevent this from happening.
How can I make this work?
This is the way i created a column with a button in it . You should be able to do similar instead of button !
fields: [
{ name: "column_id", title:"View" ,itemTemplate: function(value) {
return $("<button>").text("buttontitle")
.on("click", function() {
//do something
return false;
});
}]
This is how I (somewhat) solved my problem. In the datatable section, I added an ID field called VOYID and included that ID with the class in the href and the input:
"data": "COLUMN2",
"fnCreatedCell": function (nTd, sData, oData, iRow, iCol)
{
$(nTd).html("<a href='#' class='checkBound"+oData.VOYID+"' id='checkBound'>"+oData.COLUMN2+"</a>
<input type='text' class='editbound"+oData.VOYID+"'
id='editbound' data-uid='"+oData.VOYID+"'
data-editbound='"+oData.COLUMN2+"' value='"+oData.BOUND+"
display: none;' />");
}
Then down in the button click section, I utilized the rowData to check for the exact class. This way, when you click the link, only the unique class will open and not all of the cells in the column:
$('#example1').on('click', 'tr > td > a.checkBound', function(e)
{
e.preventDefault();
var $dataTable = $('#example1').DataTable();
var tr = $(this).closest('tr');
var data = $dataTable.rows().data();
var rowData = data[tr.index()];
var voyid = rowData.VOYID;
$('.checkBound'+voyid).hide();
$('.editbound'+voyid).show();
});
Now, when I click on the link, it is only that cell that gets the input activated:

Kendo UI Grid change row detail values from command function without detail collapse

I have a kendo grid with a detail template, which I wish to clear if the user clicks on the clear command in the parent row.
I managed to get this to work, but as soon as I set the value on the dataItem, the row detail collapses, which causes the user to loose his place.
function clearDetails(e) {
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
dataItem.set("City",""); // causes row detail collapse
}
$(document).ready(function () {
$("#grid").kendoGrid({
dataSource: {
type: "odata",
transport: {
read: "https://demos.telerik.com/kendo-ui/service/Northwind.svc/Customers"
},
},
columns: [{
field: "ContactName",
title: "Contact Name",
width: 240
}, {
field: "Country",
width: 150
}, { command: { text: "Clear", click: clearDetails }, title: " ", width: "180px" }],
detailTemplate: kendo.template($("#myRowDetailTemplate").html())
})
});
Working example:
https://jsbin.com/xuwakol/edit?html,js,output
Is there a way I can still clear the values in the row detail, without it collapsing.
I had the same issue I got around it by using the dataBinding function within the kendo grid.
Basically it checks for an item change event and will cancel the default action to close the grid. This allowed me to continue to use the set method.
Example:
$("#grid").kendoGrid({
dataBinding: function (e) {
if (e.action == "itemchange") {
e.preventDefault();
}
},
});
}
I managed to get this right by not using the set method on the dataItem. http://docs.telerik.com/kendo-ui/api/javascript/data/observableobject#methods-set
I just changed the value on the dataItem, dataItem.City =""; and with the help of jquery selectors cleared the value of the textarea.
function clearDetails(e) {
var dataItem = this.dataItem($(e.currentTarget).closest("tr"));
dataItem.City ="";
$(e.currentTarget).closest(".k-master-row").next().find("textarea[name='City']").val("");
}

kendo ui grid batch editing, set focus

I working on a kendo ui grid. The grid is not-editable as default.
In the toolbar is a 'edit' button. When the user clicks on it, the grid should be editable in batch mode like this.
The only solution to get this work is remove and recreate the grid/datasource with new properties (editable:true etc).
This works as expected. Now I want to set the focus on the first row/cell, so that the user can see that the grid is editable now (in the example below the row becomes an input field).
Any suggestions for this?
Here is a fiddle for this.
$('.k-grid-edit').on('click', function (e) {
e.preventDefault();
// remove old grid
$('#grid').html('');
// recreate grid with edit: true and new datasource
$('#grid').kendoGrid({
dataSource: dataSourceInEdit,
editable: true,
columns: [{
field: 'TableId',
title: 'Id',
width: 50
}, {
field: 'Area',
title: 'Area'
}, {
field: 'Table',
title: 'Table',
width: 60
}, {
command: 'destroy',
title: ' ',
width: 100
}]
}).data("kendoGrid");
}); // end edit
Okay, I got it:
These 2 lines make it happen:
var grid = $("#rt_tableGrid").data("kendoGrid");
grid.editRow($("#rt_tableGrid tr:eq(1)"));
Certainly only on my local script, in the Fiddle I cant´t get it to work.
Although in the Docu is written: Requires "inline" or "popup"
Documentation here

Call custom method on keypress SlickGrid

I am using slickgrid to display certain data. How can i add custom method to slickgrid rows ?
For eg: I want to open modal box with current row data whenever enter key is pressed.
You can subscribe to the onKeyDown event in the grid to check this. Something like:
grid.onKeyDown.subscribe(function(e) {
if (e.which == 13) {
// open modal window
}
});
Let me know if this helps!
If i got your requirement well, then try out this code,
createInvoiceDetailsTable : function () {
var gridOptions, gridColumns;
gridColumns = [
{id:'ean_code', name:'EAN', field:'ean_code', width:125, cssClass: 'grid-cell'},
{id:'description', name:'Product Description', field:'description', width:250, formatter:opr.invoice.productGridDescriptionFormatter, cssClass: 'grid-cell'},
{id:'qty', name:'Qty', field:'qty', width:40, , formatter:UpdateQtyBtnFormatter},
];
gridOptions = {
editable: true,
autoEdit: true,
enableAddRow: false,
enableCellNavigation: true,
asyncEditorLoading: false,
enableColumnReorder: false,
rowHeight: 35
};
dataView = new Slick.Data.DataView();
invoiceProductGrid = new Slick.Grid($('#invoice_details_grid_div'), dataView , gridColumns, gridOptions);
function UpdateQtyBtnFormatter (row, cell, value, columnDef, dataContext) {
return '<input type="button" style="width:30px; height:30px;" class="update_invoice_product_qty" id="' + value + '" value="Q"/>';
}
}
Using this update_invoice_product_qty class name you can write event.
If this is not your requirement then please share with some code or procedure which you tried earlier.

Flexigrid: selection of rows to survive refresh

I am using flexigrid in a project and I would like to be able to keep the selected rows after the grid is refreshing. I asked the same question on the flexigrid discussion board and I got this answer:
Add a click handler, save the id if the row id of the row selected. On refresh completion, select the row again (if still present)
Not sure how to proceed on this, I don't even know how a function will look like, so that's why I don't have any code to start with.
If someone could point me in the right direction will be greatly appreciated.
Thanks,
Cristian.
Flexigrid adds a class called trSelected to selected rows, so whenever a click event happens on the grid you could just look for all the selected rows and save them in some way. Below is just a quick example of what you could do:
var selectedRows = new Array();
$('#myGrid').click(function() {
selectedRows = new Array();
$(this).find('tr.trSelected').each(function(i, selectedRow) {
selectedRows.push($(selectedRow));
});
});
I have done small code to keep multi-selection between pagination and also during refresh.
$("#searchPhonoList").flexigrid($.extend({}, flexigridAttrs, {
url: './rest/phono/search',
preProcess: formatSearchPhonoResults,
onSuccess: successSearchPhono,
onSubmit: submit,
method: 'GET',
dataType: 'json',
colModel : [
{display: 'titre', name: 'titre_brut', width : 240, sortable : true, align: 'left'},
{display: 'version', name: 'version_brut', width : 60, sortable : true, align: 'left'}
],
height: "auto",
sortname: "score",
sortorder: "desc",
showTableToggleBtn: false,
showToggleBtn: false,
singleSelect: false,
onToggleCol: false,
usepager: true,
title: "Liste des candidats",
resizable: true,
rp:20,
useRp: true
}));
var searchPhonoListSelection = new Array();
$('#searchPhonoList').click(function(event){
$(' tbody tr', this).each( function(){
var id = $(this).attr('id').substr(3);
if ( searchPhonoListSelection.indexOf(id) != -1 ) {
searchPhonoListSelection.splice(searchPhonoListSelection.indexOf(id), 1);
}
});
$('.trSelected', this).each( function(){
var id = $(this).attr('id').substr(3);
if ( searchPhonoListSelection.indexOf(id) == -1 ) {
searchPhonoListSelection.push(id);
}
});
});
function successSearchPhono() {
$("#searchPhonoList tbody tr").each( function() {
var id = $(this).attr('id').substr(3);
if ( searchPhonoListSelection.indexOf(id) != -1 ) {
$(this).addClass("trSelected");
}
});
}

Categories