Dynamically added Gridster widget can't close - javascript

I have added a dynamic gridster widget with a close button.
gridster.add_widget('<li id="wdg_news" data-row="3" data-col="5" data-sizex="2" data-sizey="3" class="tile-orange" data-ng-hide="!news.length"> <div class="db-wid"><div class="db-title"> Newss <i class="icon-close"></i></div><div class="db-content cus_scroll" style="height:304px;"> <div class="w-list"> <c:forEach items="${newsList}" var="news"><div>${news.date} - ${news.summery}</div></c:forEach></div></div></div> </li>', 2, 3);
all the data is getting loaded to it without any problem and when i click the close button it goes to login screen insted of calling the javascipt.
// Remove Grid
$(".db-ctrl").on("click", function(e) {
e.preventDefault();
var parentLi = $(this).parents("li");
var eq_val = $(".gridster ul li").index(parentLi);
gridster.remove_widget($('.gridster li').eq(eq_val));
console.log(eq_val);
saveGrid();
})
This doesnt happen to already created widgets. Only to ones which created dynamically using gridster.add_widget method.
Please Help in this matter. Thanks in advance.....

What you need to do is that instead of .on("click") you need to use .delegate("click").
.on listens for elements that already exist in the DOM. .delegate listens for elements that already exist in the DOM and are added in the future (e.g. when you dynamically add a widget).
So you just need to modify your click handler
$(".gridster").delegate("click", ".db-ctrl", function(e) {
e.preventDefault();
var parentLi = $(this).parents("li");
var eq_val = $(".gridster ul li").index(parentLi);
gridster.remove_widget($('.gridster li').eq(eq_val));
console.log(eq_val);
saveGrid();
})

Related

Input value of a cloned div not changing or firing events

I have a mock hidden div that I edit, clone and show to users. In this div is an input for which I set the value attribute using jQuery (tried with probably all methods). After I generate the new div and show it to users, the input does not fire any kind of events (focus, focusout, change) neither does the value of input change in HTML.
What am I missing or doing wrong?
Edit (code): HTML
<div class="item-wrapper" id="mock-item">
<div class="item-img"></div>
<div class="item-primary">
<p class="item-name">Foo Bar</p>
<input type="text" class="set-amount">
</div>
</div>
JS:
$("div.item-wrapper").click((e) => {
let item_id = e.currentTarget.id
let itemDetails = {
item_name: $(`#${item_id} .item.name`).text(),
suggested_amount: $(`#${item_id} #item-amount`).text(),
icon_url: $(`#${item_id} .item.big`).attr("style"),
}
$(".item-img", tmp).attr("style", itemDetails.icon_url)
$("#mock-item .item-name").text(itemDetails.item_name)
$("#mock-item .set-amount")[0].setAttribute("value", itemDetails.suggested_amont)
$("#mock-item").clone().removeAttr("id").appendTo(".item-wrapper").show()
})
Cloning an element removes all the event listeners from it. If you would like to listen for all event listeners on elements with a given selector, you can use jQuery's .on:
$(document).on("click", ".class", function () {
const $this = $(this);
});
You could also set the withDataAndEvents parameter on .clone to true: .clone(true).

jQuery slideDown not working on element with dynamically assigned id

EDIT: I cleaned up the code a bit and narrowed down the problem.
So I'm working on a Wordpress site, and I'm trying to incorporate drop-downs into my menu on mobile, which means I have to use jQuery to assign classes and id's to my already existing elements. I have this code that already works on premade HTML, but fails on dynamically created id's.
Here is the code:
...
var menuCount = 0;
var contentCount = 0;
//find the mobile menu items
var submenus = $('[title="submenu"]');
if (submenus.length && submenus.parent('.fusion-mobile-nav-item')) {
console.log(submenus);
submenus.addClass('dropdown-title').append('<i id="dropdown-angle" class="fa fa-angle-down" aria-hidden="true"></i>');
submenus.each(function() {
$(this).attr("href", "#m" + menuCount++);
})
var content = submenus.parent().find('ul.sub-menu');
content.addClass('dropdown-content');
content.each(function() {
$(this).attr("id", "m" + contentCount++);
})
}
$(document).on('click', '.dropdown-title', function(e) {
var currentAttrValue = $(this).attr('href');
if ($(e.target).is('.d-active') || $(e.target).parent('.dropdown-title').is('.d-active')) {
$(this).removeClass('d-active');
$(currentAttrValue).slideUp(300).removeClass('d-open');
} else {
$('.dropdown-title').removeClass('d-active');
$('.dropdown-content').slideUp(300).removeClass('d-open');
$(this).addClass('d-active');
console.log($(currentAttrValue));
//THIS LINE FAILS
$(currentAttrValue).slideDown(300).addClass('d-open');
}
e.preventDefault();
});
I've registered the elements with the class dropdown-title using $(document).on(...) but I can't figure out what I need to do to register the elements with the custom ID's. I've tried putting the event callback inside the .each functions, I've tried making custom events to trigger, but none of them will get the 2nd to last line of code to trigger. There's no errors in the console, and when I console log the selector I get this:
[ul#m0.sub-menu.dropdown-content, context: document, selector: "#m0"]
0
:
ul#m0.sub-menu.dropdown-content
context
:
document
length
:
1
selector
:
"#m0"
proto
:
Object[0]
So jQuery knows the element is there, I just can't figure out how to register it...or maybe it's something I'm not thinking of, I don't know.
If you are creating your elements dynamically, you should be assigning the .on 'click' after creating those elements. Just declare the 'on click' callback code you posted after adding the ids and classes instead of when the page loads, so it gets attached to the elements with .dropdown-title class.
Check this jsFiddle: https://jsfiddle.net/6zayouxc/
EDIT: Your edited JS code works... There also might be some problem with your HTML or CSS, are you hiding your submenus? Make sure you are not making them transparent.
You're trying to call a function for a attribute, instead of the element. You probably want $(this).slideDown(300).addClass('d-active'); (also then you don't need $(this).addClass('d-active'); before)
Inside submenus.each loop add your callback listener.
As you are adding the class dropdown-title dynamically, it was not available at dom loading time, that is why event listener was not attached with those elemnts.
var menuCount = 0;
var contentCount = 0;
//find the mobile menu items
var submenus = $('[title="submenu"]');
if (submenus.length && submenus.parent('.fusion-mobile-nav-item')) {
console.log(submenus);
submenus.addClass('dropdown-title').append('<i id="dropdown-angle" class="fa fa-angle-down" aria-hidden="true"></i>');
submenus.each(function() {
$(this).attr("href", "#m" + menuCount++);
// add callback here
$(this).click( function(e) {
var currentAttrValue = $(this).attr('href');
if ($(e.target).is('.d-active') || $(e.target).parent('.dropdown-title').is('.d-active')) {
$(this).removeClass('d-active');
$(currentAttrValue).slideUp(300).removeClass('d-open');
} else {
$('.dropdown-title').removeClass('d-active');
$('.dropdown-content').slideUp(300).removeClass('d-open');
$(this).addClass('d-active');
console.log($(currentAttrValue));
$(currentAttrValue).slideDown(300).addClass('d-active');
}
e.preventDefault();
});
})
var content = submenus.parent().find('ul.sub-menu');
content.addClass('dropdown-content');
content.each(function() {
$(this).attr("id", "m" + contentCount++);
})
}
Turns out my problem is that jQuery is adding to both the mobile menu and the desktop menu, where the desktop menu is being loaded first when I search for that ID that's the one that jQuery finds. So it turns out I was completely wrong about my suspicions.

Foundation dropdown stop working

I have a Foundation 5 dropdown on my page, which works fine. However when I submit a form in the dropdown area a new element is added to the top of the page so all the elements are moved down.
After that, all my dropdowns stop to work. (If I skip the adding of the element to the DOM, everything is working fine)
My dropdown:
<div id="file-tab">
<i data-dropdown="shareForm16" aria-controls="shareForm16" aria-expanded="false" class="iconTrigger"></i>
<form data-dropdown-content class="share-form f-dropdown content" aria-hidden="true" tabindex="-1" action="" id="shareForm16">
...
</form>
</div>
I thought I need to rebind the foundation event listeners, but it doesn't work. Maybe I am just doing it wrong.
$('#file-tab').on("submit", 'form.share-form',function(e){
e.preventDefault();
var groupName = $(form.target).find('input[type="text"]').val();
var id = $(e.target).parent().children('input[type="hidden"]').val();
if (groupName) {
$(e.target).trigger('click');
window.currentFTT.share(id ,groupName); // adds the element to the DOM
// my attempt to rebind:
$('#'+e.target.id).foundation({bindings: 'events'});
$('i[aria-controls="'+e.target.id+'"]').foundation({bindings: 'events'});
}
});
Instead of calling foundation for individual elements, make a general call to foundation, passing 'reflow' as a parameter:
$(document).foundation('reflow');
E.g:
$('#file-tab').on("submit", 'form.share-form',function(e){
e.preventDefault();
var groupName = $(form.target).find('input[type="text"]').val();
var id = $(e.target).parent().children('input[type="hidden"]').val();
if (groupName) {
$(e.target).trigger('click');
window.currentFTT.share(id ,groupName); // adds the element to the DOM
// my attempt to rebind:
$(document).foundation('reflow');
}
});

remove onclick when attached to children

I have the following code:
layoutOverlaysBldg = $("#layout-overlays-bldg")
layoutOverlaysBldg.on("click", "div", function(event) {
var floor;
console.log("floornum: " + this.dataset.floornum);
floor = parseInt(this.dataset.floornum);
...
$("#choose-floor").fadeOut();
$("#choose-apt").fadeIn();
});
later - based on data I'm getting back from the DB - I want to remove some of the .on("click", "div", ...) from only some of the divs. I already have the selector that is getting the right divs but I cannot figure out how to remove the click event. I have tried .off("click") after selecting the right div but it has no effect.
This issue here is because you are using a delegated event. You can add or remove the event for all child elements, but not individual ones given your div selector.
With that in mind the easiest way to do what you need is to add the event based on a class, then add and remove that class on the children as needed. Something like this:
layoutOverlaysBldg = $("#layout-overlays-bldg")
layoutOverlaysBldg.on("click", "div.clickable", function(event) {
// your code...
});
You can then enable/disable the event on the child div by adding or removing the .clickable class.
You can try like this :
Example :
<div id="test">
<div id="first">first</div>
<div id="second">second</div>
</div>
<div onclick="unbindSecondDiv();">UNBIND</div>
<script>
function unbindSecondDiv()
{
test = $("#second")
test.unbind("click");
alert('Selected Area Click is Unbind');
}
$(document).ready(function(){
//BIND SELECTED DIV CLICK EVENT
test = $("#test > div")
test.bind("click" , function(event) {
alert($(this).attr('id'));
});
});
</script>
In the above example , selected DIV elements click event is bind.
And after execute function unbindSecondDiv() , second DIV click event will be unbind.
Have a try , may helps you.

JS Events not attaching to elements created after load

Problem: Creating an Element on a button click then attaching a click event to the new element.
I've had this issue several times and I always seem to find a work around but never get to the root of the issue. Take a look a the code:
HTML:
<select>
<option>567</option>
<option>789</option>
</select>
<input id="Add" value="Add" type="button"> <input id="remove" value="Remove" type="button">
<div id="container">
<span class="item">123</span>
<br/>
<span class="item">456</span>
<br/>
</div>
JavaScript
$(".item").click(function () {
if ($("#container span").hasClass("selected")) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
$("add").click(function() {
//Finds Selected option from the Select
var newSpan = document.createElement("SPAN");
newSpan.innerHTML = choice;//Value from Option
newSpan.className = "item";
var divList = $("#container");
divList.appendChild(newSpan);//I've tried using Jquery's Add method with no success
//Deletes the selected option from the select
})
Here are some methods I've already tried:
Standard jQuery click on elements with class "item"
Including using the `live()` and `on()` methods
Setting inline `onclick` event after element creation
jQuery change event on the `#Container` that uses Bind method to bind click event handler
Caveat: I can not create another select list because we are using MVC and have had issues retrieving multiple values from a list box. So there are hidden elements that are generated that MVC is actually tied to.
Use $.on instead of your standard $.click in this case:
$("#container").on("click", ".item", function(){
if ( $("#container span").hasClass("selected") ) {
$(".selected").removeClass("selected");
}
$(this).addClass("selected");
});
It looks to me like you want to move the .selected class around between .item elements. If this is the case, I would suggest doing this instead:
$("#container").on("click", ".item", function(){
$(this)
.addClass("selected")
.siblings()
.removeClass("selected");
});
Also note your $("add") should be $("#add") if you wish to bind to the element with the "add" ID. This section could also be re-written:
$("#add").click(function() {
$("<span>", { html: $("select").val() })
.addClass("item")
.appendTo("#container");
});

Categories

Resources