I am cloning some form elements and want to generate for them dynamic ids so I can acces their content later on, but I don't really know how to do that, I'm a noob with Jquery/Javascript, by the way.
My html:
<tr>
<td>
<label for="ability">Ability</label><br>
<div id="rank_ability" name="rank_ability">
<select name="ability" id="ability">
<option value=""></option>
<option value="hexa">Test</option>
</select><br>
<label for="range_ability_min">Range:</label>
<input type="textbox" name="range_ability_min" id="range_ability_min" class="small_text" value="0" /> -
<input type="textbox" mame="range_ability_max" id="range_ability_max" class="small_text" value="0" /><br>
</div>
Add Ability<br><br>
</td>
</tr>
My JS:
$(document).ready(function () {
var element, ele_nr, new_id;
$('.rank_clone').click( function() {
element = $(this).prev();
ele_nr = $('div[name="'+element.attr('name')+'"]').length;
new_id = element.attr('name') + ele_nr;
element.clone().attr('id', new_id).attr('name', new_id).insertAfter(element);
});
});
I setup a jsfiddle with what I got here: http://jsfiddle.net/xjoo4q96/
Now, I am using .prev() to select the element to clone which leads to those repeated 1 in the id/name attributes, how could I select it in another way (to mention: I really need to use 'this' because I need this little script in like 3 places, so I don't want to write it for an element with a specific id/class).
Also, I am counting only the element with the base name attribute so .lenght yelds 1 all the time, how would I go around counting all of them ? I guess I have to place them in another div or something but I don't know how would I go around couting them even then.
And, at last, how would I go around changing all the name/id attributes of the elements I have in the div ?
I'd appreciate any help. Thanks.
you can put the template in a hidden div like #tmpl, then clone and set the id attr, e.g.
$('#tmpl').children().first().clone().appendTo('#target').attr('id', 'the_generated_id');
Update
Demo of the template way: http://jsfiddle.net/xjoo4q96/1/, though it would be quite easy to adjust the code to clone the first component that already existed.
BTW, principally, id should be unique, thus the sub-element in the cloned component should use other attribute, like class or certain data- attribute, like those used in the updated fiddle.
Also you might want to call event.preventDefault() as you're clicking an <a>
You are searching already with the wrong name, since it still has the number attached. So delete it first, search for element which have a name attribute starting with this name and then use this base name to create a new one.
$(document).ready(function () {
var element, ele_nr, new_id, base_name;
$('.rank_clone').click( function() {
element = $(this).prev();
base_name = element.attr('name').replace(/[0-9]/g, '');
ele_nr = $('div[name^="'+base_name+'"]').length;
new_id = base_name + ele_nr;
element.clone().attr('id', new_id).attr('name', new_id).insertAfter(element);
});
});
And to answer your last question: you can not go around changing all ids of inner elements, it would be invalid HTML. In principal you can do the same with every id, like adding a number. If you have to do the same with all the name attributes depends on what you want to do exactly. If you have to distinguish between the first and second input, which I suggest, you have to change them too.
try to use cloneJs, it's clone ids, names input, and parametre inside functions ids of input must be like id_foo_1, id_foo_2 ,,,, and name be like inputName[0][foo], inputName[1][foo] https://github.com/yagami271/clonejs
Related
Here is my HTML:
<div class="tour" data-daily-price="357">
<h2>Paris, France Tour</h2>
<p>$<span id="total">2,499</span> for <span id="nights-count">7</span> Nights</p>
<p>
<label for="nights">Number of Nights</label>
</p>
<p>
<input type="number" id="nights" value="7">
</p>
</div>
This is my incorrect code for changing the test of the span element to read what I typed into the number input.
$(document).ready(function() {
$("#nights").on("keyup", function() {
$("#nights-count").text($("#nights").val());
});
});
This is the correct code:
$(document).ready(function() {
$("#nights").on("keyup", function() {
$("#nights-count").text($(this).val());
});
});
Why do I need to use self and not #nights for this to work?
If you have multiple id with name #nights in your document then default it select first one id with id #nights. where this will indicating the current selected DOM element instead of #nights id. If you use this it indicate to current selected DOM element, that's why you get correct output in your case there is multiple id with #nights.
It should work just fine unless #nights is not a unique ID. For example if there are multiple "tour" divs each having a #nights element. That said, $(this) is better because it doesn't require jQuery to go and parse the DOM again...
The issue is that you have more than 1 element with the id nights. Your first block of code works: http://jsfiddle.net/fomd990c/
If you have another element with the id nights it doesn't: http://jsfiddle.net/fomd990c/1/
It is generally a good idea to restrict a particular id to only one element.
so what I'm triying to achieve is that I want one element to append some other elements to div and change its ID attribute (or something similar).
i have tried something like this
$('#add3').click(function(){
$('#add3').attr("id", "add4");
$('.third_row1').append('something to append');
});
and also tried something like this:
$('#add').click(function(){
var vari = $("<div id='add2'>add another user</div>");
$('#add').remove();
$('.third_row1').append(vari);
$('.third_row1').append('something to append');
});
so clicking one button (like second example) has no effect on third, fourth ... n click
same thing with the second example
thanks in advance for help
UPD
ok, so here's how I generate selects which I want to append
<jsp:useBean id="obj1" class="com.Users" scope="page"/>
<div class="third_row1">
<select name="mySelect1" id="mySelect1">
<c:forEach var="item1" items="${obj1.items}">
<option>${item1}</option>
</c:forEach>
</select>
</div>
all I want to do is to add same select, but with different ids and names
Since elements IDs are changed dynamically, you should use delegated event handlers with .on().
For example:
$(document).on("click", "#add3", function() {
$('#add3').attr("id", "add4");
$('.third_row1').append('something to append');
});
If all these elements (#add, #add3) are inside page static element, it will be better to use this element instead of document for perfomance:
$("static_element_selector").on("click", "#add3", function() {
And just to note: since this inside event handler points to clicked DOM element, you can use this.id = "add4" instead of $('#add3').attr("id", "add4");. It is shorter and works slightly faster.
<input name="Indian_Karnataka_Bangalore" value="Bangalore" />
<input name="Indian_Andhra_Hyderabad" value="Hyderabad" />
<input name="Indian_Kerala_Trivandrum" value="Trivandrum" />
<input name="Indian_Maharashtra_Mumbai" value="Mumbai" />
At a given time, only one input element will be present in the DOM. How will I know the name of the specific input element name? I don't want to depend on values as it might change.
Using jQuery.
The INDIAN term will be static in every input element.
Actually i am trying to validate the input elements. DOM will have all the elements but at a given time only one element will be active and that element should have some value in it.
var $inputs = $('input[name*="Indian"]'),
inputsName = $inputs.attr('name');
You can use the same selectors as you would CSS.
Chris Coyier wrote a piece on attribute selectors here
var indianInputs = $("input[name^='Indian']");
//Matches all input elements whose name attrributes 'begin' with 'Indian'
This differs than the one posted by #ahren in that his selector will match all input elements whose name attribute contain the string 'Indian'.
indianInputs.attr("name");
Would return the first matched element's name attribute's value, which, for your markup will be Indian_Karnataka_Bangalore
To find the names of all indianInputs, you must iterate over all matched elements
var indianInputNames = [];
indianInputs.each(function() {
indianInputNames.push($(this).attr("name"));
});
$('input[name="element_name"]')
You have a lot of ways to select by the name of the attribute check http://api.jquery.com/category/selectors/attribute-selectors/
Try
var name = $('input[name^="Indian_"]').attr('name')
Have you tried the filter function? Something like this:
$('input:visible')
.filter(function() {
return $(this).attr("name").match(/^Indian/);
});
This will return an array of input elements whose name starts with "Indian".
There is a good example here: https://stackoverflow.com/a/193787/1237117.
I have a javascript program to filter a list of things in a HTML select control by typing a regular expression into an input (text) box. I can do the following to correctly filter a specific select control:
$(function() {
$('input[data-filterable]').keyup(
function() {
filter = new filterlist(document.myform.myselect);
filter.set(this.value);
});
});
but I have used a custom attribute (something one can now do in HTML5) called data-filterable. The attribute will store the name of the select control that is to be filtered so that JS can use the name of the control to filter the list. This would be a good idea because I will have a general function to filter any select box rather than a specific one.
Any ideas how I do this? I need something like this in the HTML:
<input data-filterable='{"to":"#selectbox1"}' size="30" type="text" />
but I'm not sure exactly what I'm doing here and what to do with the JS.
Thanks guys :).
Try this:
<input data-filterable="#selectbox1" size="30" type="text" />
$(function() {
$('input[data-filterable]').keyup(
function() {
filter = new filterlist($($(this).data('filterable'))[0]);
filter.set(this.value);
});
});
To break down the expression $($(this).data('filterable'))[0]:
$(this) wraps this in a jQuery wrapper. In our context, since it's a jQuery keyup event handler, this references the <input> DOM node.
$(this).data('filterable') retrieves the contents of the data-filterable attribute as a string. In our case, it's #selectbox1.
After that this string gets passed in to jQuery as a selector: $($(this).data('filterable')).
Finally, we take the 0'th element of the returned array which should be the DOM element of the target selectbox. Of course, if there isn't a selectbox which fits the selector this will fail rather miserably. If you suspect that this is a real scenario, check the .length of the returned array first.
Hi I am trying to get the HTML of INPUT tag. But unable to..
<input type="checkbox" name="_QS4_CNA" id="_Q0_C7" class="mrMultiple" value="NA">
<label for="_Q0_C7">
<span class="mrMultipleText" style="">None of these</span>
</label>
</input>
And I am trying access as
var dat=$(':checkbox#_Q0_C7').html();
alert(dat);
But i cannot access this. Please help me on this..
The ".html()" method gets the contents of an element, and not the element itself. In your case, the problem is that your HTML is invalid. An <input> tag cannot have content. As far as the browser is concerned, the tag ends where the <label> tag starts, and the browser just ignores the closing tag.
Note that when you've got an "id" attribute to use to find an element, you don't need any other qualifiers in the selector (like ":checkbox"). Just "#_Q0_C7" is all you need, because "id" values have to be unique anyway.
edit — Note that if all you want is to get some attribute (like the value or the "checked" status) from the element, you can certainly do that:
var $cb = $('#_Q0_C7');
var isChecked = !!$cb.prop('checked'); // force a real boolean value
var value = $cb.val();
You can try accessing the RAW underlying DOM element and use its innerHTML property.
var dat = $(":checkbox#_Q0_C7")[0].innerHTML;
But like mentioned by Pointy, that might still get you nothing. Not sure what (if any) input elements have actual siblings.