Javascript - Insert code segments at multiple locations - javascript

What I like to do is: If any of the 3 optional fields is filled out, a chunk of code(row) will be inserted into the source code(table) and then the entire code will be outputted.
My issue right now is: If more than one of the fields is entered, only the last input is inserted. I need all of them inserted. I suspect that the "code =" statement needs to be changed/relocated but not sure how to go about it. I'm a beginner in javascript, so please keep your answers as basic as you can. Thank you!!
html:
<input id="input1" onChange="update()">
<input id="input2" onChange="update()">
<input id="input3" onChange="update()">
javascript:
var source = '<table><!--PlaceHolder1--><!--PlaceHolder2--><!--PlaceHolder3--></table>';
var insert = '<tr><td>InsertText</td></tr>';
function update(){
if(document.getElementById("input1").value != ""){
var x = document.getElementById("input1").value;
var y = insert.replace("InsertText", x );
code = source.replace("<!--PlaceHolder1-->", y );
}
if(document.getElementById("input2").value != ""){
var x = document.getElementById("input2").value;
var y = insert.replace("InsertText", x );
code = source.replace("<!--PlaceHolder2-->", y );
}
if(document.getElementById("input3").value != ""){
var x = document.getElementById("input3").value;
var y = insert.replace("InsertText", x );
code = source.replace("<!--PlaceHolder3-->", y );
}
}
document.write(code);

It looks like you're losing the result of the first replace, which is in the variable "code" because you're overwriting it with the contents of "source" on subsequent replaces.
Instead of this:
code = source.replace("<!--PlaceHolder2-->", y );
Try this:
code = code.replace("<!--PlaceHolder2-->", y );
And I think you'll get what you're expecting.

Part of the problem is that you're trying to do this with string replacement. You should be using proper DOM manipulation. This will also allow you to clean up your code a lot:
window.onload = function() {
function update(e) {
var target = e.target,
num = target.getAttribute("data-num"),
td = document.querySelectorAll("#theTable td")[num - 1];
td.textContent = target.value;
td.parentNode.style.display = "table-row";
}
for (var i = 1; i <= 3; i += 1) {
document.getElementById("input" + i).onchange = update;
}
}
#theTable tr {
display: none;
}
<input id="input1" data-num="1">
<input id="input2" data-num="2">
<input id="input3" data-num="3">
<table id="theTable">
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
<tr>
<td></td>
</tr>
</table>

Related

Exclude certain rows while calculating the minimum value

I have the following table and I need to find the minimum value in that column.
In this case the value is 20.
However, I need to exclude the last 2 part names and use the rest of the values in the cell to calculate the minimum. In that case the minimum value should be 100.
Here is the code i have for calculating the minimum:
function getMin() {
var maximum = 0;
jQuery(".used").each(function() {
$used= jQuery(this).val();
var usedValue = $used.replace(/,/g, "");
value = parseFloat(usedValue);
maximum = (value > maximum) ? value : maximum;
});
var min = maximum;
jQuery(".used").each(function() {
$used = jQuery(this).val();
var usedValue = $used.replace(/,/g, "");
value = parseFloat(usedValue);
min = (value < min) ? value : min;
});
jQuery(".minimum").val(min);
}
<div><input type="text" class="minimum" name="minimum" id="minimum" value="" size="5" onchange="getMin();" readonly>cycles</div>
I couldn't find a way to exclude the last 2 values here. The number of rows can also differ and is not fixed so I need to exclude it based on those 2 string values. Any help is appreciated!! Thank you in advance!
Here is a quick and dirty solution. Loop through the parent object of each row, and ignore the value of used if the label (text) is one of those strings.
I also updated the minimum function to use the math.min on an array of values.
function getMin() {
let vals = [];
$(".row").each(function() {
if ($(this).find("label").html() != "Ignore") {
$used = $(this).find(".used").val();
var usedValue = $used.replace(/,/g, "");
vals.push(parseFloat(usedValue));
}
});
let min = Math.min(...vals);
$(".minimum").val(min);
}
getMin();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="row">
<label>Ignore</label>
<input type="text" class="used" value=41>
</div>
<div class="row">
<label>Keep</label>
<input type="text" class="used" value=222>
</div>
<div class="row">
<label>Keep</label>
<input type="text" class="used" value=200>
</div>
<div><input type="text" class="minimum" name="minimum" id="minimum" value="" size="5" onchange="" readonly>cycles</div>
I would mark these different rows in HTML somehow, let's say with excluded class. Hardcoding the labels in JavaScript asks for trouble.
Here's an example, using excluded class for these two last <tr>:
const min = Math.min(...$(':not(.excluded) .used').map(function () {
return Number($(this).val());
}).get());
You could do it like this: Exclude in your each() function every <tr> that has a first column that contains any of the 2 strings you want to exclude:
function getMin() {
var maximum = 0;
jQuery(".used").each(function() {
$used = jQuery(this).val();
var usedValue = $used.replace(/,/g, "");
value = parseFloat(usedValue);
maximum = (value > maximum) ? value : maximum;
});
var min = maximum;
jQuery("tr").each(function() {
var check = jQuery(this).find("td:nth-child(1)").text();
if (!check.includes("Fan Blade") && !check.includes("Annulus Filler"))
{
$used = jQuery(this).val();
var usedValue = $used.replace(/,/g, "");
value = parseFloat(usedValue);
min = (value < min) ? value : min;
}
});
jQuery(".minimum").val(min);
}
getMin();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td></td>
<td></td>
<td><input class="used" value="100" /></td>
</tr>
<tr>
<td>Fan Blade (26 off)</td>
<td></td>
<td><input class="used" value="50" /></td>
</tr>
<tr>
<td>Annulus Filler (26 off)</td>
<td></td>
<td><input class="used" value="50" /></td>
</tr>
</table>
<div><input type="text" class="minimum" name="minimum" id="minimum" value="" size="5" onchange="getMin();" readonly>cycles</div>

If the input I put blank, then it will count 0

I am trying to put some amount, then it will show the calculation if all input will given any number, but I want, when I do not put anything in any one of that input, then the input will count "0" automatically..
<body>
<input type='text' id='aaa'/>
<input type='text' id='bbb'/>
<input type='text' id='ccc'/>
<input type='text' id='answer' name='ans' />
<form name ="testarea" Method="GET" Action="" id='form1'>
<input type="button" onClick="Calculate();" value="calculate"/>
</form>
</body>
<script>
function Calculate()
{
var aaa= document.getElementById('aaa').value;
var bbb= document.getElementById('bbb').value;
var ccc= document.getElementById('ccc').value;
var permin = parseFloat(aaa) * 82;
var permin1 = parseFloat(bbb) * 40;
var permin2 = parseFloat(ccc) * 10;
var permin3=permin+permin1+permin2;
document.getElementById('answer').value=permin3;
document.form1.submit();
}
</script>
var aaa= document.getElementById('aaa').value;
var bbb= document.getElementById('bbb').value;
var ccc= document.getElementById('ccc').value;
var permin = (parseFloat(aaa)||0) * 82;
var permin1 = (parseFloat(bbb)||0) * 40;
var permin2 = (parseFloat(ccc)||0) * 10;
var permin3=permin+permin1+permin2;
document.getElementById('answer').value=permin3;
You can use the OR operator to replace NaN with 0 if parseFloat returns NaN.
You could shorten the upper code to:
const ids = ["aaa","bbb","ccc"];
const factors = [82,40,10];
document.getElementById("answer").value = ids.reduce((count,id,index) => {
const { value } = document.getElementById(id);
return count + (parseFloat(value) || 0) * factors[index];
}, 0);
An alternative you can do is use a default parameter for your function.
Your calculate would look something like this:
Calculate(aaa=0, bbb, ccc) {
And this question covers how to pass html elements as parameters for functions.
Instead of using an if/else construct you can rely on the falsy value of an empty string.
Therefore you can initialize all your variables like this:
var aaa = document.getElementById('aaa').value || '0';
More information on falsy values can be found on the MDN.

Javascript - SetTimeout causes Browser to freeze

The problem I'm currently running into is the following:
I have a table containing of two rows. The first row contains the letters of a given word in alphabetical order. The second row is empty at the start. Every second, one letter from the first row shall be moved to the correct position. This works correctly for the first 5 letters, but then nothing happens anymore and after a short time, the browser freezes and I get a prompt, asking to stop the skript or to keep it running.
Here's my code
test.html:
<!DOCTYPE html>
<html>
<head>
<script src=".\test.js"></script>
</head>
<body>
<div onclick="m_show_letter_example()">
<table>
<tr>
<td><input id="example_01" name="example_alphabet_01" type="text" value="A"/></td>
<td><input id="example_02" name="example_alphabet_02" type="text" value="E"/></td>
<td><input id="example_03" name="example_alphabet_03" type="text" value="E"/></td>
<td><input id="example_04" name="example_alphabet_04" type="text" value="L"/></td>
<td><input id="example_05" name="example_alphabet_05" type="text" value="M"/></td>
<td><input id="example_06" name="example_alphabet_06" type="text" value="P"/></td>
<td><input id="example_07" name="example_alphabet_07" type="text" value="S"/></td>
<td><input id="example_08" name="example_alphabet_08" type="text" value="X"/></td>
</tr>
<tr>
<td><input id="example_solution_02" name="example_solution_02" type="text"/></td>
<td><input id="example_solution_08" name="example_solution_08" type="text"/></td>
<td><input id="example_solution_01" name="example_solution_01" type="text"/></td>
<td><input id="example_solution_05" name="example_solution_05" type="text"/></td>
<td><input id="example_solution_06" name="example_solution_06" type="text"/></td>
<td><input id="example_solution_04" name="example_solution_04" type="text"/></td>
<td><input id="example_solution_03" name="example_solution_03" type="text"/></td>
<td><input id="example_solution_07" name="example_solution_07" type="text"/></td>
</tr>
</table>
</div>
</body>
And the javascript file:
test.js
var timeout = null;
function m_show_letter_example()
{
timeout = setTimeout(function()
{
var inputs = document.getElementsByTagName('input');
var unplaced_letters = [];
for (var input_index = 0; input_index < inputs.length; ++input_index)
{
if (inputs[input_index].name.indexOf('example_alphabet_') == 0) {
unplaced_letters.push(inputs[input_index]);
}
}
var random_index = 0;
var field = document.getElementsByName('example_alphabet_0' + random_index);
while (document.getElementsByName('example_alphabet_0' + random_index).length == 0 )
{
random_index = Math.floor( (Math.random() * unplaced_letters.length) + 1);
}
var letter = document.getElementById('example_0' + random_index);
var solution = document.getElementById('example_solution_0' + random_index);
solution.value = letter.value;
letter.value = "";
letter.name = "used";
m_show_letter_example();
}, 1000);
}
I would be happy to hear any insights on why this is happening and how to solve this.
In case it matters, I have tested this in Firefox and Chrome.
Thanks in advance
Edit: added test.js
The issue is because of the random number selecting in while loop.
When there are 3 values this loop is going into infinite loop.
I have made few changes in script file and also add a data-index attribute to every example_alphabet_ input tag.
var timeout = null;
function m_show_letter_example()
{
timeout = setTimeout(function()
{
var unplaced_letters = document.querySelectorAll("input[name^='example_alphabet_']");
var unplaced_index = []
for (var input_index = 0; input_index < unplaced_letters.length; ++input_index)
{
unplaced_index.push(unplaced_letters[input_index].getAttribute('data-index'));
}
var random_index = 0;
var field = document.getElementsByName('example_alphabet_0' + random_index);
while (document.getElementsByName('example_alphabet_0' + random_index).length == 0 )
{
random_index = unplaced_index[Math.floor( (Math.random() * unplaced_index.length))];
}
var letter = document.getElementById('example_0' + random_index);
var solution = document.getElementById('example_solution_0' + random_index);
solution.value = letter.value;
letter.value = "";
letter.name = "used";
m_show_letter_example();
}, 1000);
}
Hope this helps you in resolving the problem.
the problem is right here:
while (document.getElementsByName('example_alphabet_0' + random_index).length == 0 )
{
random_index = Math.floor( (Math.random() * unplaced_letters.length) + 1);
}
when this condition is true
document.getElementsByName('example_alphabet_0' + random_index).length == 0
and the length returned is always 0 the while loop will run indefinitely as there is no condition to stop it. An unending while loop will always freeze your browser.

Validating the age in a form and not getting output, not sure what's incorrect

So I'm making a form which accepts a name, an age, and an Identification Card number.
The format of the IC number is yymmdd-xx-xxxx where the first four numbers are the D.O.B. of the person. The last four numbers are a unique code of the IC and the two numbers in between are state codes for where the person is born in. What I want to do is to take the first two numbers of the IC number (year person is born in), and deduct it with the current year, and compare that to the age the person gave and the output would say that the age is correct or incorrect.
Here is what I have tried so far.
function valForm() {
function valName() {
var regexName = /^[a-zA-Z]*$/;
if (regexName.test(document.ageVal.name.value)) {
return true;
} else {
return false;
}
}
function valIc() {
var regexIc = /^\d{6}-\d{2}-\d{4}$/;
if (regexIc.test(document.ageVal.icNum.value)) {
return true;
} else {
return false;
}
}
if (!valName()) {
alert("Enter a name using only alphabets");
document.ageVal.name.focus();
document.getElementById("notifName").innerHTML = "Alphabets only";
}
if (!valIc()) {
alert("Correct format is xxxxxx-xx-xxxx");
document.ageVal.icNum.focus();
document.getElementById("notifIc").innerHTML = "Not the correct format";
}
var today = new Date();
var year = today.getFullYear();
var yr = document.getElementById("icNum");
var yrIc = parseInt(yr, 10);
while (yrIc >= 100)
yrIc = Math.floor(yrIc / 10);
fullyrIc = 1900 + yrIc;
var actAge = year - fullyrIc;
var givnAge = document.getElementById("age");
if (actAge == givnAge)
document.getElementById("output").innerHTML = "Age is correct";
else
document.getElementById("output").innerHTML = "Age is not correct";
}
<form name="ageVal" action="javascript:valForm()">
<table border="solid" width="25%">
<tr>
<td>Name: </td>
<td colspan=2>
<input type="text" name="name" id="age">
<div id="notifName"></div>
</td>
</tr>
<tr>
<td>Age: </td>
<td colspan=2>
<input type="number" name="age" id="age">
<div id="notifAge"></div>
</td>
</tr>
<tr>
<td>IC: </td>
<td colspan=2>
<input type="text" name="icNum" id="icNum">
<div id="notifIc"></div>
</td>
</tr>
<tr>
<td colspan=3 align="center">
<input type="text" name="output" id="output" disabled>
</td>
</tr>
</table>
<input type="submit" form="ageVal" value="Submit">
</form>
I can't get any output after trying out a lot and making a lot of changes. I'm still new to JS and even newer to trying regex so I'm sure I'm doing a lot of things wrong here.
After some changes I can finally get an output thanks to the first two answers but the problem now is that the calculations are not correct. How should I correct it?
output id element is input element. Use value property to set value instead of innerHTML to see any output:
if (actAge == givnAge)
document.getElementById("output").value = "Age is correct";
else
document.getElementById("output").value = "Age is not correct";
JS Fiddle
In the script you are getting the element instead of the value. Change this...
var yr = document.getElementById("icNum");
var givnAge = document.getElementById("age");
Into this...
var yr = document.getElementById("icNum").value;
var givnAge = document.getElementById("age").value;
You should have no issues now. But I do not understand what you are doing from while loop. Could you explain.
Issue 1
You need to put the javascript call in onsubmit with a return:
<form name="ageVal" method="POST" action="javascript:void(0);" onsubmit="valForm()">
<!--- rest of code -->
Issue 2
You forget to add .value on document.getElementById("icNum") and on document.getElementById("age"):
var yr = document.getElementById("icNum").value;
var givnAge = document.getElementById("age").value;
You can check your code working here:
https://jsfiddle.net/4459z225/1/
For Simple Age Calculation
replace
var today = new Date();
var year = today.getFullYear();
var yr = document.getElementById("icNum");
var yrIc = parseInt(yr, 10);
while (yrIc >= 100)
yrIc = Math.floor(yrIc / 10);
fullyrIc = 1900 + yrIc;
var actAge = year - fullyrIc;
with
var regex = /^(\d{2})(\d{2})(\d{2})/;
var dob = document.getElementById("icNum").match(regex);
var dobYear = dob[1];
var dobMonth = dob[2];
var dobDate = dob[3];
var birthday = new Date(dobYear+'/'+dobMonth+'/'+dobDate);
var ageDifMs = Date.now() - birthday.getTime();
var ageDate = new Date(ageDifMs); // miliseconds from epoch
var actAge = Math.abs(ageDate.getUTCFullYear() - 1970);

Dynamic Div ID and Creating Elements Inside it

I am creating a dynamic Div where i can import values from the showModalDialog when it is closed. So after closing the modal, i get couple of values.
What i am trying to do here is:
I have couple of dynamic div's and against each div, i have a link to open a window.
After selection of the files they are return back to the parent window as comma separated.
I want to insert those values inside the div to which that popup was opened. but in this scenario i am facing the trouble. the Divid's are generated dynamically
Here is the Complete Code for Javascript + Jquery Based, I am getting the following error.
TypeError: theDiv.appendChild is not a function
[Break On This Error]
theDiv.appendChild(newNode);
<script type="text/javascript" src="JS/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
function eliminateDuplicates(arr,divID)
{
var i,
len=arr.length,
out=[],
obj={};
for (i=0;i<len;i++)
{
obj[arr[i]]=0;
}
for (i in obj)
{
out.push(i);
}
return out;
}
function GetElementsStartingWith(tagName, subString) {
var elements = document.getElementsByTagName(tagName);
var result = [];
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.id && element.id.substr(0, subString.length) == subString) {
result.push(element);
}
}
return result;
}
Test= function(str,divID)
{
var arrID = new Array();
arrID = str.split(',');
arrID = eliminateDuplicates(arrID);
var theDiv = $("#projectsList"+divID).attr('id'); //document.getElementById('projectsList');
alert(theDiv);
var cmp= $("#projectIDS"+divID).val(); //document.getElementById("projectIDS").value;
var cnp = $("#countProj"+divID);//document.getElementById("countProj")
var cproj;
if(cnp.val().length == 0)
cproj=0;
else
cproj=parseInt(cnp.val());
for (var j=0; j<arrID.length; j++)
{
if (parseInt(cproj) + 1 > 50)
{
alert("You cannot add more than 50 Project id's ");
return;
}
if( cmp!="" && cmp.indexOf(arrID[j])!=-1)
continue;
var newNode = document.createElement('div');
newNode.style.cssText = "background:#CCCCCC;border:1px solid #666666;width:100px;word-wrap:break-word;margin:3px;float:left;color:black;text-decoration:none!important;height:auto;vertical-align:middle;padding-top:2px;";
newNode.title = arrID[j]+" ";
newNode.innerHTML = '<input type=hidden name=Proj_' + j + ' ' + 'value=' + arrID[j] + '>' + arrID[j] + ' <b>X</b>';
theDiv.appendChild(newNode);
if(cmp.length == 0)
{
//document.getElementById("projectIDS").value=arrID[j]
$("#projectIDS"+divID).val(arrID[j]);
}
else
{
//document.getElementById("projectIDS").value = document.getElementById("projectIDS").value+","+arrID[j];
$("#projectIDS"+divID).val($("#projectIDS"+divID).val()+","+arrID[j]);
}
cproj = parseInt(cproj)+1;
//document.getElementById("countProj").value =cproj;
cnp.value(cproj);
}
}
removetext = function(par)
{
var strremove=par.text();
var strexist = document.getElementById("projectIDS").value;
strremove = strremove.replace(" X","");
tempRemove(strexist, strremove);
par.remove();
var cproj;
if(document.getElementById("countProj").value.length == 0)
cproj=0;
else
{cproj=parseInt(document.getElementById('countProj').value);
cproj=parseInt(cproj)-1;}
document.getElementById("countProj").value =cproj;
}
function tempRemove(strexist,strremove)
{
var b = strexist.indexOf(strremove);
var after = strexist.indexOf(",",b);
var newstrexist;
var before = strexist.lastIndexOf(",",b);
if(after!=-1)
{newstrexist=strexist.replace(strremove+',',"");}
else if(before!=-1)
{newstrexist=strexist.replace(','+strremove,"");}
else
{newstrexist= strexist.replace(strremove,"");}
document.getElementById("projectIDS").value=newstrexist;
//remove current friend
}
function openWindow(divID)
{
var lookUpAlys=window.showModalDialog("files.cfm?d=" + Math.random() + '&fileID=' + divID,window,"center=yes;dialogWidth:895px:dialogHeight:785px;status:no");
if(lookUpAlys.forename!=undefined)
{
var temp = lookUpAlys.forename;
Test(temp,divID);
}
}
</script>
</head>
<body>
<table width="100%" border="0" cellspacing="2" cellpadding="1">
<tr>
<td>Choose</td>
<td>Files</td>
<td>Action</td>
</tr>
<cfloop from="1" to="5" index="i">
<cfoutput>
<tr>
<td><input type="checkbox" name="getFile" id="getFile" value="#i#" /></td>
<td><div id="projectsList#i#" style="width:500px;height:60px;overflow-y:scroll;border:1px solid gray;"></div><input type="text" name="projectIDS#i#" id="projectIDS#i#" data-id="#i#" value="" /><input type="text" data-id="#i#" name="countProj#i#" id="countProj#i#" value="" /></td>
<td>Files</td>
</tr>
</cfoutput>
</cfloop>
</table>
</body>
</html>
so my apologies if i had entered the code incorrectly. Basically trying do it Classic Javascript Way
This does not do what I think you think it does:
var theDiv = $("#projectsList"+divID).attr('id'); //document.getElementById('projectsList');
You should do
var theDiv = $("#projectsList"+divID)[0];
to get the DOM element.
Or, for this scenario, just do
var theDiv = document.getElementById("projectsList" + divID);
Also, I'm not sure why you are mixing raw DOM operations and jQuery wrapped operations everywhere. Just stick to one of them, and be consistent.
var container = $('.itemsList');
var divSubmit = $(document.createElement('div'));
//assigning id to div
$(divSubmit).attr('id','itemTemplate');
$(divSubmit).css({"font-family":"Gotham, Helvetica Neue, Helvetica, Arial, sans-serif","position":"relative","height": "70px","clear" : "both","background-color":"#FFF","border-bottom": "0.09em solid #EBEBEB"});
//adding class to main container
$(divSubmit).addClass('itemTemplate');
//adding Child's name label and assigning id to it.
var Name = '<label class="lblName" id="lblName" for="Name">'+getName()+'</label>';
$(divSubmit).append(Name);
$(divSubmit).append(container);
Here's a sample code. first of all there is sample container called itemslist
that will contain the generated div.
divSubmit will be gernerate dynamically and append to container.
To find some div for click event. Lets say we want to get child name.
alert($($(this).find("label.lblName")).val());

Categories

Resources