I'm trying to get a JQuery function to pick up specific changes to a form and then plug the information into equations so that each section of the form has answers created for it automatically. I got the first part of it to work (Quantity for Posts) but can't get the second part to work (Quantity for Rails). If anyone can point out or explain where I went wrong and how I could fix it it would be greatly appreciated! Thanks!
Here is a JSFiddle - http://jsfiddle.net/gv0029/ncn42/1/
HTML:
<fieldset id="fence">
<div name="inputFence" class="inputFence">
<legend><strong>Fence Description</strong>
</legend>
<label>Footage:
<input name="footage_1" class="footage" />
</label>
<select name="fenceHeight_1" class="fenceHeight">
<option value="select">Select Fence Height</option>
<option value="6" id="fH6">6 Ft.</option>
<option value="8" id="fH8">8 Ft.</option>
</select>
<legend><strong>Post Type</strong>
</legend>
<label>Post Quantity:
<input name="postQuantity_1" class="postQuantity" />
</label>
<legend><strong>Rail Type</strong>
</legend>
<select name="6foc_1" class="6foc">
<option value="select">6 Ft. on Center?</option>
<option value="no">No</option>
<option value="yes">Yes</option>
</select>
<label>Quantity:
<input class="railQuantity" name="railQuantity_1" />
</label>
</fieldset>
<div>
<input type="button" id="btnAddFence" value="Add Another Fence" />
<input type="button" id="btnDelFence" value="Remove Fence" />
</div>
</form>
JS:
//Quantity for Posts
$(document.body).on('keypress keydown keyup change', '[class^="footage"] ', function () {
var footage = parseFloat($(this).val(), 10);
var total = '';
var parts = $(this).attr('name').split("_");
var fenceNumber = parts[1];
if (!isNaN(footage)) {
total = Math.ceil(footage / 7);
$(":input[name='postQuantity_" + fenceNumber + "'" + ']').val(total.toString());
} else {
$(":input[name='postQuantity_" + fenceNumber + "'" + ']').val("");
}
});
//Quantity for Rails
$(document.body).on('keypress keydown keyup change', '[class^="footage"] [class^="fenceHeight"] [class^="6foc"]', function () {
var parts = $(this).attr('name').split("_");
var fenceNumber = parts[1];
var footage = parseFloat($(":input[name='footage_" + fenceNumber + "'" + ']').val(), 10);
var fenceHeight = $(":input[name='fenceHeight_" + fenceNumber + "'" + ']').val();
var railQuantity = $(":input[name='railQuantity_" + fenceNumber + "'" + ']').val();
var total = '';
var sfoc = $(":input[name='6foc_" + fenceNumber + "'" + ']').val();
if (fenceHeight = !NaN) {
if (sfoc == "no") {
if (fenceHeight == '8') {
total = (Math.ceil(footage / 8) * 4);
}
if (fenceHeight == '6') {
total = (Math.ceil(footage / 8) * 3);
}
railQuantity.val(total);
}
if (sfoc == "yes") {
if (fenceHeight == '8') {
total = (Math.ceil(footage / 12) * 4);
railQuantity.val(total);
}
if (fenceHeight == '6') {
alert("Error: 6ft on Center cannot use 6ft posts");
railQuantity.val("ERROR");
}
}
} else {
railQuantity.val("");
}
});
//Dynamic Fence Input Fields
$('#btnAddFence').click(function () {
// create the new element via clone()
var newElem = $('.inputFence:last').clone();
// insert the new element after the last "duplicable" input field
$('.inputFence:last').after(newElem);
// enable the "remove" button
$('#btnDelFence').removeAttr('disabled');
//get the input name and split into array (assuming your clone is always last)
var parts = $('.fenceHeight:last').attr('name').split("_");
//change the second element of the array to be one higher
parts[1]++;
//join back into a string and apply to the new element
$('.fenceHeight:last').attr('name', parts.join("_"));
//do the same for other two inputs
parts = $('.postQuantity:last').attr('name').split("_");
parts[1]++;
$('.postQuantity:last').attr('name', parts.join("_"));
parts = $('.footage:last').attr('name').split("_");
parts[1]++;
$('.footage:last').attr('name', parts.join("_"));
parts = $('.6foc:last').attr('name').split("_");
parts[1]++;
$('.6foc:last').attr('name', parts.join("_"));
});
$('#btnDelFence').click(function () {
//remove the last inputFence
$('.inputFence:last').remove();
// if only one element remains, disable the "remove" button
if ($('.inputFence').length == 1) $('#btnDelFence').attr('disabled', 'disabled');
});
$('#btnDelFence').attr('disabled', 'disabled');
You had a few problems.
First was this line:
$(document.body).on('keypress keydown keyup change', '[class^="footage"] [class^="fenceHeight"] [class^="6foc"]',
You have to separate the different inputs with a comma as shown here:
$(document.body).on('keypress keydown keyup change', '[class^="footage"],[class^="fenceHeight"],[class^="6foc"]',
Second was this line:
var fenceHeight = $(":input[name='fenceHeight_" + fenceNumber + "'" + ']').val();
You're getting the value of the select, when really you want the value of the selected option:
var fenceHeight = $(":input[name='fenceHeight_" + fenceNumber + "'" + ']').find('option:selected').val();
Third was this line:
var railQuantity = $(":input[name='railQuantity_" + fenceNumber + "'" + ']').val();
You're getting the value of this line, when down in the code you're actually trying to set the value of the value. What you want is just the element. I've left the quantity in there in case you want that later, but repurposed railQuantity:
var railQuantity = $(":input[name='railQuantity_" + fenceNumber + "'" + ']');
var railQuantityval = $(":input[name='railQuantity_" + fenceNumber + "'" + ']').val();
Fourth is your if statement:
if (fenceHeight = !NaN) {
You can't really use it like that. Use this instead:
if (!isNaN(Number(fenceHeight))) {
Down in the if statement, you also could benefit from if/else statements instead of just if statements. I've changed those to reflect this.
You were also missing the railsQuantity element in your add function, which I added for you:
parts = $('.railQuantity:last').attr('name').split("_");
parts[1]++;
$('.railQuantity:last').attr('name', parts.join("_"));
Updated fiddle here.
Related
I'm working on a tool for my job to auto generate task comments to streamline agent workflow. I'm trying to use a selector to differentiate between ticket types and generate a comment string accordingly.
The problem I'm running into is I can't seem to get the page to tell the the selector has changed, and it will only give the if condition and ignore the else.
I'm certain I'm missing something simple but can't seem to figure it out.
<!DOCTYPE html>
<html>
<body>
Select Ticket Type:
<label name="ticket" id="ticket"></label>
<select name="ticket" id="ticket">
<option value="1">SMB</option>
<option value="2">Complete</option>
</select>
<input type="text" id="ticketgen" placeholder="EnterTicket number" maxlength="8">
<input type="button" id="tickgen" value="Generate">
<p id="output"></p>
</body>
<script>
const txt1 = document.getElementById('ticketgen');
const btn1 = document.getElementById('tickgen');
const out1 = document.getElementById('output');
function fun1() {
var tick = document.getElementById('ticket');
var today = new Date();
var date = (today.getMonth() + 1) + '-' + today.getDate() + '-' + today.getFullYear();
var time = today.getHours() + ':' + today.getMinutes();
var dateTime = date + ' ' + time;
setInterval(1000);
if (tick = 1) {
out1.innerHTML = "Correspondence:" + ' ' + dateTime + ' ' + txt1.value + ' ' + "SMB Correspondence";
} else {
out1.innerHTML = "Correspondence:" + ' ' + dateTime + ' ' + txt1.value + ' ' + "# attempt, contacted CX #";
}
}
btn1.addEventListener('click', fun1);
</script>
</html>
A few issues to address:
your comparison needs a double equal - ==
tick itself is just an html element, you can't compare it to a number, you need to get the currently selected index
you use id=ticket twice, so when you get the html element by that ID, it grabs the first one, which is a label.
I believe this code should fix your issues
<!DOCTYPE html>
<html>
<body>
Select Ticket Type:
<label name="ticket" id="ticket-label"></label>
<select name="ticket" id="ticket">
<option value="1">SMB</option>
<option value="2">Complete</option>
</select>
<input type="text" id="ticketgen" placeholder="EnterTicket number" maxlength="8">
<input type="button" id="tickgen" value="Generate">
<p id="output"></p>
</body>
<script>
const txt1 = document.getElementById('ticketgen');
const btn1 = document.getElementById('tickgen');
const out1 = document.getElementById('output');
function fun1() {
var tick = document.getElementById('ticket');
var today = new Date();
var date = (today.getMonth()+1)+'-'+today.getDate()+'-'+today.getFullYear();
var time = today.getHours() + ':' + today.getMinutes();
var dateTime = date+' '+time;
setInterval(1000);
if (tick.selectedIndex == 0){
out1.innerHTML = "Correspondence:"+' '+dateTime+' '+txt1.value+' '+"SMB Correspondence";
} else {
out1.innerHTML = "Correspondence:"+' '+dateTime+' '+txt1.value+' '+"# attempt, contacted CX #";
}
}
btn1.addEventListener('click',fun1);
</script>
</html>
Your value for tick would be a string and you are checking it as integer. Try by changing it to, if (tick == "1").
Label attribute id is same as of select attribute. Try by changing the label id. All HTML attributes must have unique id / name.
In Plain JavaScript, you get the selected option value as follow
var e = document.getElementById("tick");
var value = e.options[e.selectedIndex].value;
Hope this helps! :)
I have a global variable:
var x = document.getElementById("Node").value;
Where the value is determined by a text box with the ID of "Node".
I have two functions that don't same thing if creating preset notes based on values entered into text and drop downs. How do I call the above global variable into those functions and have it added to the created statement. Both functions look the same:
This works for one function but not when there is two. What I have is several text boxes and drop downs. One of those text boxes is a global value called Node. When node is filled out, I want to be able to pull that value into both functions. Here is what I have for both.
//Declare Node as a Global Variable
var x = document.getElementById("Node").value;
//Populates the Summary box
function mySummary() {
var a = document.getElementById("Field1").value;
var b = document.getElementById("Field2").value;
var c = document.getElementById("Field3").value;
var d = document.getElementById("Field4").value;
document.getElementById("Summary").innerHTML = a + " - " + b + " - " + c + " - " + x + " -" + d;
}
//Populates the Notes box
function myNotes() {
var a = document.getElementById("Field5").value;
var b = document.getElementById("Field6").value;
var c = document.getElementById("Field7").value;
var d = document.getElementById("Field8").value;
var e = document.getElementById("Field9").value;
document.getElementById("Notes").innerHTML = x + " - " + a + " / " + b + " - " + c + "% Offline - " + d + " - " + e + " - " + f;
}
The issue is that the value of X is not being pulled into both functions at the same time for the output. The output goes into a text area
If I create a local variable in each function and make the user enter the same information twice per text box it works fine, but I want them to only enter the information once and have it pulled into each text area
You can simply use:
window.x = document.getElementById("Node").value;
Try this
(function() {
var x = document.getElementById("Node").value;
document.getElementById("Node").onchange = function() {
myNode()
};
document.getElementById("mySelect1").onchange = function() {
myNotes()
};
document.getElementById("mySelect2").onclick = function() {
summary()
};
function myNode() {
x = document.getElementById("Node").value;
}
function summary() {
var a = document.getElementById("mySelect1").value;
var b = document.getElementById("mySelect2").value;
document.getElementById("5").value = a + " - " + b + " - " + x;
}
function myNotes() {
var a = document.getElementById("mySelect1").value;
var b = document.getElementById("mySelect2").value;
document.getElementById("4").value = a + " + " + b + " + " + x;
}
}
)();
Notes : <input type="text" id="4" /><br> Summary : <input type="text" id="5" /><br>
<select id="Node">
<option value="w">w
<option value="x">x
<option value="y">y
<option value="z">z
</select>
<select id="mySelect2">
<option value="a">a
<option value="b">b
<option value="c">c
<option value="d">d
</select>
<select id="mySelect1">
<option value="1">1
<option value="2">2
<option value="3">3
<option value="4">4
</select>
I am trying to write a simple tool for some folks in my workplace. I am trying to run different functions depending on option values picked from a html select element. And I am stuck... please dont laugh.Just got back into coding 3 weeks ago.how i want this to work is the user clicks to lower dropdown menu... selects an option... then is asked for adding additional input, then that with some predefined text is added to a text area.then then the menu resets. Please make answers as simple as possible.
<!-- BEGIN ROUTING DROPDOWN MENU -->
<select id="routingdropdownmenu">
<option value="">MAKE A SELECTION</option>
<option value="1">ROUTE TO STORE</option>
<option value="2">ROUTE TO WAREHOUSE...</option>
<option value="2">CANCEL SHIPPING</option>
<script>
var mytextbox = document.getElementById('REMARKSTEXTAREA');
var mydropdown = document.getElementById('routingdropdownmenu');
mydropdown.onclick = function(){
var INVOICE = prompt("WHAT IS THE INVOICE NUMBER?");
if (INVOICE != null) {
if (mydropdown = 1) {
mytextbox.value = mytextbox.value + " ROUTING INVOICE " + INVOICE + " TO STORE ";}
else
if (mydropdown = 2) {
mytextbox.value = mytextbox.value + " ROUTING INVOICE " + INVOICE + " TO WAREHOUSE ";}
else
if (mydropdown = 3) {
mytextbox.value = mytextbox.value + "CANCELLING SHIPMENT";}
this.value = "";
</script>
</select>
<!-- END ROUTING DROPDOWN MENU -->
Did you lost your element whose id is REMARKSTEXTAREA
You need bind a onchange function not onclick
You need to use mydropdown.value to get selected values
You need to use == not = to do the switches .
Html
<input id="REMARKSTEXTAREA" />
<select id="routingdropdownmenu">
<option value="">MAKE A SELECTION</option>
<option value="1">ROUTE TO STORE</option>
<option value="2">ROUTE TO WAREHOUSE...</option>
<option value="3">CANCEL SHIPPING</option>
</select>
javascript
var mytextbox = document.getElementById('REMARKSTEXTAREA');
var mydropdown = document.getElementById('routingdropdownmenu');
mydropdown.onchange = function(){
var INVOICE = prompt("WHAT IS THE INVOICE NUMBER?");
if (INVOICE != null) {
if (mydropdown.value == 1) {
mytextbox.value = mytextbox.value + " ROUTING INVOICE " + INVOICE + " TO STORE ";
}
else if (mydropdown.value == 2) {
mytextbox.value = mytextbox.value + " ROUTING INVOICE " + INVOICE + " TO WAREHOUSE ";
}
else if (mydropdown.value == 3) {
mytextbox.value = mytextbox.value + "CANCELLING SHIPMENT";
}
}
}
How useful would this really be in a real work environment if you don't know enough to do this part?
Anyways, the change event will trigger the select's event handler. Event handler will only accept an input in the text input and will prompt for one until one is entered or cancel button is clicked in which case it quits all together.
Using a switch and the selectedIndex of the select determines what is printed in the output element.
SNIPPET
var text = document.getElementById('invNum');
var menu = document.getElementById('routeMenu');
menu.addEventListener('change', function(e) {
var INVOICE = text.value;
while (INVOICE == 'undefined' || INVOICE == '' || INVOICE == null) {
if (INVOICE == null) {
return false;
} else {
INVOICE = prompt("Enter Invoice Number First");
}
}
var out = document.getElementById('out');
var opt = menu.selectedIndex;
switch (opt) {
case 1:
out.textContent = " ROUTING INVOICE " + INVOICE + " TO STORE ";
break;
case 2:
out.textContent = " ROUTING INVOICE " + INVOICE + " TO WAREHOUSE ";
break;
case 3:
out.textContent = "CANCELLING SHIPMENT";
default:
return false;
}
}, false);
<fieldset>
<legend>Route Menu</legend>
<label>Invoice Number
<input id='invNum'>
</label>
<select id="routeMenu">
<option value="">Select Option</option>
<option value="1">Route to Store</option>
<option value="2">Route to Wharehouse</option>
<option value="3">Cancel Shipping</option>
</select>
<br/>
<br/>
<output id='out'></output>
</fieldset>
PFB java script code..
the thing is im getting alert for duplicate entry. how can avoid the repeated data?
Var activityconunt =0;
if (activityconunt !== data.iRoundId) {
alert("duplicate");
$("#selectRound_Type").append("<option name='round' id=" + data.iRoundId + ">" + data.strRoundName + "</option>");
}
my output
Solution one:
Take your data and build a clean array before. Using http://api.jquery.com/jquery.inarray/
Solution two:
Check your existing options for containing values
if($("option:contains('" + data.strRoundName + "')").length == 0)
$("#selectRound_Type").append("<option name='round' id=" + data.iRoundId + ">" + data.strRoundName + "</option>");
this should do it as well and is a shorter code
also see Fiddle
Use an array to store the data and check the new value with it:
$(function () {
var items = [];
var $select = $('select');
var $input = $('input');
var $button = $('button');
// fetch current data
$select.find('option').each(function () {
items.push($(this).text());
});
$button.on('click', function () {
var value = $input.val();
var exists = ($.inArray(value, items) != -1);
if (! exists) {
items.push(value);
$('<option></option').text(value).prependTo($select);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" />
<button>Add</button>
<br />
<select style="width: 300px;">
<option>Hello</option>
</select>
Solution for preventing duplicate values and undefined value in the list
if ($("option:contains('" + data.strRoundName + "')").length == 0
&& data.strRoundName != null
&& typeof data.strRoundName != "undefined")
$("#selectRound_Type").append("<option name='round' id="
+ data.iRoundId + ">"
+ data.strRoundName + "</option>");
I try to build an register form. This register form as text box called "address1" and near it a button called "Add Address". The function of the button - it adds text box for more addresses. the button near the previous address boxes changes to "Remove" which remove the address box and the button. The problem is: I have to set the text boxes in order - 1,2,3,... - I have to change their names and id's. For example - if I remove addressbox number 4 (name, id="address4") then all the next text boxes's names and id's should decrease by 1. I try to do this in for loop. This is hard to explain so I just give you the code. Try in your VS to write for example 'document.getElementById("address"+n).' and you'll see that you even don't see in the list you get that you can write after the dot id or name or value. I realized it is because there is a variable in this is the problem I think. Now here's the code:
<html>
<head>
<title>Untitled Page</title>
<script type="text/javascript">
var n1 = 1; //counting the buttons and divs. doesn't decrease.
//In another words - it counts the number of calls to Add()
var n3 = 1; //counting the address text fields.
//It being reduced and increased so that it will represent the exact number of text fields
function Add() {
n1++;
n3++;
s1 = "<div id='div" + n1 + "'>";
s1 += "Address <input type='text' name='address" + n3 + "' id='address" + n3 + "' />";
s1 += "<input type='button' name='add" + n1 + "' id='add" + n1 + "' value='Add Branch' onclick='Add();' /><br />";
s1 += "</div>";
var n2 = n1 - 1;
document.getElementById('div' + n2).insertAdjacentHTML('afterEnd', s1);
document.getElementById('add' + n2).onclick = function () { Remove(n2, (n3-1)); };
document.getElementById('add' + n2).value = 'Remove';
}
function Remove(nn1, nn2) { //nn1 - div number to remove. nn2 - the address field number in this div
var parent = document.getElementById('barcode');
var child = document.getElementById('div' + nn1);
parent.removeChild(child);
for (nn2 += 1; nn2 <= n3; nn2++) {
var n2 = nn2 - 1; //nn2 - current address text field. n2 - the new number for the address field
document.getElementById('address' + nn2).setAttribute('name', 'address' + n2);
document.getElementById('address' + nn2).setAttribute('id', 'address' + n2);
document.getElementById('address' + n2).setAttribute('value', 'address' + n2);
// try: document.getElementById('address' + nn2).name='address'+n2. doesn't work (for me)
}
n3--;
}
var check = false;
</script>
</head>
<body>
<form name='barcode' id='barcode' action="" >
<div id='div1'>
Address <input type='text' name='address1' id='address1' />
<input type='button' name='add1' id='add1' value='Add Branch' onclick='Add();' /><br />
</div></form>
</body>
</html>
Sorry for the disorder :) I keeped in this code only what linked to the address field and I added comments.
Thanks very much!
edit:
I forgot that you don't see the bug in this code because I already tried to fix it. Before I changed the code it ordered all the divs, text fields and add/remove buttons so all the exsisting items will always be numbered in order (1, 2, 3, ...).
The problem in the following code can be seen if you click 2 times add button, then you remove the first address field and then you click the add button again.
<html>
<head>
<script type="text/javascript">
var n1 = 1;
function Add() {
n1++;
s1 = "<div id='div" + n1 + "'>";
s1 += "Address <input type='text' name='address" + n1 + "' id='address" + n1 + "' />";
s1 += "<input type='button' name='add" + n1 + "' id='add" + n1 + "' value='Add Branch' onclick='Add()' /><br />";
s1 += "</div>";
var n2 = n1 - 1;
document.getElementById('div' + (n2)).insertAdjacentHTML('afterEnd', s1);
document.getElementById('add' + (n2)).onclick = function () { Remove(n2); };
document.getElementById('add' + (n2)).value = 'Remove';
}
function Remove(n) {
var parent = document.getElementById('barcode');
var child = document.getElementById('div' + n);
parent.removeChild(child);
for (n += 1; n <= n1; n++) {
var n2 = n1 - 1;
document.getElementById('add' + n).onclick = function () { Remove(n2); };
document.getElementById('address' + n).setAttribute('name', 'address' + n2);
document.getElementById('add' + n).setAttribute('name', 'add' + n2);
document.getElementById('address' + n).setAttribute('id', 'address' + n2);
document.getElementById('add' + n).setAttribute('id', 'add' + n2);
document.getElementById('div' + n).setAttribute('id','div' + n2);
}
n1--;
document.getElementById('add' + n1).onclick = function () { Add() };
}
</script>
</head>
<body>
<form name='barcode' id='barcode' action="" >
<div id='div1'>
Address <input type='text' name='address1' id='address1' />
<input type='button' name='add1' id='add1' value='Add Branch' onclick='Add();' /><br />
</div>
</form>
</body>
</html>
I think you are working a bit too hard to maintain the order of the addresses and i don't see a general reason to do it (if you have one, please add it to your question).
If you add the inputs with a unique index like you are doing, they will always be different and ordered.
Here's what you can do:
Pass the event caller to the functions Add and Remove and inside you can make the changes you want to those elements.
For example your Remove function (that you would call with Remove(this);) would look like this:
function Remove(callerButton) {
var parent = document.getElementById('barcode');
var child = callerButton.parentNode;
// child is the DIV you want to remove
parent.removeChild(child);
n3--;
}
This way you wouldn't need to do all the sorting you are doing right now.
At the end you can access all the remaining elements with:
var addresses = document.getElementById("barcode").getElementsByTagName("input");
for(var i = 0; i < addresses.length; i++) {
if(addresses[i].type == "text") {
// I'm printing them in the console, you can do with it whatever you like
// If you want to exclude the one with "Add Branch in front of it you can validate for address+n1
console.log("Element.id : " + addresses[i].id + " - Element.value: "+ addresses[i].value );
}
}
I added a jsFiddle with these changes (added a submit button to show the remaining fields in the form).
See if it solves your problem.