I have a row in a table that can be duplicated by javascript. In the first row I have a javascript code that makes a calculation.
After duplicating a new row the calc javascript is not working for the new row..
What i do wrong?
table row:
<table class="Parameter" id="new">
<form action="ProjectParameterNewRecord.php" method="post">
<tr>
<td>
<input type="text" id="Parameters" name="TypeOfOut" />
</td>
<td>
<?php include "ExchangeRates.php"?>
</td>
</td>
<td>
<input id="Cost" type="number" value="" class="ee105" name="Cost" onchange="changeCost()">
</td>
<td>
<input id="Amount" type="number" value="" class="ee105" name="Amount" onchange="changeAmount()">
</td>
<td><span id="minisum" name="minisum" onchange="changeminisum()"></span>
</td>
<td id="system">
<input type="hidden" id="ParameterID" name="ParameterID"></input>
</td>
<td id="system">
<input type="hidden" id="ProjectID" name="ProjectID" value="3"></input>
</td>
<td>
<input type="submit" value="Submit">
</td>
</form>
</tr>
</table>
code to create a new row:
<script>
var counter = 1;
jQuery('img.add-author').click(function(event){
event.preventDefault();
counter++;
var newRow = jQuery(' <tr class="Parameters" id="AA"><td><input type="text" id="Parameters" name="TypeOfOut"/></td><td><select id="Unit" type="text" value=" " class="ee105" name="Unit" onchange="changeUnit(this.value)"><option value="2">KM</option><option value="4">euro</option><option value="3">$</option><option value="25">WorkHour</option><option value="3">dollar</option><option value="25">WorkHour</option> </select</td></td><td><input id="Cost" type="number" value="" class="ee105" name="Cost" onchange="changeCost()"></td><td><input id="Amount" type="number" value="" class="ee105" name="Amount" onchange="changeAmount()"></td><td><span id="minisum" name="minisum" onchange="changeminisum()"></span></td><td id="system"><input type="hidden" id="ParameterID" name="ParameterID' + counter +'"></input></td><td id="system"><input type="hidden" id="ProjectID" name="ProjectID" value="3"></input></td><td><input type="submit" value="Submit"></td></tr>');
jQuery('table.Parameter#new').append(newRow);
});
</script>
javascript code to calculate:
function CalcUnitValue() {
var U = document.getElementById("Unit").value;
var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
document.getElementById("minisum").innerHTML = SUM;
document.getElementById("minisum").readOnly = true;
}
function changeCost() {
var C = document.getElementById("Cost").value;
var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
document.getElementById("minisum").innerHTML = SUM;
document.getElementById("minisum").readOnly = true;
}
function changeAmount() {
var C = document.getElementById("Amount").value;
var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
document.getElementById("minisum").innerHTML = SUM;
document.getElementById("minisum").readOnly = true;
}
function changeUnit() {
var C = document.getElementById("Amount").value;
var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
document.getElementById("minisum").innerHTML = SUM;
document.getElementById("minisum").readOnly = true;
}
function minisum() {
var SUM = -1 * ((((($('#Amount').val())) * (((($('#Cost').val())) * (($('#Unit').val())))))));
return alert(document.getElementById('minisuminput').innerHTML);
thank you :)
Your HTML is invalid. You have an extra closing </td> in the middle. You also need to put the form outside the table.
You can't have duplicate IDs in a HTML page and expect to reference anything except the first one. Use classes instead.
Don't use inline event handlers with jQuery. Use delegated jQuery handlers if you have dynamically added elements.
Use an element hidden in the page to hold your template. If you store it in the HTML, and not code, you would have noticed your </select> was missing and replaced by an extra </td>.
You mix JavaScript selectors with jQuery. Just stick to jQuery selectors. They are shorter.
None of the extra parenthesis are required for a * b * c * d equations.
inputs and img elements are meant to be self-closing, not have end tags.
All your calculations are exactly the same, so reuse the code.
Get into the habit on using consistent case (upper/lower/mixed) for variables and classes.
Use delegated event handlers like this:
$(document).on('change', '.cost,.amount,.unit,.parameters', function() {
var $tr = $(this).closest('tr');
var sum = -1 * $('.Amount', $tr).val() * $('.cost', $tr).val() * $('.Unit', $tr).val();
$(".minisum", $tr).html(sum);
}
Re templating: you can store your template row in a dummy script block, with unknown type (I use text/template) and it will be ignored by the browser.
e.g.
<script id="template" type="text/template">
<tr class="Parameters" id="AA">
<td>
<input type="text" class="Parameters" name="TypeOfOut" />
</td>
<td>
<select class="Unit ee105" type="text" value=" " name="Unit">
<option value="2">KM</option>
<option value="4">euro</option>
<option value="3">$</option>
<option value="25">WorkHour</option>
<option value="3">dollar</option>
<option value="25">WorkHour</option>
</select>
</td>
<td>
<input class="cost" type="number" value="" name="Cost">
</td>
<td>
<input class="amount ee105" type="number" value="" name="Amount">
</td>
<td><span class="minisum" name="minisum"></span></td>
<td class="system">
<input type="hidden" class="ParameterID" name="ParameterID{counter}" />
</td>
<td class="system">
<input type="hidden" class="ProjectID" name="ProjectID" value="3" />
</td>
<td>
<input type="submit" value="Submit">
</td>
</tr>
</script>
You will note a {counter} placeholder where you wanted to insert a new value. Use it as the HTML source to create new rows.
e.g.
$('table.Parameter#new').append($('#template').html().replace('{counter}', counter));
JSFiddle to play with ( most of this functional): https://jsfiddle.net/TrueBlueAussie/33e9ptgu/
It looks like your problem is coming from having duplicate ids. When there are duplicate ids, the behavior of document.getElementById() is undefined. Each browser will try to do something reasonable, but there's no way to know which element will be returned (though it's usually the first element).
One option is to change the duplicated ids to class, and then when creating a new row, give the row it's own unique id using your counter:
var newRow = jQuery(' <tr class="Parameters" id="' + counter + '"><td>.....</td></tr> ');
This will allow you to access whichever row you want for calculation, as well as it's children using jquery:
Instead of $('#Cost') or document.getElementById("minisum"), use $('#' + [number of rowid]).find('.Cost'); or $('#' + [number of rowid]).find('.minisum');
A couple of other tips:
To get the value of an <input> into your functions, simply pass it as a parameter like so: onchange="changeCost(value)". Now you can delete 3 of your 4 identical functions as well as remove the first line of the remaining one.
You don't need closing </input> tags (see here)
There are two </td> tags on your second column
Make sure you have correct tag nesting on your </tr> and </form> tags
Related
I'm working on a DnD character creator and am trying to increase certain ability scores based on race. I have a checkbox input next to every race that looks like so:
<td>
<input
type="checkbox"
id="dragonbornRace"
onchange="updateRace();"
/>
</td>
<td>Dragonborn</td>
I also already have a section for ability score that looks like this:
<td>
<input
type="number"
value="10"
id="strScore"
onchange="updateMods()"
/>
</td>
My goal is to make it so that when dragonborn checkbox is checked, the strength increases by 2. So far I have this code, but it doesn't seem to work:
function updateRace() {
var strScore = document.getElementById("strScore").value;
if (document.getElementById("dragonbornRace").checked == true) {
strScore = strScore + 2;
}
}
When I go to test, nothing occurs when I check the box. I am probably missing something obvious, but any help would be appreciated!
The reason is that you need to assign the new score value to strScore elememt.
Also,you need to pay attention to use strScore = Number(strScore) + 2; to get the expected result
function updateRace() {
var scoreEle = document.getElementById("strScore")
var strScore = scoreEle.value;
if (document.getElementById("dragonbornRace").checked == true) {
strScore = Number(strScore) + 2;
scoreEle.value = strScore;
}
}
function updateMods(){
}
<table>
<tr>
<td>
<input
type="checkbox"
id="dragonbornRace"
onchange="updateRace();"
/>
</td>
<td>Dragonborn</td>
<td>
<input
type="number"
value="10"
id="strScore"
onchange="updateMods()"
/>
</td>
</tr>
<table>
Hi I am dynamically adding rows with a button and when I am finished entering information, I would like it to then clear the contents. The button "Add Pokemon" is the one I want to press and it should clear all the contents.
function addPokemon() {
var pokemonName = document.getElementById("pokemon-name-container");
pokemonName.innerHTML = document.getElementById("pokemon-names").value;
for (var i = 0; i < element.length; i++) {
if (element[i].value !== "undefined") {
pokemonArray.push(element[i].value);
}
}
console.log(pokemonArray);
for (var i = 0; i < pokemonArray.length; i++) {
document.getElementById("pokemon-container").innerHTML += "<li>" + pokemonArray[i] + "</li>";
}
document.getElementById("pokemon-name-container").value = "";
document.getElementById("move-name").value = "";
}
This is my function I am using. ^^
And below is my HTML vv
<div>
<table>
<tbody id="tbody">
<tr>
<td>
<div id="pokemon-name-container">
<p>Pokémon Name:</p>
<input type="text" id="pokemon-names" size="30">
</td>
</tr>
<tr>
<td>
<p class="moves">Moves:</p>
</td>
</tr>
<tr>
<td>
<input class="move-container" type="text" id="move-name" placeholder="Enter move here">
</td>
<td>
<input class="button-container" type="button" id="remove-btn" value="Remove Move" onclick="removeRow()">
</td>
</tr>
</tbody>
</table>
</div>
<div>
<input type="button" class="add-move-button" id="add-move-button" value="Add Move" onclick="addRow()">
</div>
<div>
<input type="button" class="add-pokemon-button" id="add-pokemon-button" value="Add Pokémon" onclick="addPokemon()">
</div>
You could put to all the inputs you create a unique class that defines them under a parent with a unique id. Then use inside the function of javascript the next pice of code const childs = document.querySelectorAll('#idParent.classChilds') this querySelectorAll is kind of like the getElementsById but uses selectors of CSS so it's more powerfull. The querySelectorAll returns you a NodeList of all the elements that matches de DOM with the CSS query.
Then you would only need to do something similar to this using functional programming:
const childs = document.querySelectorAll('#idParent .classChilds')
childs.forEach(child=>{
child.value = ""
})
I'm not sure if this code works (I'm not with an code editor and a browser to check if there isn't mistakes), as I said, you could do something similar to it
HOPE IS HELPFULL
FYI, try to avoid the selectors like getElementById or getElementsByClass....
Try to use this:
document.querySelector('CSS SELECTOR') // GIVES YOU THE FIRST MATCH OF THE CSS SELECTOR
document.querySelectorAll('CSS SELECTOR') // GIVES YOU A NODELIST WITH ALL MATCHES
I have a simple form users can fill out and also add a new form to add multiple entries.
Everything works fine except when I enter data in the first set of inputs and click create new memberships it will take the data from the form and put it in the text boxes.
How can I stop that?
http://jsfiddle.net/811yohpn/2/
I have tried a couple different ways.
$('#education').find('input:text').val('');
$('#education: input').val('');
However that will clear all entries.
Call find on the newDiv, instead of all inputs within #education.
Updated fiddle
newDiv.find('input:text').val('');
var ed = 1;
function new_education() {
ed++;
var newDiv = $('#education div:first').clone();
newDiv.attr('id', ed);
var delLink = '<a class="btn btn-danger" style="text-align:right;margin-right:65px" href="javascript:deled(' + ed + ')" > Delete Education ' + ed + ' </a>';
newDiv.find('tr:first th').text('Education ' + ed);
newDiv.append(delLink);
newDiv.find('input:text').val(''); // <----------- added this
$('#education').append(newDiv);
}
function deled(eleId) {
d = document;
var ele = d.getElementById(eleId);
var parentEle = d.getElementById('education');
parentEle.removeChild(ele);
//ed--;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<legend>Education</legend>
<div id="education">
<div id="1">
<table border=3>
<tr>
<th colspan="4" style="background-color:#b0c4de;">Education 1</th>
</tr>
<tr>
<td>
<label>School Name</label>
<input type="text" name="schoolname[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Type</label>
<input type="text" name="degreetye[]" maxlength="30" size="30"/>
</td>
<td>
<label>Degree Field</label>
<input type="text" name="degreefield[]" maxlength="30" size="30"/>
</td>
</tr>
</table>
</div>
</div>
<br/><a class="js-addNew btn btn-info" href="javascript:new_education()"> Add New Education </a>
You need to clear the inputs under the cloned element
newDiv.find('input').val('')
Demo: Fiddle
Your selectors are selecting all input elements within the #education container, that is not what you want. The newDiv variable refers to the newly created element so you can use that to find the input elements within in and then clear it
Using jquery, I'm trying to select those inputs that have an asterisk adjacent to them.
HTML
<form name="checkout">
<table width="100%" border="0">
<tr>
<td>First Name</td>
<td><input type="text" name="FirstName" value="" />*</td>
</tr>
<tr>
<td>Last Name</td>
<td><input type="text" name="LastName" value="" /></td>
</tr>
</table>
</form>
Jquery
var elems = $("form[name='checkout'] :input").filter(function(index) {
var str = $(this).parents('td').html()
return (str.indexOf("*")!=-1)
}).length;
Result of elems should be 1 but it's not working, i.e. the form submits in spite of a return false in the handler so can't seem to catch the error details. What am I doing wrong?
var elems = $("td:contains('*') input");
This is selector for the input elements that you need.
elems.length will give you 1 in this case
Ha Ha,
Missing the onReady().
Use this one,
$(function(){
var elems = $("form[name='checkout'] :input").filter(function(index) {
var str = $(this).parents('td').html()
return (str.indexOf("*")!=-1)
}).length;
console.log(elems);
});
That should do. Cheers :).
I suggest you to use CSS :after pseudo element
<style>
.mandatory:after{
content:"*";
}
</style>
<span class="mandatroy">
<input type="text" name="FirstName" value="">
</span>
<script>
$("form[name='checkout'] .mandatory > :input")
</script>
It would be easier, if you added a class to the inputs which have an asterisk after them:
<td><input type="text" name="FirstName" class="required" />*</td>
Then you could select them by their class and do whatever you wish to them.
$("input.required").length();
Given the explicit requirement:
$('input').filter(function () {
return (this.nextSibling && this.nextSibling.nodeValue.indexOf('*') > -1) || (this.previousSibling && this.previousSibling.nodeValue.indexOf('*') > -1);
}).css('border-color','#f00');
JS Fiddle demo.
I have this form.
<table><tr><td>
<FORM>
<label> ID </label></td>
<td>
<input type=text id="inputp1_id" size=24 class="text">
</td></tr>
<tr><td>
<label>Type</label></td><td><select id="inputp1_type" name="inputp1_type"><option value="text">Text</option><option value="integer">Integer</option><option value="float">Float</option><option value="list_values">List of values</option>
<option value="range">Range</option><option value="selection_collapsed">Selection (collapsed)</option><option value="selection_expanded">Selection (expanded)</option><option value="subimage">Subimage selection</option>
<option value="polygon">Polygon selection</option><option value="horizontal_separator">Horizontal separator</option></select>
</td></tr>
<tr><td> <label > Description</label></td> <td><input type=text id="inputpi_description" size=24 class="text"> </td><!--style=" width:300px; height:20px;"-->
</tr>
<tr><td> <label>Value</label></td><td> <input type="text" name="inputp1_value" id="inputp1_value" class="text" size=24></td></tr>
<tr><td> <label > Info (help)</label></td><td>
<input type=text id="input1_value" size=24 class="text"></td></tr>
<tr><td><label > Visible?</label></td><td><input type="checkbox" name="inputp1_visible" id="inputp1_visible"></td></tr></table>
<!--</form>--></div>
But (it's possible?) can create the id's input box?
Because the variable these are "numbered".
For example the first id in the form is inputp1_id but the number i want use how variable.
It's possible create the id with the Javascript o Jquery?
l=3
Id='inputp' +l+'_id'
After this create the input text has the id=inputp3_id
Here is one example on how to generate html contents dynamically with jquery and javascript. Both methods, although they look similar, give a bit different results: jquery generates one additional <tbody> tag, while javascript inserts the new rows directly to <table>. I recommend you to inspect the result in the Firefox's DOM Inspector by pressing Ctrl+Shift+I. IT's very handy and effective tool. And here is the algorythm:
var i=0; // this is simple counter
function generate_row_dynamically_in_jquery() {
i++;
var new_row = $('<tr/>');
var new_cell1 = $('<td>ID <input type="text" name="inputp'+i+'_id" id="inputp'+i+'_id" size="24" class="text"/></td>');
var new_cell2 = $('<td>Visible? <input type="checkbox" name="inputp'+i+'_visible" id="inputp'+i+'_visible"> </td>');
new_row.append(new_cell1).append(new_cell2);
$('#table1').append(new_row);
}
function generate_row_dynamically_in_javascript() {
i++;
var new_row = document.createElement('tr');
var new_cell1 = document.createElement('td');
new_cell1.innerHTML = 'ID <input type="text" name="inputp'+i+'_id" id="inputp'+i+'_id" size="24" class="text"/>';
var new_cell2 = document.createElement('td');
new_cell2.innerHTML = ' Visible? <input type="checkbox" name="inputp'+i+'_visible" id="inputp'+i+'_visible">';
new_row.appendChild(new_cell1);
new_row.appendChild(new_cell2);
document.getElementById('table1').appendChild(new_row);
}
& #jsfiddle