insertAfter - find - on() -- not working - javascript

i think, i have all set, but it is still not working - i am appending new html element input with X delete sign. if i click on that newly added X sign, the newly added input should be deleted. what i did is:
function addmore(){
$('<input type="file" name="bild[]"/> <a class="del">X</a> <br/>').insertAfter('#more').find('.del').on('click', function(){
alert('test');
});
}
my html is:
add more
<p id="more"></p>
it is inserting well, but i cannot delete the newly added element (alert is not firing). why is this?
thanks a lot

The .find() function looks for elements that are inside the current set of matched elements, but doesn't include those matched elements. Your <a class="del"> element is part of the set of matched elements so won't be picked up.
Use .filter() instead:
....filter('.del').on('click', function() {...});

Your .find() selector doesn't actually return anything. If you look at how jQuery processes your HTML string:
> $('<input type="file" name="bild[]"/> <a class="del">X</a> <br/>')
[<input type=​"file" name=​"bild[]​">​, #text, <a class=​"del">​X​</a>​, #text, <br>​]
You'll see that it's actually parsing each of those elements and text nodes as separate elements in a selector. .find() won't return anything, as it'll look only through the descendants of those elements, not the elements themselves:
> $('<input type="file" name="bild[]"/> <a class="del">X</a> <br/>').find('.del')
[]
I'd start with something like this:
$('<input type="file" name="bild[]"/>').insertAfter('#more');
$('<a class="del">X</a>').insertAfter('#more').on('click', function(){
alert('test');
});
$('<br/>').insertAfter('#more');
Or make a generic selector from the beginning that automatically handles click events, even for elements that don't exist yet:
$('#more').on('click', '.del', function() {
alert('test');
});

Try this
function addmore(){
var element = $('<input type="file" name="bild[]"/> <a class="del">X</a> <br/>').insertAfter('#more');
element.filter(".del").on('click', function(){
alert('test');
});
}

Related

prev() not returning div element

I'm probably being especially dense about this, but I can't get an element to return using prev(). My basic HTML structure is:
<div>
<table></table>
</div>
<input type="button">
Where when I press the button, I want to get the previous element (the div element). To achieve this my button has a function attached to it with
var nearestDiv = $(this).prev();
When I've checked the contents of nearestDiv in the console it appears to be some kind of JQuery object rather than a HTML div. I've tried popping .val() at the end of .prev() but this comes back empty. How can I get the div element?
Note that my button is generated on the fly and doesn't have anything which identifies it.
you need to use jquery get function, to get a native html object and not the jquery wrapper:
$("input").on("click",function(){
console.log("jquery wrapper:",$(this).prev());
console.log("native html div object:",$(this).prev().get(0));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<table></table>
</div>
<input type="button">
If your html structure is same as you provided in the question, it will definitely return the div element. Note that there is no val() method for div element, you need to either use .html() or .text() inorder to get the contents.
$("input[type='button']").click(function () {
var div = $(this).prev();
alert(div.html());
alert(div.text());
});
Fiddle
You need to give .text() or .html() for standard HTML Elements. So your code should be:
var nearestDiv = $(this).prev().html();
var nearestDiv = $(this).prev().text();

Retain jQuery functionality when buttons are added on the go

I have a block of list element which I need to add when "Add" button is clicked.
HTML:
<li>
<div><h3 >User name sss updated this.
<input type="button" value="X" class="delete"/></br></h3>
</div>
SOME TEXT HERE
</li>
jQuery:
$(".delete").click(function(){
$(this).closest("li").slideUp();
});
$("#addPost").click(function(){
var inData = '<li><div><h3>User name sss updated this.<input type="button" value="X" class="delete"></input></br></h3></div>';
$("#midContent ul").append(inData+'Sarthak</li>');
});
This block has a delete button and a jQuery function attached to it.
If the block already exist on the page, its working fine.
But, when I add this block using jQuery append, the block is rendered rightly, but delete functionality does not work on newly added block.
Where I am going wrong?
Also, what will be the better way to add this block than hardcoding in JS code? (just by referring the element already on page by using id or class)
You need to delegate events for dynamically created DOM nodes. You can delegate to the parent div, or the document itself.
$(document).on('click', '.delete', function(e) {
//your code here
});
The second argument in the click handler is the selector for which you are attaching the click handler.
Further reading: http://learn.jquery.com/events/event-delegation/
Try to use the event .on('click',function(){}) on dynamically created elements.
$(".delete").on('click',function(){
$(this).closest("li").slideUp();
});
$("#addPost").on('click',function(){
var inData = '<li><div><h3>User name sss updated this.<input type="button" value="X" class="delete"></input></br></h3></div>';
$("#midContent ul").append(inData+'Sarthak</li>');
});
Also, why create a variable when you could append the code directly?

why this javascript code is not working?

Do you know why this is failing, I mean alert is working (it shows me that if found the button) but text or background is not changed:
$('input[type=button]').click( function() {
var button=document.getElementsByName("contactme");
alert(button.length + " elements!");
button.value="New Button Text";
button.style.backgroundImage="url(some_real_gif);"
});
HTML:
<input type="button" name="contactme" value="test"/>
Thanks...
I have to use plain java script not jQuery..
You're setting value and style of a NodeList. getElementsByName can retrieve multiple elements, as the name attribute does not have to be unique in the document (the clue's in the name!) Setting these has no effect -- it doesn't affect the properties of the element(s) within the NodeList.
Either loop through the element(s) manually (using a for loop) or fully use jQuery:
$('input[type=button]').click(function () {
var buttons = $('input[name="contactme"]');
alert(buttons.length + " elements!");
buttons.val("New Button Text");
buttons.css({backgroundImage: "url(some_real_gif)"});
});
See the jQuery API:
val
css
attribute-equals selector ([name="value"])
It looks like var button=document.getElementsByName("contactme"); would return an array of elements. Try:
var button=document.getElementsByName("contactme")[0];
getElementsByName will return a nodeList but value and style are properties of HTMLElementNodes. You have to loop over the list to get them.
$('input[type=button]').click(function() {
$("#contactme").val('New Button Text').css('background-image', 'url(some_real_gif)');
});
You would need to make sure the button id matches the name...
Because button is a list of elements (even if it is a list of one)
What you can do is use button[0].value and button[0].style.background
Or use a jQuery solution:
To change only clicked button:
$('input[type=button]').click( function()
{
$(this).val("New Button Text");
$(this).css('background-image','url("some_real_gif")');
});
To change all buttons:
$('input[type=button]').click( function()
{
$('input[type=button]').each(function(){
$(this).val("New Button Text");
$(this).css('background-image','url("some_real_gif")');
});
});

How can a function find a parent element of the anchor which originally called the function?

Ok, the question alone is making my head spin.
I have an anchor tag that is calling a function:
Add a Guest
Just for reference, this is the function that's being called:
function addPerson() {
//current keeps track of how many rows we have.
current++;
console.log($(this).parent('form').attr('id'));
var strToAdd = '<div class="row">\
<div class="column grid_2">\
<label for="two-guests-name'+current+'">Guest '+current+':</label>\
</div>\
<div class="column grid_5">\
<input name="two-guests-name'+current+'" type="text" id="two-guests-name'+current+'" value="Name" onfocus="RemoveFormatString(this, \'Name\')" /> \
<input name="two-guests-age'+current+'" type="text" class="guestage digits" id="two-guests-age'+current+'" value="Age" size="4" maxlength="3" onfocus="RemoveFormatString(this, \'Age\')" />\
</div>\
</div>'
$('#numberguests').append(strToAdd)
};
I'd like to allow this function to work on multiple forms on a single page. So my thinking was to travel back in the tree to the parent form element, get its id and use that (somehow) to allow the function to work on multiple forms in the page.
You can see I tried using a quick console.log to test my idea, but it kept coming back "Undefined". I also tried running the console.log in the anchor tag itself, but it also was "Undefined".
I tested .parents() and it works perfectly in the anchor tag, but not in the function iteslf.
Any suggestions?
You should pass $(this) into add parents and then you'll have the proper scope to work with in your function. So:
Add a Guest
and then in the function use:
function addPerson(anchorElement) {
var form = anchorElement.parents("form");
//etc.
}
Don't use the onclick attribute use jQuery event binding. As you didn't provide any info about the markup you need to fill in the selector yourself
//this binds the same function to all a tags specified by the selector
$("form somemoreselectorgotgettheright a").bind("click", function() {
console.log($(this).parent("form").attr("id"));
....
});
The this context is different. Change the onclick to this:
addPerson.call(this);
That will make the this in the function match up with the this in the anchor tag.
Or better yet, don't use an onclick attribute at all, but use a jQuery event handler attachment, like this:
$(document).ready(function() {
$('#addPerson').click(function(ev) {
ev.preventDefault();
// Do something with $(this), which is the anchor tag
});
});
And your anchor tag would not have any click handler on it:
Add a Guest
Use parents() with a selector (this will search upward through all parents until the match i found). e.g.
$(this).parents('form').[...]
Pass in the id as a parameter. Eg
Add a Guest
then...
function addPerson(parent_id) {
// do something with parent_id

jquery append to already appended div

Is it possible to append something to a div that was already appended? I tried but nothing happens.. (I'm not using linebreaks in the actual js)
$(document).ready(function() {
$('.add_text_input').click(function() {
$('li').append('<div class="input_label">Untitled</div>\
<div class="edit_label"></div>\
<input type="text" name="untitled" /><br />');
});
$('.input_label').click(function() {
var input_label = $(this).html();
$(this).hide();
$('.edit_label').append('<input type="text" name="untitled" value="' + input_label + '"/><br />');
});
});
The js is for creating text inputs and editing their labels. When clicking on the "input_label" div, it should hide using hide() and append a text input with the default "untitled" value in the "edit_label" div. It works if the divs already exist but I need to make it work via append.
Does anyone have any ideas please?
You just need to use a .live() handler here, like this:
$('.input_label').live('click', function() {
var input_label = $(this).html();
$(this).hide().next('.edit_label')
.append('<input type="text" name="untitled" value="' + input_label + '"/><br />');
});
This will work on elements regardless of when they're created, since it works off event bubbling, it'll work on any element's click event that matches the .input_label selector.
Currently with .click() it's finding all the elements that exist at document.ready time and binding to those elements, not to the selector, so it won't work for dynamically added elements.

Categories

Resources