For loop breaking IndexOf - javascript

Well I've ripped my hair off because I assumed I was finished this script but suddenly adding ONE more for loop broke every single indexOf, I tried to create checks so the console wouldn't freak out, but sadly no success. using a static value for "z" or LevelCheck allows for all the indexOfs to work properly but as soon as a for loop is involved, it seems none of the indexOfs wishes to work
<script type="text/javascript">
var tempval = new Array();
function Renew(){ //Reset tempval back to val
for(d=0;d<val.length;d++){
tempval[d] = val[d];
}
}
function UpdateLoop(){
Renew();
var Levels = document.getElementById("Lvl");
if(Levels){
for(z=0; z<=Levels.value; z++){
Update(z);
}
}
}
function Update(LevelCheck){
for (i=0; i<=key.length; i++){
if(key[i] != null){
if ( key[i].indexOf("rate") > -1 ) { //Search through
for (r=0; r<=key.length; r++){
if(key[i].indexOf(key[r]) > -1){ //Finds out which form it should replace
var raw=tempval[i];
for (y=0; y<=key.length; y++){
if(key[i] != "movespeed" && key[i] != "Movrate"){ //add a check to see if string is not there
var item = document.getElementById(key[y]);
if (item) { //Make it use formula value and then put that result into a value and loop back into function until level reached. If level changed to a lower number, reset to original value and repeat
//raw=raw.replace(key[y],document.getElementById(key[y]).value); //replace this with val[y]
raw=raw.replace(key[y],tempval[y]);
}
}
else
break;
}
if(raw != null){
if(raw.indexOf("Mov") > -1){
for(x=0; x<=key.length; x++){
if(key[x].indexOf("movespeed") > -1){
//raw=raw.replace("Mov",document.getElementById(key[x]).value);
raw=raw.replace("Mov",tempval[x]);
break;
}
}
}
if(raw.indexOf("Lvl") > -1){
raw=raw.replace("Lvl",document.getElementById('Lvl').value);
}
if(raw.indexOf("Exp") > -1){
raw=raw.replace("Exp","0");
}
}
if( document.getElementById('Lvl').value == LevelCheck){
alert("Input:"+tempval[i]);
if(key[i] == "Movrate"){
document.getElementById("movespeed").value = eval(raw);
}
else{
var check = document.getElementById(key[r]);
if (check){
document.getElementById(key[r]).value = eval(raw);
}
}
}
else{
tempval[r] = eval(raw);
}
break; //So it doesn't keep searching
}
}
}
}
}
}
</script>
Html portion(This is generated via php so I just used what the browser generated)
<table>
<tbody>
<tr>
<td>Creature Name:</td>
<td>
<input type="Text" name="CName" value="Thing" size="10%">
</td>
</tr>
<tr>
<td>Level:</td>
<td>
<input type="Text" id="Lvl" name="level" onchange="" value="1" size="10%">
</td>
</tr>
<tr>
<td>movespeed:</td>
<td>
<input type="Text" name="movespeed" id="movespeed" value="1" size="10%">
</td>
</tr>
<tr>
<td>str:</td>
<td>
<input type="Text" name="str" id="str" value="4" size="10%">
</td>
</tr>
<tr>
<td>dex:</td>
<td>
<input type="Text" name="dex" id="dex" value="3" size="10%">
</td>
</tr>
<tr>
<td>int:</td>
<td>
<input type="Text" name="int" id="int" value="1" size="10%">
</td>
</tr>
<tr>
<td>will:</td>
<td>
<input type="Text" name="will" id="will" value="2" size="10%">
</td>
</tr>
<script type="text/javascript">
var key=new Array();
var val=new Array();
key.push("movespeed");
val.push("1");
key.push("str");
val.push("4");
key.push("dex");
val.push("3");
key.push("int");
val.push("1");
key.push("will");
val.push("2");
key.push("Movrate");
val.push("Mov+1");
key.push("strrate");
val.push("1+str");
key.push("dexrate");
val.push("1+dex+(str/4)");
key.push("intrate");
val.push("1+int");
key.push("willrate");
val.push("1+will");
</script>
<tr>
<td>
<input type="button" name="button" value="Use Formula" onclick="UpdateLoop();">
</td>
<td>
<input type="submit" value="Save">
</td>
Console:
Uncaught TypeError: Object 2 has no method 'indexOf' Monsters.php:62
Update Monsters.php:62
UpdateLoop Monsters.php:39
onclick Monsters.php:28

you need to change your Update function to the following:
function UpdateLoop(){
var Levels = document.getElementById("Lvl");
if(Levels){
for(z=0; z<=Levels.value; z++){
Renew();
Update(z);
}
}
}
After processing Level 0, the tempval array had the values from Level 0, which wiped out the original values from the val array.
Making this change fixed the problem in my tests: http://jsfiddle.net/jimmym715/xTUND/
oh, and what MaxArt said in the comments above is right on the money... there are far better ways to accomplish what you're going for here

Turns out that flat numbers are NOT strings so in order to safely go through every value .toString() had to be present, thanks everyone for trying though.
so it would look like:
key[i].toString().indexOf(key[r])

Related

How to calculate to variable in javascript and print them in the html page

I try to get result from html table witch excepted only numbers i check them throw if statement if variable 1 bigger than variable 2 print content and that works good.
Now i am trying in the if statement to print variable 1 - variable 2 but it doesn't wanna work.
Here is the snippet:
$(document).ready(function() {
var vastInkomen = 0;
$('.txtBox').keyup(function() {
vastInkomen = 0;
$('.txtBox').each(function() {
var txtBoxVal = $(this).val();
vastInkomen += Number(txtBoxVal);
});
$('#vastInkomen').val(vastInkomen);
writeResult();
});
var vastLasten = 0;
$('.vast_lasten').keyup(function() {
vastLasten = 0;
$('.vast_lasten').each(function() {
var vastLastenVal = $(this).val();
vastLasten += Number(vastLastenVal);
});
$('#vastLasten').val(vastLasten);
writeResult();
});
function writeResult() {
if (vastInkomen !== 0 && vastLasten !== 0) {
if (vastInkomen > vastLasten) {
$('#result').text("Some text and work good!") +
vastLasten - vastInkomen;
} else if (vastInkomen < vastLasten) {
//$('#result-amount').console(vastInkomen -vastLasten);
$('#result').text("some text and work good.");
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>content1</td>
<td><input class="txtBox" type="number" name="content2" />
</td>
</tr>
<tr>
<td>content3</td>
<td><input class="txtBox" type="number" name="content3" />
</td>
</tr>
<tr>
<td>content4</td>
<td>
<input class="txtBox" type="number" name="content4" />
</td>
</tr>
</table>
<table>
<tr>
<td>content</td>
<td><input class="vast_lasten" type="number" name="content" /></td>
</tr>
<tr>
<td>content1</td>
<td><input class="vast_lasten" type="number" name="content1" /></td>
</tr>
<tr>
<td>content2</td>
<td><input class="vast_lasten" type="texnumber" name="content2" /></td>
</tr>
</table>
<div class="col">
<h3>Het resultaat is:</h3>
<p id="result"></p>
</div>
This will work:
var result = vastLasten - vastInkomen;
$('#result').text("Some text and work good!" + result);
You can use .text() to set the content of an element, but everything should be within the parenthesis.
I added an extra variable result because you cannot use + and - both here; it will result in NaN as it will try to sum the values.
This works as well:
$('#result').text("Some text and work good!" + (vastLasten - vastInkomen));

Traversing through a table with javascript to compare with row values

my table looks like this.
<body>
<table class="tblTest">
<tr>
<td>
<label>wer</label></td>
<td>
<label>ur4</label></td>
<td>
<label>ksdj</label></td>
</tr>
<tr>
<td>
<label>eiejr</label></td>
<td>
<label>ur4</label></td>
<td>
<label>yutu56</label></td>
</tr>
<tr>
<td>
<input type="text" /></td>
<td>
<input type="text" /></td>
<td>
<input type="text" />
</td>
</tr>
<tr>
<td>
<label>jweee</label>
</td>
<td>
<label>male</label>
</td>
<td>
<label>ur4</label>
</td>
</tr>
<tr>
<td>
<label>ssssss</label>
</td>
<td>
<label>male</label>
</td>
<td>
<label>ur4s</label></td>
</tr>
<tr>
<td>
<input type="text" /></td>
<td>
<input type="radio" name="gender" value="male" />Male
<br />
<input type="radio" name="gender" value="female" />Female
</td>
<td>
<select name="cars" style="width: 128px">
<option selected="selected" value="Select">Select</option>
<option value="saab">BMW</option>
<option value="fiat">Fiat</option>
<option value="audi">Audi</option>
</select>
</td>
</tr>
</table> <br />
<button type="button" onclick="function1()">Submit</button>
I want a Java script/jQuery which will check the two labels and if there is a mismatch then it will make the Text Box Red and if not then green. I can't use getElementById for the labels only I have to traverse through it and get the td index and do the task. I Don't know how to get prev and closest elements. Please help me with this.
The function which I'm trying is
function function1() {
var inputcontrols = document.getElementsByTagName('input');
for (var i = 0; i < inputcontrols.length; ++i)
{
var element = inputcontrols[i];
//element.style.background = "#90EE90"; by default making it green
var ind = $(this).closest('td').prev('td').text();
alert(ind);
}
Trying to get the td text in "ind", but its returning empty.
First get all the inputs, and use the each loop to iterate these. And by using the index to get the appropriate label texts.
The reason text() did not work for you, is because you are trying to get the text from the td element. This is empty, because it only contains a HTMLElement label. Look at the jQuery specs to see the difference between text() and html()
function function1() {
$('table').each(function(n, table) {
$(table).find('tr').each(function(n, tr) {
tr = $(tr);
var td = undefined;
var c = 0;
tr.find('input,select').each(function(i, input) {
if(!td || !td.is($(input).closest('td'))) {
td = $(input).closest('td');
c++;
}
var lbl1 = $(tr.prev().prev().find('td')[c]).find('label').text();
var lbl2 = $(tr.prev().find('td')[c]).find('label').text();
if(lbl1 === lbl2) {
$(input).css('backgroundColor', 'green');
} else {
$(input).css('backgroundColor', 'red');
}
});
});
});
}
The first problem I see is that you're using $(this) which is what how you chain the function scope in jQuery. For example:
$('a').each(function() {
// 'this' scopes to the current 'a' element inside the 'each' loop
$(this).css('color', '#FF0000');
});
Since you've already found your input controls and stored them in var element you need to pass that element into jQuery so it knows what you're looking for.
var element = inputcontrols[i];
$(element).closest('td').prev('td').text();
Next, if you're trying to compare the text field to the previous label you need to fix your traversal steps to be:
From the text field
Find its parent tr not td (go up to the row)
Find its the previous tr (go back a row)
Find its child label (drill down into the previous row)
Get the text from the label
assuming that you only have two table rows, you can try this-
function function1() {
var inputs = $('.tblTest input');
var tr1 = $('.tblTest tr:nth(0)');
var tr2 = $('.tblTest tr:nth(1)');
for (var i = 0; i < inputs.length; ++i)
{
var element = inputcontrols[i];
if(tr1.find('td:nth('+ i +') label').html().trim() == tr2.find('td:nth('+ i +') label').html().trim()) {
element.style.background = "green";
}
else {
element.style.background = "red";
}
}
}

Get the value of: e.target.parentElement.parentElement.childNodes[1]

I have this element in the DOM, which I can read by using this:
e.target.parentElement.parentElement.childNodes[1]
It renders as this (in the console):
e.target.parentElement.parentElement.childNodes[1]
<td>​
"
1
"
<input length=​"9" data-val=​"true" data-val-number=​"The field TarriffID must be a number." data-val-required=​"The TarriffID field is required." id=​"TarriffID" name=​"TarriffID" type=​"hidden" value=​"44">​
</td>​
This is the Markup for it:
<tbody id="TarriffsGrid">
#if (Model.ContractTarriffsList.Count != 0)
{
foreach (var tarriff in Model.ContractTarriffsList)
{
var count = 1;
<tr>
<td>
#(count.ToString(CultureInfo.InvariantCulture))
#Html.Hidden("TarriffID", tarriff.TarriffID.ToString(CultureInfo.InvariantCulture), "TarriffID")
</td>
<td>
#(Math.Round(tarriff.ExcessValue, 2))
</td>
<td>
#(Math.Round(tarriff.Rate, 2))
</td>
<td>
<input type="radio" name="radioInput" id="radioInput" class="tarriffRadioButton" />
</td>
</tr>
count++;
}
}
</tbody>
I would like to get the value of (44), but this is not happening with any of the following variations:
e.target.parentElement.parentElement.childNodes[1].val();
e.target.parentElement.parentElement.childNodes[1].val;
e.target.parentElement.parentElement.childNodes[1].value;
e.target.parentElement.parentElement.childNodes[1].value();
e.target.parentElement.parentElement.childNodes[1].text;
e.target.parentElement.parentElement.childNodes[1].innerText;
...etc.
What could possibly be the solution here please?
Solved with this:
var tarriffID = e.target.parentElement.parentElement.childNodes[1].firstChild.value;
Many thanks.
Edit
It was actually this (one step deeper):
e.target.parentElement.parentElement.childNodes[1].childNodes[1].value;

OCR Web Validation using Javascript

I am a Computing teacher trying to stay one step ahead of my pupils whom are working on a assessment to with validating web forms using HTML and JavaScript. So far, I have managed to do the following but can no longer move forward:
<head>
<title>Exam entry</title>
<script language="javascript" type="text/javascript">
function validateForm() {
var result = true;
var msg="";
if (document.ExamEntry.name.value=="") {
msg+='You must enter your name';
document.ExamEntry.name.focus();
document.getElementById("name").style.color="#FF0000";
result = false;
}
if (document.ExamEntry.subject.value=="") {
msg+=' You must enter the subject';
document.ExamEntry.subject.focus();
document.getElementById("subject").style.color="#FF0000";
result = false;
}
if (document.ExamEntry.examnumber.value=="") {
msg+=' You must enter the examination number';
document.ExamEntry.examnumber.focus();
document.getElementById("examnumber").style.color="#FF0000";
result = false;
}
if(document.getElementById("examnumber").value.length!=4)
{
msg+='You must have exactly 4 digits in the examination number textbox';
document.ExamEntry.examnumber.focus();
document.getElementById("examnumber").style.color="#FF0000"
result = false;
}
function checkRadio() {
var user_input = "";
var len = document.ExamEntry.entry.length;
var i;
for (i=0;i< len;i++) {
if (document.ExamEntry.entry[i].length.checked) {
user_input = document.ExamEntry.entry[i].value;
break;
}
}
if (msg==""){
return result;
}
else
{
alert(msg);
return result;
}
}
function resetForm()
{
document.getElementById('ExamEntry').reset();
document.getElementById("name").style.color="#000000";
document.getElementById("subject").style.color="#000000";
document.getElementById("examnumber").style.color="#000000";
}
</script>
</head>
<body>
<h1>Exam Entry Form</h1>
<form name='ExamEntry' method='post' action='success.html'>
<table width='50%' border='0'>
<tr>
<td id='name'>Name</td>
<td><input type='text' name='name' /></td>
</tr>
<tr>
<td id='subject'>Subject</td>
<td><input type='text' name='subject' /></td>
</tr>
<tr>
<td id='examnumber'>Examination Number</td>
<td><input type='text' name='examnumber'></td>
</tr>
<tr>
<td id='entry'>Level of Entry</td>
<td><input type='radio' name='entry' value='gcse'>GCSE<BR></td>
<td><input type='radio' name='entry' value='as'>AS<BR></td>
<td><input type='radio' name='entry' value='a2'>A2<BR></td>
</tr>
<tr>
<td><input type='submit' name='Submit' value='Submit' onclick='return (validateForm());'></td>
<td><input type='reset' name='Reset' value='Reset' onclick=' (resetForm());'></td>
</tr>
</table>
</form>
</body>
What I want to do and what I am trying to do are two different things and it's now hit the point where I am banging my head against a brick wall.
What I WANT to do is be able to:
Extend the Javascript code to make sure that the user’s examination number is exactly 4 digits.
Add a set of radio buttons to the form to accept a level of entry such as GCSE, AS or A2. Write a function that displays the level of entry to the user in an alert box so that the level can be confirmed or rejected.
Can anyone help me before I totally lose the plot?
It's been a long time I have tried pure JS. It's a pleasure to try it out anytime though. So, someone's lukcy and I had some free time. I am a very tiny bit OCD when it comes to coding and I ended up cleaning a lot of your code, such as
Always enclose HTML attributes in double quotes - not a hard rule though.
Always close the input attributes - /> - not a hard rule though.
Define your elements and resue where needed in JS
Alwayst try and keep your JS separate from HTML - it's a good practice.
And follow the good old basics
As a result, here we go:
Demo: Fiddle
HTML:
<h1>Exam Entry Form</h1>
<form name="ExamEntry" method="post" action="#">
<table width="50%" border="0">
<tr>
<td id="name">Name</td>
<td><input type="text" name="name" /></td>
</tr>
<tr>
<td id="subject">Subject</td>
<td><input type="text" name="subject" /></td>
</tr>
<tr>
<td id="examnumber">Examination Number</td>
<td><input type="text" name="examnumber" /></td>
</tr>
<tr>
<td id="entry">Level of Entry</td>
<td><input type="radio" name="entry" value="gcse" />GCSE<BR></td>
<td><input type="radio" name="entry" value="as" />AS<BR></td>
<td><input type="radio" name="entry" value="a2" />A2<BR></td>
</tr>
<tr>
<td><input type="submit" name="Submit" value="Submit" /></td>
<td><input type="reset" name="Reset" value="Reset" onclick="resetForm();"></td>
</tr>
</table>
</form>
JS:
var form = document.forms['ExamEntry'];
var iName = form.elements['name'];
var iSubject = form.elements['subject'];
var iExamNumber = form.elements['examnumber'];
var iLevel = form.elements['entry'];
function validateForm() {
var result = true;
var msg = "";
if (iName.value=="") {
msg+='You must enter your name';
iName.focus();
iName.style.color="#FF0000";
result = false;
} else if (iSubject.value=="") {
msg+=' You must enter the subject';
iSubject.focus();
iSubject.style.color="#FF0000";
result = false;
} else if (iExamNumber.value=="" || !/^\d{4}$/.test(iExamNumber.value)) {
msg+=' You must enter a valid examination number';
iExamNumber.focus();
iExamNumber.style.color="#FF0000";
result = false;
} else if(!checkEntry()) {
msg+=' You must select a level';
result = false;
} else {
var cfm = confirm("You have selected " + checkEntry() + ". Are you sure to punish yourself?");
if (!cfm) {
result = false;
}
}
if (!result && msg != "") alert (msg);
return result;
}
function checkEntry() {
for (var i=0; i<iLevel.length; i++) {
if (iLevel[i].checked) {
return iLevel[i].value.toUpperCase();
}
}
return false;
}
function resetForm() {
form.reset();
iName.style.color="#000000";
iSubject.style.color="#000000";
iExamNumber.style.color="#000000";
}
form.onsubmit = validateForm;
form.onreset = resetForm;
First you added the function checkRadio inside of function validateForm
Also, this line
if(document.getElementById("examnumber").value.length!=4)
actually points to this piece of html
<td id='examnumber'>Examination Number</td>
The td element can't hold values... You need to change the line to this:
if (document.ExamEntry.examnumber.value.length!=4) {
This jsfiddle should help you out...

Can't delete first row

<table id="tableID">
<tr>
<th>Attr</th>
<th>Val</th>
</tr>
<td>
<input type="checkbox" name="firstChk" />
</td>
<td>
<input type="text" name="firstAttr" />
</td>
<td>
<input type="text" name="firstVal" />
</td>
</table>
<input type="button" value="Add A Row" onclick="javascript: addARow('tableID')" />
<input type="button" value="Delete" onclick="javascript: deleteARow('tableID')" />
This separate js file gets called:
function deleteARow(tID) {
try {
var tableObj = document.getElementById(tID);
var numRows = tableObj.rows.length;
// starts at 1 because never delete row that holds table headers
for(var index=1; index < numRows; index++) {
var rowObj = tableObj.rows[index];
// rowObj.cells[0] gives the td, then childNodes[0] gives checkbox element
var chkboxObj = rowObj.cells[0].childNodes[0];
if(null != chkboxObj && true == chkboxObj.checked) {
tableObj.deleteRow(index);
/* next 2 lines are necessary because DOM's tr indices shift back
* with a deletion
*/
numRows--;
index--;
}
} // end for
} // end try
catch(e) {
alert(e);
}
} // end function
This code can delete any row and any number of rows after clicking the "Delete" button EXCEPT for the first row that has a checkbox(the one whose xpath is //table/tr[1]). I've traced through the code by hand multple times and have been unable to debug it, so I've posted the code with my comments.
What's wrong with the code? I wish I could figure out how to use the js debugger in firebug :(
There were a few issues with your code.
First, the markup for your table was malformed. You have td's without parent tr's.
Second, the logic that you used to get the checkbox object was not returning the checkbox. So, when you hit your if statement, chkboxObj.checked returned undefined.
Here's the updated/working code:
HTML
<table id="tableID">
<tr>
<th>Attr</th>
<th>Val</th>
</tr>
<tr>
<td>
<input type="checkbox" name="firstChk" />
</td>
<td>
<input type="text" name="firstAttr" />
</td>
<td>
<input type="text" name="firstVal" />
</td>
</tr>
</table>
<input type="button" value="Add A Row" onclick="addARow('tableID')" />
<input type="button" value="Delete" onclick="deleteARow('tableID')" />
JavaScript
function deleteARow(tID) {
try {
var tableObj = document.getElementById(tID);
var numRows = tableObj.rows.length;
// starts at 1 because never delete row that holds table headers
for (var index = 1; index < numRows; index++) {
var rowObj = tableObj.rows[index];
// rowObj.cells[0] gives the td, then childNodes[0] gives checkbox element
// This was not returning the checkbox element. See updated code:
// Get first input in row - this will be the checkbox
var chkboxObj = rowObj.cells[0].getElementsByTagName("input")[0];
if (chkboxObj != null && chkboxObj.checked == true) {
tableObj.deleteRow(index);
/* next 2 lines are necessary because DOM's tr indices shift back
* with a deletion
*/
numRows--;
index--;
}
} // end for
} // end try
catch (e) {
alert(e);
}
} // end function
Also, here's a working fiddle.

Categories