I have to clone my <tr> and I have list of checkbox like code below and when I add new row with list of checkbox and then I click on check box to show value in textbox field_resultsthe value not show only on first textbox not yet clone.
How when I add new tr and then when I click on which list of checkbox in which tr they will show value of my click in the same tr.
$("#add-new").on("click", function () {
$tr = $(this).closest("tr").next().clone(true);
$tr.insertAfter($(this).closest("tr"));
});
$(document).ready(function () {
$checks = $('#mych_box :checkbox');
$checks.on('change', function () {
var string = $checks.filter(":checked").map(function (i, v) {
return this.value;
}).get().join(",");
console.log(string);
$('#field_results').val(string);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<tr>
<td>
<button type="button" id="add-new">Add New</button>
</td>
</tr>
<tr>
<td>
<input type="text" id="field_results" name="field_results[]"/><br>
<div class="multiselect" style="height: 100px;width: auto;" id="mych_box">
<label>
<input type="checkbox" id="virt_software_chb1" name="virt_software[]" value="White"/>White
<input type="checkbox" id="virt_software_chb2" name="virt_software[]" value="Red"/>Red
<input type="checkbox" id="virt_software_chb3" name="virt_software[]" value="Blue"/>Blue
</label>
</div>
</td>
</tr>
As defined above use true in clone to bind default events and use class instead of id to group element
$(".virt_software_chb").on('change', function () {
var string = $(this).closest('td').find('.virt_software_chb').filter(":checked").map(function (i, v) {
return this.value;
}).get().join(",");
$(this).closest('td').find('.field_results').val(string);
});
$("#add-new").on("click", function () {
$tr = $(this).closest("tr").next().clone(true);
$tr.insertAfter($(this).closest("tr"));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>
<button type="button" id="add-new">Add New</button>
</td>
</tr>
<tr>
<td>
<input type="text" class="field_results" name="field_results[]"/><br>
<div class="multiselect" style="height: 100px;width: auto;" id="mych_box">
<label>
<input type="checkbox" class="virt_software_chb" name="virt_software[]" value="White"/>White
<input type="checkbox" class="virt_software_chb" name="virt_software[]" value="Red"/>Red
<input type="checkbox" class="virt_software_chb" name="virt_software[]" value="White"/>White
</label>
</div>
</td>
</tr>
</table>
withDataAndEvents (default: false)
A Boolean indicating whether event handlers should be copied along with the elements. As of jQuery 1.4, element data will be copied as well. - clone()
Try passing in true and see what you get.
$tr = $(this).closest("tr").next().clone(true);
Related
The script below creates a new line of text boxes and a button. However, when the button is clicked, the new field would like to have new button text and a new design.
$(function () {
var newRow = $(".addRows").clone();
$("#addButton").on("click", function () {
let row = newRow.clone().appendTo("#TextBoxesGroup tbody");
$("tr").find("#addButton").css( "border-color", "red" );
});
});
<table id="TextBoxesGroup">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate[]" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate[]" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton" value="add row" />
</td>
</tr>
</table>
<script type = "text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
For example, the created new button should be with text delete and color red.
Thanks for the help or recommendation
I think using templates might make it easier and cleaner to modify the elements. Here is a quick guide for basic templating with vanillajs https://gomakethings.com/html-templates-with-vanilla-javascript/
This allows you to easily pass in IDs for your inputs.
I am not sure if you are just trying to toggle a second row or add multiple rows. If you simply want to toggle the second row and not add more than that then only use the second part of the js, and remove the first template. Likewise if you want to add multiple you can remove the second part (currently commented out) of the js and the second template.
(function (){
// Interpolate function from https://gomakethings.com/html-templates-with-vanilla-javascript/
//Lets us pass a unique id to the template
function interpolate (str, params) {
let names = Object.keys(params);
let vals = Object.values(params);
return new Function(...names, `return \`${str}\`;`)(...vals);
}
//Using document on click as we are adding new buttons to the DOM and want the event to trigger on them as well
$(document).on('click', '.add-button', function () {
let id = $('.addRows').length + 1; //Use this for our row ID
let newRow = interpolate(row_template.innerHTML, {id}); //Generate our row html from the template
$(this).closest('.addRows').after(newRow); //Add the html to the table
});
//Remove button
$(document).on('click', '.remove-button', function () {
$(this).closest('.addRows').remove();
});
})();
//Use the below INSTEAD of the above for just the single extra toggling row.
/*(function (){
//Add new row from simple template
$(document).on('click', '.add-button', function () {
$("#TextBoxesGroup tbody").append(row_template_single.innerHTML);
});
//Remove the row
$(document).on('click', '.remove-button', function () {
$(this).closest('.addRows').remove();
});
})();*/
/*Style for red remove button*/
.remove-button {
background-color: #f77;
color: white;
}
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<table id="TextBoxesGroup">
<tbody>
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_1" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_2" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton_1" class="add-button" value="Add row" />
</td>
</tr>
</tbody>
</table>
<!-- Template allowing to add multiple new rows with unique input names via id passed -->
<template id="row_template">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_${id}" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_${id}" class="picker" value="" size="6">
</td>
<td>
<input type="button" id="addButton_${id}" class="add-button" value="Add row" />
<input type="button" class="remove-button" value="Remove row" />
</td>
</tr>
</template>
<!-- Template for just 'toggling' a second row -->
<!-- <template id="row_template_single">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_2" class="picker" value="" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_2" class="picker" value="" size="6">
</td>
<td>
<input type="button" class="remove-button" value="Remove row" />
</td>
</tr>
</template> -->
I noticed my previous answer did not properly handle adding items in-between other items, i.e. not at the end of the list.
The following will better handle adding and removing items, while keeping the ids in order. This instead renders the fields based on the data we keep and manage in JavaScript.
(function () {
$(document).ready(function () {
field_data.init()
})
let field_data = {
data: [],
init: function () {
this.cacheDom();
this.bindEvents();
this.data.push(this.getItem());
this.renderData();
},
cacheDom: function () {
this.$render_container = $('#render_container');
this.row_template_html = $('#row_template').html();
},
bindEvents: function () {
$(document).on('click', '.remove-button', this.removeItem);
$(document).on('click', '.add-button', this.addItem);
this.$render_container.on('change', 'input', this.inputChange);
},
//When an item gets added, add new empty item to the data and re-render.
addItem: function () {
let target = parseInt($(this).attr('data-target'));
field_data.data.splice(target+1, 0, field_data.getItem());
field_data.renderData();
},
//When an item gets removed, remove it from the data and re-render.
removeItem: function () {
let target = parseInt($(this).attr('data-target'));
if (field_data.data.length > 1) { //Prevent from removing last item.
field_data.data.splice(target, 1);
field_data.renderData();
}
},
//Get a new/empty item.
getItem: function () {
return {
start_date: '',
end_date: '',
}
},
//Update the data when a value of an input changes
inputChange: function () {
let $this = $(this);
let id = parseInt($this.attr('data-id'));
let target = $this.attr('data-target');
field_data.data[id][target] = $this.val();
},
//Render the data according to the template.
renderData: function () {
let html = '';
for (let i = 0; i < field_data.data.length; i++) {
//Generate our row html from the template
html += field_data.getRowTemplate(
{
id: i,
start_date: field_data.data[i].start_date,
end_date: field_data.data[i].end_date,
}
);
}
field_data.$render_container.html(html);
},
//Gets the html for a single row based on our template
getRowTemplate: function (params) {
let names = Object.keys(params);
let values = Object.values(params);
return new Function(...names, `return \`${field_data.row_template_html}\`;`)(...values);
},
}
})();
.remove-button {
background-color: #f77;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="TextBoxesGroup">
<tbody id="render_container">
</tbody>
</table>
<template id="row_template">
<tr class="addRows">
<td>Start Date:</td>
<td>
<input type="text" name="StartDate_${id}" data-id="${id}" data-target="start_date" class="picker" value="${start_date}" size="6">
</td>
<td>End Date:</td>
<td>
<input type="text" name="EndDate_${id}" data-id="${id}" data-target="end_date" class="picker" value="${end_date}" size="6">
</td>
<td>
<input type="button" class="add-button" data-target="${id}" id="addButton_${id}" value="Add row"/>
<input type="button" class="remove-button" data-target="${id}" value="Remove row"/>
</td>
</tr>
</template>
Below in the example, I want that each time when the add button is clicked to take the element inside the template div and append it to the landingzone class element. But at the same time I need the NEWID to change for the new element. Of course this is just an example, the table stuff can be a div or anything else.
the form:
<form method="post">
<input type="text" name="title">
<input type="text" name="number">
<table>
<thead>
<tr> <th>Parts</th> </tr>
</thead>
<tbody class="landingzone">
</tbody>
</table>
<input type="submit" value="Save">
<input type="button" name"add" class="add" value="Save">
</form>
the template:
<div class="template" style="display: hidden">
<tr id="NEWID">
<td>
<input type="text" name="part_NEWID">
</td>
</tr>
</div>
What would be the best way to accomplish this?
Here's an example for your need. The javascript will work without changing any html except in place of name"add" should be name="add"
What i have done here is i'm getting the id of the template tr and setting it with increment and also the input field name.
var $landingzone = $('.landingzone');
var $add = $('.add');
var desiredId = 'id';
$add.on('click', function() {
var $template = $('.template').find('tr');
var id = $template.attr('id');
var idArr = id.split('-');
if (!idArr[1]) {
id = desiredId + '-1';
} else {
id = desiredId + '-' + (parseInt(idArr[1]) + 1);
}
$template.attr('id', id);
$template.find('input').attr('name', 'part_'+id);
console.log('input id--->'+id, 'input name--->'+'part_'+id);
$landingzone.append($template.clone());
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form method="post">
<input type="text" name="title">
<input type="text" name="number">
<table>
<thead>
<tr>
<th>Parts</th>
</tr>
</thead>
<tbody class="landingzone">
</tbody>
</table>
<input type="submit" value="Save">
<input type="button" name="add" class="add" value="Add">
</form>
<table class="template" style="display: none">
<tr id="NEWID">
<td>
<input type="text" name="part_NEWID">
</td>
</tr>
</table>
Like #Andrea said in her comment, some more details would be appreciated ...
I think what you are after is:
const $template = $('.template').clone()
$template.attr('id', 'someId')
$template.find('input[name="part_NEWID"]').attr('name', 'part_someId')
$('.landingzone').append($template)
And if you need it in a function:
function appendTemplateToLandingZone (newId) {
const $template = $('.template').clone()
$template.attr('id', newId)
$template.find('input[name="part_NEWID"]').attr('name', 'part_' + newId)
$('.landingzone').append($template)
}
I haven't tested this, so it might need a slight adjustment. If you'll provide a basic jsbin I'll make it work there.
I have a table inside a table where checkbuttons are attached with every field. There are three levels
1). Select All info
2). Parent
3). Child
What i want to do is that if i select "Select All Info" check button, it selects all the check boxes which is working fine. What i can't able to do is that if i select a "Parent" check box, it should select all the child's check boxes. I am trying to increment the Child_id field but didn't get any fruitful results.
Below is the code I am trying, any help or guidance would be useful
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<script>
$(function select(){
$("#Select_All").change(function () {
$("#Parent_Id, #Child_Id").prop("checked", this.checked);
});
$("#Parent_Id").change(function(){
var i=0;
$('#Child_Id').each(function(){
i++;
var newID='Child_Id'+i;
$(this).attr('id', newID);
$(this).val(i);
$(newID).prop("checked", this.checked);
});});});
</script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<TABLE BORDER="3" CELLPADDING="10" CELLSPACING="10">
<input type="checkbox" id = "Select_All" name="Main" />Select All Information
<TD>
<input type="checkbox" id = "Parent_Id" name="PPP" class = "Parent_Class" />parent
<TABLE BORDER="3" CELLPADDING="3" CELLSPACING="3">
<div>
<TD>
<input type="checkbox" id = "Child_Id" name="CCC" class = "Child_Class" /> Child1 </TD>
<TD>
<input type="checkbox" id = "Child_Id" name="CCC" class = "Child_Class" />Child2</TD>
<TR>
<TD>
<input type="checkbox" id = "Child_Id" name="CCC" class = "Child_Class" /> Child3</TD>
<TD> <input type="checkbox" id = "Child_Id" name="CCC" class = "Child_Class" />Child4
</TD>
</TR>
</div>
</TABLE>
</TD>
<TD> <input type="checkbox" id = "Child_Id" name="CCC" class = "Child_Class" />
A table inside a table.</TD>
</TABLE>
Try this:
$("#Select_All").change(function () {
$("#Parent_Id, #Child_Id").prop("checked", this.checked);
});
$("#Parent_Id").change(function(){
//var i=0;
var isParentChecked = $(this).prop('checked');
$('.Child_Class').each(function(){
//i++;
//var newID='#Child_Id'+i;
//console.log(newID);
//$(this).attr('id', newID);
//$(this).val(i);
$(this).prop("checked",isParentChecked);
});
});
Since you change the id of each child element, then you check/uncheck the top most parent (Select_All) there is only "parent" element will be affected, so I comment some of lines of code to make it run properly.
DEMO
I have then following table:
<table style="width:100%" id="testTable">
<tr>
<th>length per</th>
<th>width per</th>
<th>length</th>
<th>width</th>
<th>total</th>
</tr>
<tr align='right'>
<td>
<input type="text" name="length-per-input">
</td>
<td>
<input type="text" name="width-per-input">
</td>
<td>
<input type="text" name="length-total-input">
</td>
<td>
<input type="text" name="width-total-input">
</td>
<td>
<input type="text" name="total-output" disabled="disabled">
</td>
</tr>
<tr align='right'>
<td>
<input type="text" name="length-per-input">
</td>
<td>
<input type="text" name="width-per-input">
</td>
<td>
<input type="text" name="length-total-input">
</td>
<td>
<input type="text" name="width-total-input">
</td>
<td>
<input type="text" name="total-output" disabled="disabled">
</td>
</tr>
</table>
<input type=button value='+' onclick="addRow()" />
<input type=button value='Calculate' onclick="Calculate()" />
I also have the javascript which adds the value and puts it in total:
<script>
function Calculate() {
var lengthPerInput = $("input[name='length-per-input']").val();
var widthPerInput = $("input[name='width-per-input']").val();
var lengthTotal = $("input[name='length-total-input']").val();
var widthTotal = $("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
$("input[name='total-output']").val(total);
}
</script>
The aim here is to have it iterate over the two rows, then add each one separately.
I know how to get each row by using:
$('#testTable tr').each(function(){
console.log(this);
$(this).find('length-per-input').each(function(){
console.log(this);
})
})
But using the row (accessed via "this") I don't know how to get the correct cells, get their value, then perform the calculate on that row for the total.
Any advice on this please? Thank you!
function Calculate(tr_row) {
var lengthPerInput = tr_row.find("input[name='length-per-input']").val();
var widthPerInput = tr_row.find("input[name='width-per-input']").val();
var lengthTotal = tr_row.find("input[name='length-total-input']").val();
var widthTotal = tr_row.find("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
tr_row.find("input[name='total-output']").val(total);
}
For every row you call function to summ the values
To the function you pass the row, then it can collect values on that row
$('#testTable tr').each(function(){
Calculate($(this))
})
You can use each() function to iterate through table and use find() function to find cell values.
function Calculate() {
$('#testTable tr').each(function() {
var lengthPerInput = $(this).find("input[name='length-per-input']").val();
var widthPerInput = $(this).find("input[name='width-per-input']").val();
var lengthTotal = $(this).find("input[name='length-total-input']").val();
var widthTotal = $(this).find("input[name='width-total-input']").val();
var total = (lengthTotal/lengthPerInput) + (widthTotal/widthPerInput);
$(this).find("input[name='total-output']").val(total);
});
}
Working Plunker
How to get a table cell value using jQuery?
I have a table in which there are checkboxes, some checkboxes are disabled. I want to add an onclick attribute to all disabled checkboxes using JavaScript or jQuery.
HTML
<table class="docs_table" id="myTable2">
<tr id="node-22" class="disabled_element">
<td title="Document can't be selected.">
<input type="checkbox" name="docs" id="/root/docname" value="/root/docname" disabled />
</td>
</tr>
<tr id="node-23" class="">
<td title="">
<input type="checkbox" name="docs" id="/root/docname2" value="/root/docname2" />
</td>
</tr>
<tr id="node-24" class="disabled_element">
<td title="Document can't be selected.">
<input type="checkbox" name="docs" id="/root/docname3" value="/root/docname3" disabled />
</td>
</tr>
</table>
In above code the docname input box should get below as onclick.
onclick="javascript:if(confirm('Press OK to confirm')){ document.location='/pathtoscript?command=dosomething&name=docname'};return false;"
and docname3 should get the below
onclick="javascript:if(confirm('Press OK to confirm')){ document.location='/pathtoscript?command=dosomething&name=docname3'};return false;"
What I tried
$('table tr td input[type="checkbox"]').each(function () {
if ($( this ).prop('disabled')) {
$( this ).closest('tr').addClass('lineThrough');
$( this ).attr('onClick','onclick="javascript:if(confirm('Press OK to confirm')){ document.location='/pathtoscript?command=dosomething&name=docname'};return false;"');
}
});
But it doesn't work, and also I wonder how to deal with different docname because in onclick statement name=docname will be different for each input box.
Fiddle
I did it using this answer.
<table class="docs_table" id="myTable2">
<tr id="node-22" class="disabled_element">
<td title="Document is being edited by someone.">
<div style="display:inline-block; position:relative;">
<input type="checkbox" name="docs" id="/root/docname" value="/root/docname" disabled />
<div style="position:absolute; left:0; right:0; top:0; bottom:0;"></div>
</div>
</td>
</tr>
<tr id="node-23" class="child">
<td title="">
<input type="checkbox" name="docs" id="/root/docname2" value="/root/docname2" />
</td>
</tr>
<tr id="node-22" class="disabled_element">
<td title="Document is being edited by someone.">
<div style="display:inline-block; position:relative;">
<input type="checkbox" name="docs" id="/root/docname3" value="/root/docname3" disabled />
<div style="position:absolute; left:0; right:0; top:0; bottom:0;"></div>
</div>
</td>
$('table tr td input[type="checkbox"] + div').each(function () {
if ($(this).prev('input[disabled]')) {
$(this).closest('tr').addClass('lineThrough');
$(this).click(function () {
if (confirm('Press OK to confirm')) {
var docname = $(this).prev('input[disabled]').prop('value');
docname = docname.substring(docname.lastIndexOf('/') + 1);
document.location = '/pathtoscript?command=dosomething&name=' + docname;
}
});
}
});
Disabled elements don't generate mouse events. So basically what I did is added a div around the disabled inputs and added some JS to match it.
JSFiddle
In case, it is not possible for you to change your existing HTML structure and want to perform the action on click of the closest <td> element, please use the below code.
Javascript (jQuery)
$(document).ready(function(){
$('table tr td input[type="checkbox"]').each(function () {
if ($( this ).prop('disabled')) {
$( this ).closest('tr').addClass('lineThrough');
var valStr = $(this).val();
$( this ).closest('td').attr('onClick', 'clickFn("'+valStr+'");');
//console.log($( this ).closest('td').attr('onClick'));
}});
});
function clickFn(valStr){
if(confirm('Press OK to confirm')){
valStr = valStr.substring(valStr.lastIndexOf('/') + 1);
newHref = '/pathtoscript?command=dosomething&name=' +valStr;
//console.log(newHref);
document.location = newHref;
}
}
Demo