Add or remove input field, depending on checkbox, using JavaScript - javascript

I have <form> element with some textfields and selections, so I want several new <input type="text"> to be added, when a checkbox is checked and delete them, when it's unchecked.
What is best way to do so?
Is it possible to assign new element to variable or object and then use this variable or object as a reference to delete new elements, because it's supposed several elements to be added at the same time (e.g. <br><inpit type="text">), and I think, that adding them separately is not the best way, so deleting too.
I'm using JQuery as a framework.
<form name="add_subject">
<table cellspacing="1">
<tr>
<td class="key">Day</td>
<td class="value">
<select size="7" name="day">
<option value="1">...</option>
<option value="2">...</option>
</select>
</td>
</tr>
<tr>
<td class="key">Groups</td>
<td class="value">
<input type="checkbox" name="sg">
</td>
</tr>
<tr>
<td class="key">Lecture</td>
<td class="value">
<input type="text" size="50" maxlength="50" name="lec1"> /***/
</td>
</tr>
<tr>
<td class="key">Auditory</td>
<td class="value">
<input type="text" size="4" maxlength="4" name="aud1"> /***/
</td>
</tr>
</table>
I want to add <br><input type="text"> : <input type="text"> after existing <input> field, where /***/ is given, when the checkbox is cheked and remove, when it's not.
What is the best way?
Thanks!

I would already put the input fields in the markup, for example:
<td class="value">
<input type="text" size="50" maxlength="50" name="lec1">
<div class="some-class">
<input type="text"> : <input type="text">
</div>
</td>
etc. Then make them hidden by default with this CSS rule:
div.some-class {
display: none;
}
Now add an event handler to your checkbox, that simply toggles the visibility of your some-class divs whenever the checkbox is clicked:
$(document).ready(function() {
var visible = false;
$('input[name="sg"]').click(function() {
var divs = $('div.some-class');
if (visible) {
divs.each(function() {
this.style.display = 'none';
});
visible = false;
}
else {
divs.each(function() {
this.style.display = 'block';
});
visible = true;
}
});
});

Try to debug the next please if does not work properly (there is an idea):
$( '.value>[type=checkbox]' ).click(
function()
{
if( $( this ).is(':checked') )
{
$( 'td.value' ).append( '<br id="myinput"><input type="text"> : <input type="text">' );
}
else
{
$( '#myinput' ).remove();
}
}
)

Related

how to get value of checked box where values are dynamiclly in ng-repeat

this html code
in this code value of ng-repeat coming dynamically feedback value is training,nature of work, etc i have to fetch value checked radio button in five option poor,average,good,excellent
<form name="exitEmp" ng-submit=submit(exitEmp) novalidate>
<table>
<tr>
<th>S.No</th>
<br />
<th>Factors</th>
<th>Poor</th>
<th>Average</th>
<th>Above Average</th>
<th>Good</th>
<th>Excellent</th>
</tr>
<div>
<div>
<tr ng-if="feedback.qtype=='radio'" ng-repeat="feedback in empratingquestion" >
<td>1</td>
<td>{{feedback.question}}</td>
<td><input type="radio" name="feedback" ng-checked="feedback.checked" ng-change="handleRadioClick(feedback)"></td>
<td><input type="radio"></td>
<td><input type="radio"></td>
<td><input type="radio"></td>
<td><input type="radio"></td>
</tr>
</div>
</div>
</div>
</table>
I created a small demo that could help you finding a solution for your problem. To understand the problem in a bit deeper way, you have to know how radio buttons actually allow you to select only 1 of them per row
Radio buttons work on the principle that only one value can be selected for a certain name. They are grouped in such a way, as such one important part of your code change should be that you give your radiobuttons a unique name per question, in my example, I name the radio buttons based on the current question, like so:
<td><input type="radio" name="{{evaluation.id}}-evaluation" value="-1" ng-model="evaluation.value" /></td>
<td><input type="radio" name="{{evaluation.id}}-evaluation" value="0" ng-model="evaluation.value" /></td>
<td><input type="radio" name="{{evaluation.id}}-evaluation" value="1" ng-model="evaluation.value" /></td>
As you can see, they have the same name for this question (based on their id), and 3 different values that are linked to a property on the question
I don't have to set the checked value per radio button, it will be checked when it's value equals to the value of the input element (eg: -1 for Bad, 0 for Neutral and 1 for Good)
As such, there is no need for a clickhandler on the elements, you just change the value of the current question.
Furthermore, it's important that your HTML layout is a valid one. Your current code has div elements where they shouldn't be allowed, and you have more closing than opening tags. You could check to use the code I used and alter your html in a similar way.
angular.module('demoApp', []).controller('feedbackController', ['$scope', function($scope) {
var evaluationQuestions = [
{
id: 'quality',
question: 'Quality',
value: 0
},
{
id: 'overview',
question: 'Overview',
value: 0
},
{
id: 'content',
question: 'Content',
value: 0
}
];
function showEvaluationResults() {
console.log( $scope.evaluationQuestions.map(function( item ) {
return item.question + ' has value ' + item.value;
}).join('\r\n') )
}
function reset() {
$scope.evaluationQuestions.forEach(function(item) {
item.value = 0;
});
}
$scope.evaluationQuestions = evaluationQuestions;
$scope.showEvaluationResults = showEvaluationResults;
$scope.reset = reset;
return $scope;
}]);
.separator {
width: 10px;
border-left: solid 1px #000;
}
table {
border-spacing: 0 0;
}
table td, table th {
padding: 10px;
text-align: left;
}
table th {
font-size: 0.6em;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="demoApp">
<div ng-controller="feedbackController">
<table>
<tr>
<th>Question</th>
<th class="separator"></th>
<th>Bad</th>
<th>Neutral</th>
<th>Good</th>
</tr>
<tr ng-repeat="evaluation in evaluationQuestions">
<td>{{ evaluation.question }}</td>
<td class="separator"></td>
<td><input type="radio" name="{{evaluation.id}}-evaluation" value="-1" ng-model="evaluation.value" /></td>
<td><input type="radio" name="{{evaluation.id}}-evaluation" value="0" ng-model="evaluation.value" /></td>
<td><input type="radio" name="{{evaluation.id}}-evaluation" value="1" ng-model="evaluation.value" /></td>
</tr>
</table>
<button type="button" ng-click="showEvaluationResults()">
Show current results
</button>
<button type="button" ng-click="reset()">
Reset
</button>
</div>
</div>

How to get nth div's child element value using jquery or javascript

I want to get the value of 4th div's child input element.
Basically im getting checked chekbox value and would like to add the associated input box value using "this"keyword
Here is my html code
<div class="container">
<div class="cell-checkbox" style="float:left;margin-right:5%;">
<input type="checkbox" name="select" value="7" class="big">
</div>
<div class="cell-desc" style="float:left;margin-right:5%;width:30%;">
<!-- Content -->
</div>
<div class="cell-cart"> //input box is inside this div
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td align="right">
<table align="center" class="cellBuy">
<tbody>
<tr align="right">
<td width="1%">
<input type="hidden" name="buyid" id="buyid" value="7">
<input type="hidden" name="category" value="464">
<input type="hidden" name="itemid" value="">
<input name="qty" id="qty" size="6" maxlength="6" value="1" class="input"> /*want to get this input text value
</td>
<td height="20">
<div align="left">
<input type="button" class="btn-BuyOff" value="Buy" id="addtocart" name="addtocart">
</div>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
</div>
I have tried the below mentioned code but its not working
var result = [];
$(':checkbox:checked').each(function (i) {
result.push($(this).val() + "," + $(this).parent().next().find('#qty').val());// this is for finding quantity field value
});
var strreuslt = result.join(';');
alert(strreuslt);
Try using closest to get the closest parent that contains both inputs and than trigger the find
$(':checkbox:checked').each(function (i) {
result.push($(this).val() + "," + $(this).closest('.container').find('input[name="qty"]').val());
});
or:
$(':checkbox:checked').each(function (i) {
result.push($(this).val() + "," + $(this).parent().siblings('.cell-cart').find('input[name="qty"]').val());
});
Note: if you have multiple groups of inputs you will need to wrap each group in a dom element preferably ul li
$(':checkbox').eq(3)
This gives you 4th element in jquery. Indexing starts from zero, so .eq(3) will give 4th child.
Use name instead, and never use same id for multiple elements:
$(this).parent().siblings('.cell-cart').find('[name=qty]').val();
Or use this if container contain multiple <div class="cell-cart">:
$(this).parent().next().next().find('[name=qty]').val();
You have issue with dom traversing. $(this).parent() do not return div having input checkbox element in it. You should rather traverse to closest div with class container and then find input checkbox in it. Like this:
var result = [];
$(':checkbox:checked').each(function (i) {
result.push($(this).val() + "," + $(this).closest('.container').find('[name="qty"]').val());// this is for finding quantity field value
});
var strreuslt = result.join(';');
alert(strreuslt);

jquery / javascript to sum field only if checkbox on same row is checked

I have a jquery / javascript function that totals the number of cubes in my order. this works 100% and is below.
function calculateTotalVolume() {
var grandTotalCubes = 0;
$("table.authors-list").find('input[name^="cubicvolume"]').each(function () {
grandTotalCubes += +$(this).val();
});
$("#grandtotalcubes").text(grandTotalCubes.toFixed(2));
}
as mentioned the above works great. I need a second function to total the same field but only if an checkbox named treated is checked. each row has the checkbox named treated but as the table is dynamically generated, a counter is appended to the name each time hence my use of name^="treated"
I am after something like below but this doesn't work:
function calculateTotalTreatedVolume() {
var grandTotaltreatedCubes = 0;
$("table.authors-list").find('input[name^="cubicvolume"]').each(function () {
if($("table.authors-list").find('checkbox[name^="treated"]').checked){
alert('10');
grandTotaltreatedCubes += +$(this).val();
}
});
$("#grandtotaltreatedcubes").text(grandTotaltreatedCubes.toFixed(2));
}
help appreciated as always.
UPDATE
Rendered HTML output [1 dynamic row added]: (Still in development so very rough, please excuse it)
<table class="authors-list" border=1>
<thead>
<tr>
<td></td><td>Product</td><td>Price/Cube</td><td>Qty</td><td>line total cost</td><td>Discount</td><td>Cubes per bundle</td><td>pcs per bundle</td><td>cubic vol</td><td>Bundles</td><td><input type="checkbox" class="checkall"> Treated</td>
</tr>
</thead>
<tbody>
<tr>
<td><a class="deleteRow"> <img src="http://devryan.tekwani.co.za/application/assets/images/delete2.png" /></a></td>
<td><input type="text" id="product" name="product" />
<input type="hidden" id="price" name="price" readonly="readonly"/></td>
<td><input type="text" id="adjustedprice" name="adjustedprice" /></td>
<td><input type="text" id="qty" name="qty" /></td>
<td><input type="text" id="linetotal" name="linetotal" readonly="readonly"/></td>
<td><input type="text" id="discount" name="discount" /></td>
<td>
<input type="text" id="cubesperbundle" name="cubesperbundle" >
</td>
<td>
<input type="text" id="pcsperbundle" name="pcsperbundle" >
</td>
<td>
<input type="text" id="cubicvolume" name="cubicvolume" size='5' disabled>
</td>
<td><input type="text" id="totalbundles" name="totalbundles" size='5' disabled ></td>
<td valign="top" ><input type="checkbox" id="treated" name="treated" ></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="15"><input type="button" id="addrow" value="Add Product" /></td>
</tr>
<tr>
<td colspan="3">Grand Total: R<span id="grandtotal"></span></td>
<td colspan="2">Ave Discount: <span id="avediscount"></span>%</td>
<td colspan="1">Total Cubes: <span id="grandtotalcubes"></span></td>
<td colspan="15">Treated Cubes: <span id="grandtotaltreatedcubes"></span></td>
</tr>
<tr>
<td colspan="15"><textarea rows="1" cols="50" placeholder="Specific Comments"></textarea><textarea rows="1" cols="20" placeholder="Customer Reference"></textarea>
</td>
</tr>
</tfoot>
</table>
First go the parent tr and then using find to find the checkbox in current row and also use checked with DOM object not jQuery object, you can use indexer to convert jQuery object to DOM object.
Change
if($("table.authors-list").find('checkbox[name^="treated"]').checked){
To
if($(this).closest('tr').find('checkbox[name^="treated"]')[0].checked){
checked is a property of the actual DOM element, and what you have is a jQuery element. You need to change this:
$("table.authors-list").find('checkbox[name^="treated"]').checked
To this:
$("table.authors-list").find('checkbox[name^="treated"]')[0].checked
-^- // get DOM element
Or more jQuery-ish:
$("table.authors-list").find('checkbox[name^="treated"]').is(':checked')
You can iterate through the "checked" checkboxes using $("table.authors-list").find('checkbox[name^="treated"]:checked') and use the value of the input nearest to it (assumed to be in the same row).
Assuming your table has many rows each having a checkbox and an input, you can use:
function calculateTotalTreatedVolume() {
var grandTotaltreatedCubes = 0;
// iterate through the "checked" checkboxes
$("table.authors-list").find('input[type="checkbox"][name^="treated"]:checked').each(function () {
// use the value of the input in the same row
grandTotaltreatedCubes += +$(this).closest('tr').find('input[name^="cubicvolume"]').val();
});
$("#grandtotaltreatedcubes").text(grandTotaltreatedCubes.toFixed(2));
}
Try this:
var grandTotaltreatedCubes = 0;
// Cache the table object here for faster processing of your code..
var $table = $("table.authors-list");
$table.find('input[name^="cubicvolume"]').each(function () {
// Check if checkbox is checked or not here using is(':checked')
if ($table.find('checkbox[name^="treated"]').is(':checked')) {
grandTotaltreatedCubes += $(this).val();
}
});
$("#grandtotaltreatedcubes").text(grandTotaltreatedCubes.toFixed(2));
Change the following line
if($("table.authors-list").find('input[name^="treated"]').checked){
To this
if($("table.authors-list").find('input[name^="treated"]').is(':checked')){

Getting Relative Values in Each Loop jQuery

I'm having an issue pulling the relative values in .each() loop in jQuery. I have a series of table rows that have an text input and a radio button next to them. I want to loop through each row, and if the radio button is selected, save the value for the text input.
However, so far whenever I run my loop, it seems to recognize that one of the radio values is selected, and then it automatically saves the first input, regardless of which row. I thought that by running through each row, the code would only be executed in that particular rows HTML -- I believe it's touching all the rows instead. Can anyone help?
Here's my jQuery:
$('#valueTable tbody tr').each( function() {
//$(this).css('background', 'blue');
if($('td input[name=DefaultVal]:checked').size() > 0){
$('td input[name=DefaultVal]:checked').parent().css('background', 'red')
selectedDefVal = $('td:first-child input[name=valueTextField]').val();
//alert(selectedDefVal)
} else {
alert('not checked')
}
});
Here's my HTML:
<table border="0" id="valueTable">
<tr>
<td width="70%" style="white-space: nowrap;"><input size="80" type="text" name="valueTextField" placeholder="Enter Value" value="" ></td>
<td width="70%" class="default_container">Default
<input type="radio" name="DefaultVal" checked="true" class="defaultValFind" />
</td>
</tr>
<tr>
<td width="70%" style="white-space: nowrap;"><input size="80" type="text" name="valueTextField" placeholder="Enter Value" value="2" ></td>
<td width="70%" class="default_container">Default
<input type="radio" name="DefaultVal" class="defaultValFind" />
</td>
</tr>
<tr>
<td width="70%" style="white-space: nowrap;"><input size="80" type="text" name="valueTextField" placeholder="Enter Value" value="fffffff" ></td>
<td width="70%" class="default_container">Default
<input type="radio" name="DefaultVal" class="defaultValFind" />
</td>
</tr>
</table>
You need to use something like $(this):
$('#valueTable tbody tr').each(function() {
if($(this).find('td input[name=DefaultVal]:checked').length){
$(this).find('td input[name=DefaultVal]:checked').parent().css('background', 'red');
selectedDefVal = $(this).find('td:first-child input[name=valueTextField]').val();
} else {
alert('not checked')
}
});
$('#valueTable tbody tr').each( function() {
//$(this).css('background', 'blue');
if($('td input[name=DefaultVal]:checked', this).size() > 0){
$('td input[name=DefaultVal]:checked', this).parent().css('background', 'red')
selectedDefVal = $('td:first-child input[name=valueTextField]', this).val();
//alert(selectedDefVal)
} else {
alert('not checked')
}
});
I thinks when using $ to select children elments, you forget to specify the parent scope. if omitted, it will be window by default. In this .each case, this will point to the tr element in every loop.

edit in place

I have a table like this
<tr>
<td>No.</td>
<td>Username</td>
<td>Password</td>
<td>Valid Until</td>
<td>Delete</td>
<td>Edit</td>
</tr>
<tr>
<td>1</td>
<td id="1">
<div class="1u" style="display: none;">Username</div>
<input type="text" class="inputTxt" value="Username" style="display: block;"/>
</td>
<td id="1">
<div class="1p" style="display: none;">Password</div>
<input type="text" class="inputTxt" value="Password" style="display: block;"/></td>
<td>18 Jul 09</td>
<td><button value="1" class="deleteThis">x</button></td>
<td class="editRow">Edit</td>
</tr>
When edit is clicked i run this function this replaces the text with input field, so what i want is to cancel this back to text when somewhere else is click instead of save.
$('.editRow').click(function() {
var row = $(this).parent('tr');
row.find('.1u').slideUp('fast');
row.find('.1p').slideUp('fast');
row.find('.inputTxt').slideDown('fast');
}).blur(function() {
row.find('.inputTxt').slideUp('fast');
row.find('.1u').slideDown('fast');
row.find('.1p').slideDown('fast');
});
with this function text changes to input fields but input fields doesnt change back to text when i click somewhere else.
Thank You.
There's a nice plugin for this
Just edited my function because the plugin didn't suite well for my application
$('.editRow').live('click', function() {
var row = $(this).parent('td').parent('tr');
row.find('.1u').slideUp('fast');
row.find('.1p').slideUp('fast');
row.find('.inputTxt').slideDown('fast');
$(this).parent('td').empty().append('<a href=# class=cancel>Cancel</a> / <a href=# class=save>Save</a>');
});
Your blur is applying on the button td.editRow but not applying on the input fields. I think you should separate the code and it should work.
$('.editRow').click(function() {
var row = $(this).parent('tr');
row.find('.1u').slideUp('fast');
row.find('.1p').slideUp('fast');
row.find('.inputTxt')
.slideDown('fast')
.blur(function() {
row.find('.inputTxt').slideUp('fast');
row.find('.1u').slideDown('fast');
row.find('.1p').slideDown('fast');
});
});

Categories