Select and change input value in table using data-attribute and JavaScript - javascript

I have a table with input fields, and I would like to fill this fields with some data, that users can change if they like.
//Server side processing gives me an array like:
var data = [];
data.push({"calcname" : "calc1", "value" : 5});
data.push({"calcname" : "calc2", "value" : 10});
//The data array may not have data for all the rows, and the order of items may not be the same.
//For each data item, I select the appropriate row:
for (var i = 0; i < data.length; i++) {
var myRow = $('[data-calcname="' + data.calcname + '"]')[0];
//And now, try to select the input in each row, but I can't get it to work..:
//var myInput = myRow.find("input:text")
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr data-calcname="calc1">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
<tr data-calcname="calc2">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
</table>
However, I have trouble selecting the various input fields, in order to fill them out, as shown in the snippet.
I guess there is an easy jQuery syntax to do this, but despite my best efforts, I have not been able to find it.
How can I achieve this?

You can, in a cleaner way, iterate over the data array with Array.prototype.forEach() and execute a provided function once for each array el element.
The rest is jQuery.
Code:
//Server side processing gives me an array like:
var data = [];
data.push({"calcname" : "calc1", "value" : 5});
data.push({"calcname" : "calc2", "value" : 10});
data.forEach(function(el) {
$('tr[data-calcname="' + el.calcname + '"]').find('input:text').val(el.value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr data-calcname="calc1">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
<tr data-calcname="calc2">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
</table>

//Server side processing gives me an array like:
var data = [];
data.push({"calcname" : "calc1", "value" : 5});
data.push({"calcname" : "calc2", "value" : 10});
//The data array may not have data for all the rows, and the order of items may not be the same.
//For each data item, I select the appropriate row:
for (var i = 0; i < data.length; i++) {
var myRow = $('[data-calcname="' + data[i].calcname + '"]').find("input").val(data[i].value);
//And now, try to select the input in each row, but I can't get it to work..:
//var myInput = myRow.find("input:text")
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr data-calcname="calc1">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
<tr data-calcname="calc2">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
</table>
Use attribute selector to select the td. By combining with data[i].calcname to get the desired, with .find() to get the input.
Set the value using .val()

You need to write you selector of the tr like this var myRow = $('tr[data-calcname="' + data[i].calcname + '"]')
In your case data[i] would be: data[0] = ({"calcname" : "calc1", "value" : 5}) data[1] = ({"calcname" : "calc2", "value" : 10})
//Server side processing gives me an array like:
var data = [];
data.push({"calcname" : "calc1", "value" : 5});
data.push({"calcname" : "calc2", "value" : 10});
//The data array may not have data for all the rows, and the order of items may not be the same.
//For each data item, I select the appropriate row:
for (var i = 0; i < data.length; i++) {
var myRow = $('tr[data-calcname="' + data[i].calcname + '"]');
var myInput = myRow.find("input:text").val(data[i].value);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr data-calcname="calc1">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
<tr data-calcname="calc2">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
</table>

As data is an array i.e. data[i], use index to access the elements, also there is no need use [0] which returns the reference to DOM element.
var data = [];
data.push({"calcname" : "calc1", "value" : 5});
data.push({"calcname" : "calc2", "value" : 10});
for (var i = 0; i < data.length; i++) {
var myRow = $('[data-calcname="' + data[i].calcname + '"]');
var myInput = myRow.find("input:text");
myInput.val(data[i].value)
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr data-calcname="calc1">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
<tr data-calcname="calc2">
<td>
SomeName
</td>
<td>
SomeDescription
</td>
<td>
<input type="text">
</td>
</tr>
</table>

You set up a for loop correctly but now you need to use your index i to access the desired element in your array data: data[i].calcname
You don't need to get the row but you need to get the input inside that row: $('[data-calcname="' + data[i].calcname + '"] td input')
You change a textfield's title by setting its value property: myInput.value = "new value"
//Server side processing gives me an array like:
var data = [];
data.push({"calcname" : "calc1", "value" : 5});
data.push({"calcname" : "calc2", "value" : 10});
//The data array may not have data for all the rows, and the order of items may not be the same.
//For each data item, I select the appropriate row:
for (var i = 0; i < data.length; i++) {
var myInput = $('[data-calcname="' + data[i].calcname + '"] td input')[0];
myInput.value = data[i].value
}
The for of loop
If you don't understand step 1. Maybe it is simpler to use the for of loop:
for (let element of data) {
var myInput = $('[data-calcname="' + element.calcname + '"] td input')[0];
myInput.value = element.value
}

Related

Get the all the text (single and multi-line) between HTML table tags <table><tbody><th><tr><td> and generate json

I have the below HTML Table and I want to get the data between the tags which are sometimes single line and sometimes multi-line.
<table>
<tbody>
<tr>
<th>Role</th>
<th>Device Name</th>
<th>IP Address </th>
<th>MAC Address </th>
<th>Registered </th>
<th>Subscribers </th>
<th>Events </th>
</tr>
<tr>
<td>
CM
</td>
<td>
-
</td>
<td>192.168.7.110 </td>
<td>506182488323 </td>
<td>XYZ
</td>
<td> Shkdsd30ec1
</td>
<td>Events
</td>
</tr>
</tbody>
</table>
I want to generate the JSON with this table like the below code using javascript
{
"Role" : "CM",
"Device Name" : "-",
"IP Address" : "192.168.7.110",
"MAC Address" : "506182488323",
"Registered" : "XYZ",
"Subscribers" : "Shkdsd30ec1",
"Events" : "Events"
}
If there are more tags with the key should get incremented like Role->Role1->Role2 and so on.
Assuming that you have this table alone in your HTML body...
let t = document.getElementsByTagName("table");
let trs = t[0].getElementsByTagName("tr");
let oKeys = [], oVals = [];
let ths = trs[0].getElementsByTagName("th");
let tds = trs[1].getElementsByTagName("td");
ths = Array.from(ths);
tds = Array.from(tds);
ths.map( item => {
oKeys.push(item.innerText);
return ;
});
tds.map( item => {
oVals.push(item.innerText);
return ;
});
console.log("O keys ", oKeys);
console.log("oVals ", oVals);
let newObj = {};
oKeys.map( (key, i) => {
let val = oVals[i];
Object.assign(newObj, {[key] : val })
});
console.log(newObj);
<table id="myTable">
<tbody>
<tr>
<th>Role</th>
<th>Device Name</th>
<th>IP Address </th>
<th>MAC Address </th>
<th>Registered </th>
<th>Subscribers </th>
<th>Events </th>
</tr>
<tr>
<td>
CM
</td>
<td>
-
</td>
<td>192.168.7.110 </td>
<td>506182488323 </td>
<td>XYZ
</td>
<td> Shkdsd30ec1
</td>
<td>Events
</td>
</tr>
</tbody>
</table>
newObj holds your desired data. You can add more to the above logic..
Using jQuery for dom selection, this JS code should work
var myRows = [];
var headersText = [];
var $headers = $("th");
// Loop through grabbing everything
var $rows = $("tbody tr").each(function(index) {
$cells = $(this).find("td");
myRows[index] = {};
$cells.each(function(cellIndex) {
// Set the header text
if(headersText[cellIndex] === undefined) {
headersText[cellIndex] = $($headers[cellIndex]).text();
}
// Update the row object with the header/cell combo
myRows[index][headersText[cellIndex]] = $(this).text();
});
});
// Let's put this in the object like you want and convert to JSON (Note: jQuery will also do this for you on the Ajax request)
var myObj = {
"myrows": myRows
};
console.log(myRows);
this code snippet was collected from this thread

Delete an item in array which is stored in localStorage

Im display some data into table and for each row there is Delete button, when button clicked it should Delete item in array which is stored in localStorage by passing id and than Assign it back to LocalStorage.
HTML:
<table>
<tbody id="ResultProduct">
<tr class="RMAJS">
<td><input type="text" id="item1" name="itemName" value="Computer" /></td>
<td><a data-localstorage-id='ae90ac1a-64c4-49a7-b588-ae6b69a37d47' class="deletebtn">Delete</a></td>
</tr>
<tr class="RMAJS">
<td><input type="text" id="item2" name="itemName" value="Mobile" /></td>
<td><a data-localstorage-id='6b1ccc7e-322c-4f5f-81f9-b1fd68c0eb8b' class="deletebtn">Delete</a></td>
</tr>
</tbody>
</table>
LocalStorage :
["ae90ac1a-64c4-49a7-b588-ae6b69a37d47","6b1ccc7e-322c-4f5f-81f9-b1fd68c0eb8b"]
0: "ae90ac1a-64c4-49a7-b588-ae6b69a37d47"
1: "6b1ccc7e-322c-4f5f-81f9-b1fd68c0eb8b"
JavaScript :
$('#ResultProduct').on('click', '.deletebtn', function (e) {
var targetElement = $(e.target);
var getID = $(targetElement).attr("data-localstorage-id");
var getLocalStorage = JSON.parse(localStorage.getItem("users"));
for (var i = 0; i < getLocalStorage.length; i++) {
var Val = getLocalStorage[i]
//Here is my problem for example i want to delete this item
//"6b1ccc7e-322c-4f5f-81f9-b1fd68c0eb8b" from array
//How can i do that ??
localStorage.setItem('users', JSON.stringify(??)); //Assign it back to LocalStorage.
}
$(targetElement).closest("tr.RMAJS").remove();
})
$('#ResultProduct').on('click', '.deletebtn', function (e) {
var targetElement = $(e.target);
var getID = $(targetElement).attr("data-localstorage-id");
var getLocalStorage = JSON.parse(localStorage.getItem('users'));
getLocalStorage = getLocalStorage.filter(e => e !== getID);
localStorage.setItem('users', JSON.stringify(getLocalStorage));
$(targetElement).closest("tr.RMAJS").remove();
});

Get number from every input in table

I have a table, which has an input at the end of each line.
Here is the input:
<td><input data-price='<?= floatval($row['Prix']); ?>' ?>' type="number" name="quantity" id="quantity"></td>
I have a script that takes the price of the data-price in the input and multiplies
it with the number in the input. Right now my script starts off by adding all of the prices, but then it multiplies the total by only the first input in my table.
How can I change my code so that it multiplies each price by the quantity in the input?
Here is the script:
document.getElementById("submit").onclick = function giveTotal() {
var total = 0;
var grandTotal = document.getElementById('grandTotal');
var quantity = document.getElementById('quantity');
var nodes = document.getElementsByName('quantity');
[].forEach.call(nodes, function(node) {
console.log(quantity.value);
console.log(node.dataset.price);
total += (parseFloat(node.dataset.price) * quantity.value)
})
grandTotal.innerHTML = total;
console.log('Total: ' + total);
};
IDs are unique -- no two elements can have the same ID. When you use document.getElementById(), it will return only the first element that matches that ID and no other.
You already have access to each input from your nodes variable, and you're already iterating over them in your forEach loop. So instead of multiplying by quantity.value, you should just be multiplying by node.value so that you're using the value of each specific input.
You need to select each table row by itself like this:
(In this example I assume your table has the id orders)
document.getElementById("submit").onclick = function giveTotal() {
// Get the table element (id="orders")
const $table = document.getElementById('orders');
// Get the grand total element
const $grandTotal = document.getElementById('grandTotal');
// Temporary variable
let total = 0;
// For each input element in the table add the price*value to total
table.querySelectorAll('input').forEach($input => {
total += (parseFloat($input.dataset.price) * $input.value)
});
// Write total to $grandTotal element
$grandTotal.innerText = total;
// Debug output
console.log('Total: ' + total);
};
You can get table rows and process them. Something like this.
document.getElementById('submit').onclick = function() {
var total = Array.from(document.querySelector('#cart tbody')
.querySelectorAll('tr')) //get array
.reduce((acc, cur) => acc + cur.querySelector('td:first-child').innerText * cur.querySelector('input').value, 0);
console.log(total);
};
<table id="cart">
<thead>
<tr>
<th>Price</th>
<th>Qty</th>
</tr>
</thead>
<tbody>
<tr>
<td>5.45</td>
<td><input name="qty" type="text" value="0" />
<!--number is ok too -->
</td>
</tr>
<tr>
<td>7.80</td>
<td><input name="qty" type="text" value="0" />
<!--number is ok too -->
</td>
</tr>
<tr>
<td>0.95</td>
<td><input name="qty" type="text" value="0" />
<!--number is ok too -->
</td>
</tr>
</tbody>
</table>
<button type="button" id="submit">Submit</button>

jquery efficient way to select tablerow data

I have a table with multiple rows of the same pattern:
<tr role="row" class="even">
<td><input type="checkbox" id="valj4"></td>
<td>Generell grupp</td>
<td>IKT Ipad11- Mirko</td>
<td>Grundinställningar</td>
</tr>
Each row has a checkbox with unique ID, what would be the most efficient way to get a list of UUIDs for the rows with a checked checkbox. I would like to use jQuery.
$(function() {
var texts = [];
$('tr td:has(input:checkbox:checked) ~ td > a').each(function(i, e) {
texts.push($(e).attr('href'));
});
$('#result').html(texts.join('<br/>'));
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr role="row" class="even">
<td>
<input type="checkbox" id="valj4" checked>
</td>
<td>Generell grupp</td>
<td>IKT Ipad11- Mirko (...5)
</td>
<td>Grundinställningar</td>
</tr>
<tr role="row" class="even">
<td>
<input type="checkbox" id="valj4">
</td>
<td>Generell grupp</td>
<td>IKT Ipad11- Mirko (...6)
</td>
<td>Grundinställningar</td>
</tr>
<tr role="row" class="even">
<td>
<input type="checkbox" id="valj4" checked>
</td>
<td>Generell grupp</td>
<td>IKT Ipad11- Mirko (...7)
</td>
<td>Grundinställningar</td>
</tr>
</table>
<div id="result"/>
Getting the UUID is then an easy exercise in string chopping.
I assume your table has an id and it's "#table-id":
$("#table-id").find(":checked")
would get you all the checked checkboxes and radio boxes.
$("#table-id").find("input[type='checkbox']:checked")
would get you all the checked checkboxes.
var ids = "";
$("#table-id").find("input[type='checkbox']:checked").each(function(){
ids += $(this).attr("id") + ",";
});
would give you a comma seperated list containing the ids of checked checkboxes in the table.
and the UUIDS list:
var UUIDs = "";
$("#table-id").find("input[type='checkbox']:checked").each(function(){
var href = $(this).closest("tr").find("td > a").first().attr("href");
var UUID = href.split('?')[1];
UUIDS += UUID + ",";
});
I would try the following
var ids = [];
$("#table input:checkbox:checked").each(function () {
var uuid = getParameter($(this).closest('tr').find('a').eq(0).attr('href'))
ids.push(uuid);
});
function getParameter(url) {
var regex = new RegExp("[\\?&]uuid=([^&#]*)"),
results = regex.exec(url);
return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}
where #table is the id of your table
Example
jQuery('#formId').find('tr[class=even]').each(function () {
var rowId = "";
this.find('input[type=checkbox]').each(function() {
if(this.checked) {
rowId = "row" + $(this).val();
}
});
$(this).attr('id', rowId);
});
Create a new list of UUIDs.
var listOfUUIDs = [];
Get the checked input, go up to grandparent (the tr), then find the a inside it.
Go through the list of a's, adding UUIDs to the list.
$("tr input[checked=checked]").parent().parent().find("td a").each(function(){
listOfUUIDs.push(
$(this).prop('href').substr(indexOf("uuid=") + 5)
)
});
This should give you what you need.
$('tr').each(function(index) {
var $this = $(this),
input = $this.find('input'),
result = '';
if ( input.is(':checked') ) {
var uuid = $this.find('a').attr('href').replace(/^\/Home\/DeviceDetails\?uuid=/g, ""),
result = result + index + '. ' + input.attr('id') + ' has the uuid: ' + uuid + '<br />';
}
$('#result').html(result);
});
try this
$( "input[type=checkbox]" ).change(function() {
if($(this).is(":checked")) {
alert($(this).attr("id"));
}
});

Getting Value from html form with the same name attribute under Loop

I have a form which displays multiple rows from database with 4 columns. From these record I need to write a new value in 4th column and update database record. But whenever I try, only First Row value can be updated/read. But not the other rows!! This can be due to the same "name=redirection" as it is given to each from "for loop". So, how can I get the values from other rows too??
for (int i=0; i<domains.size(); i++) {
domainprops = (String[]) domains.get(i);
%>
<table cellspacing="0" cellpadding="10" border="0" class="tableview" width="100%">
<td width="150"><input type="text" id="domains" name="domains" value="<%=domainprops[0]%>"></td>
<td width="160"><input type="text" name="defaulturl" value="<%=domainprops[1]%>" size="30"></td>
<td width="160"><input type="text" name="redirecturl" value="<%=domainprops[2]%>" size="30"></td>
<td width="160"> <input type="text" id="redirection" name="redirection"></td>
<td align="right"><a href="javascript:win2('recordUpdate.jsp?domains=<%=domainprops[0]%>
')">[Update]</a></td>
</tr>
</table>
<% } %>
Javascript Code :
function win2(urlPath) {
var winl = (screen.width-200)/2;
var wint = (screen.height-100)/2;
var settings = 'height=100,width=200,directories=no,resizable=no,status=no,scrollbars=no,menubar=no,location=no,top=' + wint + ',left=' + winl;
var changeurls=document.getElementById("redirection").value;
urlPath+='&rdirect='+changeurls
editWin.focus();
}
An ID in the DOM is supposed to be unique. If any element in the DOM has an ID, it should not be shared by any other element.
What I would suggest doing is appending your loop counter on to the end of the ID. This will ensure that every element you create in the DOM has its own unique ID.
for (int i=0; i<domains.size(); i++) {
domainprops = (String[]) domains.get(i);
...
<input type="text" id="domains_<%= i %>" name="domains" value="<%=domainprops[0]%>">
...
<input type="text" id="redirection_<%= i %>" name="redirection"></td>
</tr>
</table>
}
Next, pass the loop counter to the win2 function call:
<td align="right"><a href="javascript:win2('recordUpdate.jsp?domains=<%=domainprops[0]%>
', <%= i %>)">[Update]</a></td>
Finally, adjust the function itself...
function win2(urlPath, loopID) {
...
var changeurls=document.getElementById("redirection_" + loopID).value;
urlPath+='&rdirect='+changeurls
...
}
EDIT: Please read the answer referring to having multiple elements with the same ID. You should not be using multiple of the same ID.
You could use Javascript to iterate over redirection form elements.
function loopThroughRedirection(form) {
var result = "";
for (var i = 0; i < form.elements.length; i++) {
if (form.elements[i].name == 'redirection') {
// Do something to retrieve the value of redirection
result += form.elements[i].value
}
}
return result;
}

Categories