jQuery .remove() does not work with div created inside the function - javascript

I've tried a couple of things since yesterday, but I can't achieve my goal.
The idea is :
When clicking on a character "Div", it appears a little menu to change a parameter inside my website. The problem is, I want to remove the "Class Picker", but it just does not work.
var CharacterClasses = [
{ id: 1, name: 'Warrior', cssClass: 'warrior'},
{ id: 2, name: 'Paladin', cssClass: 'paladin'},
...
]
$('.group_miniature').click( function(){
// Removing all existant class choices
$(".group-panel_class_picker").remove()
// Creating the class picker
var Panel = $("<div id=\"panel_class_picker\"></div>").addClass('group-panel_class_picker')
// Append the whole thing
$(this).append(Panel)
// Iterating each class to add a div
CharacterClasses.forEach( function(item){
// Creating the div
let btn_class = $("<div>&nbsp</div>").addClass( [item.cssClass,'group-btn_class'] )
Panel.append(btn_class)
Panel.on("click", ".group-btn_class", function(event){
$(this).parent().remove() // This is my problem, it does not remove the parent
console.log('Click :)') // This appears in my console
})
})
})

Panel.on("click", ".group-btn_class", function(event){
$(this).parent().hide()
event.stopPropagation()
console.log('Click criss')
})
I discovered that I had to add event.stopPropagation()
Now it works just fine ! :)

Related

How to get ID of link that opened Fancybox3 within onComplete?

I have seen what looks like it could be the solution to this issue in other questions on stackoverflow, but NONE of them have worked.
I am trying to get the innertext of the link that was clicked to open Fancybox:
$("a.turnDateLink").each(function() {
var that = $(this);
$( "a.turnDateLink" ).fancybox({
'type': 'modal',
'onComplete': function() {
var currentday = $(that).text();
console.log(currentday);
},
'afterClose': clearCurrentDay,
'fullScreen' : false
});
});
It only returns the innerText of the last a.turnDateLink. EVERY TIME! ugh.
Keep in mind that I would like to use the fancybox grouping with this.
See the Fancybox documentation to understand grouping: http://fancyapps.com/fancybox/3/docs/#usage
If you have a group of items, you can use the same attribute
data-fancybox value for each of them to create a gallery. Each group
should have a unique value:
Check documentation about events - http://fancyapps.com/fancybox/3/docs/#events
The first examaple contains useful tips, including how to find clicked element:
onComplete: function( instance, slide ) {
// Tip: Each event passes useful information within the event object:
// Object containing references to interface elements
// (background, buttons, caption, etc)
// console.info( instance.$refs );
// Current slide options
// console.info( slide.opts );
// Clicked element
// console.info( slide.opts.$orig );
// Reference to DOM element of the slide
// console.info( slide.$slide );
}
Try like this.Change $( "a.turnDateLink" ) to that.
$("a.turnDateLink").each(function() {
var that = $(this);
that.fancybox({
'type': 'modal',
'onComplete': function() {
$("#currentday").html('');
var currentday = that.text();
console.log(currentday);
},
'afterClose': clearCurrentDay,
'fullScreen' : false
});
});

How to access caller element inside callback function

I have a jquery-ui button test-button that has a data attribute.
That button calls a custom widget customWidget that has a callback function fnSaveCallback.
$(".test-button").button({
icons: {
primary: 'icon-test icon-mixed icon-custom'
},
text: false
}).customWidget({
id: "custom-widget",
title: "My custom widget",
fnSaveCallback: function() {
// Need to get the data-test attribute from the "test-button"
}
});
I'm having problems trying to access the the test-button in order to get the value of the data-attribute from the callback function.
Any idea how can i do that? Thanks in advance!
I've found an easy way to handle this adding a class on the click event.
$(".test-button").button({
icons: {
primary: 'icon-test icon-mixed icon-custom'
},
text: false
}).click(function() {
// remove opener class from other test-buttons
$(.test-button.opener).removeClass("opener");
// add opener class to the clicked button
$(this).addClass("opener");
}.customWidget({
id: "custom-widget",
title: "My custom widget",
fnSaveCallback: function() {
// Get the data-test attribute from the "test-button"
$(".test-button.opener").data("test");
}
});
You need to have a reference of the element somewhere.
const test_button = document.getElementById('test-button');
and then in fvSaveCallback:
fnSaveCallback: function() {
// Need to get the data-test attribute from the "test-button"
console.log(test_button.dataset.test);
}
EDIT: After your edit, as far as I understand you are trying to apply that method to all .test-button buttons.
You should only need to get a list of nodes, and iterate through it :)
const test_buttons = document.getElementsByClassName('test-button')
;
for (let i = 0; i < test_buttons.length; i++)
{ const button = test_buttons[i]; //This is the button
// Do with 'button' whatever you want here.
console.log(button.dataset.some_data);
}

Select2 Event for creating a new tag

I'm using the jQuery Select2 (v4) plugin for a tag selector.
I want to listen for when a new tag is created in the select element and fire an ajax request to store the new tag. I discovered there is the createTag event but this seems to fire every time a letter is entered into the select2 element. As shown in my fiddle: http://jsfiddle.net/3qkgagwk/1/
Is there a similar event that only fires when the new tag has finished being entered? I.e. it's enclosed by a grey box enclosing it.
I can't find any native method unfortunately. But if you're interested in simple "workarounds", maybe this get you closer:
$('.select2').select2({
tags: true,
tokenSeparators: [",", " "],
createTag: function (tag) {
return {
id: tag.term,
text: tag.term,
// add indicator:
isNew : true
};
}
}).on("select2:select", function(e) {
if(e.params.data.isNew){
// append the new option element prenamently:
$(this).find('[value="'+e.params.data.id+'"]').replaceWith('<option selected value="'+e.params.data.id+'">'+e.params.data.text+'</option>');
// store the new tag:
$.ajax({
// ...
});
}
});
DEMO
[EDIT]
(Small update: see #Alex comment below)
The above will work only if the tag is added with mouse. For tags added by hitting space or comma, use change event.
Then you can filter option with data-select2-tag="true" attribute (new added tag):
$('.select2').select2({
tags: true,
tokenSeparators: [",", " "]
}).on("change", function(e) {
var isNew = $(this).find('[data-select2-tag="true"]');
if(isNew.length && $.inArray(isNew.val(), $(this).val()) !== -1){
isNew.replaceWith('<option selected value="'+isNew.val()+'">'+isNew.val()+'</option>');
$.ajax({
// ... store tag ...
});
}
});
DEMO 2
The only event listener that worked for me when creating a new tag was:
.on("select2:close", function() {
(my code)
})
This was triggered for new tags and selecting from the list. change, select2:select, select2:selecting and any others did not work.
One more simple check will be this based on the difference in the args of the event .....
While I was dealing with this situation, I had seen this difference; that when the new element is created the event args data does not have an element object but it exists when selecting an already available option...
.on('select2:selecting', function (e) {
if (typeof e.params.args.data.element == 'undefined') {
// do a further check if the item created id is not empty..
if( e.params.args.data.id != "" ){
// code to be executed after new tag creation
}
}
})
Another workaround. Just insert it to the beginning:
}).on('select2:selecting', function (evt) {
var stringOriginal = (function (value) {
// creation of new tag
if (!_.isString(value)) {
return value.html();
}
// picking existing
return value;
})(evt.params.args.data.text);
........
It relies on underscore.js for checking if it's string or not. You can replace _.isString method with whatever you like.
It uses the fact that when new term is created it's always an object.

Running same JQuery function on many elements with same id

I'm sure this is going to be simple well i hope it is. After racking my brain for days I have finally sorted my last problem thanks you someone on here, But now I have a new problem. I am dynamically creating blogs hundreds of them. I'm using JQuery to load a editor into a simple modal window like so
<a class="blog_btns" id="edit" data-id="$b_blog_id" href="">Edit</a>
then the JQuery
jQuery(function($) {
var contact = {
message: null,
init: function() {
$('#edit').each(function() {
$(this).click(function(e) {
e.preventDefault();
// load the contact form using ajax
var blogid = $(this).data('id');
$.get("../_Includes/edit.php?blogid=" + blogid, function(data) {
// create a modal dialog with the data
$(data).modal({
closeHTML: "<a href='#' title='Close' class='modal-close'>x</a>",
position: ["15%", ],
overlayId: 'contact-overlay',
containerId: 'contact-container',
onOpen: contact.open,
onShow: contact.show,
onClose: contact.close
});
});
});
});
},
open: function(dialog) {
dialog.overlay.fadeIn(200, function() {
dialog.container.fadeIn(200, function() {
dialog.data.fadeIn(200, function() {
$('#contact-container').animate({
height: h
}, function() {
$('#contact-container form').fadeIn(200, function() {
});
});
});
});
});
},
show: function(dialog) {
//to be filled in later
},
close: function(dialog) {
dialog.overlay.fadeOut(200, function() {
$.modal.close();
});
},
};
contact.init();
});
the problem I have is i have hundreds of
<a class="blog_btns" id="edit" data-id="$b_blog_id" href="">Edit</a>
but I want the all to run the same jQuery function above.
Can anyone help? Is there a simple way of doing this?
...many elements with same id...
That's the problem, you can't have multiple elements with the same id.
You probably want to use a class:
<a class="blog_btns edit" data-id="$b_blog_id" href="">Edit</a>
<!-- Added ---------^ -->
Then:
$('.edit').each(...);
// ^---- ., not #, for class
But you probably don't want to use each, just do:
$('.edit').click(function(e) {
// ...
});
There's no need to loop through them individually.
Another approach you might consider is rather than hooking click on each individual "edit" link, you might want to use event delegation. With that, you hook the event on an element that contains all of these "edit" links (there's bound to be a reasonable one, body is always possible as a last resort), but tell jQuery not to notify you of the event unless it passed through one of these on its way to that element in the bubbling. That looks like this:
$("selector for the container").on("click", ".edit", function(e) {
// ...
});
Within the handler, this will still be the "edit" link.
Use class instead of id as according to HTML standards each element should have a unique id.
id: This attribute assigns a name to an element. This name must be unique in a document.
class: This attribute assigns a class name or set of class names to an
element. Any number of elements may be assigned the same class name or
names. Multiple class names must be separated by white space
characters.
http://www.w3.org/TR/html401/struct/global.html
so use class instead of id
<a class="blog_btns edit" data-id="$b_blog_id" href="">Edit</a>
and refer to it with $('.edit')

AgilityJS Add and Remove Event

Good morning,
I try these days to make AgilityJS work, and i'm still stuck with these two naturals events : add and remove.
(function(window){
var Test = $$({
model : {},
view : {
format : '<div></div>'
},
controller : {
'create' : function(){
console.log('create');
},
'add' : function(){
console.log('add');
},
'remove' : function(){
console.log('remove');
}
}
});
$(document).ready(function(){
$$.document.append(Test, '#test');
var t = setTimeout(function(){
console.log('time out');
$$.document.remove(Test);
}, 1000);
});
})(window);
I've got in my html a div with an id of #test.
Do someone knows how to make them work?
Thanks.
This events are not referring to the moment when the object is added to another one (like window) but they are triggered when you insert another agility object inside the one with binds.
The event remove are working just fine but the event add was replaced by events append and prepend in this commit: https://github.com/arturadib/agility/commit/1b2483333dde3f55b3305f2746e4dd6730a1c364
You can see an example of the remove and append events here:
http://jsbin.com/welcome/14942/edit

Categories