I have a list
<ul id="list">
<li> element one <span class="remover">X</span></li>
<li> element two <span class="remover">X</span></li>
</ul>
and this list is dynamically appended with
<input type="text" id="adder">
<button id="add">Add</button>
<script>
$("#add").click(function(){
$("#list").append('<li>'+$("#adder").val()+' <span class="remover">X</span></li>');
});
</script>
but the problem is this with part
<script>
$(".remover").click(function(){
$(this).parent().remove();
});
</script>
The remove works perfectly with the static added items, but when it comes to the new appended items nothing happens on click, doesn't even trigger the function
I'd suggest:
$('#list').on('click', '.remover', function(e){
$(this).parent().remove();
});
JS Fiddle demo.
References:
on().
parent().
remove().
Call the click function on list and set remover as target like so:
$( '#list' ).on( 'click', '.remover', function (e) {
$(e.target).parent().remove();
});
You can't set a click event directly on it, it has to be set on the element that never is added to the page.
you should use
on('click',function(){})
not
.click()
refer to : http://api.jquery.com/on/
as click will relate to current item within document , while on is related to future items that will be added to document , however you should always use on with something that already exists in your document like for example the parent of the future added element so use something like
$("#parent").children("li").children('.remover').on("click",function(){bla bla bla;});
Related
I'm creating a dynamic menu where I can add and remove a new form.
<input type="button" value="generate form" id="test"/>
<div id="form1"></div>
<script>
$(document).ready(function() {
$("#test").click(function() {
$("#form1").append("<select id='score-attempt'><option value='penalty'>penalty</option></select><input type='button' value='remove' id='remove'/><br>");
});
$("#form1 #remove").click(function() {
alert($(this).index());
});
});
The problem is that clicking on remove never triggers the alert box.
Thanks
The problem is that the element is added later and doesn't exist when the dom is loaded. Therefore the click event has to be delegated from an already existing element, e.g. like this:
$(document).on("click", "#remove", function(){
alert($(this).index() );
});
Instead of $(document) every other static parent element can be used for event delegation, just as example.
Update for the comments: as mentioned, $(document) only as example. I'd also prefer to use $("#form1") here like mithunsatheesh suggested.
And for reference: https://api.jquery.com/on/#on-events-selector-data-handler, section "Direct and delegated events":
"Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on()."
Update for the correct index: you'll get the correct index using e.g.
$("#form1").on("click", ".remove", function(){
alert($(".remove").index($(this)));
});
with the adjustment to use remove as class instead of id for the remove-button. IDs have to be unique, so classes are a better solution. index() starts counting with 0, so you'll get 0 for the first one.
As working example: Fiddle
You need to add an event handler on your #form1 input with #remove.
Look here, here and here.
Here is the working jsfiddle for you.
I'm using JS to create the HTML below. (It's a bootstrap dropdown button)
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle my-status" data-toggle="dropdown">
Status <span class="caret"></span>
</button>
<ul class="dropdown-menu status-menu" role="menu">
<li>None</li>
</ul>
</div>
And in JQuery I'm trying to process clicks on the link inside there.
$('li').on('click', 'a.status', function(e) {
e.preventDefault();
alert("hi");
});
I've tried about 6 different ways to select those links, but nothing I do seems to be catching it.
Since they're created dynamically, I know I need to use the 'on' function, but it just doesn't seem to be working in the least.
I can get it to work in a JSFiddle, but the code there isn't created dynamically - which is the issue I think.
Is there something stupidly obvious that I'm missing here?
If that whole chunk of HTML is dynamic, then you need to target the container that HTML is appended to and use on
$(containerOfAppendedContent).on("click", ".btn-group li a", function() {
Assuming the entire block of code you posted is created dynamically, or even just the list, when you bind events to dynamically added elements, you need to bind to elements that are already in the DOM when the code is executed. Try:
$(document).on('click', 'a.status', function(e) {
e.preventDefault();
alert("hi");
});
$(document) is a worst case scenario, so if you have an element closer to the ones being added dynamically that exists when the jQuery is executed, use that over document.
Make sure you are selecting a static parent, so if li is dynamically created too, use its parent or its parent's parent
$('div.btn-group').on('click', 'ul li a.status', function(e) {
e.preventDefault();
alert("hi");
});
if that div is also dynamically created you could go up to the body or even document
$(document).on('click', 'ul li a.status', function(e) {
e.preventDefault();
alert("hi");
});
Why don't you generate the ancor tag with a onclick function?
<li>None</li>
<script>
function DoSomething(){
// Do your work
}
</script>
Hope this helps
Use this
change li to document
$(document).on('click', 'a.status', function(e) {
e.preventDefault();
alert("hi");
});
I'm trying to create a function that starts when you click on a specific link in a listview.
The issue is that event doesn't seem to fire when you click the link. The list is created dynamically. I'm not sure if that causes an issue.
<label for="listviewForLastTenCalls">Last Ten Calls:</label>
<ul data-role="listview" id="listviewForLastTenCalls">
</ul>
<script>
$('#listviewForLastTenCalls li').click(function(){
//alert('click event handler fired');
</script>
Demo
<ul data-role="listview" id="listviewForLastTenCalls">
<!-- items dynamically generated -->
</ul>
JS
$(document).on('click', '#listviewForLastTenCalls li a', function () {
// code
});
The issue is you are adding the click listener after you have created the list. When you first create the listener there is nothing for it to listen to. You need to add the on click event after you add the <li>
$('#listviewForLastTenCalls li a').click( function () {
// code
});
I hope this is not your fully markup,...
<label for="listviewForLastTenCalls">Last Ten Calls:</label>
<ul data-role="listview" id="listviewForLastTenCalls">
</ul>
<script>
$('#listviewForLastTenCalls li').click(function(){
//alert('click event handler fired');
}); //<--
</script>
And if the list is creadted dynamically, you have to attach the event, after list was created...
You have to do event delegation for dynamically added elements.
$('"#listviewForLastTenCalls"').on("click",'li' ,function(){
alert('triggered');
});
And why on() works ??
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on().
Something like this:
$(function() {
$("#listviewForLastTenCalls li").on('click', function() { alert('clicked'); });
});
I am currently attempting to make a dropdown menu where selecting one of the links from the menu will change the hidden value as well as the text of the hyperlink. This is based upon Twitter's Bootstrap dropdown, and uses jQuery:
<div id="periodChooser" class="btn-group">
<input type="hidden" value="1" name="dtype" id="dtype1"></input>
<a data-toggle="dropdown" href="javascript:;">Weekend</a>
<ul class="dropdown-menu">
<li>Weekend</li>
<li>Week</li>
<li>Midweek</li>
</ul>
</div>
The script that I have attempted to write is as follows:
<script>
jQuery(function($){
$('#periodChooser').each(function() {
$('.dropdown-menu a').click(function() {
$('.btn-group').find('input[type=hidden]').val($(this)
.data('value')).change();
$('.btn-group').find('.btn:eq(0)').text($(this).text());
});
});
});
</script>
Unfortunately, whilst it doesn't return any specific error, the code does not work. Any suggestions?
Bind event out side each
<script>
$('#periodChooser .dropdown-menu a').click(function() {
$('.btn-group').find('input[type=hidden]').val($(this)
.data('value')).change();
$('.btn-group').find('.btn:eq(0)').text($(this).text());
});
</script>
I think that this can be optimized and made more re-usable.
First of all, you are using jQuery selectors like $('.btn-group') very ineffectively.
Secondly it will break, if you will use more than one "widget", because the context is whole document and it will find all elements with that class .btn-group.
Thirdly it would be more effective to use single event handler that is being binded to the parent <ul> element instead of each <a> element. It's called "event delegation". http://api.jquery.com/delegate/
<script>
$('#periodChooser').each(function() {
var $input = $('input', this),
$select = $('>a', this);
$('ul', this).on('click', 'a', function() {
var $this = $(this);
$input.val($this.data('value')).change();
$select.html($this.html());
});
});
</script>
I made this code available in JSBin: http://jsbin.com/welcome/38724/edit
What I did here?
<script>
$('#periodChooser').each(function() {
// Find and store input and "select" element only once.
var $input = $('input', this),
$select = $('>a', this); // This finds only direct child element <a>
// Find the <ul> element inside the #periodChooser
// Bind a click event that will "bubble up" from <a> elements that are children of it
$('ul', this).on('click', 'a', function() {
// Wrap a jQuery around the <a> element
var $this = $(this);
// Set the input value and execute "change" event(s)
$input.val($this.data('value')).change();
// Change the "select" title. Doesn't matter if you use html() or text() - choose yourself!
$select.html($this.html());
});
});
</script>
Now, you can use this to make multiple widgets inside single page! :)
<script>
$('.btn-group').each( /* Well, you know, the function goes here... */ );
</script>
Of course, threre are many other things that has to be done here, like opening and closing the "option list", scrolling and probably many other things...
I want to find the order of the <li> the user has clicked. For eg.,
<ul>
<li id="li1">This is list one</li>
<li id="li2">This is list Two</li>
<li id="li3">This is list three</li>
</ul>
When the user clicks on the list item 2, then I had to retrieve the id of that item as li2. How to achieve this?
As pointed out below there are a couple of ways to add the event handlers. .bind is one, .click another. You can also create the function with your logic separately and refer to it in you bind or click event attachment.
<script type="text/javascript">
// version 1 with bind
$(function(){
$("li").bind("click", function(){alert(this.id);});
})
</script>
<script type="text/javascript">
// version 2 with click and the separated method
$(function(){
$("li").click(listClickHandler);
})
function listClickHandler(){
alert(this.id);
}
</script>
separating your handler methods from your handler assignments makes a lot of sense when you are assigning event handlers on the fly or at different points in the page life cycle. The reason I use bind more often then click is that bind can be used for a lot of different events so it would be easy to imagine creating an event assignment factory:
<script type="text/javascript">
// version 3, event assignment factory
function assign(selector, event, method){
$(selector).bind(event, method);
}
$(function(){
assign(".menu li", "click", listClickHandler);
assign(".menu li", "mouseover", listHoverHandler);
})
function listClickHandler(){...};
function listHoverHandler(){...};
</script>
hopefully this is more then you will ever need.
Assuming there are just these li items on the page, the following would alert the id of the li if the user clicks on it.
<!-- on the side: you could leave out the type attribute, when using HTML5 -->
<script type="text/javascript" charset="utf-8">
$(document).ready(function(){
$("li").click(function(){
alert($(this).attr("id"));
});
});
</script>
More on click: http://api.jquery.com/click/
Mode on attr: http://api.jquery.com/attr/
Alternatively to Gabriels answer:
$("li").click(function(){
alert($(this).attr('id'));
});
$('li').click(function(){
alert(this.id);
});
There is no need for an extra $()-function call: this.id works as well.
you might need to loop through your li list. I think you want to generate li ids depending on their index relative to the parent ul. right? you can that with following code
$("ul li").each(function(index, node){
$(this).click(function(){
alert("You clicked on li"+index);
});
});
See this http://www.jsfiddle.net/w9qpj/1/ for live example.
For fetching index of particular li you can use jQuery index function http://api.jquery.com/index/.
or for fetching li using its index you can use jQuery eq function http://api.jquery.com/eq/
$('ul li').eq(2).css('background-color', 'red');
Above code will make ul's 3rd li element's bacground color red.