Convert table with select fields to js array - javascript

function extractTable() {
var csvTable = document.querySelector("#csv_table");
var newTableObj = [];
var tableRows = [].reduce.call(csvTable.rows, function(res, row) {
res[row.cells[0].textContent] = row.cells[1].textContent;
return res
}, {});
delete tableRows['Column value']; // Removes the header row
// Create an object
newTableObj.push(tableRows);
console.log(newTableObj);
// Create a JSON
let jsonTable = JSON.stringify(tableRows, null, 2);
console.log(jsonTable);
};
<table id="csv_table" class="sms_table">
<thead>
<tr>
<th>Column value</th>
<th>Field</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name</td>
<td>
<select id="select_path" class="field_select">
<option selected="selected" value="">Please assign a Field</option>
<option value="a">A</option>
<option value="b">B</option>
</select>
</td>
</tr>
<tr>
<td>Prefix</td>
<td>
<select id="select_path" class="field_select">
<option selected="selected" value="">Please assign a Field</option>
<option value="a">A</option>
<option value="b">B</option>
</select>
</td>
</tr>
<tr>
<td>First</td>
<td>
<select id="select_path" class="field_select">
<option selected="selected" value="">Please assign a Field</option>
<option value="a">A</option>
<option value="b">B</option>
</select>
</td>
</tr>
<tr>
<td>Last</td>
<td>
<select id="select_path" class="field_select">
<option selected="selected" value="">Please assign a Field</option>
<option value="a">A</option>
<option value="b">B</option>
</select>
</td>
</tr>
</tbody>
</table>
<button id="extractTable" onclick="extractTable()">Extract table</button>
I have a simple two column table which is generated based upon the results of a parsed CSV file. The left column contains all of the values extracted, and the right column are a series of dropdowns which people can select a value.
I have some code which runs through the rows and extracts the values, which then I can drop into a multidimensional array or JSON.
I would like to be able to store these for use elsewhere but seem completely unable to extract the values of the dropdown field. Can anyone please help me?
My HTML table is something like this:
<table id="csv_table" class="sms_table">
<thead>
<tr>
<th>Column value</th>
<th>Field</th>
</tr>
</thead>
<tbody>
<tr>
<td>Name</td>
<td>
<select id="select_path" class="field_select">
<option selected="selected" value="">Please assign a Field</option>
<option value="a">A</option>
<option value="b">B</option>
</select>
</td>
</tr>
<tr>
<td>Prefix</td>
<td>
<select id="select_path" class="field_select">
<option selected="selected" value="">Please assign a Field</option>
<option value="a">A</option>
<option value="b">B</option>
</select>
</td>
</tr>
</tbody>
</table>
<button id="extractTable" onclick="extractTable()">Extract table</button>
My Js is:
function extractTable() {
var csvTable = document.querySelector("#csv_table");
var newTableObj = [];
var tableRows = [].reduce.call(csvTable.rows, function(res, row) {
res[row.cells[0].textContent] = row.cells[1].textContent;
return res
}, {});
delete tableRows['Column value']; // Removes the header row
// Create an object
newTableObj.push(tableRows);
console.log(newTableObj);
// Create a JSON
let jsonTable = JSON.stringify(tableRows, null, 2);
console.log(jsonTable);
};
My example codepen is here: https://codepen.io/AllenT871/pen/XoazJz?editors=1011#
I appreciate any help you can provide.

Instead of getting all the table you could get only the selectors using document.getElementsByClassName o document.getElementsByTagName
Then you can iterate (but its NOT an iterable you cannot use map or reduce) and get the selected value of every select.
I hope it helps
All code:
function extractTable() {
var tableItems = document.getElementsByClassName("field_select");
var tableRows = [];
for(var i = 0; i<tableItems.length; i++){
var e = tableItems[i]
var option = e.options[e.selectedIndex].value;
console.log(option)
tableRows.push(option);
}
// Create a JSON
let jsonTable = JSON.stringify(tableRows, null, 2);
console.log(jsonTable);
};

Related

display an alert message if an option is selected while selecting other option

displaying an alert message when selecting an option jQuery
if any of the ports has selected(rate == "MAC"), an alert message should be displayed when selecting MAX in other ports
if any of the ports has selected(rate == "MAX") an alert message should be displayed when selecting MAC in other ports
If MAC is selected then you cannot select MAX in any of the other select boxes and vice versa. An alert message should be displayed
<table>
<thead>
<tr>
<th>Port</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
<tr>
<td class="port">1</td>
<td>
<select class= rate>
<option value=""></option>
<option value="1">MAC</option>
<option value="2">MAX</option>
<option value="3">MIN</option>
</select>
</td>
</tr>
<tr>
<td class="port">2</td>
<td>
<select class= rate>
<option value=""></option>
<option value="1">MAC</option>
<option value="2">MAX</option>
<option value="3">MIN</option>
</select>
</td>
</tr>
<tr>
<td class="port">3</td>
<td>
<select class= rate>
<option value=""></option>
<option value="1">MAC</option>
<option value="2">MAX</option>
<option value="3">MIN</option>
</select>
</td>
</tr>
</tbody>
</table>
$(document).ready(function() {
$("select.rate").change(function() {
var rate = $(this).find("option:selected").text();
var this_ = $(this)
$("select.rate").not(this).each(function() {
var values = $(this).find("option:selected").text();
if (rate == 'MAC' && values == 'MAX') {
alert("Since you have selected MAC, you can't select MAX");
this_.val("")
return false;
}
})
});
});
You can .each loop to iterate through all select-boxes and check if the text of option is same or not depending on this show your message and reset that select-box.
Demo Code :
$(document).ready(function() {
$("select.rate").change(function() {
var rate = $(this).find("option:selected").text(); //get option text
var this_ = $(this)
//loop through other slects but not the one where change has occur
$("select.rate").not(this).each(function() {
var values = $(this).find("option:selected").text();
//compare...
if (rate == 'MAC' && values == 'MAX') {
alert("Since you have selected MAX, you can't select MAC");
this_.val("") //reset
return false; //break through loop
}
if (rate == 'MAX' && values == 'MAC') {
alert("Since you have selected MAC, you can't select MAX")
this_.val("")
return false;
}
})
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Port</th>
<th>Rate</th>
</tr>
</thead>
<tbody>
<tr>
<td class="port">1</td>
<td>
<select class="rate">
<option value=""></option>
<option value="1">MAC</option>
<option value="2">MAX</option>
<option value="3">MIN</option>
</select>
</td>
</tr>
<tr>
<td class="port">2</td>
<td>
<select class="rate">
<option value=""></option>
<option value="1">MAC</option>
<option value="2">MAX</option>
<option value="3">MIN</option>
</select>
</td>
</tr>
<tr>
<td class="port">3</td>
<td>
<select class="rate">
<option value=""></option>
<option value="1">MAC</option>
<option value="2">MAX</option>
<option value="3">MIN</option>
</select>
</td>
</tr>
</tbody>
</table>

Get all select in table and replace them with their option

Say I've got a table and I would like to change every select with it's options.
So for example if the table has this :
<td>
<select>
<option>first option</option>
<option selected>second option</option>
<option>third option</option>
</select>
</td>
It should become this :
<td>
second option
</td>
Here's what I've tried :
$('#table select').find(":selected").each(function() {
this.replaceWith(this.text());
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
<html>
<body>
<table id="table">
<thead>
<th>test</th>
</thead>
<tbody>
<tr>
<td>
<select>
<option>first option</option>
<option selected>second option</option>
<option>third option</option>
</select>
</td>
</tr>
<tr>
<td>
<select>
<option>first option</option>
<option>second option</option>
<option selected>third option</option>
</select>
</td>
</tr>
</tbody>
</table>
</body>
</html>
But I get a this.text is not a function, how can I point out to the text of the select items? I'm lost.
You figured out that the this keyword refers to the element selected. But text is a jQuery function and not present as a method on this.
To be able to use this and jQuery you need to wrap it into $(this)
. Use parents to select the TD and then change with text.
This should get the desired result as provided by your example.
$('#table select').find(":selected").each(function() {
$(this).parents("td").text($(this).text());
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<html>
<body>
<table id="table">
<thead>
<th>test</th>
</thead>
<tbody>
<tr>
<td>
<select>
<option>first option</option>
<option selected>second option</option>
<option>third option</option>
</select>
</td>
</tr>
<tr>
<td>
<select>
<option>first option</option>
<option>second option</option>
<option selected>third option</option>
</select>
</td>
</tr>
</tbody>
</table>
</body>
</html>
Vanilla solution (without jQuery)
//Vanilla solution
//Array.from: casts a node list (array like) to actual Array; supported by all major browsers except IE
//querySelector is used to select the elements. Then loop with array's forEach
Array.from(document.querySelectorAll("#table select > option:checked")).forEach(function(element) {
//element refers to the selected element
//go up two elements to the TD and save to parent
var parent = element.parentElement.parentElement;
//use replaceChild and createTextNode
//createTextNode creates a node from the string provided.
var textNode = document.createTextNode(element.textContent);
//replace from the parent
parent.replaceChild(textNode, parent.querySelector("select"));
});
<html>
<body>
<table id="table">
<thead>
<th>test</th>
</thead>
<tbody>
<tr>
<td>
<select>
<option>first option</option>
<option selected>second option</option>
<option>third option</option>
</select>
</td>
</tr>
<tr>
<td>
<select>
<option>first option</option>
<option>second option</option>
<option selected>third option</option>
</select>
</td>
</tr>
</tbody>
</table>
</body>
</html>

How to put data from jquery each into object variable

I have several select tags with different values of name attribute. I must get each of the value and put it into object variable. How to do it?
My code:
var obj = {};
$('.variants tbody tr td.value').children('select').each(function(index, value) {
alert($(this).attr('name'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="variants">
<tbody>
<tr>
<td>1</td>
<td class="value">
<select name="color">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</td>
</tr>
<tr>
<td>2</td>
<td class="value">
<select name="size">
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</td>
</tr>
<tr>
<td>3</td>
<td class="value">
<select name="material">
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
</td>
</tr>
</tbody>
</table>
Here, I must get
{"color":"selected_option_value", "size":"selected_option_value", "material":"selected_option_value"}
You should select all select elements in the table (you don’t need such a complex jQuery query to achieve so), iterate thru the collection; then for each element of the collection get its name (using the attr() function) and selected value (using the val() function) and create a property on the output object (obj) using the name of the select and assign its value to the select value.
// define the container object
var obj = {};
// for each select in the table
$('.variants select').each(function(index, select) {
// set the current item as a jQuery object
var current = $(select);
// sets the object key using the name of the select and the current selected value as the object key value
obj[current.attr('name')] = current.val();
});
// output
console.log(obj);
You could do the same using vanilla JavaScript too as in the other answers examples.
You can loop through the selection inputs with a forEach loop and fill in the obj object:
Select the input boxes and unwrap them in an array:
[...document.querySelectorAll('.value')]
in the loop select the child select element with:
menu.querySelector('select')
then add a new key/value pair in obj:
obj[element.getAttribute('name')] = element.value
↑ ↑
key value
So the full code looks like:
const obj = {}
document.querySelector('.button').addEventListener('click', (e) => {
[...document.querySelectorAll('.value')].forEach(menu => {
const element = menu.querySelector('select');
obj[element.getAttribute('name')] = element.value
})
console.log(obj)
})
I have set an event listener to show it working:
const obj = {}
document.querySelector('.button').addEventListener('click', (e) => {
[...document.querySelectorAll('.value')].forEach(menu => {
const element = menu.querySelector('select');
obj[element.getAttribute('name')] = element.value
})
console.log(obj)
})
<table class="variants">
<tbody>
<tr>
<td>1</td>
<td class="value">
<select name="color">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</td>
</tr>
<tr>
<td>2</td>
<td class="value">
<select name="size">
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</td>
</tr>
<tr>
<td>3</td>
<td class="value">
<select name="material">
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
</td>
</tr>
</tbody>
</table>
<button class="button">Give object</button>
You don't need jQuery to do this you, this will return an object on page load. You will have to wrap this in a function and add an event listener to return an object when the select values have changed or on form submission if thats what you are trying to accomplish
const variantsTable = document.querySelector('.variants')
const variantsSelects = Array.from(variantsTable.querySelectorAll('select'))
const obj = {}
variantsSelects.forEach(item => {
obj[item.name] = item.value
})
console.log(obj)
Output :
{"color":"1","size":"4","material":"7"}
You can try here :
const obj = {};
$('table.variants td.value select').each(function(index) {
obj[$(this).attr("name")] = $(this).val();
});
$("#output").text(JSON.stringify(obj));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="variants">
<tbody>
<tr>
<td>1</td>
<td class="value">
<select name="color">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</td>
</tr>
<tr>
<td>2</td>
<td class="value">
<select name="size">
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</td>
</tr>
<tr>
<td>3</td>
<td class="value">
<select name="material">
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
</select>
</td>
</tr>
</tbody>
</table>
<pre id="output"></pre>

How to change value when select option is change?

Following is my html code which is generated by php while loop :
<select class="menu_extra_item">
<option>--Qnt--</option>
<option>1</option>
<option>2</option>
<option>2</option>
</select>
<select class="menu_extra_item"/>
<option>--Qnt--</option>
<option>1</option>
<option>2</option>
<option>2</option>
</select>
<tr class="menu_extra_item_change">
<td>$32</td>
</tr>
<tr class="menu_extra_item_change">
<td>$10</td>
</tr>
I want to change the value (price like $32) when select option is change.
For e.g.
I select (first select) option `1`then it will be show `$32`
I select (first select) option `2`then it will be show `$62`
I select (second select) option `1`then it will be show `$10`
I select (second select) option `2`then it will be show `$20`
To get this output I am using following jQuery code but it's not working exactly what I want :(
jQuery code :
$(".menu_extra_item").each(function() {
$(this).change(function() {
var menu_extra_item =$(this).val();
var menu_extra_item_change = parseInt($('.menu_extra_item_change').text().replace(/[^0-9.]/g, ""));
alert(menu_extra_item_change);
var total_ex_price = menu_extra_item * menu_extra_item_change;
$(".menu_extra_item_change").each(function() {
$(".menu_extra_item_change").text("$"+total_ex_price);
});
});
});
You can also try this:
var prices = [32,10];
$("body").on("change",".menu_extra_item",function() {
var selInd = $(this).index() - 1;
var newVal = prices[selInd] * $(this).val();
$(".menu_extra_item_change").eq(selInd).text("$" + newVal);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select class="menu_extra_item">
<option>--Qnt--</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<select class="menu_extra_item">
<option>--Qnt--</option>
<option>1</option>
<option>2</option>
<option>3</option>
</select>
<table>
<tr class="menu_extra_item_change">
<td>$32</td>
</tr>
<tr class="menu_extra_item_change">
<td>$10</td>
</tr>
</table>
I corrected the faulty HTML, added data attribute to "link" each select to its corresponding price.
I also added a cell for total price, because each time the selection is made the price is multiplied from the value in the cell: so it continue to increase giving a bad result.
Here is a working solution:
$(document).ready(function(){
$(".menu_extra_item").on("change", function() {
var priceid = $(this).data("priceid");
var qty = parseInt($(this).val());
var price = parseInt($("#" + priceid).text().replace(/[^0-9.]/g, ""));
var total_ex_price = price * qty;
$("#total" + priceid).text("$"+total_ex_price);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="menu_extra_item" data-priceid="price1">
<option>--Qnt--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select class="menu_extra_item" data-priceid="price2">
<option>--Qnt--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<table>
<tr class="menu_extra_item_change">
<td>Unit price</td>
<td id="price1">$32</td>
<td>Total</td>
<td id="totalprice1">$32</td>
</tr>
<tr class="menu_extra_item_change">
<td>Unit price</td>
<td id="price2">$10</td>
<td>Total</td>
<td id="totalprice2">$10</td>
</tr>
</table>
You can do that by using data attributes. Check here
https://jsfiddle.net/v6qmhw77/
<select class="change-me" data-price="32" data-target=".element-1">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select class="change-me" data-price="10" data-target=".element-2">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<div class="element-1"></div>
<div class="element-2"></div>
jQuery(document).ready(function(){
$('.change-me').change(function(){
var target = $(this).data('target');
var price = $(this).data('price');
var cost = parseInt(price) * $(this).val();
$(target).html("$"+cost);
});
});
That's easy.
$(".menu_extra_item").change(function() {
var multiplier = +$(this).val() || 1;
$(".menu_extra_item_change td").text(function() {
var baseValue = +$(this).data("baseValue");
return "$" + (multiplier * baseValue);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class="menu_extra_item">
<option>Qnt</option>
<option value="1">1</option>
<option value="2">2</option>
</select>
<table>
<tr class="menu_extra_item_change">
<td data-base-value="32">$32</td>
</tr>
<tr class="menu_extra_item_change">
<td data-base-value="10">$10</td>
</tr>
</table>
This is not right way but If you want to go what you already have then follow this.
JsFiddle: https://jsfiddle.net/syjuLyh8/1/
<select class="menu_extra_item">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select class="menu_extra_item">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<table>
<tr class="menu_extra_item_change">
<td>$32</td>
</tr>
<tr class="menu_extra_item_change">
<td>$10</td>
</tr>
</table>
JS:
$(".menu_extra_item").each(function(index) {
var menu_extra_item_change = parseInt($('.menu_extra_item_change td').eq(index).text().replace(/[^0-9.]/g,""));
$(this).change(function() {
var menu_extra_item = $(this).val();
var total_ex_price = menu_extra_item * menu_extra_item_change;
$(".menu_extra_item_change").eq(index).text("$" + total_ex_price);
});
});

Set "Select" option for all checked rows in jquery?

Still learning jquery here, so forgive any ignorance.
I have a table that contains a number of rows. Each row has a <select> tag and I want to "toggle" its value when I execute a function. So here's what the table looks like for example:
<table align="center" class="table table-bordered table-hover table-condensed table-responsive">
<thead>
...
</thead>
<tbody>
<tr>
<td class="text-center"><input id="item_ids_" name="item_ids[]" type="checkbox" value="11521"></td>
<td class="text-center">Item value here</td>
<td class="text-center">
<select class="form-control" id="item_11521_color" name="item[11521][color]">
<option selected="selected" value="None">None</option>
<option value="Blue">Blue</option>
<option value="Orange">Orange</option>
<option value="Green">Green</option>
<option value="Yellow">Yellow</option>
<option value="Purple">Purple</option>
</select>
</td>
<td class="text-center">
<select class="form-control" id="item_11521_test" name="item[11521][test]">
<option selected="selected" value="None">None</option>
<option value="First">First</option>
<option value="Second">Second</option>
</select>
</td>
</tr>
</tbody>
</table>
How can I iterate through each row and change the value (and text) <option value="Blue"> to <option value="Orange"> etc each time I run this function?
Is this what you are looking for? (code updated)
$("#change").on("click", function() {
// loop throw all rows
$("table tr").each(function() {
// on a row, find the checkbox and change the values if it's checked
if($(this).find("input[type='checkbox']").prop("checked")) {
$(this).find(".color-select").val("Green");
$(this).find(".position-select").val("First");
}
});
});
Added a button to perform the change:
<button id="change">change all to Green and first</button>
And classes to the selects for simplicity:
<select class="form-control color-select" id="item_11521_color" name="item[11521 [color]">
<select class="form-control position-select" id="item_11521_test" name="item[11521][test]">
EDIT:
Made required changes to the code.
The updated fiddle: http://jsfiddle.net/theagitator/44vqugf0/1/

Categories