I am running a loop which is appending input fields. Now, as I am using a loop, all the attributes are similars. So, when I need to grab any one of the then I am grabbing more than one field.
How do I dynamically change the attributes according to the index, so that I can grab the correct input field ?
ebs_no = data.number_ebs;
for(i=0;i<ebs_no;i++){
$('form.ebs').append("<br>EBS"+(i+1)+"</br>");
$('form.ebs').append('<br> SNAPSHOTNO <input type="text" name="'+i+'"></br>');
$('form.ebs').append('<input type="submit" name="submit">');
$('[name='+i+']').on('submit',function(){
alert($('[name='+i+']').val());
});
}
Replace this:
alert($('[name='+i+']').val());
by this:
alert($(this).val());
The code $(this) refers to the element being treated
Your are looking for event delegation.It is used for created Dynamically DOM elements and use class instead of iterare i in the loop
ebs_no = data.number_ebs;
for (i = 0; i < ebs_no; i++) {
$('form.ebs').append("<br>EBS" + (i + 1) + "</br>");
$('form.ebs').append('<br> SNAPSHOTNO <input type="text" class="someClass" name="' + i + '"></br>');
$('form.ebs').append('<input type="submit" name="submit">');
$('[name=' + i + ']').on('submit', function () {
alert($('[name=' + i + ']').val());
});
}
$(document).on('submit', '.someClass', function () {
alert($(this).val());
});
Related
I want to add a new a element when I click the button but it doesnt work
<div id="add-container">
<input type="text"> <button>add</button>
<div id="megobrebi">
<a>Levani</a>
<a>Markozi</a>
<a>Zuka</a>
<a>Sandro</a>
</div>
</div>
$(document).ready(function() {
$('#add-container').on('click', 'button', function(){
var value = $('#add-container input').val;
var html = '<a>' + value + '</a>'
$('$megobrebi').prepend(html);
})
})
You have two errors in the handler for the click event on the button.
First, you need to call the jQuery val method in order to get the value of the input.
Second, the selector for the DOM element where you want to prepend is not right.
Therefore, the code should be:
$('#add-container').on('click', 'button', function(){
var value = $('#add-container input').val();
var html = '<a>' + value + '</a>'
$('#megobrebi').prepend(html);
})
The last line should be
$('#megobrebi').prepend(html);
Change your script code to
$(document).ready(function() {
$('#add-container button').on('click', function(e){
e.preventDefault(); // You may use this line if you wish to disable the default functionality button.
var value = $('#add-container input').val();
var html = '<a>' + value + '</a>';
$('#megobrebi').prepend(html);
});
});
I'm learning and trying to put together a little bit of jquery. Admittedly I'm finding it difficult to find a good basics guide, particularly, when adding multiple actions to one page.
I read somewhere that the document listener should only be used once. I believe I'm using it twice here, but not 100% sure how to bring it into one listener.
Also because I've been hacking bits of script together, I think I'm using parts of javascript and parts of jQuery. Is this correct?
A critique of the code below [which does work] and any advice on how best to approach learning jQuery would be most helpful. Thanks.
Script 1 styles a group of 3 radio buttons depending on which one is clicked.
Script 2 appends new inputs to the bottom of a form.
var stateNo = <?php echo $HighestPlayerID; ?> + 1;
$(document).on('click', 'input', function () {
var name = $(this).attr("name");
if ($('input[name="' + name + '"]:eq(1)')[0].checked) {
$('label[name="' + name + '"]:eq(1)').addClass('nostate');
$('label[name="' + name + '"]').removeClass('selected');
}
else {
$('label[name="' + name + '"]').removeClass('nostate selected');
if ($('input[name="' + name + '"]:eq(0)')[0].checked) {
$('label[name="' + name + '"]:eq(0)').addClass('selected');
}
else {
$('label[name="' + name + '"]:eq(2)').addClass('selected');
}
}
});
$(document).on('click', 'button[name=btnbtn]', function () {
var stateName = 'state[' + stateNo + ']';
var newPlayerAppend = `` +
`<tr><td>` +
`<input type="hidden" name="state['` + stateNo + `'][PlayerID]" value="` + stateNo + `" /></td>` +
`<td><input name="` + stateName + `[Name]" value="Name"></td>` +
`<td><input name="` + stateName + `[Team]" type="radio" value="A">` +
`<td><input name="` + stateName + `[Team]" type="radio" value="">` +
`<td><input name="` + stateName + `[Team]" type="radio" value="B">` +
`</td></tr>`;
$("tbody").append(newPlayerAppend);
stateNo++;
});
HTML for the 3 radio button inputs
<td class="Choice">
<label name="state[1][Team]" class="teampick Astate ">A
<input name="state[1][Team]" type="radio" value="A" />
</label>
<label name="state[1][Team]" class="smallx nostate ">X
<input name="state[1][Team]" type="radio" value="" checked />
</label>
<label name="state[1][Team]" class="teampick Bstate">B
<input name="state[1][Team]" type="radio" value="B" />
</label>
</td>
Some of the code can be written more concisely, or more the jQuery way, but first I want to highlight an issue with your current solution:
The following would generate invalid HTML, if it were not that browsers try to solve the inconsistency:
$("tbody").append(newPlayerAppend);
A tbody element cannot have input elements as direct children. If you really want the added content to be part of the table, you need to add a row and a cell, and put the new input elements in there.
Here is the code I would suggest, that does approximately the same as your code:
$(document).on('click', 'input', function () {
$('label[name="' + $(this).attr('name') + '"]')
.removeClass('nostate selected')
.has(':checked')
.addClass(function () {
return $(this).is('.smallx') ? 'nostate' : 'selected';
});
});
$(document).on('click', 'button[name=btnbtn]', function () {
$('tbody').append($('<tr>').append($('<td>').append(
$('<input>').attr({name: `state[${stateNo}][PlayerID]`, value: stateNo, type: 'hidden'}),
$('<input>').attr({name: `state[${stateNo}][Name]`, value: 'Name'}),
$('<input>').attr({name: `state[${stateNo}][Team]`, value: 'A', type: 'radio'})
)));
stateNo++;
});
There is no issue in having two handlers. They deal with different target elements, and even if they would deal with the same elements, it would still not be a real problem: the DOM is designed to deal with multiple event handlers.
There are 2 places you are using anonymous functions. If the code block moves to a named function, the entire code becomes more maintainable. It also helps better in debugging by telling you upfront which function name the error may lie in.
Once you have named functions you will realise that you really do have 2 event listeners for click. So there isn't much benefit of moving them in one listener (or one function you may be referring to). These both event listeners attach on document object and listen to a click event.
Class names are always better when hyphenated. a-state over Astate.
If it works it is correct code, for once you asked about correctness.
It is absolutely fine to have multiple listeners but I usually prefer making everything under one roof. Consider making code as simple as possible which saves lot of time during maintenance.
you can use $(function() {}) or document.ready().
$(document).ready(function() {
$('input[type="radio"]').click(function() {
var thisa = $(this).parent();
var name = $(this).attr("name");
// Remove :selected class from the previous selected labels.
$('label[name="' + name + '"]').removeClass('selected');
// Add conditional class with tenary operator.
thisa.parent().hasClass("smallx") ? thisa.addClass('nostate') : thisa.addClass('selected');
});
$('button[name=btnbtn]').click(function() {
var stateName = 'state[' + stateNo + ']';
// Add TR and TD before appending the row to tbody
var newPlayerAppend = `<tr><td>` +
`<input type="hidden" name="state['` + stateNo + `'][PlayerID]" value="` + stateNo + `" />` +
`<input name="` + stateName + `[Name]" value="Name">` +
`<input name="` + stateName + `[Team]" type="radio" value="A"></td></tr>`;
$("tbody").append(newPlayerAppend);
stateNo++;
});
});
Hope this helps.
I am trying to add some textbox value to some other divs.
What I'd like to obtain is somthing like this:
textbox id = "text-box-name-1" ----> div id = "div-name-1"
textbox id = "text-box-name-2" ----> div id = "div-name-2"
textbox id = "text-box-name-3" ----> div id = "div-name-3"
and so on....
How can i do this? mind that the number of divs and textboxes are dynamically generated.!
Any suggestion will be really appreciated.
Thanks
EDIT
function test() {
var rooms = $("#howmanyrooms").val();
var roomcounter = 1;
for (var i = 0; i < rooms; i++) {
$("<div class='appendeddiv'>Room-" + roomcounter++ + "</div>").appendTo(".housecontainer");
$("<span>Room-" + roomcounter + " name</span> <input type='text' placeholder='name' id='room-" + roomcounter + "-id'></div></br>").appendTo(".infoncontainer");
};
if ($('.housecontainer').find('.appendeddiv').length) {
$("#buttonaddrooms").hide();
}
};
i have already this code that allows me to create as many divs and textboxes as i type inside the textbox as value.
Now, i want be able to set, for example as div title, what the user type inside the textbox, and the only way that i've thought till now is using the id that are dynamically generated by the code that i already have.
Thanks for editing the post...
I would suggest first to add one class as an identifier to the Textbox and Div so we can attach event with the help of jQuery
$("<div class='appendeddiv targetDiv_"+ roomcounter +"'>Room-" + roomcounter + "</div>").appendTo(".housecontainer");
$("<span>Room-" + roomcounter + " name</span> <input type='text' placeholder='name' id='room-" + roomcounter + "-id' lang='textInput' class='targetText_"+ roomcounter +"'></div></br>").appendTo(".infoncontainer");
After that following script will do the trick :)
<script type='text/javascript>
$(function(){
$("input.textInput").on("keyup",function(){
var target = $(this).attr("lang").replace("Text", "Div");
$("."+target).text($(this).val());
});
});
</script>
As per your fiddle If you want to update value mannualy onclick of any button then write this method.
<script type='text/javascript'>
function update(){
$("input.textInput").each(function(){
var target = $(this).attr("lang").replace("Text", "Div");
$("."+target).text($(this).val());
});
}
</script>
I'm pretty new to JQuery, as you can tell by my question...
The user can append many new input fields to the form. This works great, but how can they delete a specific field? If they append 5 input fields, how do they delete lets say the third field?
Below is my following code. What is currently does is always delete the first item when clicked.
$("#addNewItem").click(function(){
$("#invoice_items").append('<input type="text" name="name[]" value="name" id="item_name" class="item_name" /><img src="images/delete.png" />');
});
$("#delete_input").live("click", function(){
$("#item_name").remove();
$(this).remove();
});
How about using additional container for inputs?
http://jsfiddle.net/dFpMV/
$("#addNewItem").click(function(){
$("#invoice_items").append('<div class="input-container"><input type="text" name="name[]" value="name" id="item_name" class="item_name" />X<img src="images/delete.png" /></div>');
});
$("#delete_input").live("click", function(){
$(this).parent().remove();
});
First, count the number of inputs you've added and store it in a variable.
Then, when you add the element, make a unique identifier based on that number.
$("#invoice_items").append('<input type="text" name="name[]" value="name" id="item'+count'" class="item_name" /><img src="images/delete.png" />');
I would avoid using the specific item name as the id in this case, use something generic like item0, item1 etc.
Then, to remove
$("#item" + desiredNumber).remove();
$(this).remove();
all links need to have unique id. Allowing to append element with specified id twice is an error. What you could do is to add an artificial number at the end of id to make them unique. I would wrap both input and link into a div, i would assign an unique id to it, assign a class to delete link instead of id and remove div like ($this).parent().remove()
If you are using jQuery 1.7+: Also note that .live() is deprecated and you should use .on() instead (note that syntax is however a little bit different).
I made 2 examples for you and adding a dummy variable so you can see whats happend:
1 If you know how to DOM will look like and the relationship between the delete link and the input you can simply traversing to the previous item.
$("#delete_input").live("click", function(){
$(this).prev().remove();
$(this).remove();
});
http://jsfiddle.net/JgKRw/ Example nr 1 in action
2 You give each item a unique number when you add them to the DOM.
var dummyId = 0;
$("#addNewItem").click(function(){
dummyId++;
$("#invoice_items").append('<input type="text" name="name[]" value="name ' + dummyId + '" id="item_name" class="item_name" data-id="' + dummyId + '" /><a data-id="' + dummyId + '" href="#" id="delete_input">' + dummyId + '<img src="images/delete.png" /></a>');
});
$("#delete_input").live("click", function(){
var deletedId = $(this).data("id"); // Get the ID of the clicked link
$("input[data-id='" + deletedId + "']").remove(); // Seach for an input which has the ID
$(this).remove();
});
http://jsfiddle.net/JgKRw/1/ Example nr 2 in Action
I would implemented number 2, couse else you have to take care of the script if you want to change the UI.
Btw you should only have one element assigned to an ID, so change your ID and use classes insteed.
http://api.jquery.com/class-selector/
Given the markup you appending it should be simply $(this).prev().remove(); and ignore the IDs.
Here's my fiddle:
http://jsfiddle.net/JfUAa/
(function () {
var count = 0,
items = document.getElementById("input_items"),
$items = $(items),
tpl = '<div><input type="text" id="{{id}}" />delete</div>';
function addItem(){
$items.append(tpl.replace("{{id}}", count++));
}
function remove(){
items.removeChild(this.parentNode);
}
$("#addNewItem").click(addItem);
$items.on("click", "a", remove);
}());
Let's say I have three related text input fields:
<input name="x1" class="xField" value="" /><div class="note" style="display:none;">Match</div>
<input name="x2" class="xField" value="" /><div class="note" style="display:none;">Match</div>
<input name="x3" class="xField" value="" /><div class="note" style="display:none;">Match</div>
Now, when the value of any of these changes, and it matches the value of another one of the related fields, I want to "un-hide" the .note div next to each input with matching value.
So, this is what I have so far:
$(function() {
$(".xField").change(updateCommentsDisplay);
function updateCommentsDisplay() {
var $aVisibleNotes = [];
$(".xField").each(function() {
// If more than one field with the same value, add the next note div to an array
if ($(".xField[value="+$(this).val()).length > 1)
$aVisibleNotes.push($(this).next(".note");
});
$.each($aVisibleNotes, function(){
$(this).show();
});
}
});
This just doesn't feel efficient. I feel like I should be able to do this without loops. Any suggestions?
To do it without loops, simply use selectors. Also specify not(this) if you don't want the input to show the note following it.
$(".xField").keyup(function(){
var val=$(this).val();
$('.xField[value='+val+']').not(this).next(":hidden").show();
});
You can combine selectors to get the result....xField, same value, different input = show the next note.
$('.xField').change(function() {
var x = $(this);
$('.xField[value="' + x.val() + '"]')
.not(this).next('.note').show();
});
Instead of looping through each input just use a selector to find the inputs whose value matches:
$(function() {
$(".xField").change(function(){
var field_val = $(this).val();
$(".xField[value='" + field_val + "']").show();
});
});
For one thing, you should save the results of $(".xField');
So:
$(function() {
var xFields = $('.xField');
xFields.change(updateCommentsDisplay);
function updateCommentsDisplay() {
var $aVisibleNotes = [];
xFields.each(function() {
// If more than one field with the same value, add the next note div to an array
if(xFields.find('[value="' + $(this).val() + '"]').size() > 1)
$aVisibleNotes.push($(this).next(".note");
});
$.each($aVisibleNotes, function(){
$(this).show();
});
}
});
It also might be faster to use an actual value comparison instead of the Sizzle engine to find matches. You'd want to test it on jsperf, but I have a hunch.
turn them on and off if matches or no matches:
$(".xField").change(function() {
updateCommentsDisplay();
});
function updateCommentsDisplay() {
$(".xField").each(function() {
if ($(".xField[value=" + $(this).val() + "]").length > 1) {
$(this).next(".note").show();
}
else {
$(this).next(".note").hide();
};
});
};
See it in action: http://jsfiddle.net/MarkSchultheiss/UrBEk/