How can I use the same passValue function twice in Javascript? - javascript

I want to pass the value of a input field in two spots. But my code only will pass it once. Is there a way to rewrite this to have it show up again down the code?
//HTML:
<input type="text" name="amount" onchange="passValue(this, 'preview_amount')"/>
//Outputs first value
<span id="preview_amount"></span>
//Outputs Nothing
<span id="preview_amount"></span>
//Javascript:
function passValue(e, target){
document.getElementById(target).innerHTML = e.value;
}

Your ids must be unique. Try this... It might work.
//HTML:
<input type="text" name="amount" onchange="passValue(this, 'preview_amount1', 'preview_amount2');"/>
//Outputs first value
<span id="preview_amount1"></span>
//Outputs Nothing
<span id="preview_amount2"></span>
//Javascript:
function passValue(e){
for(var i = 1; i < arguments.length; ++i){
if (document.getElementById(arguments[i]))
document.getElementById(arguments[i]).innerHTML = e.value;
}
}
With this you can pass any number of ids to passValue function without having to change it.

You cannot have duplicate element id's within a DOM document. ids MUST be unique.
Using jquery, and unique IDs, your problem becomes simple:
<input ... onChange="passValue(this, '#preview_amount1, #preview_amount2');" />
<span id="preview_amount1"></span>
<span id="preview_amount2"></span>
function passValue(e, targets) {
$(targets).innerHTML = e.value;
}
note the different IDs for the two spans, and how those IDs are passed withing the onChange handler.

Also try this one.
<input type="text" id="amount">
<div class="preview_amount"></div>
<div class="preview_amount"></div>
JQUERY
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type = "text/javascript">
$(document).ready(function() {
$('#id').keypress(function() {
$('.preview_amount').html($(this).val());
});
});
</script>

You can set class name for all the spans you want to update onchange and then set innerHTML according to this class so you won't have to pass different id's to the function.
Fiddle
<input type="text" name="amount" onchange="passValue(this.value)"/>
<span class="set_values_here" id="preview_amount_1"></span>
<span class="set_values_here" id="preview_amount_2"></span>
<script>
function passValue(new_value) {
var els = document.getElementsByClassName("set_values_here");
for(var i=0; i<els.length; i++)
{
document.getElementById(els[i].id).innerHTML = new_value;
}
}
</script>

Related

Variable multiplier

I have created a simple calculator that takes variable #1 and variable #2 and multiplies them to generate a result.
When I change variable #1 the result instantly changes. However, when I change variable #2 the result remains unchanged.
How do I reconfigure my code so that the result instantly changes when either variable is altered?
HTML:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h6>Variable #1</h6>
<input id="var1">
<h6>Variable #2</h6>
<input id="var2">
<h6>Result</h6>
<input readonly="readonly" id="result">
<script>
$(document).ready(function(){
var mt=$("#var1");
mt.keyup(function(){
var total=isNaN(parseInt(mt.val()* $("#var2").val())) ? 0 :(mt.val()* $("#result").val())
$("#result").val(total);
});
});
</script>
You have many things going wrong here,
you need to bind keyup event in var1 textbox and var2 textbox both
Also, your multiply formula is also wrong. Here is the desire code:
$(document).ready(function(){
var mt=$("#var1,#var2");
mt.keyup(function(){
debugger;
var total= 0;
if(!isNaN(parseInt($("#var1").val())* parseInt(parseInt($("#var2").val())))){
total= parseInt($("#var1").val())* parseInt(parseInt($("#var2").val()));
}
$("#result").val(total);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h6>Variable #1</h6>
<input id="var1">
<h6>Variable #2</h6>
<input id="var2">
<h6>Result</h6>
<input readonly="readonly" id="result">
Consider binding keyup events on both #var1 and #var2 inputs using the following jQuery syntax #var1, #var2 to achieve this desired behaviour, as shown:
$(document).ready(function(){
// Select and bind keyup event to both "var" input elements using
// this syntax
$('#var1, #var2')
.keyup(function(){
// Adjust your keyup handler to perform calculation when keyup
// occurs on either input field
var total= 0;
if(!isNaN(parseInt($("#var1").val())* parseInt($("#var2").val()))){
total = parseFloat($("#var1").val())* parseFloat($("#var2").val());
}
$("#result").val(total);
});
});
I just want to answer in vanilla Javascript for future reference of the problem..
I make var1,var2 class="input", then querySelect them both, then loop them, so that when you put any number to them, their value(product) will be produce in the id="result"
if you did not put any number to them, the default value is zero(0) for both of them, so let say, you only put 10 to var1, then the output will only be 10, and if you put non numeric character, then the output is NaN.
let input = document.querySelectorAll(".input");
let var1 = document.querySelector("#var1");
let var2 = document.querySelector("#var2");
let output = document.querySelector("#result");
function result(var1=0,var2=0) {
output.value = Number(var1)*Number(var2);
}
for(let i=0;i<input.length;i++)
{
input[i].addEventListener(`keyup`,()=>result(var1.value,var2.value))
}
<h6>Variable #1</h6>
<input id="var1" class="input">
<h6>Variable #2</h6>
<input id="var2" class="input">
<h6>Result</h6>
<input readonly="readonly" id="result">
By the way you can also make the code much shorter by instead of putting the id var1,var2 value, you can instead just put the input class[0], and [1] it's the same..
so it can also be done this way.
let input = document.querySelectorAll(".input");
let output = document.querySelector("#result");
function result(var1=0,var2=0) {
output.value = Number(var1)*Number(var2);
}
for(let i=0;i<input.length;i++)
{
input[i].addEventListener(`keyup`,()=>result(input[0].value,input[1].value))
}
<h6>Variable #1</h6>
<input id="var1" class="input">
<h6>Variable #2</h6>
<input id="var2" class="input">
<h6>Result</h6>
<input readonly="readonly" id="result">
By the way if you want to follow the same logic by using ternary operator,
let's follow his example, by using ternary operator,
change the result function to this.
function result(var1=0,var2=0) {
(var1*var2 ===0)? output.value=0: output.value=Number(var1) * Number(var2);
}

Iterating over dynamically generated input field ids and using keyup to get their values in a separate input field

The mandatory div id gets different numbers of inputs field displayed in it dynamically. Each input field starting from the first gets an id attr1, then attr2,..attr[n]. I need a way to get this into an array that gets the value of each input field with keyup and puts them into a separate input field with id detail.
This code works but returns undefined in some case when the hard coded input field ids exceed the generated input field ids. Thanks.
<div id="attributes"> <!--Start of Div Refreshed on Ajax Page Refresh-->
<div id="mandatory">
</div>
</div>
var total = '#attr1, #attr2';
$("#attributes").on('keyup', total, function(){
update();
})
function update() {
$("#detail").val($('#attr1').val() + "," $('#attr2').val());
}
If I understood right your question I think you're looking for something like that:
var fields = $("#mandatory").find("input"),
ids = [];
fields.each(function(){
$(this).on("keyup", function(){
var val = "";
ids = [];
fields.each(function(){
val += $(this).val() + (fields.length === ($(this).index() + 1) ? "": ", ");
ids.push($(this).get(0).id);
});
$("#detail").val(val);
console.log(ids)
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="attributes">
<div id="mandatory">
<input id="one" class="one" value="54"/>
<input id="two" class="two" value="55"/>
<input id="three" class="three" value="587"/>
</div>
</div>
<input id="detail" type="text" />
I'm not sure if this is what you're looking for, but I think it'll take you down the right path. In this example, any time a text input field is generated, an input event handler is attached to it that changes the value of a main textarea. If this isn't quite what you're looking for, please let me know and I'll be happy to try to work it out more.
document.getElementById('adder').onclick = function() {
var dynamicTextbox = document.createElement('input');
dynamicTextbox.setAttribute('type', 'text');
dynamicTextbox.setAttribute('class', 'dynamicText');
dynamicTextbox.addEventListener("input", function() {
var allTextboxes = document.getElementsByClassName('dynamicText');
var allValues = '';
for (var i=0; i < allTextboxes.length; i++) {
allValues += allTextboxes[i].value;
}
document.getElementById('detail').value = allValues;
});
document.getElementById('textboxes').appendChild(dynamicTextbox);
}
<textarea id="detail"></textarea>
<input id="adder" type="button" value="Add Text Field" />
<div id="textboxes"></div>

How to get all labels and its input elements in javascript

I would like to get all labels and its input elements using Javascript.
I have also radio, checkboxes and textarea elements.
Then I want to put it in an array of objects.
This is what I have done,
var html = data;
var array = [];
for(var i=0;i<$("input").length;i++){
array[i] = {label:"",val:$("input").eq(i).val()};
}
console.log(array);
By the way, doesn't have for attributes and also their next sibling is not always the input/radio/checkbox/textarea element. Sometimes,the structures are,
<label>Something:</label><Br/ ><input type="text" />
How can I do what I want in this situation?
You can use map() method to generate the array and use prevAll() method with jQuery :first pseudo-class selector to get the label(you can't use prev() method since there is a br tag in between).
var array = $("input").map(function(){
return {
label : $(this).prevAll('label:first').text(),
val:$(this).val()
};
}).get();
console.log(array);
FYI : If the input is wrapped by label in some case then you can use closest() method to get the wrapped element. Although you can use :input to select all form elements.
var array = $(":input").map(function() {
return {
label: $(this).prevAll('label:first').text(),
val: $(this).val()
};
}).get();
console.log(array);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Some</label>
<Br/>
<input type="text" value="1" />
<label>Some1</label>
<Br/>
<input type="text" value="11" />
<label>Some2</label>
<Br/>
<input type="text" value="2" />
<label>Some3</label>
<Br/>
<input type="text" value="4" />
<label>Some4</label>
<Br/>
<input type="text" value="3" />
<label>Some422</label>
<Br/>
<select><option value="1"></option><select>
You're using labels wrong so I'm going to assume what you really want is just some identifying attribute of the text field checkbox etc to associate with the value.
Here is my go
https://jsfiddle.net/1akh5qg9/
HTML
<form id="test-form">
<label>Label1:</label>
<input class="get-value" name="input1" type="text" />
<br>
<label>Label2:</label>
<input class="get-value" name="input2" type="text" />
<br>
<label>Label3:</label>
<input class="get-value" type="checkbox" name="checkbox1">I have a bike
<br>
<br>
<button id="submit-button">Get Values</button>
</form>
Javascript
let btn = document.getElementById('submit-button');
let form = document.forms['test-form'].getElementsByClassName('get-value');
let valueArr = [];
// attach onclick handler
btn.onclick = function(e) {
e.preventDefault();
getFormValues();
}
// getFormValues
function getFormValues() {
for (var x of form){
valueArr.push({label:x.name ,value:x.value})
}
console.log(valueArr);
}
Results
[
{label:"input1", value:"test1"},
{label:"input2", value:"test1"},
{label:"checkbox1", value:"on"}
]
For you to get the label tags in your HTML form you first have to get the label tag from the DOM and follow up with the code below:
// get array of label tags in the DOM
const label = document.getElementsByTagName("label")
for (k = 0; k < label.length; k++){
const labelText = Array.prototype.filter
.call(label[k].childNodes, x => x.nodeName === "#text")
.map(x => x.textContent)
console.log(labelText)
}
If you want to select all elements (labels, inputs) into a single array, try using a custom attribute and use a selector like this $('*[data-all-labels-inputs]');
I would recommend doing something up-front in the HTML to mark the items you want to get.
You could put the label and input pairs in a DIV to indicate that they go together and then give the DIV a class that you could filter and loop on.
You could also use data-tag attributes to name the pairs. Say give all the labels and inputs the attribute data-LabelInp="NameA". Then you can select all labels with attribute data-LabelInp, get the value of the attribute and find the matching input with data-LabelInp === that value.

how to get input array value by key with javascript function?

Here is sample code i try to create input array with key and on change i want to get the value of individual input array value.
<input type="text" name="items[1]" value="443" onchange="get_items(1)">
<input type="text" name="items[2]" value="233" onchange="get_items(2)">
<script>
function get_items(key)
{
alert($("items["+key+"]").val());
}
</script>
Simply pass this context as argument and get value.
<input type="text" name="items[1]" value="443" onchange="get_items(this)">
<input type="text" name="items[2]" value="233" onchange="get_items(this)">
<script>
function get_items(ele) {
alert(ele.value);
}
</script>
Refer fiddle
HTML:
<input type="text" name="items[1]" value="443" onchange="get_items(1)">
<input type="text" name="items[2]" value="233" onchange="get_items(2)">
JS:
function get_items(key)
{
alert($('input[name="items['+key+']"]').val());
}
You can get the event's target from event,
function get_items(e) {
console.log(e.target.value);
}
<input type="text" name="items[1]" value="443" onchange="get_items(event)">
<input type="text" name="items[2]" value="233" onchange="get_items(event)">
or, better, attach your listener in javascript:
function get_items(e) {
console.log(e.target.value);
};
var inputs = document.querySelectorAll("input");
for (var i = 0, el; i < inputs.length; i += 1) {
el = inputs[i]
el.addEventListener("change", get_items);
};
<input type="text" name="items[1]" value="443">
<input type="text" name="items[2]" value="233">
Here is some code that does what (I think) you are trying to do:
<input type="text" name="item1" value="443" onchange="javascript:get_items(1)">
<input type="text" name="item2" value="233" onchange="javascript:get_items(2)">
<script>
function get_items(key)
{
//alert($("items["+key+"]").val());
var input = $('input[name="item' + key + '"]');
var value = input.val();
alert(value);
}
</script>
jsfiddle: https://jsfiddle.net/9kvv2q7p/4/
You can use this
function get_items(key) {
alert($("input[name='items[" + key + "]']").val());
}
I hope I was helpfull
Your HTML is missing a closing quote for the name attributes.
The name attribute should not contain [ or ]
characters. Adding these characters will complicate matters.
You should hook up your event handlers in JavaScript, not HTML.
When practical, elements should have unique id attributes added to them, which will make accessing and identifying them much easier in JavaScript and CSS
Rather than trying to identify the textboxes with indexes, just gather them up and place them into an array or array-like container, where indexes will be automatically assigned to them.
Here is a working example of how to get values by index:
// This will scan the DOM and place all matched elements into a node list
// which is an array-like object
var textBoxes = document.querySelectorAll("input[type=text]");
// Or, you can get references to them individually:
var txt1 = document.getElementById("txt1");
var txt2 = document.getElementById("txt2");
// And, put them into an array on your own:
var ary = [txt1, txt2];
// No matter how you got your references to them, it's best to hook
// them up to event handler in JavaScript, not HTML
txt1.addEventListener("change", get_items2);
txt2.addEventListener("change", get_items2);
function get_items(key) {
// You can certainly pass a key to this function
// to identify which element you are talking about
alert(textBoxes[key].value);
}
function get_items2(evt) {
// But, event handlers are automatically passed
// a reference to the object that fired the event
alert(evt.target.value);
}
get_items(0); // Call the function to get first textbox value
get_items(1); // Call the function to get second textbox value
<input type="text" id="txt1" name="txt1" value="443">
<input type="text" id="txt2" name="txt2" value="233">

Selecting specific element within a div?

I am building a contact form, and I am having problems with jQuery. I want to select specific input fields that have an error and apply the class err. Unfortunately, my code selects all inputs when there is an error. I am having trouble identifying which part of my logic is wrong.
$('#send_mail').click(function(){
$("#contact_body").find('label').each(function(){
var contact_label = $('input[required=true], textarea[required=true]');
var label_check = $(this).find(contact_label);
$(contact_label).removeClass('err');
if (!$.trim($(label_check).val())){
$(contact_label).addClass('err');
}
});
});
The order of my HTML goes something like so:
#contact_body
<label>
<input>
</label>
This selects all input and textarea elements:
var contact_label = $('input[required=true], textarea[required=true]');
Instead, you should restrict it to the elements within the label:
var contact_label = $(this).find('input[required=true], textarea[required=true]');
Note that $(contact_label) and contact_label are equivalent in your code, as well as $(label_check) and label_check.
Also, you can use the state parameter of toggleClass() to simplify this:
contact_label.removeClass('err');
if (!$.trim(label_check.val())){
contact_label.addClass('err');
}
… to this:
contact_label.toggleClass('err', !$.trim(label_check.val()));
Here's the updated event:
$('#send_mail').click(function(){
$('#contact_body').find('label').each(function(){
var contact_label = $(this).find('input[required=true], textarea[required=true]');
var label_check = $(this).find(contact_label);
contact_label.toggleClass('err', !$.trim(label_check.val()));
});
});
I think your original code would work if you just changed this line:
$(contact_label).addClass('err');
To this:
$(label_check).addClass('err');
Because $(contact_label) references all the required inputs, whereas $(label_check) references only the input being checked.
But your code could be simplified, and you make unnecessary calls to $(), giving it an argument that is already a JQuery object.
I also do not see that you need to loop through the labels. You could loop through the required inputs instead.
$('#send_mail').click(function(){
$("#contact_body").find(':input[required]').each(function() {
var $input = $(this);
$input.removeClass('err');
if (!$.trim($input.val())){
$input.addClass('err');
}
});
});
Which could be shortened by using the .toggleClass() function:
$('#send_mail').click(function(){
$("#contact_body").find(':input[required]').each(function() {
$(this).toggleClass('err', !$.trim($input.val()));
});
});
Notes:
The selector ':input' matches <input>, <select> and <textarea> elements.
This is a slightly different approach. Gives a bit more flexibility.
arr = ['first', 'last', 'email', 'msg']; //IDs of fields to check
$('#send_mail').click(function(){
$('input, textarea').removeClass('err');
for (var i=0; i<arr.length-1; i++) { //Loop through all field IDs
if ( $('#'+arr[i]).val() == '' ) {
$('#'+arr[i]).addClass('err').focus();
return false;
}
}
//AJAX to send email goes here
alert('Email sent');
});
.err{background:yellow;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<label for="first">First Name:</label>
<input id="first" type="text" required /><br>
<label for="last">Last Name:</label>
<input id="last" type="text" required/><br>
<label for="email">Email:</label>
<input id="email" type="email" required /><br>
<label for="msg">Message:</label>
<textarea id="msg" required></textarea>
<button id="send_mail">Send</button>
you can simplify the code, there will be less mistakes:
$('#send_mail').click(function(){
$("#contact_body").find('label').each(function(){
var field = $(this).find('[required=true]');
if ($.trim($(field).val())){
$(this).removeClass('err');
}
});
});

Categories