Set specific row selected by default in slickgrid - slickgrid

I am trying to select the specific row (row with today's date) of grid after its creation.
Please find the following function which I am calling after creating the grid.
Here, sgDataView is dataview and sgGrid is already loaded slick grid
function SetDefaultDateSelected() {
for (var rowIndex = 0; sgDataView.getLength(); rowIndex++) {
var gridRow = sgDataView.getItem(rowIndex);
if (gridRow.Date == $.datepicker.formatDate('dd-M-yy', new Date())) {
sgGrid.setSelectedRows(gridRow);
sgGrid.scrollRowIntoView(rowIndex);
break;
}
}
}
Could anyone please let me know why sgGrid.setSelectedRows(gridRow); is not setting the selected row?
Please let me know in case of any other approach.

SlickGrid's function setSelectedRows does not accept a)single values b)items, it needs indexes of items
so basically you need sgGrid.setSelectedRows([rowIndex]); instead of sgGrid.setSelectedRows(gridRow);

Related

Kendo Data Grid "Add new Record" ignores validation rules

I have a DataGrid component with remote CRUD operations.
I have a problem with the validation of its grid fields.
When I click "Add new Record", a new empty line is added to the datagrid.
Without filling in any values, and clicking on "Save Changes" button, the create operation is processed even if no required values are filled.
For example name:
name: {
editable: true,
nullable: false,
validation: {
required: {
message: "Please enter a First name"
}
}
},
Validation Message is displayed only when I click into the name cell.
Is there any way to solve this issue?
I tried enable/ disable batch editing, etc... but without luck.
I recently bumped into this issue as well, it gave me plenty of head scratching, but there are two options.
Use inline editing
Force validation on new cells
I did not go with option 1 for numerous reasons including the fact that you now need to have an edit, update, and cancel button per row before it would do any validation.
Option 2
Got the idea from Brian Roth # the Telerik forums, see here. I used his solution but optimized it a little bit.
In the saveChanges event, implement this:
saveChanges: function (e) {
if (!checkCells(this)) {
e.preventDefault(); //prevents save if validation fails
}
}
checkForInvalidCells will basically go through every new row's cells, open for edit and attempt to close (and in the process, firing the validation). If validation was not successful, then prevent the save.
function checkCells(grid)
{
var rows = grid.tbody.find("tr"); //get rows
for (var i = 0; i < rows.length; i++) {
var rowModel = grid.dataItem(rows[i]); //get row data
if (rowModel && rowModel.isNew()) {
var colCells = $(rows[i]).find("td"); //get cells
for (var j = 0; j < colCells.length; j++) {
if ($(colCells[j]).hasClass('k-group-cell'))
continue; //grouping enabled will add extra td columns that aren't actual columns
grid.editCell($(colCells[j])); //open for edit
if (!grid.editable.end()) { //trigger validation
return false; //if fail, return false
}
else {
grid.closeCell(); //if success, keep checking
}
}
}
}
return true; //all cells are valid
}
In case you are comparing my implementation and his, the difference is:
Made it cleaner without the need for break statement and bool flag
Kept save event variable e logic in the event itself
Utilized isNew() method to check for a new row, a new row's ID/Key may not always be 0, especially if it is an editable field and you have already put info in that field
I account for grouping enabled, grouping will introduce extra td columns that shouldn't be checked for saving
Overall, I hate doing hacks like this, but sometimes it's what you gotta do. Be aware that if you are adding a LOT of new rows at a time, the check will take substantially longer.
Also, each check will move the grid's scroll view to the cell that was last checked (since you are opening the cells for editing, programmatically). If all your new rows are visible at the top of the grid, this is no problem for you, but if you are appending new rows at the bottom, the user may find it strange that the grid has scrolled after saving.
This was a huge help. Thank you very much, #gitsitgo.
I needed to make minor changes to get this to work in my grid, so I thought I'd post it here.
var checkCells = (grid: any): boolean => {
var rows = grid.tbody.find("tr"); //get rows
for (var i = 0; i < rows.length; i++) {
var rowModel = grid.dataItem(rows[i]); //get row data
if (rowModel && rowModel.isNew() || rowModel.IsUpdated) {
var colCells = $(rows[i]).find("td"); //get cells
for (var j = 0; j < colCells.length; j++) {
if ($(colCells[j]).hasClass('k-group-cell'))
continue; //grouping enabled will add extra td columns that aren't actual columns
if ($(colCells[j]).hasClass('k-hierarchy-cell'))
continue; //hierarchy cell is not actual column
grid.editCell($(colCells[j])); //open for edit
if (grid.editable) { //check if editable
if (!grid.editable.end()) { //trigger validation
return false; //if fail, return false
}
else {
grid.closeCell(); //if success, keep checking
}
}
}
}
}
return true; //all cells are valid
}
The differences are:
Checks grid.editable is not null before calling grid.editable.end(). This was the main change that I needed as I have cells that are not editable.
Runs validation for both new and updated rows. Note that IsNew() is a function whereas IsUpdated is a boolean.
Skips cells with class k-hierarchy-cell. This is only needed in hierarchical grids (which is what I'm using this for).

Kendo - Grid - Remove Multiple Rows

I have the following code that remove rows that are checked (each row has a checkbox and I have a Filter button (and other buttons) in the toolbar).
var grid = $("#resultsGrid").data("kendoGrid");
grid.tbody.find("input:checked").closest("tr").each( function(index) {
grid.removeRow($(this));
});
However, performance starts to become an issue when there are > 20 rows being removed. However, kendo filters (removes) 20 rows or more much faster. How is kendo filtering removing multiple rows from the view? Or is there some other better way to remove multiple rows from the grid? Thanks in advance for your help.
** Updated Fiddle to new location - Same code as before **
Try dealing with the data directly. Have the checkbox hooked to the row's Id and filter on that.
I linked a fiddle that removes array elements and then re-creates the grid. The 2 text boxes at the top of the grid capture the range of Ids that you want to remove (this would be the same array of your checkboxIds). Then I cycled through those "remove Ids", removed them from the data array and remade the grid.
I slightly modified a previous fiddle and that's why I'm re-creating the grid instead of dealing with the DataSource object directly. But I hope you get the gist of what I'm doing.
I have 1000 records in this example (only 3 columns) but it removes 950 records very quickly.
Fiddle- Remove from data array
Let me know if you need an example of this with the KendoUI DataSource object.
I included this code below because StackOverflow wouldn't let me post without it.
function filterData() {
var val1 = $("#val1").val();
var val2 = $("#val2").val();
var removeIndexes = new Array();
for (var i = val1; i <= val2; i++) {
removeIndexes.push(i);
}
$(removeIndexes).each(function(removeIndex) {
var removeItemId = this;
$(randomData).each(function(dataIndex) {
var continueLoop = true;
if (this.Id == removeItemId) {
randomData.splice(dataIndex, 1);
continueLoop = false;
}
return continueLoop;
});
});
createGrid();
}
You should use batch updates:
$("#resultsGrid").kendoGrid({
dataSource: {
batch: true,
...
}, ...});
var grid = $("#resultsGrid").data("kendoGrid");
grid.tbody.find("input:checked").closest("tr").each( function() {
var dataItem = grid.dataItem(this);
grid.dataSource.remove(dataItem);
});
grid.dataSource.sync(); // this applies batched changes

Slickgrid add new row on demand

Is there a way to add a new row to a slickgrid on demand? For example, have a button on the page that shows the new row when clicked.
It can be done easily using dataView.addItem(params), just replace params with your parameters..
function addNewRow(){
var item = { "id": "new_" + (Math.round(Math.random() * 10000)), "Controller": tempcont, "SrNo1": tempsrno };
dataView.addItem(item);
}
here id, Controller, SrNo1 are ids of colunm
You can add a row dynamically, such as with a button click, by subscribing the "onAddNewRow" listener to your grid object. As many have suggested, it is best to use the dataView plugin to interface with your data. Note that you'll want the "enableAddRow" option set to "true".
Firstly, DataView requires that a unique row "id" be set when adding a new row. The best way to calculate this is by using dataView.getLength() which will give you the number of rows that currently exist in you grid (which we'll use as the id for the new row). The DataView addItem function expects an item object. So we create an empty item object and append the id to it.
Secondly, you'll be only focusing a single cell when you add your data. After you've entered that data (by blurring that cell), DataView will notice that you have not entered data for any of the remaining cells in the row (of course) and will default their values to "undefined". This is not really a desired effect. So what you can do is loop through the columns you've explicitly set and append them to our item object with a value of "" (empty string).
Thirdly, we don't want all the cells to be blank. Actually, we want the original cell's entered data to appear. We have that data so we can set it last so that it will overwrite the "" (empty string) value we previously set.
Lastly, we'll want to update the grid such that it displays all of these changes.
grid.onAddNewRow.subscribe(function (e, args) {
var input = args.item;
var col = Object.keys(input)[0]
var cellVal = input[Object.keys(input)[0]]
// firstly
var item = {};
item.id = dataView.getLength();
// secondly
$.each(columns, function(count, value) {
colName = value.name
console.log(colName)
item[colName] = ""
})
// thirdly
item[col] = cellVal
dataView.addItem(item);
// lastly
grid.invalidateRows(args.rows);
grid.updateRowCount();
grid.render();
grid.resizeCanvas();
});
I hope this helps. Cheers!
You can always add new rows to the grid. All you need to do is add the data object for the row to your grid data.
Assume you create your grid from a data source - myGridData (which is an array of objects).
Just push the new row object to this array. Call the invalidate method on the grid.
Done :)
Beside creating the new row, I needed it to be shown, so that the user can start writing on it. I'm using pagination, so here is what I did:
//get pagination info
var pageInfo = dataView.getPagingInfo();
//add new row
dataView.addItem({id: pageInfo.totalRows});
//got to last page
dataView.setPagingOptions({pageNum: pageInfo.totalPages});
//got to first cell of new row
var aux = totalRows/ pageInfo.pageSize;
var row = Math.round((aux - Math.floor(aux)) * pageInfo.pageSize, 0);
grid.gotoCell(row, 0 ,true);
Before I use pagination, I just needed this:
var newId = dataView.getLength();
dataView.addItem({id: newId});
grid.gotoCell(newId, 0 ,true);
var newRow = {col1: "col1", col2: "col2"};
var rowData = grid.getData();
rowData.splice(0, 0, newRow);
grid.setData(rowData);
grid.render();
grid.scrollRowIntoView(0, false);
Working fine for me.

How to sum the Row data while selecting the Checkbox in the JQGrid

while selecting the checkbox in the jqgrid i need to sum the values of row data in jqgrid and i need to display those data in the footer of the jqgrid.Please help me out how to achieve that.
Thanks in Advance,
Silambarasan,
You can use footerData method. See here and here for details and demo examples.
I got the answer ,i solved that issue.
The Answer is.
footerrow:true,
userDataOnFooter:true,
onSelectRow: function(rowId)
{ handleSelectedRow(rowId); },
function handleSelectedRow(id) {
var jqgcell = jQuery('#list1').getCell(id, 'headerId');
var amount = jQuery('#list1').getCell(id, 'amount');
var cbIsChecked = (jQuery("#jqg_list1_"+jqgcell).attr('checked'));
if(cbIsChecked==true)
{
if(amount!=null)
{
totalAmt = parseInt(totalAmt) + parseInt(amount);
}
}else
{
if(amount!=null)
{
totalAmt = parseInt(totalAmt) - parseInt(amount);
}
}
myGrid.jqGrid('footerData','set',{needbydate:'Total Amount:',amount:totalAmt});
}
The above function is used to get the values of the selected row by clicking the checkbox you will get the value from that by calling the external function like "handleSelectedRow" you pass your row object from that you do your operation and finally update your answer by using the jqGrid function like "myGrid.jqGrid('footerData','set',{needbydate:'Total Amount:',amount:totalAmt}); "
It will update in your footer.

JQGrid setCell customFormatter

I'm using setCell to set the value of a cell. The problem is it is still calling the customFormatter specified for the column. Is there anyway I can set the value of this cell without it having to go through the customFormatter?
First of all the custom formatter will be used on every grid refresh, so to set the cell value you have to do this after the custom formatter. The best place to do this is inside of loadComplete or gridComplete event handler.
To set the cell value you can use jQuery.text for example. So you should get jQuery object which represent the cell (<td> element) and then use jQuery.text or jQuery.html to change the cell contain. How I understand you, you knows the rowid of the cell and the column name which you want to change. The following code could be:
loadComplete: function() {
var rowid = '2', colName = 'ship_via', tr,
cm = this.p.colModel, iCol = 0, cCol = cm.length;
for (; iCol<cCol; iCol++) {
if (cm[iCol].name === colName) {
// the column found
tr = this.rows.namedItem(rowid);
if (tr) {
// if the row with the rowid there are on the page
$(tr.cells[iCol]).text('Bla Bla');
}
break;
}
}
}
See the corresponding demo here.

Resources