I use SheetJS to upload an excel sheet to a ui.table. While uploading I add a technical ID to my column names, which I will need later on in my project. This is how I am adding the technical ID:
getColumnNames: function(worksheet, aData) {
var firstRow = aData[0];
var oColumns = [];
var cells = Object.keys(worksheet);
for (var i = 0; i < Object.keys(firstRow).length; i++) {
var columnName = Object.keys(firstRow)[i];
var technicalName = "COL" + ('0' + (i+1)).slice(-2);
oColumns.push({
columnId: columnName,
technicalId: technicalName
});
}
return oColumns;
},
When creating the Model, I bind both the columnId and the technicalId to each column.
My users should have the option to reorder the table columns in order to do a mapping to another table. (Context here is not really relevant) So basically there is another table below my uploaded table and a user should be able to reorder the columns of the "uploadTable" to match them with the table below.
Now in order to do a proper mapping, my technical ID has to be adjusted after the reordering is done. Therefore I'd like to add a function that's being executed after the user clicked a "refresh" button.
This function should adjust the technical columnNames. --> E.g. data gets uploaded, column on position 1 has the technical ID "COL01" now it gets dragged to position 2 --> technical ID should change to COL02 and vice versa.
I believe, the only way to do this is by accessing the DomRef of the table, because that's the only place where the actual current table structure is stored, but I'm not exactly sure how I would proceed.
My reordering function only gets the data so far:
onReorder : function() {
var table = this.getView().byId("uploadData");
var currentStructre = table.getDomRef();
},
I would appreciate any hints towards this. If anything is unclear, I'm happy to explain it!
sap.ui.table.Table allows its columns to be reordered by dragging and dropping, and the event columnMove is fired after.
One could keep track of and update some sequence label (e.g. ids) using an approach like this:
Remember ids (for example column label as id):
ids = oTable.getColumns().map(oColumn => oColumn.getAggregation('label').getText())
Update ids:
oTable.attachColumnMove(function(oEvent) {
var from = oEvent.getParameter('column').getIndex();
var to = oEvent.getParameter('newPos');
var name = names.splice(from, 1);
names.splice(to, 0, name);
// Then write new ids to model;
})
Related
I'm trying to compare two variables and find out if they have the same position to display the second variable, I'm trying to find out the second variable (Artist name) based off of the first input which was the Track Name, based off of the position on the data table.
All the track names are on the same position as the artist who made the song so I want to be able to display that when they input it.
My Code so far to choose the track name based off of a drop down with all 200 songs.
onEvent("fighter1", "change", function( ) {
var Track = getProperty("fighter1", "text");
setProperty("songLabel_1", "text", "");
var ChosenTrack = Track.substring (0,100);
var TrackName = getColumn("Spotify Charts: Top 200 Artist and Song", "Track");
for (var i = 0; i < TrackName.length; i++) {
if (ChosenTrack == TrackName) {
}
setProperty("songLabel_1", "text", ChosenTrack);
}
});
How would I structure it so that when the Track chosen pulls up its corresponding artist and displays it on a different label?
I'm using Code.org to program this.
I have created a table in HTML with information in it by doing like this:
var tab = document.querySelector("table");
for (var obj of death_row) {
var row = `<tr><td>${obj.first_name}</td>
<td>${obj.last_name}</td>
<td>${obj.age_at_execution}</td>
<td>${obj.weight}</td>
<td>${obj.height}</td></tr>`;
tab.innerHTML += row;
}
I have created two buttons called "metric" and "imperial" and when the user clicks on them, the values in height and weight has to change to metric values (default table is showing imperial values). The code I have written for the metric button looks as so:
//Changes the height and weight values to metric values when clicking on "metric"-button.
document.getElementById("metric").onclick = function() {
var tab = document.querySelector("table");
for (var obj of death_row) {
var row = `<tr><td>${obj.first_name}</td>
<td>${obj.last_name}</td>
<td>${obj.age_at_execution}</td>
<td>${((obj.weight)/2.2046).toFixed(1)}</td>
<td>${(((Number(obj.height[0])*12*2.54) + (Number(obj.height[3])*2.54))/100).toFixed(2)}</td></tr>`;
tab.innerHTML += row;
}
};
//Changes the values back to imperial values when user clicks on the 'imperial' button
document.getElementById("imperial").onclick = function() {
var tab = document.querySelector("table");
for (var obj of death_row) {
var row = `<tr><td>${obj.first_name}</td>
<td>${obj.last_name}</td>
<td>${obj.age_at_execution}</td>
<td>${obj.weight}</td>
<td>${obj.height}</td></tr>`;
tab.innerHTML += row;
}
};
The code when clicking the imperial-button is the same as the first piece of code I posted above as the default values is imperial. The problem is that they wont work together. They work individually if I out-comment the others and I can't really seem to be able to identify the problem, so I was hoping one of you would be able to :) Also, when I Add these adjustments to the obj.height:
${(((Number(obj.height[0])*12*2.54) + (Number(obj.height[3])*2.54))/100).toFixed(2)}
I seem to lose a lot of data in the table, which I find very weird as I lose no data by adding the "/2.2046).toFixed(1)" adjustment to the weight object.. Maybe some of you have better luck at seeing through my mistakes:)
Thank you very much:)
The codepen helped immensely! I mentioned looking at the console output at one point. That's critically important because it's telling you what went wrong, so make sure you know how to see it. In codepen its at the bottom left as well, and there's a red exclamation mark in the JS showing that an error is present. When I hit the Metric button I see:
TypeError: obj.height is null
That's because some of your data has null for width or height instead of the value you're expecting, so it "crashes" and just stops at whatever row caused the problem. That's why some rows disappeared.
Two fixes I see:
Fix your data so that the values don't have null in them
Make the code more robust so it doesn't crash on invalid data (this is always preferable for any program).
For the second option, you can fix the code like this:
function MetricValues() {
var tab = document.querySelector("table");
tab.innerHTML = "";
for (var obj of death_row) {
var height = obj.height || "0' 0\"";
var row = `<tr><td>${obj.first_name}</td>
<td>${obj.last_name}</td>
<td>${obj.age_at_execution}</td>
<td>${((obj.weight)/2.2046).toFixed(1)}</td>
<td>${(((Number(height[0])*12*2.54) + (Number(height[3])*2.54))/100).toFixed(2)}</td></tr>`;
tab.innerHTML += row;
}
};
Using a temporary variable var height = obj.height || "0' 0\""; which defaults to 0' 0" fixes the crash.
BTW you definitely should read up on functions.
I currently have a jQuery Datatable, which upon a row being clicked on, the data from that row is outputted to textboxes and select boxes. I'm trying to make it so whatever is entered into the textboxes, will be saved/entered into the selected row upon pressing the saverow button.
Here's my JSFiddle: JSFiddle
Javascript:
var table = $('#example').DataTable();
(function () {
var table = document.querySelector('#example');
var name = document.querySelector('#nameinput');
var format = document.querySelector('#formatinput');
var address = document.querySelector('#addressinput');
var report = document.querySelector('#reportinput');
var alarm = document.querySelector('#alarminput');
table.addEventListener('click', onTableClick);
function onTableClick (e) {
var tr = e.target.parentElement;
var data = [];
for (var td of tr.children) {
data.push(td.innerHTML);
}
name.value = data[0];
address.value = data[1];
format.value = data[2];
report.value = data[3];
alarm.value = data[4];
console.log(alarm.value);
}
$("#saverow").click(function() {
var table1 = $('#data-table').DataTable();
var data = [];
data[0] = name.value;
data[4] = alarm.value;
console.log(name.value);
console.log(alarm.value);
table1.draw(true);
});
})();`
With the saverow code, I thought by trying to make the columns equal to the value of the textbox, then redrawing the table would work. The console does have the correct output when you type something new into the textbox then pressing Save. I just cant figure out how to put that back into the selected row.
I'm not wanting to do the inline editing if possible. Trying to keep it in this format.
I don't know if this counts as an answer, but you're not actually doing anything with that data variable in the save row click. You take the datatable, do nothing to change it, and then redraw it. So it's not surprising nothing is happening.
See this change to your fiddle to get the rows adding:
https://jsfiddle.net/o92g9goL/14/
Primarily, you need to set the table and datatable into different arrays. Also do it inside the main function. Also you need to actually add this code:
datatable.row.add(data).draw(false);
As for the editing, you'll need to make sure that you don't just prepopulate it, but make an actual reference to that row, otherwise how will it know to update it?
I've been trying to find a good match to my question, but nothing really concrete. I'm still learning and don't know exactly what I'm missing.
So my code can be found here: Fiddle
This is a simplified version of what I'm working with. In the final version, I will upload a csv file to the html table you see there (id="dvCSV"). Upon uploading, the table will look like it is shown (with added dropdowns and a column of checkboxes). The checkboxes come "pre-chcecked" when I generate them but what I want is the user to be able to turn "off" the rows that I do not want to calculate on.
I'll run you through the process:
This function reads the columns that the user designates. I don't know which column they will upload the data into.
function CheckLocations() {
//Checks the uploaded data for the locations of the Lat/Lon Data based on user dropdowns
colLocs[0] = ($('#Value_0 :selected').text());
colLocs[1] = ($('#Value_1 :selected').text());
colLocs[2] = ($('#Value_2 :selected').text());
colLocs[3] = ($('#Value_3 :selected').text());
LatColumn = colLocs.indexOf("Lat");
LongColumn = colLocs.indexOf("Long");
}
function AllTheSame(array) { //if they do not designate the checkboxes, I prompt them to
var first = array[0];
return array.every(function (element) {
return element === first;
});
}
This function takes all of the data in the designated columns and places them into an array for calculation.
function data2Array() {
//gets the lat and long data from the assigned columns and transfers them to an array for calculation
$("#dvCSV tr td:nth-child(" + (LatColumn + 1) + ")").each(function () {
var tdNode = $("<td/>");
tdNode.html(this.innerHTML);
LatData.push(tdNode.text());
});
LatData.splice(0, 2);
LatData.unshift(1, 1);
$("#dvCSV tr td:nth-child(" + (LongColumn + 1) + ")").each(function () {
var tdNode = $("<td/>");
tdNode.html(this.innerHTML);
LongData.push(tdNode.text());
});
LongData.splice(0, 2); //these two lines remove the first two items then replace them with 0
LongData.unshift(1, 1);
}
The first of these functions removes the checkbox column after calculations are done then new calculated columns are appended at the end. The second one was my attempt to read the checkboxes into an array. Ideally I'd want an array of values true or false, then do the calculations and return the calculated values back to the dvCSV table. For the td's where no calculation was performed, the cell would be empty.
function removeChecks() {
$("#dvCSV th:last-child, #dvCSV td:last-child").remove();
}
function makeCheckArray() {
var searchIDs = $("#dvCSV tbody td:last() input:checkbox:checked").map(function () {
return $(this).val();
}).get();
alert(searchIDs);
}
Hopefully I made the problem clear. Any help would be appreciated.
Pass a class when your table is generated into the tr element. Then create an on change method for your checkboxes. Read more here: http://api.jquery.com/on/
Also if you cannot get the inserted rows id's from your table then start a counter outside of your js like this
counter = 0;
Then inside of your loop add counter++
SO..
<tr class="row-1">
<td>
</td>
</tr>
Then add this snippet outside all of your other JS
$( "tr" ).on( "change", function() {
//do something
$(this+'.row-'+(counter)).hide();
});
This should get you headed in the right direction.
I have a table that is built dynamically from a user specified query to a database and I want to give the user the option to edit the data from the generated HTML table. When the user double clicks on the row containing the data they want to edit, I have a new row appear underneath it with textboxes for them to submit new values. Right now, when the user clicks double clicks two rows, both rows of textboxes remain in the table and I want to delete the first row before the second shows up. My question is, what is a good was to find table rows containing textboxes so that I can perhaps use JavaScript's deleteRow() function?
I'm generating rows like so:
function editRow(row) {
var table = document.getElementById("data");
var newRow = table.insertRow(row.rowIndex + 1);
var cell;
for (var i = 0; i < row.childNodes.length; i++) {
cell = newRow.insertCell(i);
textBox = document.createElement("input");
textBox.type = "text";
textBox.placeholder = row.childNodes[i].innerHTML;
textBox.style.textAlign = "center";
textBox.style.width = "90%";
cell.appendChild(textBox);
}
}
and the only way I can I can think of doing it is something like (pseudo code):
for all table rows
if row.childNodes.innerHTML contains 'input'
deleteRow(index)
Thanks for the help
You could use jQuery. Assuming row is a DOM element, this should work:
var textBoxes = $("input:text", row);
i guess the easiest option would be to add the created rows to an array. This way you simply have to delete the rows inside the array and not iterate through the whole table.
I ended up doing the following:
function editRow(row) {
var table = document.getElementById("data");
clearExistingTextBoxes(table);
...
}
function clearExistingTextBoxes(table) {
var tBoxRow = table.getElementsByTagName("input");
if (tBoxRow.length > 0) {
tBoxRow = tBoxRow[0].parentNode.parentNode;
table.deleteRow(tBoxRow.rowIndex);
}
}
Assuming I'm only going to be clearing one row at a time.