The plan for what I'm building is: You can click a button to create some houses, and they will be assigned a random ID. (I know is not a unique ID right now).
When you click on one of the houses that you have created you will be able to see some information about the house and a DELETE button:
$('.House').click(function(){
var iDivHouseId = $(this).attr('id');
var oHouse = findHouseId(iDivHouseId);
$('#ShowId').text("ID: " + oHouse.getId());
$('#ShowStreetName').text("Street name: " +oHouse.getStreetName());
$('#ShowNumber').text("Number: " +oHouse.getNumber());
$('#WindowDisplayPersonInfo').append('<input type="button" id="DeleteHouse" value="DELETE" />');
$('#DeleteHouse').click(function () {
$(?????).remove();
});
});
But as marked with the question marks, I don't know what I have to put in to delete the house by it's randomly created ID. I can just add the class .House, but then all houses will be deleted.
// Also, right now, several delete buttons shows when you click the house a couple of times, since it appends a new button each time. How do I replace the old button with a new, instead of just creating a new each time.
I would make the delete button static markup, so you don't have to append it or bind the click handler multiple times. I would then keep track of the current element id using data() and reference that from your click handler.
$('.House').click(function(){
var iDivHouseId = $(this).attr('id');
$('#WindowDisplayPersonInfo').data('current-elem-id', iDivHouseId);
var oHouse = findHouseId(iDivHouseId);
$('#ShowId').text("ID: " + oHouse.getId());
$('#ShowStreetName').text("Street name: " +oHouse.getStreetName());
$('#ShowNumber').text("Number: " +oHouse.getNumber());
});
$('#DeleteHouse').click(function () {
$('#' + $('#WindowDisplayPersonInfo').data('current-elem-id')).remove();
});
By the JSFiddle, if you want to just remove the div from the right side you can try remove the launcher of the click event. To prevent errors with "this" in js, as it always changes values, you can receive a argument in your click function.
Something like this:
$('.House').click(function(e){
var iDivHouseId = $(this).attr('id');
var oHouse = findHouseId(iDivHouseId);
$('#ShowId').text("ID: " + oHouse.getId());
$('#ShowStreetName').text("Street name: " +oHouse.getStreetName());
$('#ShowNumber').text("Number: " +oHouse.getNumber());
$('#WindowDisplayPersonInfo').append('<input type="button" id="DeleteHouse" value="DELETE" />');
$('#DeleteHouse').click(function () {
$(oHouse).remove();
$(e.target).remove();
});
});
});
Related
EDIT: This is a more sound approach, since provided answer may have bugs when implementing a tags, or img tags.
================================================================
I am calling blog data from an API. (I've reformatted the data into an array by month).
So far, the blog titles print to the web page. I'd like a user to be able to click a title and have its description revealed.
Here is some of my code so far:
var blogPosts = $('#blog-posts');
$.each(byMonth, function(key, value) {
var outer = byMonth[key]
$.each(outer, function(k, v) {
var inner = outer[k]
var monthBlogPosts = $('<div class = "month"> </div>').appendTo(blogPosts);
$.each(inner, function(i, obj) {
title = inner[i].Title
description = inner[i].Description
date = inner[i].DatePublished
$('<div class = "title-list"><h3 class = "unique-title">' + title + '</h3></div>').appendTo(monthBlogPosts)
// if a title is clicked, show its Description
showDescription(description);
})
})
});
function showDescription(d){
$('.unique-title').on('click', function(){
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
}
When I click a title, all descriptions print instead of the matching description. I understand this is because I called the function in a nested loop, but I've also had trouble calling the description variable outside of it.
I have also tried
showDescription(title, description)
//...
function showDescription(t, d){
$(title).on('click', function(){
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
}
but then nothing is printed to the html page.
Essentially, I'd like to grab the title index, and print it's respective description when its clicked.
you should use event delegation to attach a click event to the document that will bubble up and trigger when .title-list is the event target.
$(document).on('click', '.title-list', function(event) {
showDescription(event.currentTarget) // pass the element being clicked (we will need it later)
})
you would also need to modify the way you get the description.
you could store you description in a data attribute of .title-list like so:
$('<div class = "title-list" data-description="'+ description +'"><h3 class = "unique-title">' + title + '</h3></div>').appendTo(monthBlogPosts)
so you can now modify showDescription() so it would get the data from the element we pass to the function
function showDescription(element){
var d = $(element).data('description')
$('<p>' + d + '</p>').appendTo('body')
console.log(d)
})
So ok. From whatever I could understand (by looking at your code). You cannot register an event with simple on for dynamically added element. You have to use on delegate.
Try this
1) remove the function call (inside a loop)
2) delete the entire function showDescription and add event as below:
$('#blog-posts').on('click', '.unique-title',function(){
alert('title clicked').
});
3) As to display the description I think the best way will be to add the description in a div and hide it. Display it later once the title is clicked.
(inside the loop)
$('<div class = "desc" style="display:none">' + description + '</div>').appendTo(monthBlogPosts);
then on #2 above. Replace with this.
$('#blog-posts').on('click', '.unique-title',function(){
$(this).next('.desc').show(); //I am assuming desc will be next to the clicked title here. You can modify it as needed.
});
Finally, this is just an overview of a code so might not work as expected but I am pretty sure this should give you an idea and get you started
I got a question, what I have already solved, but it's just so annoying.
I have a js code, which is putting down some html code when a button is pushed with "append", and with that code I'm giving an id to an x button, and an id to the container element. I wanted to use these id-s to identify them with a click function, to remove the html code:
var num = 0;
$('.button').click(funcion(){
num++;
var code = '\
<div class="container" id="text' + num + '">\
<div id="x' + num + '">\
x\
</div>\
Some stuff\
</div>\
';
$('.puthere').append(code);
$('#x' + num).click(function(){
$('#text' + num).remove();
});
});
Now the annoying part is the click function on the x. What I would expect is, that this code would work somehow like this:
1st click on the "button" class element should give this code:
$('#x1').click(function(){
$('#text1').remove();
});
after 2nd click I should have this:
$('#x1').click(function(){
$('#text1').remove();
});
$('#x2').click(function(){
$('#text2').remove();
});
instead what I'm getting after the 2nd click is this:
$('#x1').click(function(){
$('#text2').remove();
});
$('#x2').click(function(){
$('#text2').remove();
});
so it's always the last element what the x buttons want to remove. My question is, why can my "num" variable stay "1" at the #x1, but not at the #text1?
My solution was to address the parent element instead:
$('#x' + num).click(function(){
$(this).parent('.container').remove();
});
I know, that there is the "live" function too, what I could use, and I wouldn't need to mess with id-s, but that just seems more heavy. Is that correct? Or I'm overcomplicating things too much without making it more efficent?
It's because num is global and you access it after you create second button. To fix this you can wrap your code with anonymouse self executing function:
(function(num) {
$('#x' + num).click(function(){
$('#text' + num).remove();
});
})(num);
or better use only one click
$('.parent').on('click', '.container > div', function() {
$(this).parent().remove();
});
I have a form where I add inputs dynamically. When I add a new input I increment a global id variable and concatenate it to the input's id so it will be unique. I also create a delete button for each input that should remove that input and himself (through removing the container <div> they are in). I do the remove process by adding an anonymous function to the delete button's click event via JQuery:
$('#deletebutton' + id).click(function(){
$('#inputcontainer' + id).remove();
});
The only problem with this solution that it isn't work in the way I excepted it. When I click any of the delete buttons it will delete the last input container because when I click, it executes the anonymous function and evaluate the id variable at that time, so the selected id will be the last input's id. So always the last input container will be deleted.
Is there a way to rewrite this function so when I add it to the click event, than it will evaluate the id, inject it and handle the selection as if it had been written like #inputcontainer1, #inputcontainer2, etc.
I can make this by adding the function's body to the button's onclick() event:
var newbutton = '<button id="deletebutton' + id + '" type="button" onclick="javascript:$(\'#inputcontainer' + id + '\').remove();">x</button>';
But is there a way doing this with the JQuery click() way?
To answer the specific question, you'd have to dig the id out of the DOM:
$('#deletebutton' + id).click(function(){
var id = $(this).attr("id").replace('deletebutton','');
$('#inputcontainer' + id).remove();
});
You could also store it as data when you create the delete button:
<button data-id="1" id="deletebutton1">
$('#deletebutton' + id).click(function(){
var id = $(this).data("id");
$('#inputcontainer' + id).remove();
});
Note that in both of these cases, id is a string, not an integer.
When I click any of the delete buttons it will delete the last input container [...]
If your 1st snippet is inside a loop, id probably isn't being scoped to each iteration. So, by the time one of the click() events is triggered and it's trying to use .remove(), id will have already been set to the last value given while looping.
You can use an IIFE to create an additional function scope for keeping a different id for each iteration (ref: closure).
/* loop */ {
var id = ...;
(function (id) {
$('#deletebutton' + id).click(function(){
$('#inputcontainer' + id).remove();
});
})(id);
}
Though, for future reference, ECMAScript 6 is adding block scoping which should allow for:
/* loop */ {
let id = ...;
$('#deletebutton' + id).click(function(){
$('#inputcontainer' + id).remove();
});
}
$('#deletebutton' + id).click(function(){
$(this).parent().remove();
});
If the container isn't a direct parent and doesn't have a class you could do:
$('#deletebutton' + id).click(function(){
var idNum = $(this).attr("id").replace('deletebutton','');
$("#inputcontainer"+idNum).remove();
});
If you've got appropriate classes (or can add them), this would be best:
$(document).on("click",".deleteButton",function() {
$(this).parents(".inputContainer").remove();
});
I am designing a website which is like bulletin board with stickers on it. So each sticker has a close button. But I cannot find the id of the sticker, which the user clicked on the close button.
stickerId = 1;
function createSticker(jsonNewSticker){ // receives json
str = "<b>Email:</b> "+ jsonNewSticker.email+
"</br> <b>Title:</b> "+ jsonNewSticker.title+
"</br> <b>Summary:</b> "+ jsonNewSticker.summary+
"</br> <b>Description:</b> "+ jsonNewSticker.description +
"</br> <b>Entry expires: </b>" + jsonNewSticker.expiration_date;
$("#mainForSticks").prepend("<div id= seq-"+ stickerId +" ></div>");
$("#seq-"+ stickerId).attr("class","sticker");
$("#seq-"+ stickerId).html(str);
$("#seq-"+ stickerId).append("<div id=report><a class=link href=javascript:reportCounter()>Report</a></div>"); // report
$("#report").attr("class","reportText");
$("#seq-"+ stickerId).append("<div id=deleteSticker><a class=link href=javascript:deleteSticker()><b>X</b></a></div>"); // delete
$("#deleteSticker").attr("class","delSticker");
//currentId = $(this).attr('id');
stickerId++;
}
so here each sticker has an id: seq-1 seq-2 seq-3 ...
function deleteSticker(){
// how can I get id of specific sticker
}
The sticker is relative to the close button so you don't really need the ID. I just use the closest() method and the appropriate selector.
However, whether you need ID or not, I put a dynamic handler on the sticker close buttons here. You can add as many stickers as you want. This makes your inline javascript call to javascript:anything obsolete, making the code easier to maintain.
The handler here is using deleteSticker as its callback but you can do whatever you want in it including get the ID (which I show in the alert) or delete the sticker, etc.
Bonus points for stickers with colors? :D
Fiddle
var deleteSticker = function(){
var sticker = $(this).closest('[id^="seq"]');
alert("your sticker # is: "+sticker.attr('id'));
sticker.remove();
}
$('#mainForSticks').on('click', 'a', deleteSticker);
You can pass the Id in deleteSticker function and use it like this
function deleteSticker(item){
var element=document.getElementById(item)
}
and add this function like this
var elementId="seq-"+ stickerId;
$("#seq-"+ stickerId).append("<div id=deleteSticker><a class=link href=javascript:deleteSticker(elementId)><b>X</b></a></div>"); // delete
You can achieve this in two ways.
1st way is passing parameter to it like:
$("#seq-"+ stickerId).append("<div id=deleteSticker><a class=link href=javascript:deleteSticker(" + stickerId +")><b>X</b></a></div>"); // delete
function deleteSticker(ID){
var x = $("#" + ID);
}
2nd way is starts with selector, like:
$(function(){
$('div[id^="#seq-"]').click(function(){
// here is your click.
});
});
Change
$("#seq-"+ stickerId).attr("class","sticker");
$("#seq-"+ stickerId).html(str);
$("#seq-"+ stickerId).append("<div id=report><a class=link href=javascript:reportCounter()>Report</a></div>"); // report
$("#report").attr("class","reportText");
$("#seq-"+ stickerId).append("<div id=deleteSticker><a class=link href=javascript:deleteSticker()><b>X</b></a></div>"); // delete
$("#deleteSticker").attr("class","delSticker");
To this:
$("#seq-"+ stickerId)
.attr("class","sticker")
.html(str)
.append("<div id='report' class='reportText'><a class=link href='#'>Report</a></div>") // report
.append("<div id='deleteSticker' class='delSticker'><a class=link href='#'><b>X</b></a></div>"); // delete
Add this code outside of the function, in jQuery $(document).ready({, i.e.:
$(document).ready({
$('body').on('click', '.delSticker', function() {
deleteSticker(this);
});
});
Then, change your deleteSticker() to:
function deleteSticker(elem) {
$(elem).parents('.sticker').remove();
}
This is a good place for data attributes. They allow unobtrusive JavaScript and don't have any reliance on the document structure (e.g. as does the looking for the closest matching element).
Demo: http://jsfiddle.net/EN5Ht/2/
I suggest adding the ID of the associated item when the delete button is being generated.
As a side note, it appears that you may be assigning duplicate IDs ("report" and "deleteSticker") if you call createSticker() more than once. IDs must be unique.
Sample HTML
<button data-role="delete-button" data-id="seq-1">Delete</button>
<button data-role="delete-button" data-id="seq-2">Delete</button>
<button data-role="delete-button" data-id="seq-3">Delete</button>
<div id="seq-1">Item 1</div>
<div id="seq-2">Item 2</div>
<div id="seq-3">Item 3</div>
Note that there is no inline JavaScript and that we added a data-role and a data-id to each element. The delete buttons can be any element you want; they can be located anywhere within the document.
JavaScript
$("body").on("click", "[data-role='delete-button']", function(){
var button = $(this);
$("#" + button.data("id")).remove();
});
We then listen for all click events on matching elements (now, or dynamically added later) which are designated as delete buttons.
When the event is fired, we retrieve the button responsible and get the value of its data-id attribute. This tells us the associated element, which can then be hidden/removed as desired.
I have a website where user can select an item, the detail is then displayed, including the quantity. I have also included a button inside the div so that when clicked, it should decrease the quantity by 1.
$("#btnBuy1").click(function()
{
if (!sessionStorage['quantity1'])
{
sessionStorage['quantity1']=1;
}
else
{
sessionStorage['quantity1']++;
}
$("#dropbox").html('<div id = "1"><img class = "thumb" id = "t1" src="../images/birthday_metoyou.jpg" />' + teddy[1].desc + ", Price £"
+ teddy[1].price + ", Quantity: " + sessionStorage.getItem('quantity1') + "<button id = 'btnRemove1'>Remove</button></div><br/>");
updateBasket();
sessionStorage["total1"] = parseInt(sessionStorage.getItem('quantity1')) * teddy[1].price;
updateSubtotal();
if (Modernizr.sessionstorage)
{ // check if the browser supports sessionStorage
myids.push(teddy[1].partnum); // add the current username to the myids array
sessionStorage["ids"]=JSON.stringify(myids); // convert it to a string and put into sessionStorage
}
else
{
// use cookies instead of sessionStorage
}
});
$("#btnRemove1").click(function()
{
alert(remove);
});
I put in an alert message to see if the button is working properly, but when I click the btnRemove1 button, nothing happens.
Since the button is dynamically added, can you try:
$(document).on('click', '#btnRemove1', function() {
{
alert("remove"); //I dont know what remove was is the example, added quotes around it.
});
That is because the button is added later (dynamicly). You will have to use a delegate.
You don't have to use body for this. Any non dynamicly inserted element that is a parent of #btnRemove1 will do.
$('body').on('click','#btnRemove1',function(){
alert(remove);
});
The reason is that you bind the event before the element #btnRemove1 is present on your page. Therefore there is nothing to bind the event to. The body element however - will be present on the page and delegate your event to #btnRemove1.
You can either tie the event to the document (what jQuery live used to do before it was deprecated)
now it is:
$(document).on("click", "#btnRemove1", function(){})
or you can rebind the event after #btnRemove1 is added to the Dom.
Most likely, your Remove button isn't in the DOM before you try to attach the click event to it. It is hard to tell from your code snippets, but if the Buy button action hasn't completed successfully, then Remove won't exist.
At the point that you attach the click event to Remove, try console logging $("#btnRemove1").length to see if it exists, or use break points.
An improvement to your code would be to cache in a variable $("#dropbox") and then look for your buttons within it, as in:
var $dropBoxNode = $("#dropbox");
$dropBoxNode.find("#btnRemove1");
And you should use .on() instead of the deprecated .click().
Try putting the remove button click handler addition after you create the remove button
///Code snippit
$("#dropbox").html('<div id = "1"><img class = "thumb" id = "t1" src="../images/birthday_metoyou.jpg" />' + teddy[1].desc + ", Price £"
+ teddy[1].price + ", Quantity: " + sessionStorage.getItem('quantity1') + "<button id = 'btnRemove1'>Remove</button></div><br/>");
$("#btnRemove1").click(function()
{
alert(remove);
});
updateBasket();
///Code snippit
$('a.edit').on('click','a.edit',function(){
if (confirm("Are you sure you want to Edit this Photo?"))
{
....
....
}
});
Not Working When Data is Loading with AJAX on a DIV Area
Just Like
EDIT