Suppose you have the following code to update many elements:
<div class='item'>
Name:<input type='text' name='name' data-id='123' value='Name 1'>
<button class='update'>update</button>
</div>
<div class='item'>
Name:<input type='text' name='name' data-id='456' value='Name 2'>
<button class='update'>update</button>
</div>
And JavaScript to handle the update:
function updateName(name, id){
...
}
What is the jQuery handler that can find the value and id and call updateName?
$('button.update').click(function() {
name = ?
id = ?
updateName(name, id)
}
EDIT:
The expected behavior is that when the user updates the input field, the updated value is sent to updateName(), not the original value.
Also, note that the data-id and value are on the input, not the button.
http://jsfiddle.net/e3g6nfc1/8/
Inside event handlers this is the unwrapped DOM element
$('button.update').click(function() {
var name = this.name
var id = $(this).data('id');
updateName(name, id)
}
note that you want var in this case or else name and id jump out of the scope of that function and possibly become global variables.
I've argued before that this is awkward and bad to use. You can achieve the same effect without using it like so:
$('button.update').click(function(e) {
var name = e.currentTarget.name
var id = $(e.currentTarget).data('id');
updateName(name, id)
}
You also don't have to use jquery for data. on reasonably modern browsers $(domElement).data('foo') is equivalent to domElement.dataset['foo']
Edit: Not sure if I missed this in the question or if it got edited but it seems like you're asking not for attributes on the button but the element before it. In that case you want $.fn.prev which will look something like this
$('button.update').click(function(e) {
var $prev = $(e.currentTarget).prev();
updateName($prev.name, $prev.data('id'))
}
note that this assumes that the input element is directly before the button. If you want to find the closest preceding input element you would use $.fn.prevAll
var $prev = $(e.currentTarget).prevAll('input').last();
Like this:
$('button.update').click(function() {
name = $(this).attr('name');//to get value of name attribute
id = $(this).data('id'); // to get value of attribute data-id
updateName(name, id)
}
You may also use prop() method to get name or data-id:
name = $(this).prop('name');
id = $(this).prop('data-id');
But best is to use data() method for data-* attribute.
Not sure why the answers here are trying to find the input attributes on the button element...
<div id="container">
<div class='item'>
Name:<input type='text' name='name' data-id='123' value='Name 1'>
<button class='update'>update</button>
</div>
<div class='item'>
Name:<input type='text' name='name' data-id='456' value='Name 2'>
<button class='update'>update</button>
</div>
</div>
Delegating the events to attach only to the container (selecting only those children with .update class), catching them as they "bubble up". previousElementSibling used to target the input but jQuery selectors could also be used to find it if the layout were more complex.
$('#container').on('click','.update',function(e) {
updateName(
e.currentTarget.previousElementSibling.name,
$(e.currentTarget.previousElementSibling).data('id')
);
});
JSFiddle
Related
I have a text input box where a user inputs what data-* they want to look for in the DOM. I get this user input on a button click then do a little bit of parsing. How would I get the value of the entered text to be the final part of the HTMLElement.dataset selector?
//HTML for text input
<div class="form-group">
<label for="specificSelector">Specific Selector</label>
<input type="text" class="form-control" id="specificSelector" placeholder="Enter the specific selector here">
</div>
<p id="a"></p>
//JavaScript
var specificSelector = document.getElementById("specificSelector").value;
var a = document.getElementById("a"); // Test element
var parsedSelector = specificSelector.match(/data-(.*)/)[1];
console.log("Parsed selector: ", parsedSelector);
//I need to pass the value of the parsedSelector to the below line
var aData = a.dataset.parsedSelector;
console.log("aData: ", aData);
I have read this from MDN Developers but can't figure it out. It looks like you have to pass the data attribute in camel case but might not be able to do it via a variable?
Thanks in advance.
When you need to access an object property via a variable, you need to use array-bracket syntax.
In the example below, type "data-test" into the text box and then hit TAB.
// Get a reference to the input
var specificSelector = document.getElementById("specificSelector");
var a = document.getElementById("a"); // Test element
// Set up an event handler for when the data is changed and the
// input loses focus
specificSelector.addEventListener("change", function(){
// Extract the custom name portion of the data- attribute
var parsedSelector = specificSelector.value.match(/data-(.*)/)[1];
console.log("Parsed selector: ", parsedSelector);
// Pass the string (stored in the variable) into the dataset object
// of another element to look up the object key.
var aData = a.dataset[parsedSelector];
console.log("aData: ", aData);
});
<div class="form-group">
<label for="specificSelector">Specific Selector</label>
<input type="text" class="form-control" id="specificSelector" placeholder="Enter the specific selector here">
</div>
<div id="a" data-test="test2"></div>
I have html elements as:
<input type=hidden class=txtCustomerId value=".parent::current()." />";
<input type=button class=printToTextarea value='Get to box' />
and jquery:
$(".printToTextarea").on("click", function () {
var array = $('.txtCustomerId').map(function() {
return this.value;
}).get();
loadxmldoc(array);
});
It passing all elements as array from hidden field with class name txtCustomerId while I need only current element when button click. Button is also array and both should have same index.
The following code using eq() and index() meet the requirement at much extent.
$(".printToTextarea").on("click", function () {
var i = $('.printToTextarea').index(this);
var custid=$('.txtCustomerId').eq(i).val();
loadxmldoc(custid);
$("#textInput").focus();
});
Change:
$('.txtCustomerId')
to:
$(this).prev('.txtCustomerId')
Well you are selecting all of the elements. So you need to select the one that is related. With your example, you would use prev() to get a reference to the element.
$(".printToTextarea").on("click", function () {
var button = $(this);
var inputValue = button.prev(".txtCustomerId").val();
console.log(inputValue);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type=hidden class=txtCustomerId value="hello" />
<input type=button class=printToTextarea value='Get to box' />
But how you get the input really depends on your HTML. So if the structure is different than the two elements beside each other, than the way to select it would change.
I created a div dynamically and attached to div. I'm trying to add data from query and load it to that text field. But, I'm unable to select the dynamically created elements because its not visible in the DOM, since its already loaded.
This is what I have fiddle
<div id="parent">
<input id='childButton' type="button" value="Add"/>
<div id="child" data-row="0">
<input type="text" value="" />
</div>
</div>
var rowNum = 0;
$('#parent').on('click', '#childButton', function() {
var clone = $('#child').clone().attr('data-row', ++rowNum);
$('#parent').append(clone);
console.log($('#child[data-row=1]').length);
});
The problem is the id selector, will return only the first element with the given id. In your case you are creating multiple elements with the id child. So #child will return the first child element, but then applying the data-row rule will filter out the selected element so you are getting 0 are the result.
The solution is to use a class instead of id to select the element
var rowNum = 0;
$('#parent').on('click', '#childButton', function() {
var clone = $('#child').clone().attr('data-row', ++rowNum).removeAttr('id');
$('#parent').append(clone);
//here clone refers to the dynamically create element
//but if you want to fetch the element using a selector then
snippet.log($('.child[data-row=1]').length);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<div id="parent">
<input id='childButton' type="button" value="Add" />
<div id="child" class="child" data-row="0">
<input type="text" value="" />
</div>
</div>
You're cloned element with same id, if you want to check just use
console.log($('div[data-row=1]').length);
Like others said, an ids should be unique. Use class definition instead for child id name.
When you're cloning an element with id, change the id (fiddle):
var rowNum = 0;
$('#parent').on('click', '#childButton', function() {
var origin = $('#child');
var originId = $('#child').attr('id');
var cloneId = originId + rowNum;
var clone = $('#child').clone().attr('data-row', ++rowNum).attr('id', cloneId);
$('#parent').append(clone);
console.log($('#' + cloneId).length);
});
DEMO
var rowNum = 0;
$('#parent').on('click', '#childButton', function() {
var clone = $('#child').clone().attr('data-row', ++rowNum);
$('#parent').append(clone);
console.log($('#parent input:text').length);
});
You can also select the input by using the selector input:text
UPDATE
DEMO
IF you want to select the specific input to set value into you can use the index and set the value by finding that index
I think your selector is wrong it must be:
console.log($('#child[data-row="1"]').length);
and consider to remove the id attr in order to avoid multiple ids.
Demo: http://jsfiddle.net/o1j7z1gL/
I want to get the name of the two <p> elements in my html file using id after the button is clicked. but in my code, when I clicked the button, i it only outputs "print". How can I do this?
This is my HTML code:
<p id="name" name="print">hey</p>
<p id="name" name="this">hey</p>
<button id="btn11">test11</button>
This is my javascript code:
$("#btn11").click(function(){
alert($("#name").attr("name"));
});
use class instead of ID and
<p class= "name" name = "print">hey</p>
<p class= "name" name = "this">hey/p>
<button id="btn11">test11</button>
$("#btn11").click(function(){
$('.name').each(function () {
alert( $(this).attr('name'));
});
});
Id should be unique in HTML. Instead of id use class like this
Html:
<p class="name" name="print">hey</p>
<p class="name" name="this">hey</p>
<button id="btn11">test11</button>
jquery:
$("#btn11").click(function(){
var getName = $(".name").map(function() {
return $(this).attr("name");
}).get();
console.log(getName);
});
id should be unique in html. You should use class attribute:
<p class="name" data-name="print">hey</p>
<p class="name" data-name="this">hey</p>
<button id="btn11">test11</button>
$("#btn11").click(function(){
$.each($(".name"), function(i, v) {
console.log($(v).data("name"))
})
});
Also, name is not a property of <p> tag. See Element.name
You should not use dupicate IDs in HTML, still you want to use the the same here is the code which works as you expected
$("#btn11").click(function () {
$("p[id='name']").each(function (e) {
alert($(this).attr("name"));
});
});
DEMO HERE
id should be unique. not recommended to use duplicate id's in the html document.
still if you want continue with your old code.
you can also do like this
document.querySelectorAll('p[id=name]')[0]
Extremely bad practice.
Two separate elements should NOT contain the same ID nor name. Apply a class name and iterate (using an each or map) through the class name. There are many ways to do this (I already see some solid examples here). Then, make use the data attribute to store unique data per each element.
I want the value of last textbox to be grabbed by the varialble on multiple textbox with same ID.
HTML
<input type="text" id="get"><br>
<input type="text" id="get"><br>
<button id="grab">Click</button><br>
SCRIPT
$("#grab").click(function(){
var value = $("#get").val();
});
Or, a way to delete the first textbox might also work. Working Example
Your HTML is invalid: HTML elements can't have the same id attribute.
Use the class attribute, instead.
You can then use .last() to get the last element that matches the .get selector:
$("#grab").click(function(){
var value = $(".get").last().val();
alert(value);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" class="get" value="foo"><br>
<input type="text" class="get" value="bar"><br>
<button id="grab">Click</button><br>
(I added the value attributes for demonstrative purposes. Obviously, they can be removed.)
If you want to get the first element's value if the second one is empty, you could do this:
$("#grab").click(function(){
var firstValue = $(".get").val(); // `.val()` gets the first element's value by default
var secondValue = $(".get").last().val();
var result = secondValue || firstValue;
alert(result);
});
If you don't have any control on ids you should use following solution. If you can change the ids you should change them.
You approach will not work because the id is not unique. It will always get the first input.
$("#grab").click(function() {
// var value = $(this).prev("input").val(); // Will work when there is no `<br>`
alert($('input[id="get"]').last().val());
});
Here $('input[id="get"]') will get all the elements having id get and last() will get the last element from it.
Demo: https://jsfiddle.net/orghoLzg/1/