Set .focus on second last input, not first or last - javascript

I have dynamically created inputs via a button, two get created at a time and I'd like the focus to be on the first of the two each time a set is added, so theoretically it'll always be the second last input
I currently use $('input:text:visible:first').focus(); but is there a way to do this but get the second last?
Input1.1
Input1.2
Input2.1
Input2.2
# user creates new input set via button
Input3.1 <---Focus on this one
Input3.2

One solution is to use eq(-2).focus(); (eq() documentation). From there you can read that the argument can be a negative number that represent the next:
indexFromEnd / Type: Integer / An integer indicating the position of the element, counting backwards from the last element in the set.
I have made a simple example to demostrate his use:
$("#myBtn").click(function()
{
$('<input value="new">').appendTo(".wrapper");
$('<input value="new">').appendTo(".wrapper");
$(".wrapper input").eq(-2).focus();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
<input type="text" value="input1">
<input type="text" value="input2">
<input type="text" value="input3">
<input type="text" value="input4">
</div>
<button id="myBtn">ADD</button>

You can use input:nth-last-child(n) where n is any number
function createInput() {
let str = `<div class ='ipCon'>
<input type='text'>
<input type='text'>
<input type='text'>
</div>`;
document.getElementById('con').innerHTML = str;
document.getElementsByClassName('ipCon')[0].querySelector('input:nth-last-child(2)').focus()
}
input:focus {
background-color: yellow;
}
<div id='con'>
</div>
<button type='button' onclick='createInput()'> Create Inputs</button>

Related

JavaScript change value and data from value in a span

I need help with this. I need to make the value in the other place change all the time while user session is active. How can I get the value from a span and make other value in a data change?
Look at there!
1 <div class="pt-uea-container">
2 <span class="pt-uea-currency pt-uea-currency-before"> € </span>
3 <input type="text" class="pt-field pt-uea-custom-amount" autocomplete="off" name="pt_items[1][amount]" id="pt_uea_custom_amount_1" value="199" placeholder="" data-parsley-errors-container="#pt_uea_custom_amount_errors_1">
4 <input type="hidden" class="pt-field pt-uea-custom-amount-formatted" name="pt_items[1][amount]" value="199" data-pt-price="199">
5 <input type="hidden" name="pt_items[1][label]" value="Amount:">
6 <input type="hidden" name="pt_items[1][tax_percentage]" value="0">
7 <input type="hidden" name="pt_items[1][type]" value="open">
8 <div id="pt_uea_custom_amount_errors_1"></div>
9 <span class="form-price-value">85</span>
10 </div>
The value in row 9 needs to constantly change values in row 3 and 4 on the same session. Don't mind the value in row 6.
Let me know how I can get this done. Or maybe a different approach?
Greetings!
========
So this is what I got for now from you guys:
jQuery(document).ready(function($) {
var checkViewport = setInterval(function() {
var spanVal = $('.form-price-value').text();
$('#pt_uea_custom_amount_1').val(spanVal);
$('#pt_uea_custom_amount_formatted_1').val(spanVal);
$('#pt_uea_custom_amount_formatted_1').attr('data-pt-price', spanVal);
}, 1000);
});
This code works, but it only affects my needs when I put my mouse in pt-field pt-uea-custom-amount and add a space in it. Then it does apply to the page source. But this is not correct. The source needs to get changed too without touching that class or a space or something!
You can easily do this with the help of jQuery.
With the help of jQuery I would do like this.
Understanding what input field needs to be tracked for changes. I will give all this field a class (track-me).
In the document ready, I will look for changes for that tracked field.
On change of that field I will get the value and put in other input fields (class copy-to - or you can do whatever you like).
See an example below,
HTML
<form>
<div class="">
<input type="text" class="track-me" value=""/>
</div>
<div class="">
<input type="text" class="copy-to" value=""/>
</div>
<div class="">
<input type="text" class="copy-to" value=""/>
</div>
<div class="">
<input type="text" class="copy-to" value=""/>
</div>
<div class="">
<div class="">Please type anything in the first input box</div>
</div>
</form>
jQuery
$(document).ready(function(){
$('.track-me').change(function (){
$('.copy-to').val($(this).val())
});
});
I made comments in the above jQuery code so you can understand. Also, I have made a fiddle so you can play and have a look. In this fiddle, I am using Bootstrap4 just for the purpose of styling, you don't have to worry about that.
Link to fiddle
https://jsfiddle.net/anjanasilva/r21u4fmh/21/
I hope this helps. Feel free to ask me any questions if you have. Cheers.
This is not an ideal solution. I'm not sure there is a verified way of listening for when the innerHTML of a span element changes. This sort of stuff is usually based on user interaction, and the value of the span will be modified by your page. The best solution would be to use the same method that updates the span element to update the values of you hidden input fields.
However, I've placed an interval that will run every second, that takes the text value of the span element and gives it to the values of the 2 input fields:
function start() {
setInterval(function() {
document.getElementById("pt_uea_custom_amount_1").value = document.getElementById("price_value").innerHTML;
document.getElementById("pt_uea_custom_amount_2").value = document.getElementById("price_value").innerHTML;
}, 1000);
}
window.onload = start();
<div class="pt-uea-container">
<span class="pt-uea-currency pt-uea-currency-before"> € </span>
<input type="text" class="pt-field pt-uea-custom-amount" autocomplete="off" name="pt_items[1][amount]" id="pt_uea_custom_amount_1" value="199" placeholder="" data-parsley-errors-container="#pt_uea_custom_amount_errors_1">
<input type="hidden" class="pt-field pt-uea-custom-amount-formatted" name="pt_items[1][amount]" value="199" data-pt-price="199" id="pt_uea_custom_amount_2">
<input type="hidden" name="pt_items[1][label]" value="Amount:">
<input type="hidden" name="pt_items[1][tax_percentage]" value="0">
<input type="hidden" name="pt_items[1][type]" value="open">
<div id="pt_uea_custom_amount_errors_1"></div>
<span id="price_value" class="form-price-value">85</span>
</div>
MutationObserver should work here..
const formValuePrice = document.querySelector( '.form-price-value' );
const inputText = document.querySelector( 'input[type="text"]' );
// timer to change values
window.setInterval( () => {
formValuePrice.textContent = Math.round( Math.random() * 100 );
}, 1000 );
// mutation observer
const observer = new MutationObserver( ( mutationsList ) => {
inputText.value = formValuePrice.textContent;
} );
observer.observe( formValuePrice, { childList: true } );
https://codepen.io/anon/pen/LgWXrz?editors=1111
try this, simple using jquery, you can check in inspect element for value attribute data-pt-price
Update: you can using jquery event .on() like change, click, keyup or else to Attach an event handler function for one or more events to the selected elements,
you can read the doc here.
here the updated code
$(function() {
var spanVal = $('#price_value').text();
$('#pt_uea_custom_amount_1').val(spanVal);
$('#pt_uea_custom_amount_formatted_1').val(spanVal);
$('#pt_uea_custom_amount_formatted_1').attr('data-pt-price', spanVal);
$('#pt_uea_custom_amount_1').on('change click keyup', function() {
$('#pt_uea_custom_amount_formatted_1').val($(this).val());
$('#price_value').text($(this).val());
$('#pt_uea_custom_amount_formatted_1').attr('data-pt-price', $(this).val());
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="pt-uea-container">
<span class="pt-uea-currency pt-uea-currency-before"> € </span>
<input type="text" class="pt-field pt-uea-custom-amount" autocomplete="off" name="pt_items[1][amount]" id="pt_uea_custom_amount_1" value="199" placeholder="" data-parsley-errors-container="#pt_uea_custom_amount_errors_1">
<input type="hidden" class="pt-field pt-uea-custom-amount-formatted" name="pt_items[1][amount]" value="199" data-pt-price="199" id="pt_uea_custom_amount_2">
<input type="hidden" name="pt_items[1][label]" value="Amount:">
<input type="hidden" name="pt_items[1][tax_percentage]" value="0">
<input type="hidden" name="pt_items[1][type]" value="open">
<div id="pt_uea_custom_amount_errors_1"></div>
<span id="price_value" class="form-price-value">85</span>
</div>

Javascript concat clearing input fields

function js() {
document.getElementById("example").innerHTML = document.getElementById("example").innerHTML+"<input type=\"text\" name=\"name\" />";
}
<div id="example">
<input type="text" name="name[]" />
</div>
<button type="button" onclick="js();">Click</button>
I have a form, which need variable number of input types.
<form action="" method="">
[...]
<div id="mezok">
<div id="input_id">
<input type="text" name="name" />
</div>
</div>
[...]
</form>
I add and remove further inputs (along with their divs!) via an ajax call. Javascript calls a php which generates a new input_id div, and then concatenates to the rest of the div id="mezok". Adding and removing inputs are fine as long as everything is empty. However, when I add a new div when there is something in the input, it clears the rest of the inputs.
document.getElementById("mezok").innerHTML = document.getElementById("mezok").innerHTML+http.responseText;
document.getElementById("mezok").innerHTML += http.responseText;
document.getElementById("mezok").innerHTML.concat(http.responseText);
(The last one is not working at all...)
TL;DR: concat input to input, values of inputs disappear. :'(
Don't use innerHTML. What you are doing is redrawing the entire container contents, deleting existent inputs and creating new inputs each time. My experience says that when you are accessing innerHTML, recheck your code as you are probably doing something weird.
What you have to do is to create inputs individually and append them to the container, without touching the rest of the inputs. Is like appending elements to an array.
This way the code is more self-explanatory, and better, is way more performant:
function js() {
var input = document.createElement("input"); // Create a new input element. Is like "<input>".
input.setAttribute("type", "text"); // Set the 'type' attribute to 'text'. Is like having '<input type="text">'
input.setAttribute("name", "name[]"); // Set the 'name' attribute to 'name[]'. Is like having '<input name="name[]">' but because you already have set the type, now is like having '<input type="text" name="name[]">'
document.getElementById("example").appendChild(input); // Push it to the container
}
<div id="example">
<input type="text" name="name[]" />
</div>
<button type="button" onclick="js();">Click</button>
The code below could be a solution for you. In this way you're not going to overwrite the existing inputs with the associated values while you're adding new inputs.
function js() {
var inputElementToAppend = document.createElement('input');
inputElementToAppend.innerHTML = "<input type=\"text\" name=\"name\" />";
document.getElementById("example").appendChild(inputElementToAppend.firstChild);
}
<div id="example">
<input type="text" name="name[]" />
</div>
<button type="button" onclick="js();">Click</button>
Let me know if this worked for you.
Following working fine for me.
<button onclick="myFunction()">Try it</button>
<p id="demo">ABC</p>
<script>
function myFunction() {
var x = document.getElementById("myP").innerHTML;
document.getElementById("demo").innerHTML += `<input type=\"text\" name=\"name\" />`;
}
<script>
I would recommend to use appendChild and removeChild instead of innerHTML

I am currently experimenting with simple addition by adding the values of three input elements

I am currently experimenting with simple addition by adding the values of three input elements.
I have three input elements and a button element with an onclick listener to invoke my function. The function is to simply return the output of the sum of those values inputted by the user in an h2 element, and that is all. Here are the HTML and JS:
<div class="inputFields">
<input class="lado" type="text" />
<input class="lado" type="text" />
<input class="lado" type="text" />
</div>
<button type="button" onclick="getArea()">click</button>
<h2 id="areaResult"></h2>
var s1 = document.getElementsByClassName('lado')[0].value;
var s2 = document.getElementsByClassName('lado')[1].value;
var s3 = document.getElementsByClassName('lado')[2].value;
/*to my understanding, the .value property (like .innerHTML) renders a
string value. Do please correct me if I'm wrong.*/
function getArea() {
document.getElementById('areaResult').innerHTML =
Number(s1) + Number(s2) + Number(s3);
/*Utilized Number() method to convert the string values rendered by
the .value properties to number values so as to perform addition
arithmetic operation rather than concatenation.*/
}
The output for some mysterious reason to me however is always 0 no matter what numbers I input or even if I input non-numerical characters.
What am I doing wrong?
Declare all the variables inside the function.
You do not need to write document.getElementsByClassName every time. Simply use a variable to store all the class element then use index to get the value from that variable like the following:
function getArea() {
var lado = document.getElementsByClassName('lado');
var s1 = lado[0].value;
var s2 = lado[1].value;
var s3 = lado[2].value;
document.getElementById('areaResult').innerHTML =
Number(s1) + Number(s2) + Number(s3);
}
<div class="inputFields">
<input class="lado" type="text" />
<input class="lado" type="text" />
<input class="lado" type="text" />
</div>
<button type="button" onclick="getArea()">click</button>
<h2 id="areaResult"></h2>

Increment of counter on dynamic addition of rows

I'm trying to add the rows dynamically plus auto-increment of a counter.I want to start with 1 then 2 then 3 and so on . I have added my code on plunker ,in which every time the max value is getting in first column like 4 then 1,1,2,3.Where am i going wrong ?i Want it to be 1,2,3,4.
Here is the plunker link http://plnkr.co/edit/GuDbJ3SHOPvWkHfNfd8E?p=preview
var _counter = 0;
function Add() {
_counter++;
var oClone = document.getElementById("template").cloneNode(true);
oClone.id += (_counter + "");
document.getElementById("placeholder1").appendChild(oClone);
document.getElementById("myVal").value=_counter;
}
<div id="placeholder1">
<div id="template">
<div>
Value:<input type="text" id="myVal" placeholder="1">
Quantity:<input type="text" placeholder="Qty">
<input type="button" onClick="Add()" value="Click! ">
</div>
</div>
I think it is because you have multiple divs with the id="myVal". The id attribute should be unique on the page. If not, your page will still load, but you may have unexpected behavior.
You are changing the id of the template div, but not the myVal div.
I assume you are looking for something like this:
var _counter = 0;
function Add() {
_counter++;
var oClone = document.getElementById("template").cloneNode(true);
oClone.id += (_counter + "");
document.getElementById("placeholder1").appendChild(oClone);
oClone.getElementsByClassName("myVal")[0].value = _counter;
}
<div id="placeholder1">
<div id="template">
<div>
Value:
<input type="text" class="myVal" placeholder="1">Quantity:
<input type="text" placeholder="Qty">
<input type="button" onClick="Add()" value="Click! ">
</div>
</div>
</div>
In your original you are cloning your template with the same id for the input. So when you do document.getElementById("myVal").value=_counter;, you only get the first input. I changed it to use class instead and get the input with the appropriate class that is a child of the cloned node.

How can I concatenate value in HTML and JavaScript?

For example
<input type="text" name="disp">
<input type="button" name="but0" value="0" onclick=""+"calc.disp.value=0"+"">
Here if I click the button 0 means it should display the 0 in text box. If I click the button it should concatenate in that box. But it replaces that is the code is wrong.
As far as I understand it, you want each button click to add 0 to the text box contents. So it starts out empty, and when you push the button the first time, the contents changes to 0. Pushing it a second time changes the contents to 00.
Assuming that's correct, try this:
<input type="text" name="disp">
<input type="button" name="but0" value="0" onclick="calc.disp.value=calc.disp.value + '0';">
If you are allowed to use jQuery I would suggest that as the code needed then becomes a lot easier to see what is going on:
First add an id attribute to each input.
<input type="text" name="disp" id="textBox">
<input id="button0" type="button" name="but0" value="0">
you want to add 0s? so if you entered 1 then you hit the 0 button it will show 10 then again will change to 100:
<script type="text/ecmascript">
$(document).ready(function()
{
$("#button0").click(function()
{
var textVal = $("#textBox").val();
$("#textBox").val(textVal + 0);
});
});
</script>
Example here
Hi you can do it by following way
<input type="text" name="tst" id="tst">
<input type="button" value="0" onclick="javascript:document.getElementById('tst').value = document.getElementById('tst').value + this.value "
var sum = document.getElementById("id1").value
+ document.getElementById("id2").value
+ document.getElementById("id3").value;

Categories

Resources