I have an html table with cells that can be edited when clicked on. I am trying to figure out the best method to change cell data in cells following an edited cell.
For example, say the table comes populated by random numbers or letters. When I changed a cell to "14" I want the cells after it to change automatically to 15, 16, 17,n+1..ect. Or if I entered "h" the following cells would change to i,j,k,l...z stopping at z.
The number one seems pretty easy as I could just create a loop and i++ for each cell. However, the letter one doesn't seem as simple. Would I need to create an alphabet array and find the edited cell letter within it then proceed to the end of the array inserting each into the follow cells?
This can actually be done with a fairly simple function call like this one:
function NextChar(c){
return String.fromCharCode(c.charCodeAt(0) + 1);
}
where c is the alphabetic character that is entered into the cell, passed as a parameter.
I can see this question was done quite some time ago, so this answer is more for people who make come seeking answers later.
I would make arrays with character sequences as you said and use the jQuery.inArray() API to detect which sequence the edited cells content is in.
Check it out: http://api.jquery.com/jQuery.inArray/
Related
So, I'm trying to read data from a cell in Google Spreadsheet's script and something's not right for me. I made a quick test function that takes the data from the cell, turns it to a string and returns the result, like so:
function TEST(str)
{
return str.toString();
}
Then I made two test cells:
A1 with "17"
A2 with "135,136"
A3 with "1,11,29,43,68,74,109,122"
Then I called my function and I'm baffled by results
TEST(A1) returns "17"
TEST(A2) returns "135.136"
TEST(A3) returns "1,11,29,43,68,74,109,122"
So it seems that if there is exactly one comma it gets cast to a full-stop instead but if there are multiple none of them get replaced. What is going on and how can I read data from a cell as a string with 100% certainty that it won't get changed in any way?
Issue:
Some locations use , as decimal separator. So, 135,136 is a valid number(=135.136). But, 1,11,29,43,68,74,109,122 is not. Valid numbers are by default aligned to the right of the cell(Clear cell formatting to witness).
Solution(s):
Set your locale properly, if you're going to use ,s as commas and not as decimal separators OR
Input numbers as text. Use ' before inputting data in each cell. '135,136 OR
Send inputs as Text. =TEST(TO_TEXT(A1)) OR
Use range#getDisplayValues() instead.
The A Column where this data is stored, it's format should be changed and that would solve the issue.
Select A Column --> Format --> Number -- Plain Text. Changing the format will serve the purpose.
Hope it could help!.
As we have find and replace logic in Excel and many other documents, how to implement the same using Handsontable? I tried to find the same in the Handsontable site but could not find. All i could find was "search" using searchbox.
Im new to Handsontable. Any help on this would be great.
You can easily reuse the search function already present in the Handsontable documentation example for the first part of the problem.
You then have to add a field where you can put the value you want to replace the cells that have been match, and use the below simple function to replace those values by the new one :
Handsontable.dom.addEvent(Replace, 'click', function() {
// Replace the value of every cell that have been match by the search query
for (row = 0, r_len = queryResult.length; row < r_len; row++) {
hot.setDataAtCell(queryResult[row].row, queryResult[row].col, replace);
}
// Reset all the fields
SearchField="";
ReplaceField="";
queryResult="";
document.getElementById('Search').value='';
document.getElementById('ReplaceWith').value='';
});
See this working jsFiddle example.
Adding to https://stackoverflow.com/a/50228873/9230481
Note that this fail if you enable any form of sorting or filtering (e.g. columnSorting: true) because the matches in „visual indices“, which change after sorting. To solve this you need map the indices to physical ones right after the search finished. See https://handsontable.com/docs/api/core/#tophysicalrow and https://handsontable.com/docs/api/core/#tophysicalcolumn
In the replace function you need to map physical indices back to visual indices as setDataAtCell expects visual indices: https://handsontable.com/docs/api/core/#setdataatcell
Software
I'm using Pentaho Data Integration 5.4
Input data & explanation
Input data from a file (simplified, there are more columns):
number name
1009 ProductA
2150 ProductB
3235 ProductC
ProductD
ProductE
1234 ProductF
7765 ProductG
4566 ProductH
ProductI
9907 ProductJ
The issue is that I had an Excel file format xlsx which has the data with merged cells, and for one value of id there are 1..n rows of values.
After converting that file to csv values for next rows (other than first) are missing, despite the one column which was not merged (see example id=3, id=6).
I'm generating a sequence using step Add sequence, the input is sorted the way it was originally stored in a file.
Steps to achieve the goal
Basically what I need to do is:
Find first non-null value that has sequence_number less than current_row.sequence_number
Concatenate the value from field name to that matching row
Keep scanning next rows with sequence_number higher than the last scanned
As stated before, there can be 1..n rows of values for such case.
Expected output
number name
1009 ProductA
2150 ProductB
3235 ProductC; ProductD; ProductE
1234 ProductF
7765 ProductG
4566 ProductH; ProductI
9907 ProductJ
My approach
I believe I'm able to do this in a loop, by using Analytic Query and calculating LAG(1) and then concatenating the column name for one row with null values and discarding other column values from null row - and then doing this in a loop (for like 20 times assuming this is maximum), but I do consider this a bad idea.
There are probably better ways to achieve this result using for example Java Script step with scanning the rows backward from current (based on sequence number), but I'm unaware of those functions, if they do exist.
How can I achieve this using Modified Java Script Value step, or any other efficient way without using a loop for entire content of the file until there are no empty rows?
To solve this, I would use Modified Java Script Value to save the last seen product and use this for all rows, and then use Group By to group the columns.
Introduction
Merged adjacent cells in Excel files are presented on the image below.
When opened as a plain text file, it actually creates gaps (data from merged cell is missing) for every row but first that contains the merged cell.
number name
1000/P um6p1
um1p2
um1p3
1500 um2p1
9823 um3p1
83424 um4p1
um4p2
um4p3
um4p4
21390 um5p1
While #bolav answer addresses the problem, there is a simplier and probably more efficient approach to this issue in Kettle.
Approach
In Microsoft Excel Input step go to Fields tab and mark Repeat option as Y for columns that store values in merged cells
Use Sort rows on number column because Group by step needs the input to be sorted
Group by on field number and aggregate name with Concatenate strings separated by as type and ; as value
From Pentaho User Guide:
Repeat If set to Y, will repeat this value if the field in the next row is empty.
Could not find a clear explanation of how to achieve this. Does JS have a straight forward method for taking the entire column from a grid and populating an array with one cell value per array element. I do know the value of each cell. But I want to make an array of all the individual cell values. I am relatively new to JS and thought it might be wiser to ask here than to go on mashing code together seeing no results.
Thank you so much, Luxy
For example,
My cell value is in params.data["Bug Feature"] // which prints each value 0, 13, text, text, 0...
What I want is to make an array of the single values to an array.
I didn't mean to get a full implementation. I just wanted to know the right way. This is what I am doing currently. But it is making each cell value an array which is not what I am looking for.
var sortBUGFeatures = jQuery.makeArray(params.data["Bug Feature"]);
i did it in jQuery but I thought JS would be little simpler for me
I have a long table with columns of schedule data that I'm loading via a form with jQuery load(). I have access to these html pages with the table data and can add classes/data attributes etc.
My form has select fields for hours and minutes (defaulting to the current time) and I'm trying to get the next closest time plus the four after that.
The time data in my tables are all formatted as <td>H:MM</td>.
Ideally with jQuery, I was wondering how I can strip the table data of everything but those times. Alternatively, since I can reformat this data would I be making my life easier to format it a certain way?
Things I've tried - I am admittedly a novice at js so these things may seem silly:
Reading the first character of each cell and comparing it to the
selected hour. This is obviously a problem with 10, 11, 12 and is
really intensive (this is a mobile site)
Using a single time select field thenCreating an Array of each
column to compare with the selected time. Couldn't get this working
and also creates an issue with having to use a single select for
every time.
Basically looking for a little guidance on how to get this working short of, or maybe including, copying all the html tables into JSON format...
May as well post http://jsbin.com/ozebos/16/edit, though I was beaten to it :)
Basic mode of operation is similar to #nrabinowitz
On load, parse the time strings in some way and add to data on each row
On filter (i.e. user manipulates a form), the chosen time is parsed in the same way. The rows are filtered on row.data('time') >= chosen_time
The resulting array of elements limited to 5 (closest time plus four as OP requested) using .slice(0, 5)
All rows are hidden, these rows are displayed.
Some assumptions have been made, so this code serves only as a pointer to a solution.
I thought this was an interesting question, so I put together a jsFiddle here: http://jsfiddle.net/nrabinowitz/T4ng8/
The basic steps here are:
Parse the time data ahead of time and store using .data(). To facilitate comparison, I'm suggesting storing the time data as a float, using parseFloat(hh + '.' + mm).
In your change handler, use a loop to go through the cells in sequence, stopping when you find the index of the cell with a time value higher than your selected time. Decrement the index, since you've gone one step too far
Use .toggle(i >= index && i < index+4) in an .each() loop to hide and show the appropriate rows.
Here's how to do it on client side. This is just an outline, but should give you an idea.
// Create a sorted array of times from the table
var times = []
$('#mytable td').each(function(cell) {
times.push(cell.innerHTML);
});
times.sort();
// Those times are strings, and they can be compared, e.g. '16.30' > '12.30' returns true.
var currentTime = '12:30' // you probably need to read this from your select
var i = 0;
while (times[i] < currentTime || i=times.length) {
i++;
}
var closestTime = times[i];
var closestTimes = times.slice(i, i+4);
If you want to access not the times, but actually the cells containing the times, you can find them like this:
$('#mytable td').each(function() {
if ($(this).text() in closestTimes) {
// do something to that cell
}
})