Unable to set focus on and edit a cell in slick grid - javascript

I am using slick grid. On top of the grid, we have a text box. When user enters a value in textbox and tabs out, we need to enter a new row into the grid.
This is how the code looks:
gridOptions = {
useCheckBoxField: 'selected',
data: 'data',
columns: 'columns',
enableCellNavigation: true,
enableColumnReorder: true,
editable: true,
autoEdit: true,
multiColumnSort: true,
rowSelectionModel: 'selectedRows',
enableAddRow: true
}
This is how the first column looks which I am trying to edit.
{id: 'id', name: 'id', field: 'id', editor: Slick.Acsiom.Editors.Text, sortable: true, width: 210, minWidth: 100},
This is the code to enter new row and then make the first cell editable and set the focus on the cell.
var d =  $scope.$grid.grid.getData();
$scope.$grid.grid.invalidateRow(d.length);
//Adds the new row as the first row.
d.unshift(item);
$scope.$grid.grid.updateRowCount();
$scope.$grid.grid.setData(d);
$scope.selectedRows = [];
$scope.selectedRows = [0];
//Sets the first row and first column as editable
$scope.$grid.grid.setActiveCell($scope.selectedRows,0);
$scope.$grid.grid.gotoCell(0,0,true);
Problem: Everything works fine, except the cell remains uneditable. User has to manually click on cell to edit it. How can I make the cell editable as soon as a row is added?

Use grid.editActiveCell - see more here https://github.com/mleibman/SlickGrid/wiki/Slick.Grid#wiki-editActiveCell
After setting active cell, make it editable.
var grid = $scope.$grid.grid;
var row = $scope.selectedRows[0];
var col = 0;
grid.setActiveCell(row, col);
grid.editActiveCell(Slick.Acsiom.Editors.Text);

Having a similar problem, I needed the following three lines to open a cell for editing.
grid.setActiveCell(row, col);
grid.setOptions({editable: true});
grid.editActiveCell(grid.getCellEditor());
If a cell was validated for editing, I used the booleans 'editCell' and 'cellEditOpen', and set grid.setOptions({editable: false}); as necessary

Related

Show/ Hide column in dojo grid based on condition

Guys i have a column which i want to hide and show based on condition in settings ... so how to do that in dojo ... here is my code
this._grid = new Grid({
myColumn,
{field: 'description' ,label:'description', dismissOnEnter: false, editor: 'textBox', autoSave: true, renderCell: function(object, data, td, options){
td.innerHTML = data;
}}]
});
var myColumn = {
field: 'myColumn',
label: 'myColumn',
editor: Select,
hidden:false, /* hide or show based on condition*/
autoSave: true,
};
any help will be greatly appreciated ... thanks
use grid.layout.setColumnVisibility(0,true); to show or hide a column of your grid dynamically.
If you have more columns to hide or show then use
grid.beginUpdate()
grid.layout.setColumnVisibility(i, visible);
grid.endUpdate();
i is the column index which you want to hide/show and visible is true/false
Hope this helps.
**********************update**********
adding jsfiddle
**************update 2*****************
take a look into this extension
https://github.com/SitePen/dgrid/blob/v1.2.1/doc/components/extensions/ColumnHider.md
You can easily use CSS
grid.styleColumn("idOfColumn", "display: none;");

angular ui-grid highlight entire row by cell click

It looks like a simple task, but I already spent 4 hours to find a solution. How can I highlight the entire row by cell click?
On register api I have next
$scope.gridOptions.onRegisterApi = function(gridApi){
$scope.gridApi = gridApi;
gridApi.cellNav.on.navigate($scope,function(selected){
if('.ui-grid-cell-focus '){
console.log("fired class")
$(selected.row.entity).addClass('ui-grid-cell-focus')
}
console.log("fired cell")
$(selected.row.entity).addClass('ui-grid-cell-focus')
});
};
I see how click on cell is fired, but I cannot force to color the row and I don't want to select the row, because I use check box selection for this purpose, I just want to highlight the row by click on any cell in this row. Could somebody tell me where my mistake is?
Attached plunker
One way to accomplish what you want is to add a cellClass definition to your columnDefs. That function takes two params: grid and row.
$scope.gridOptions.columnDefs = [{
name: 'id',
width: '150',
cellTemplate: "",
cellClass: getCellClass
}, {
name: 'name',
width: '200',
cellClass: getCellClass
} ...
];
function getCellClass(grid, row) {
return row.uid === selectedRow ? 'highlight' : '';
}
On click you could set a variable to the uid of the row, and inside the cellClass function you can check if the uid of the current row matches the uid of the selected, if so, you can set the class to a class that properly reflects the background color of the selected row.
var selectedRow = null;
gridApi.cellNav.on.navigate($scope, function(selected) {
if ('.ui-grid-cell-focus ') {
selectedRow = selected.row.uid;
gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
}
});
Here's a link to your updated plunker: http://plnkr.co/edit/AgpAI2cmdqgNsSLVNjYA?p=preview
If you don't like the cellClass approach you could define custom cellTemplates and similarly react to a property you set on the row entity.

jqGrid edit custom function

I have a problem with data validation on an editable cell. I make some cells of one column editable based on the values of these cells. Here is the code of the grid:
jQuery("#cart").jqGrid({
datatype: 'local',
autowidth: true,
height: tabHeight,
gridview: true,
shrinkToFit: true,
autoencode: true,
loadtext: "იტვირთება",
multiselect: true,
idPrefix:"b",
colNames: ['დასახელება', 'რაოდენობა მინ.', 'რაოდენობა მაქს.', 'პოზიცია', 'რაოდენობა', 'ფასი'],
colModel: [{
name: 'asktx',
index: 'asktx',
width: 40,
sorttype: "string",
},
{
name: 'menge_min',
index: 'menge_min',
width: 30,
sorttype: "number",
hidden: true
},
{
name: 'menge_max',
index: 'menge_max',
width: 30,
sorttype: "number",
hidden: true
},
{
name: 'srvpos',
index: 'svrpos',
hidden: true
},
{
name: 'menge',
index: 'menge',
width: 30,
sorttype: "number",
editrules: {
required: true, number: true, custom: true, custom_func: checkInterval
},
editable: true,
},
{
name: 'price',
index: 'price',
width: 30,
sorttype: "string",
search: false,
}],
viewrecords: true,
caption: "არჩეული მომსახურებები",
gridComplete: function () {
var $this = $(this), ids = $this.jqGrid('getDataIDs'), i, l = ids.length;
for (i = 0; i < l; i++) {
var rowData = jQuery(this).getRowData(ids[i]);
if (rowData.menge_min != rowData.menge_max && !rowData.menge) {
menge_min = rowData.menge_min;
menge_max = rowData.menge_max;
$this.jqGrid('editRow', ids[i], true);
}
}
}
});
I am using gridComplete to check if values of two cells are equal and if they are not, I am making a column called "menge" editable in that row. I have also done the validation for constant values, like if I need to check whether this menge value is between a and b, I can do that and all is fine, although now I need to validate that field value based on the values of "menge_min" and "menge_max" field values, that are hidden. I see that custom function "checkInterval" can have only two parameters, so I can not pass the row ID there. Is there any way for getting some kind of information about the row which is currently being edited in custom validation function?
I fill the grid based on click event on another grid, here is the validation function for now:
var checkInterval = function (value, colname) {
value = parseInt(value);
mange_min = parseInt(menge_min);
menge_max = parseInt(menge_max);
if (value < menge_min || value > menge_max) {
return [false, "რაოდენობა უნდა იყოს " + menge_min + "-" + menge_max + " ინტერვალში"];
} else {
return [true];
}
}
As for multiple editable rows, it is kind of requirement and the user knows he/she entered a correct value if there is no validation error popup and continue to edit other rows. The jqGrid version is 4.5.1.
here is the select event of the other grid:
onSelectRow: function (id) {
if (id && id !== lastSel) {
jQuery(this).restoreRow(lastSel);
lastSel = id;
var celValue = jQuery(this).getRowData(id);
var rowCount = $("#cart").getGridParam("reccount") + 1;
if (celValue.menge_min == celValue.menge_max )
celValue.menge = celValue.menge_min;
var newID = id + rowCount;
jQuery("#cart").jqGrid('addRowData', newID, celValue);
}
}
I see that your problem is accessing to the content of menge_max in menge_min column inside of custom_func callback.
You current code set menge_min and menge_max to the values from the last row of the grid. The loop inside of gridComplete overwrite the value of the variables.
I would recommend you don't start editing mode for multiple rows. It generates many problems. For example the rows could be modified, but not saved. The sorting and filtering (searching) are blocked in the grid. One can use the possibility only after saving of changes in all rows. Typically one implement starting of editing on click on any cell of the grid. The user sees the starting of editing and he/she can press Enter to save the data. Between editing the rows the user can sort or filter the grid (you can add call of filterToolbar method to create the filter bar). In the way the user can easy find the requested row of data and then edit the data.
The version 4.5.1, which you currently use, is very old. It was published about 3 years ago. You have no callbacks with exception custom_func, which you can use and because you edit multiple rows at the same time.
The simplest way to solve your problems would be updating to free jqGrid 4.13.0. Free jqGrid is the fork of jqGrid which I develop starting with the end 2014. It have enchantment which you need. I implemented alternative way to specify custom validation. Instead of usage custom: true, custom_func: checkInterval one can use custom: checkInterval instead (custom property is not Boolean, but callback function instead). In the case the custom callback would get one parameter options with many properties which you can use. The properties are described here (see the comment for additional information). You could need options.rowid and to use var item = $(this).jqGrid("getLocalRow", options.rowid); to get full item of data where item.menge_max and item.menge_min can be used.
Additionally I would recommend you to use addRow inside of onSelectRow or parent grid. You can use initdata option to specify the data of the grid and no rowID. The documentation of addRow described the default value of rowID incorrectly. The default value of rowID is null, even for the version 4.5.1 (see the line of code), and jqGrid generates unique rowid automatically in the case. You can then remove the code from gridComplete. If you would implement starting of inline editing on selection the rows in the grid then the user can do all what he need without any restrictions.
The last remark. If you would migrate to free jqGrid you can remove menge_min, menge_max and svrpos columns from the grid. Instead of that you can use additionalProperties: ["menge_min", "menge_max", "svrpos"]. It informs free jqGrid to save the value of the properties in the local data, but not place the information in some hidden cells of the grid (no unneeded information in the DOM of the page).
In any way you can remove unneeded sorttype: "string" and index properties from colModel.

How to prevent kogrid to automatically select newly added items, preserving current selection?

I've following issue: I have two kogrids on my page. One one the left, one on the right side.
Between them I added two buttons so that the user can move selected items from the left to the right side and the other way round.
Therefor my view model has 4 arrays, ItemsA, SelectedItemsA, ItemsB and selectedItemsB. The two kogrids are configured as followed:
<div data-bind="koGrid: {
data: ItemsA,
selectedItems: SelectedItemsA,
displaySelectionCheckbox: false,
enableRowReordering: true,
enableSorting: false,
columnDefs: [
{ field: 'Name', cellTemplate: tableCellTemplate, cellClass: 'player-row' },
{ field: 'ClubName', displayName: 'Mannschaft' },
{ field: 'DisplayPosition', displayName: 'Position', cellTemplate: playerPositionNameTemplate}
],
footerVisible: false
}">
</div>
On moving items from left to the right, I will push every item from SelectedItemsA into ItemsB via:
$.each(self.SelectedItemsA(), function(idx, player) {
self.ItemsB.push(player);
});
And cleaning the selection on the left side via:
self.ItemsA.removeAll(self.SelectedItemsA());
They items will appear correctly in the grid on the right side bounded to ItemsB, but they are automatically selected. So if I want to move a single item back, I first have to deselect all items I moved previously! How can I prevent kogrid from automatically selecting newly added items?
Its a bug in koGrid.
In koGrid-2.1.1.debug.js:
self.setRenderedRows = function (newRows) {
self.renderedRows(newRows);
self.refreshDomSizes();
};
newRows is an array of the rows you selected / copied.
koGrid copies them as they are, that means, that newRows.selected() (observable) is true.
UPDATE
Turns out, the above change would also de-select rows after they scrolled out of vision range. But i figured you can just set __kg_selected__ to false for each row you want to copy.
Say:
ko.utils.arrayForEach(self.SelectedItemsA(), function(player) {
player.__kg_selected__ = false;
});
and then push them all to the new array:
ko.utils.arrayPushAll(self.ItemsB(), self.SelectedItemsA());

HTML Table Filter Script + sortable table: Always show tfoot and thead

I use this wonderful script to make my table sortable and add some filters to it. My problem is that I need always to see the second row in the thead (that with the checkbox) . I avoided sorting the row when clicked (by making it td instead th although it's in the thead).
So the main problem is that I need to see the checkbox (thead/td, and it shouldn't be active when clicked to sort the table as the row above) and also always see the tfoot - which is also hidden when add filter...
Here are my settings
var Props = {
popup_filters: true,
mark_active_columns: true,
sort: true,
sort_config: {
sort_types:['EU','EU','EU','EU','EU','EU','EU','EU','EU','EU','EU','EU','EU','EU']
},
loader: true,
loader_html: '<img src="/images/load.gif" style="vertical-align:middle; margin:0 5px 0 5px"><span>Зареждане...</span>',
mark_active_columns: true,
col_0: "select",
col_1: "multiple",
col_2: "select",
col_3: "select",
cEUtom_slc_options: {
cols:[1],
texts: [['0- 50','60 - 80','80 - 100']],
values: [
['<=50','>60 && <=80','>80 && <=100']
],
sorts: [false],
sort_config: {
sort_types:['EU','EU','EU','EU','EU','EU','EU','EU','EU','EU','EU','EU','EU','EU']
},
},
themes: {
name:['MyTheme'],
src:['TableFilter/TF_Themes/MyTheme/MyTheme.css'],
description:['My stylesheet'],
initialize:[null]
}
};
setFilterGrid("advancedtable1",Props );
I found what I needed
first what we need to do is to get the row number of the footer:
var totRowIndex = tf_Tag(tf_Id('advancedtable1'),"tr").length; //advancedtable1 is the table id
then I added this
rows_always_visible:[2,totRowIndex] to the table props where 2 is the row in the th wich i wanted to always see and totRowIndex is the footer row.

Categories