Adding new instance of row, unable to update cell raw values - javascript

I've stumped myself on what I thought was a pretty simple JavaScript function. The function takes 2 parameters. The first is a listbox (oField), and the second is a table (nTable).
The listbox is populated by the user, and each time this listbox's values are changed, I want the function below to be called, to recreate nTable, the original header, and rows for each value in the list box.
function table_build(oField, nTable){
//clear table when selection changes
nTable._HeaderRow.setInstances(1);
//add new selection to table
for(i=0;i<oField.length;i++){
nTable._HeaderRow.addInstance(true);
nTable.HeaderRow[i+1].Cell1.rawValue = oField.getDisplayItem(i);
}
}
The issue that I am having is with the following line:
nTable.HeaderRow[i+1].Cell1.rawValue = oField.getDisplayItem(i);
I am able to update the value of the header row using:
nTable.HeaderRow.Cell1.rawValue = oField.getDisplayItem(i);
Which is weird, because I would have expected it to require HeaderRow[0] after the new instance is added.
What is wrong here?

I have worked out a solution. The addInstance() function returns the new row instance. So I have updated my table_build() function to assign that value to a variable(nRow), then use nRow to reference the row.
var nRow = nTable._HeaderRow.addInstance(true);
nRow.Cell1.rawValue = oField.getDisplayItem(i);
Hope this helps anyone else with a similar query :)

Related

How to add IF/ELSE function in data validation in-cell dropdown function?

I'm trying to create an in-cell data validation drop down menu (in google spreadsheet) by using If/Else function.
Actually, I've 2 range of lists from which I only want to show one decided by a variable cell.
It sounds like this: If A1 is ABC then show range 1 in-cell dropdown & if A1 is XYZ then show range 2 in-cell dropdown.
Here's the code. Let me know what I'm doing wrong.
function dataval (){
var cell = SpreadsheetApp.getActive().getRange('B12');
if (cell=="Price") {
var cell = SpreadsheetApp.getActive().getRange('C12');
var range = SpreadsheetApp.getActive().getRange('D12:D19');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cell.setDataValidation(rule);
};
if (cell=="Technical") {
var cell = SpreadsheetApp.getActive().getRange('C12');
var range = SpreadsheetApp.getActive().getRange('E12:E19');
var rule = SpreadsheetApp.newDataValidation().requireValueInRange(range).build();
cell.setDataValidation(rule);
};
};
P.S.: I'm new to coding & this is my first ever ever post on SOF.
A problem with your code is the comparison cell=="Price". The variable cell is an object of class Range, not a string. To get the value it contains, you need cell.getValue(), so the comparison would be cell.getValue() == "Price".
You should also handle the event of the content of B12 changing. A simple way is to put the data validation code in onEdit trigger, and check whether the edit was to B12: e.g.,
if (e.range.getA1Notation() == 'B12') {
// change data validation
}
If the goal was simply to have a rule that forces inputs to be in one of two ranges, depending on another cell, that can be done without a script, using a custom formula with if and index. But that wouldn't provide a dropdown of values.

How to replace old table with new one in Handsontable?

I have an interface that allows users to type in MySQL queries and click a button to execute the queries. Then the result of the queries is displayed in a table created by Handsontable. I do it with the following code:
var output = document.getElementById("output");
var hot = new Handsontable(output, table_setting);
The problem now is, every time the button is clicked, it creates a new table over the old one. I would like the new one to replace the old one. I tried using output.innerHTML = ""; before var hot = new Handsontable(output, table_setting); to get rid of the old table. This seems to get rid of the old table, but the new table does not appear anymore. What is the best way to do this?
Thank you!
You want to first do hot.destroy() and THEN create a new hot instance.

Delaying select2 opening to fill it with data

I have a dropdown which I'm filling data by calling a function list(), which makes json calls and filters necessary data according to different parameters (It's very complex, and I'm not using the built in ajax feature).
Here's my code:
$("select.mission:visible").on("select2-opening", function() { list(); });
It works flawlessly, except for one little problem - updating the list is done while opening so the updated list doesn't show when you first open the dropdown. On the second open it shows the correct options.
I considered using select2-focus, but it's called twice, in the beginning and in the end. The second call repopulates the list and while the selected option is still highlighted, the value passes down as undefined.
The solution I look for is delaying the opening of the list to let it populate.
Any ideas in this direction or another?
it is a bit late for this question. I have the similar problem as you and I have solve it as below:
$("select.mission:visible").on("select2-open", function() {
$.getJSON("path-to-json", function(data) {
var results_data = [];
$.each(data.feed.entry, function(i, entry) {
results_data.push({'id':entry.id, 'text':entry.text})
});
// if your element select.mission:visible is select convert it to input:hidden
var id = $(this).attr('id') // get old id
var name = $(this).attr('name') // get old name
var oldVal = $(this).val() // get old value
$('select.missions').empty(); // empty select options
$(this).select2('distroy') // destroy current select2 obj
$(this).replaceWith(`<input type='hidden' class='mission' id='${id}' name='${name}'>`) // convert select element to input element
$(this).val(oldVal) // set new input element to previous value
$(this).select2({data:results_data}) // set new option items to new input element select2
$(this).select2('open') // force select2 element to open dropdown
});
});
Because I don't know which version of select2 you're using, but from your code, I assumed you are using select2 version 3.x. For more detail check it at https://select2.github.io/select2/

Knowing which column is being updated

I am trying to get handsontable to give me which column is being updated, but have not been able to find a proper solution. I understand they are using a textarea to get the input and then putting the values into a table, but I just cannot figure out how to find out which column is being update.
Any help would be appreciated.
Thanks
This method will tell you what row/column is selected:
$('#example1grid').handsontable('getSelected')
This will be return the same coordinates as the currently edited cell, except for cases when there are multiple cells selected (but even then the currenyly edited cell is always within selected cells).
I am thinking about creating a new method getCurrent or callback onBeginEditing to return currently edited cell. Which would be better for you? I think the callback would be better.
onChange: function (data) {
for (i in data) {
if(data[i][2] != data[i][3]) {
var column = $('#dataTableLoc td:nth-child(' + (data[i][1] + 1) + ')')[0].innerText;
}
}
}
This is obviously far from elegant. It will conflict with any extensions like the "removeRow" example in buttons.html but obviously can be adjusted accordingly. Its necessary when pulling data from an SQL table and trying to update using a query.

Storing data in javascript for server side processing

The problem is simple. I have something like chessboard in HTML. The fields have coordinates, stored in ID attribute (ROW|COLUMN)
Clicking on a specific field makes it marked/unmarked. What is more, selected field's row and column are stored in a <input type="hidden"/> in the form of ROW|COLUMN,ROW|COLUMN,...
For every click I have to process the value of input hidden to check whether the field is already stored, add new field, remove existing and so on. It's a little awkward.
Are there any better ways? Or maybe it is the best way?:)
You don't have to store the fields state in an input field. Better use the a global JavaScript array or manipulate the DOM and serialize it's state before sending it to the server.
Here is some sample code in a JSFiddle: http://jsfiddle.net/U2D9Q/
The important part is where the className of the columns
$td.bind("click", function(e) {
$(this).toggleClass("selected");
});
and how it's serialized when you click the button
var serialize_table = function() {
var output = new Array();
$("table tbody").children().each(function(y) {
var row = new Array();
$(this).children().each(function(x) {
row[x] = $(this).get(0).className;
});
output[y] = row;
});
return output;
}
I used jQuery to keep the code clean. Feel free to use any JS Framework you like or write native JS.

Categories

Resources