Adding Excel like functionality to jqgrid of already editable cells - javascript

I have a jqGrid with only certain columns that are editable and I would like to be able to implement functionality similar to excel when you press tab and enter. These columns are editable from the start, because I call editRow on every row in loadComplete, so that the user may click in any one of the cells in these columns and change the information. I would like it to be such that when you press tab the cursor goes to the next editable cell in the current row until it gets to the end and upon pressing tab again, goes to the first editable cell of the next row; and upon pressing enter goes to the first editable cell of the next row no matter what cell you happen to be in of the previous row. Every time cell focus is changed, data is saved to the server.
I've been doing quite a bit of research, but none of it has worked. I have the functionality for each keypress in the colModel under editoptions and dataEvents as a keydown event that checks to see which button has been pressed and then executes the appropriate code. The first thing I tried used the editCell method of jqGrid where I passed it the row and column of the next cell I would like to move the cursor to, but that didn't work and I think it is because I've already called editRow on every row. I've also tried changing the focus to the cell I'm trying to go to by using $.click() or $.focus() but that has not worked either.
Something extra to note is that when these columns are blurred, I recompute the column totals on the client side. I have tried putting the different things I've tried to change focus inside setTimeout but that hasn't worked either.
I basically would like to keep it where all of the cells in the columns that I want to be editable are editable at any time and the user may either click on that specific cell or tab/enter over to it to edit it. This is how it looks for clarification:
http://cl.ly/2W3E1U3i1k3K0W2Y0r0n
Thanks for the help!

I was able to figure it out and I'm not sure why it took me so long to figure out. Nothing that jqgrid provided worked and I had tried many different things from jQuery and I finally found something that works:
{
type: 'keydown',
fn: function(e) {
var key = e.charCode || e.keyCode;
//TAB
if(key == jq.ui.keyCode.TAB) {
setTimeout(function() {
jq('#' + currentRowId + '_nextColName').focus();
jq('#' + currentRowId + '_nextColName').select();
}, 500);
}
//ENTER
else if (key == jq.ui.keyCode.ENTER) {
var nextRow = parseInt(currentRowId) + 1;
jq('#' + currentRowId + '_thisColName').blur();
jq('#' + nextRow + '_firstColName').select();
}
}
}
This makes it so that tab takes you to the next column and enter always takes you to the first column of the next row while maintaining that all of the cells are always editable and you can click on any editable cell at any time.

Related

Select text inside html table cell upon tabbing into the cell

I feel silly for asking this, it seems like it should be very simple, and yet after several hours - here I am.
I have an HTML Table with <td> cells inside. Each cell has a default of "0". I'm trying to figure out how to select the cell contents upon tabbing and/or clicking into the cell. I've tried using CSS (i.e,. user-select: all; user-select: text) and the best I can do with javascript is to clear the cell on click:
document.getElementById(tableId).addEventListener('click', (e) => {
if (!e.target.contentEditable === "true") return; //using this to register clicks on a cell
e.target.innerText = ""
})
I'd really like to just select the contents - not clear them - so the user can leave the value there and tab to the next one if they want to keep the default value. I've tried using "focus" events and the like, to no avail. How do I just select the text inside?
Any help is appreciated! Thanks!
"Try using onfocus" (on the cells in the table)

How do I set the focus on the first editable cell in a row onRowClicked?

I have an ag-grid that I need to be able to edit via the keyboard. I have the editType set to fullRow and I'd like to be able to add javascript so that when I fire the onRowEditingStarted event, it goes to the first editable cell because occasionally, my grid is larger than the screen.
I can get the rowIndex, but I cannot get a hold of the collection of columns to look at the properties. I want to keep the rowIndex, but get the first editable column and set focus there. (Right now, it's whatever is incidentally selected to fire the event.)
Does anyone have an example that I can look at?
I've tried looking through the objects produced here:
onRowEditingStarted: function(params) {
console.log("started row editing");
console.log(params);
}
This gives me an event where I can get the rowIndex and the columnApi. I would expect somewhere in here is a collection to do a for loop, but I don't see it.
You could do something like in your onRowEditingStarted
// scrolls to the first column, or first editable column. you can pass in the correct index
var firstEditCol = params.columnApi.getAllDisplayedColumns()[0];
/////
params.api.ensureColumnVisible(firstEditCol );
// sets focus into the first grid cell
params.api.setFocusedCell(params.rowIndex, firstEditCol);
This example from docs is a good starting point

Google Script behaving differently when in spreadsheet open trigger or assigned to button

I have a spreadsheet that is intended to keep track of expenses. Since more often than not, what I want is to append new expenses at the end of the table, I have created a script (mostly by importing an example found here in Stack Overflow) that jumps to the first blank line based on column A as follows:
function jumpToBlankLine() {
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getRange("A:A").getValues();
var maxIndex = values.reduce(function(maxIndex, row, index) {
return row[0] === "" ? maxIndex : index;
}, 0);
sheet.setActiveRange(sheet.getRange(maxIndex + 2, 1));
}
If anyone have comments or suggestions about the function above, they will be welcome! But my question is regarding it's behavior.
Behavior 1:
I have set a trigger upon spreadsheet opening that works perfectly: after loading the spreadsheet it jumps to the first blank line in column A and if I start typing right after (the expense date in my case), the cell starts to get filled by what I'm typing.
Behavior 2:
But, when I assign this same function to a button (a drawing) and I click it, the spreadsheet goes to the right cell, but it ignores what I type right after. To have the cell filled by what I'm typing, I must click on it.
The behavior I want is like Behavior 1 above. I have also tried the function Sheet.activate() with no success.
Anybody have any ideas about why this is happening or a possible solution or workaround?
Thanks in advance!
It's happening because the drawing that you clicked on to run the script is actually the active object. You can confirm this by hitting return after you click on the drawing that runs the script.
Adding the below line of code to the onOpen function works as you expect but it still requires 2 clicks but less mouse travel than the drawing and doesn't require that you scroll to find it. (It creates a custom menu next to the help menu in sheets)
SpreadsheetApp.getUi().createMenu('Custom Function').addItem('Go to last row','onOpen').addToUi();

Clear previous selection only if checkbox is not clicked in jQgrid?

I have a grid setup with multiselect: true because I need to be able to delete more than one row at the same time. On the onSelectRow event I am loading some data based on the ID and displaying it to the end user. So far so good.
This is the example where everything works fine, the data for ID=219109 is being displayed:
Now look at the following example:
In the example above the first row still highlighted and then I clicked a second one. Because of multiselect is enabled I was able to select both at the same time. The onSelectRow event still working properly which means is loading the data for the ID=282006 but visually it could be confusing for the end user.
What I want to do is to reset the previous selected rows and just highlight the last one I have clicked.
For example using the same images:
Load a fresh grid with no rows selected
Click on ID=219109: highlight and select this row
Click on ID=282006: clear the grid and highlight this row
However this should only happen when I click in any other place than the checkbox.
In the image above if I click on any column rather than the first one (the one having the checkbox) I should be able to clear the grid selection and choose the last one but if I click on the checkbox it does not matter because is the only way to delete more than one at the time.
I have tried the following:
onSelectRow: function () {
var rowid = $(this).jqGrid('getGridParam', 'selrow');
$(this).jqGrid("resetSelection");
$(this).jqGrid("setSelection", rowid);
}
But it's not working since the behavior is not consistent. You can check the demo here.
Any ideas in how to achieve this?
It seems to me that you need just add the option
multiboxonly: true
and remove your current onSelectRow code. See https://jsfiddle.net/OlegKi/949pLpfv/3/. If the user clicks multiple times on checkbox the rows will be selected. The click on another part of the row will deselect all previously selected rows and select only the clicked row.

Javascript coding seems to stall

Sorry for the vague title but here is my problem :
I have an HTML table that I am generating from Javascript, this is fine and the table generates as expected with no problems.
When the user clicks on a cell it will highlight that cell (or un-highlight if the cell is highlighted), this again works fine.
We then needed the ability to drag over the cells (whilst the mouse is down) and highlight the cells they hovered, this I managed to do but it was not the best solution so it was asked if we could select a cell, then hover to another cell and all the cells in between become highlighted.
For example :
Start Cell = Row 1, Cell 1
End Cell = Row 3, Cell 3
Highlighted Cells = R1C1, R1C2, R1C3, R2C1, R2C2, R2C3, R3C1, R3C2, R3C3.
I have managed to sort of get this solution to work, here is a JSFiddle to show the solution, if you click on the first cell and hold the mouse down and drag to the last cell it works fine.
My Problem is that if you drag from the last cell (bottom left) to the top cell (top right) the highlighting effect seems to stall randomly until you are on row 2 or 3.
Is there any reason why this would be occurring? Is my code incorrect / inefficient for this?
I've been stuck with this for sometime and can't seem to find any reason why it would be occurring.
Any help is greatly appreciated.
P.S. - This solution MUST be a fully Javascript solution, jQuery cannot be used for this solution unfortunately as we require this to be a single HTML File and must be possible to use without an Internet Connection.
When you extract rowNum and cellNum, in ClickCell function, you have to convert value to interger:
var RowNum = parseInt(cellID.substring(1, cellID.indexOf('C')), 10);
var CellNum = parseInt(cellID.substring(cellID.indexOf('C') + 1, cellID.length), 10);

Categories