Adding custom attribute values of dynamically created dropdowns to another element - javascript

I have a bit of HTML here:
<tr taskId="(#=obj.task.id#)" assigId="(#=obj.assig.id#)" class="assigEditRow" >
<td><select name="resourceId" class="get-resources formElements"></select></td>
<td><span class="resources-units"></span></td>
<td><span class="resources-quantity"></span></td>
<td><input type="text" placeholder="Required Q"></td>
<td align="center"><span class="teamworkIcon delAssig" style="cursor: pointer">d</span></td>
</tr>
And a bit of JS here:
'use strict';
function addResourceFunction(){
let ResourcesJSON = (json) => {
let Resources = json;
console.log(Resources);
let contactsLength = json.length;
let arrayCounter = -1;
let resID;
let resName;
let resUnit;
let resQuantity;
let Option = $('<option />');
let assignedID = $('tr.assigEditRow:last').attr("assigId");
while(arrayCounter <= contactsLength) {
arrayCounter++;
resID = Resources[arrayCounter].ID;
resName = Resources[arrayCounter].name;
resUnit = Resources[arrayCounter].unit;
resQuantity = Resources[arrayCounter].quantity;
$('.assigEditRow').last().find('select').append($('<option>', {
value: resName.toString(),
text: resName.toString(),
resourceID: resID.toString(),
resourceUnit: resUnit.toString(),
resourceQuantity: resQuantity.toString()
}));
}
}
$.getJSON("MY JSON URL IS HERE", function(json) {
ResourcesJSON(json);
});
};
So what's actually going on here: I get my data from the URL (JSON array), trigger the addResourceFunction() on click to create a new table row and to add a new select with options passed from the array. As you see from my HTML markup, the select input is placed in td.get-resources, and all that works good. I get my date set, I populate the select field and all works good. I can add as many rows/select dropdowns as I want.
Also, every option has a few custom attributes (you can see it in my JS code above), and I want to add the values of those attributes to the second and third column of the row (in HTML those are span.resources-units and span.resources-quantity). The thing is, I have no clue how to make it work 1:1, meaning that one select dropdown "alters" only units and quantity of its own row. Below is the code for that:
let idCounter = 1;
$(document).on('change', '.get-resources', function() {
$('.assigEditRow').last().find('.resources-units').attr('id', 'units-' + idCounter);
$('.assigEditRow').last().find('.resources-quantity').attr('id', 'quantity-' + idCounter);
this.resourceUn = $( ".get-resources option:selected" ).attr( "resourceUnit" );
this.resourceQuant = $( ".get-resources option:selected" ).attr( "resourceQuantity" );
$('#units-' + idCounter).append(this.resourceUn);
$('#quantity-' + idCounter).append(this.resourceQuant);
idCounter++;
});
What happens is that if I add one select input, and change options, the thing works. When I add another one and change its options, it gets attributes of the first one. Adding more - same thing. Whatever I change, it takes the attribute value of the first item added.

Try getting the id from the element instead of from the variable, since you always update the element with the id of the counter, instead of the element with the id of the row that was clicked.
Hmm, what does the counter do exactly? The more I look at it, the less I understand. What I do know is that you're not selecting the correct elements by using the idCounter to reference the correct row.
You want to do something like
$(document).on('change', '.get-resources', function() {
//var row = this;
this.find(/* Some path to the second column */).att(/* some att to change */);
this.find(/* Some path to the third column */).att(/* some att to change */);
});
where you always use the row as the root again, instead of finding a certain id, so you only update that row.
Native:
<table>
<tr>
<td>
<select>
<option data-text="resName1" data-resourceID="resID1" data-resourceUnit="resUnit1" data-resourceQuantity="resQuantity1">1</option>
<option data-text="resName2" data-resourceID="resID2" data-resourceUnit="resUnit2" data-resourceQuantity="resQuantity2">2</option>
<option data-text="resName3" data-resourceID="resID3" data-resourceUnit="resUnit3" data-resourceQuantity="resQuantity3">3</option>
</select>
</td>
<td>
<div class="column2"></div>
</td>
<td>
<div class="column3"></div>
</td>
</tr>
</table>
<script>
document.addEventListener('change', function ( event ) {
var select = event.target,
option = select.options[select.selectedIndex],
values = {
'text' : option.getAttribute('data-text'),
'resourceID' : option.getAttribute('data-resourceID'),
'resourceUnit' : option.getAttribute('data-resourceUnit'),
'resourceQuantity' : option.getAttribute('data-resourceQuantity')
},
row = select.parentNode.parentNode,/* depending on how deep the select is nested into the tr element */
column2 = row.querySelector('.column2'),
column3 = row.querySelector('.column3');
column2.textContent = 'some string with the values you want';
column3.textContent = 'some string with the other values you want';
});
</script>
Basically you start with the select that was changed, from there you get the option node that was clicked. Then you get the attributes you need from that option. Then you go up a few nodes to the row parent and find the two columns inside that row. Then you can set the content of these two columns.

Related

clear a hidden input when cloning row

Im using a function to clone html table rows, with input fields, to allow the user multiple inputs.
my html looks like this
<table id="ID_1">
<tr id="tr_id1">
<td><input type="hidden" value="databaseid"/></td>
<td>Inputfield 1</td>
<td>Inputfield 2 </td>
</tr>
</table>
<button onclick="cloneRow('ID_1', 'tr_id1')"></button>
and my javascript
function cloneRow(tablename,rowname) {
var row = document.getElementById(rowname); // find row to copy
var table = document.getElementById(tablename); // find table to append to
var clone = row.cloneNode(true); // copy children too
clone.id = "newID"; // change id or other attributes/contents
table.appendChild(clone); // add new row to end of table
$('.pickDate').each(function() {
$(this).datepicker({ dateFormat: 'dd.mm.yy' });
});
}
For further work on the next page, I need only the first <td><input type="hidden" value="databaseid"/></td> so by copying, it should only copy the hidden input, but without the value in side, value should look like value=""
How can this be solved? (jQuery can be used)
Fiddle http://jsfiddle.net/21sv1bug/
$(row).find('input:hidden').val('')
use above after your function call
You can empty the value of the input in the row with this jQuery code:
$(row).find('input').val('')
try this:
function cloneRow(tablename,rowname) {
var value=$(this).prev('table').find('input:hidden').val(); // store the value in a variable
$(this).prev('table').find('input:hidden').val(''); // empty the input
var row = document.getElementById(rowname); // find row to copy
var table = document.getElementById(tablename); // find table to append to
var clone = row.cloneNode(true); // copy children too
clone.id = "newID"; // change id or other attributes/contents
table.appendChild(clone); // add new row to end of table
$(this).prev('table').find('input:hidden').val(value); // put the value in its place again
$('.pickDate').each(function() {
$(this).datepicker({ dateFormat: 'dd.mm.yy' });
});
}
UPDATE:
A Working DEMO using jQuery:
$('button').click(function(){
var clone=$(this).prev('table').find('tr:first').clone();
clone.attr('id','newID');
clone.find('input:hidden').val('');
$(this).prev('table').append(clone);
});

editing dynamically generated table

I have a dynamically generated tables the foot of the table contain some text fields when click on save i want to add the value of text fields to the body of that table .
here is the table
<table border="1" class="entity_table">
<tfoot>
<tr>
<td>
<div class="pane1"></div>
<div class="pane2">
<input type="text" id="name"><br>
<select id="data">
<option value="1">int</option>
<option value="2">tinyint</option>
</select>
<br><span id="save">save</span>
</div>
</td>
</tr>
</tfoot>
<tbody class="table-body" id='myid'></tbody>
</table>
i did this but this is id specific ..i want to update that specific table on which it is clicked and edited .
var myName = document.getElementById("name");
var data = document.getElementById("data");
var Mtable = document.getElementById("myid");
var rowCount = Mtable.rows.length;
var mrow = Mtable.insertRow(rowCount);
var mcell = mrow.insertCell(0);
mcell.innerHTML = myName.value;
var mcell1 = mrow.insertCell(1);
mcell1.innerHTML = size.value;
i want to update each dynamically generated table with values that is entered in its table's foot section
You can use below jQuery :
$(function(){
$('#save').click(function(){
$(this).closest('table').find('tbody').append('<tr><td>'+$('#name').val()+' and '+$('#data').val()+'</td></tr>');
});
});
Demo
EDIT - to eliminate input and select box id dependency use below code :
$(function(){
$('#save').click(function(){
var name = $(this).closest('tr').find('input[type=text]').val();
var data = $(this).closest('tr').find('select').val();
$(this).closest('table').find('tbody').append('<tr><td>'+name+' and '+data+'</td></tr>');
});
});
Demo
So if I understood this right, you dont want to use element's ID to select it.
You have some else options if you dont want to work with elements IDs:
1) You can add them some data- attribute, for example: data-id. And based on this you select your element like this:
myElement.querySelector("[data-id='X']") where myElement is some parent element of your tables and X is their ID which you generated before (lets say it will start from 0 and will increment with every next table).
2) If possible, work with objects. When you create your tables, you either create them with raw text with defining html elements or you create new elements with calling createElement("table") on document keyword. If second option is your option, you can save this elements to some array (myTables in this case) and then approach this elements in a standard way - lets say:
myTables[0].getElementsByTagName("input")
Hope it helps your issue. Hope I understood issue you were asking about.

Making a pre-populated form a HTML table in jquery

I am trying to create a prepopulated form that pulls values from any selected row in a HTML table . The HTML page is populated by a JSP .
my table looks like this
<table id="data-table" id="test">
<thead>
<tr>
<th>value1</th>
<th>value2</th>
<th>value3</th>
<th>value4</th>
</tr>
</thead>
<tbody>
<tr>
<td id="class1"><%= value.valueOne() %></td>
<td id="class2"><%= value.valueTwo() %></td>
<td id="class3"><%= value.valueThree() %></td>
<td id="class4"><%= value.valueFour() %></td>
</tr>
<%
}
%>
</tbody>
</table>
I want to obtain a prepopulated form with the row values on click of a particular row . I have some js code that does this .
$(document).on("click", ".data-table .class1", function(e) {
var value = $(this).closest('tr').val();
console.log(value);
// Just to check if I get the correct value
});
unfortunately I cannot understand how to get the values for that particular row from the DOM and populate it in a form , That I want to overlay over the table . I would appreciate any pointers . I really would have written more code but I dnt know Jquery and am stuck
Your general strategy should be this:
Populate the table on the server side: done
Have the form pre-existing in the page, but hidden with css (display:none)
Register a click listener on all tr elements to:
find the values inside each td within the tr
select the corresponding form inputs
populate the inputs using jQuery's val(value) function.
unhide the form if it's hidden
With this in mind, I would change your click listener from document to something like this. (Note: I'm assuming value.valueOne() are just numbers or strings, and don't contain any html.
//target just TR elements
$('tr').click(function(){
values = [];
$(this).children().each(function(){
//add contents to the value array.
values.push($(this).html())
});
//fill in the form values
populateForm(values);
});
Populate form would completely depend on your form's HTML, but to get you started here's an idea of what it might look like:
function populateForm(values){
//set the value of the input with id of name to the value in the first td.
$('#name').val(values[0]);
//show the form (id inputForm) now that it's populated
$('#inputForm').show();
}
A couple things are wrong with your html markup and your JQuery selector. You'll never be able to execute the code you've provided...
You have two 'id' parameters in this element, <table id="data-table" id="test">... This will work with the JQuery I've fixed below, but it's malformed html either way.
In your selector, you are using the syntax for finding an element based on it's css class attribute, however your elements in your HTML have those values set as 'id' attributes. Thus, this, $(document).on("click", ".data-table .class1", function(e) {... should be written as follows, $(document).on("click", "#data-table #class1", function(e) {
Now, if you are attempting to get the values within all of the 'td' elements within a row, then all you really need to do is get the parent element of the 'td' that was clicked, and then get it's children. Then, for each child, get their values.
Like this...
$(document).on("click", "#data-table #class1", function(e) {
var elements = $(this).parent().children();
$.each(elements, function(index, el){
alert($(el).html());
});
});
I've saved a JSFiddle for you to see this in action... http://jsfiddle.net/2LjQM/
val() is used to return value of form inputs. You are using it to try to get the value of a row and row has no value.
Without seeing what your output into the TD as html, I assume it is a form control
Try
$(document).on("click", ".data-table .class1", function(e) {
var value = $(this).find(':input').val(); // `:input pseudo selector wull access any form control input,select,textarea
console.log(value);
// Just to check if I get the correct value
});
EDIT: if the TD contains text
var value = $(this).text();
Instead of scraping the DOM, you could invert the logic, and build the rows using javascript instead. Check out this jsBin to see the solution in action: http://jsbin.com/aligaZi/2/edit?js,output
Start with an empty table:
<table class="data-table" id="test">
<thead>
<tr>
<th>value1</th>
<th>value2</th>
<th>value3</th>
<th>value4</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Since you need to fill a form with the data, I'll be using a simple one as an example:
<form class="data-form">
<label>Value1<input class="value1" /></label>
<label>Value2<input class="value2" /></label>
<label>Value3<input class="value3" /></label>
<label>Value4<input class="value4" /></label>
</form>
Then, on the javascript side:
$(function() {
// Interpolate the values somehow.
// I'm not familiar with JSP syntax, but it shouldn't be too hard.
// I will use dummy data instead.
var tableData = [
{
value1: "row1-v1",
value2: "row1-v2",
value3: "row1-v3",
value4: "row1-v4"
}, {
value1: "row2-v1",
value2: "row2-v2",
value3: "row2-v3",
value4: "row2-v4"
}
];
// For each object, create an HTML row
var rows = $.map(tableData, function(rowData) {
var row = $("<tr></tr>");
row.append($('<td class="class1"></td>').html(rowData.value1));
row.append($('<td class="class2"></td>').html(rowData.value2));
row.append($('<td class="class3"></td>').html(rowData.value3));
row.append($('<td class="class4"></td>').html(rowData.value4));
// When this row is clicked, the form must be filled with this object's data
row.on("click", function() {
fillForm(rowData);
});
return row;
});
$(".data-table").append(rows);
function fillForm(rowData) {
var form = $(".data-form");
form.find("input.value1").val(rowData.value1);
form.find("input.value2").val(rowData.value2);
form.find("input.value3").val(rowData.value3);
form.find("input.value4").val(rowData.value4);
}
});

Unable to fetch value : JQUERY

I m creating dynamic rows with two td and text Host-Address is dynamically populated from GET request.
<tr>
<td class='hostId'>Host-Address</td>
<td>
<input id="btnProv" type='button' onClick="enablePro()" class='btn-success' value="Provision">
</td></tr>
I need to fetch that value using jquery
function enablePro(){
//var ipAddr = $(this).parent().siblings("td").first().text();
var row = $(this).closest('tr');
var ipAddr = row.find('td.hostId').text();
alert(ipAddr);
}
But i get a empty alert box Please enlight my mistake
You need to pass this to the function
onClick="enablePro(this)"
function enablePro(elem){
var row = $(elem).closest('tr');
this refers to the window object inside the function when you bind events inline.
Bind the event using javascript instead of inline events, then this points to the element that triggered the event.
$('.btn-success').click(enablePro);
Check Fiddle
You have to pass this or this.id to the function:
this refers to the object of that control while this.id will give you the id of control
onClick="enablePro(this.id)"
function enablePro("#"+sender){
var row = $(sender).closest('tr');
var ipAddr = row.find('td.hostId').text();
alert(ipAddr);
}

How to assign array variable to select box dropdown options?

I have a form which is largely populated by checkboxes. The checkboxes each have an ID "value" that corresponds to an item within a javascript array. The array items hold some text that will populate a textarea.
I would like to include some dropdown boxes to clean up the site; however, I cannot seem to assign an array ID to the dropdown options? Can this be done in a selectbox option? Is there a workaround to simulate a selectbox without using the tab?
My html is basically:
<div>
<input type=checkbox id=array1 name=textArray></input>
<input type=checkbox id=array1 name=textArray></input>
<input type=checkbox id=array1 name=textArray></input>
...
<select><option 1><option 2>...</select>
</div>
<div>
<form>
<textarea id=outPut></textarea>
</form>
</div>
And my js is:
var textArray = {
array1: 'some text here',
array2: 'some more text',
array3: 'some other text',
...
array90: 'the last text'
};
// variable assigned to chosen item
var selectedInputs = document.getElementsByName("textArray");
for (var i = 0; i < selectedInputs.length; i++) {
selectedInputs[i].onchange = function() {
chosenItem = this;
printText();
};
}
// Script to add items to the Comments section text area
var mytextbox = document.getElementById('outPut');
var chosenItem = null;
function printText(){
if(chosenItem !== null){
mytextbox.value += textArray[chosenItem.id] + "";
// resets the radio box values after output is displayed
chosenItem.checked = false;
// resets these variables to the null state
chosenItem = null;
}
}
How can I associate an item in my js array with one of the selectbox choices?
I found it very difficult to understand what you're asking but I threw this together and hopefully it'll be helpful.
Important bit is
var selectNode = document.getElementById('select'); // <select id="select">
selectNode.onchange = function () {
if (selectNode.selectedIndex !== 0) {
chosenItem = selectNode.options[selectNode.selectedIndex];
selectNode.selectedIndex = 0;
printText();
}
}
and not to use the id attribute for what you're doing (I used data-i).
I'd also like to say that if you're cleaning up code this would be a good time to strongly reconsider how you're passing variables between functions; setting a value in the global namespace and relying on it in the next invocation is just asking for trouble (race conditions, conflicts with other bits of code, etc).
<option value="whatever">1</option> This has been part of HTML from the beginning.

Categories