Delegating click function to appended div - javascript

I am having trouble understanding how to attach a click function to an element inside my appended portion. I looked through the answers of previous question but can’t figure out out to apply it to my code. Can anyone help? What I am trying to achieve: When the user clicks on news, a news feed toggles down. The sections of news seen can be clicked to remove the current toggle into a new section (concerts).
edit: The problem is that the ’news feed’ is inside a container. When the user clicks a menu tab either box-toggle 1,2,3, etc will remove the contents of the container (news feed) and replace it with the new appended box-toggle. Im trying to get the news1clone to act in the same manner. Deleting in the contents (news feed) and appending the appropriate box toggle.
$('#news').click(function() {
$('.nav li').removeClass('active');
$(this).addClass('active');
$('.box-toggle').remove();
$('.box-toggleclone').remove();
$('.box-toggle1').remove();
$('.box-toggle2').remove();
$('.box-toggle3').remove();
$('#box').removeClass('box-zoom');
$('#box').addClass('box-reg');
$('.placer2').append('<div class = "box-toggleclone">'+
'<div class = "newsbodyclone">'+
'<div class = "newsheaderclone"><h1>News</h1></div>'+
'<div class = "news1clone">'+
'<div class = "news1clone-photo">'+
'</div>'+
'<div class = "news1clone-info">'+
'<p>MAY XX, 2015</p>'+
'<h2>OPENING<br>'+
'SPRING FASHION PARTY<h2>'+
'</div>'+
'</div>'+
'<div class = "news2clone">'+
'<div class = "news2clone-photo">'+
'<img src="album-cover/tyler.jpg" alt = "photo-carosel">'+
'</div>'+
'<div class = "news2clone-info">'+
'<p>MAY 28, 2015</p>'+
'<h2>TYLER THE CREATOR<br>'+
'Primavera Sound Concert<h2>'+
'</div>'+
'</div>'+
'<div class = "news3clone">'+
'<div class = "news3clone-photo">'+
'<img src="album-cover/jcole.jpg" alt = "photo-carosel">'+
'</div>'+
'<div class = "news3clone-info">'+
'<p>J. Cole, Latest album</p>'+
'<h2>2014 Forest Hills Drive<br>'+
'(2014)<h2>'+
'</div>'+
'</div>'+
'</div>'+
'</div>');
$('.placer2').delegate('click','.news2clone',(function() {
$('.box-toggle').remove();
$('.box-toggleclone').remove();
$('.box-toggle1').remove();
$('.box-toggle2').remove();
$('.box-toggle3').remove();
$('#box').removeClass('box-zoom');
$('#box').addClass('box-reg');
$('.placer2').append('<div class = "box-toggle2">'+
'<div class = "concert-body">'+
'<div class = "concert1">'+
'<div class = "concert1-photo">'+
'<img src="album-cover/dmx.jpg" alt = "photo-carosel">'+
'</div>'+
'<div class = "concert1-info">'+
'<p>Sunday, May 24 2015</p>'+
'<h2>DMX CONCERT<br>'+
'<h2>'+
'</div>'+
'</div>'+
'<div class = "concert2">'+
'<div class = "concert2-photo">'+
'<img src="album-cover/tyler.jpg" alt = "photo-carosel">'+
'</div>'+
'<div class = "concert2-info">'+
'<p>Thursday, May 28 2015</p>'+
'<h2>TYLER THE CREATOR<br>'+
'Primavera Sound<h2>'+
'</div>'+
'</div>'+
'</div>'+
'</div>');
})
);
});

I would recommend using jquery's 'on' method instead of delegate. The trick here is setting the correct context. The first selector needs to be an element that is there on page load and not ajaxed in or injected later.
Try adding the 'document' as the context and it should work.
$(document).on('click','.news2clone',(function() {
// $(document) is your context and .news2clone would be the trigger inside that context.

Generally, you could use
$('<YOUR CSS SELECTOR HERE>').click(function(){<THE CODE THAT YOU WANT TO EXECUTE HERE>}).
You, you just have pass a selector that matches against any element that you want to attach this function and it is compatible with it.
You can also access the item that is executing the function with $(this).
For example, in your div that has a class named "box-toggle2":
$('div.box-toggle2').click(function(){
$(this).hide(); // JUST AS AN EXAMPLE, I'M TRYING TO HIDE THIS DIV.
});
I think that function within the click event handler will execute for all the divs that have the box-toggle2 class.

Related

Zoom in dynamically displayed image with materialbox

So i'd like to zoom on my dynamically displayed image when I click on it. I'm using cordova and materializecss. I'd like to use the materialbox function. (materialbox here) I've tried many ways but didn't manage to figure it out. Here's my simplified code :
Displaying images :
function createHtmlGall(imgTab) {
let htmlGall = ""
imgTab.forEach(function(element) {
htmlGall += '<div class="col s12 m4 l3">'
htmlGall += '<img src="' + element + '" class="materialbox responsive-img card">'
htmlGall += '</div>'
})
$( "#imagesDiv" ).html(htmlGall)
}
trying to set a zoom effect on click :
$(document).on( "click", ".materialbox").materialbox()
I'd like to use jquery if possible.

"change" not working like "click"

So I have a web page that looks like this to start with, essentially...
<div id="videonotes_container">
<div id="videonotes_information">
<div id="videonotes_name">Name</div>
<div id="videonotes_points">100 points etc</div>
<div id="videonotes_instructions">
Instructions
</div>
**<div id="videonotes_quicklinks">
<!-- this is where the quick links to the past comments go. -->
</div>**
</div>
<div id="videonotes_video">
<div id="videonotes_video_player"></div>
<div id="videonotes_video_player_overlay"></div>
</div>
<div id="videonotes_controls">
<div id="videonotes_start" class="videonotes_videocontrol">-></div>
<div id="videonotes_pause" class="videonotes_videocontrol">::</div>
<div id="videonotes_stop" class="videonotes_videocontrol">STOP</div>
<div id="videonotes_back30" class="videonotes_videocontrol">RW30</div>
<div id="videonotes_forward30" class="videonotes_videocontrol">FF30</div>
</div>
</div>
and the bit in bold is an area which is dynamically populated by javascript after the page has loaded, with a function that looks like this...
function videonotes_addNote(user_note_id, time, note, rating, feedback) {
// add a new div...
var html_fb = "";
var html_hl = "";
html_hl += "<div class=\"videonotes_note_time\">"+time.toFixed(0)+"</div>";
html_hl += "<div class=\"videonotes_note_note\" data-id=\""+user_note_id+"\" contenteditable>"+note+"</div>";
html_hl += "<div class=\"videonotes_note_comments\">"+rating+"</div>";
// iterate over the feedback and add it into the program.
feedback.forEach(function(value) {
html_fb += "<div class=\"videonotes_note_feedback_note\"><span class=\"videonotes_note_feedback_intro\">"+value.username+" ("+value.timestamp+") said</span> "+value.feedback+"</div>";
html_fb += "<div class=\"videonotes_note_feedback_useful\" data-id=\""+value.noteid+"\">";
html_fb += "<div class=\"videonotes_note_feedback_useful_yes videonotes_note_feedback_useful_button\">ACC</div>";
html_fb += "<div class=\"videonotes_note_feedback_useful_no videonotes_note_feedback_useful_button\">NAC</div>";
html_fb += "</div>";
});
// create a new note on the notes box...
var new_note = $('<div/>', { 'class':'videonotes_note' }).appendTo('#videonotes_quicklinks');
// add the headline to the div...
$('<div/>', { 'class':'videonotes_note_headline', 'html': html_hl, 'click':function(){ videonotes_clickNote(this, time); },}).appendTo(new_note);
// and add the feedback
$('<div/>', { 'class': 'videonotes_note_feedback', 'html': html_fb }).appendTo(new_note);
}
You will note there are a few bits created from this - there are onclick events created which will open feedback on this particular note and navigate to a part of a video. This all works just fine, and the onclick events work just fine for the dynamically created elements. The exception is that for each note you should be able to rewrite it in the div, so you can click the div with the note in, it will naviagte to the correct part of the video (works), it iwll open up the feedback (works) and when you EDIT the .videonotes_note_note class it will fire an update using this method:
$('#videonotes_container').on("change", '.videonotes_note_note', function() { videonotes_update_note($(this).data('id'), $(this).value()); })
However this does not work. I have tried $(document) and all other parent, pre loaded divs I can think of but it still doesnt fire that particular event. There is no difference in the way I am creating this listener to the others, and all the clicks work fine, but the change doesnt.
Am I misunderstanding how the change element works?
change event is not supported on the div tag, you can get the list of input on which change event get fired . https://www.w3schools.com/jsref/event_onchange.asp

Dynamically Load a React Component using Javascript

I want to load a React Component from a Javascript file when a click event is triggered.
So basically,
function checkScript()
{
var tab_content = document.getElementById('tab-content');
var a = '<div id="notifications" class="tab-pane fade">'+
'<h2 class="notify">Notify</h2>'+
'<div id="NotifyComponent">'+
'Waiting to load notify'+
'</div>'+
'</div>';
tab_content.innerHTML = tab_content.innerHTML + a;
loadScript('/components/notifications.js', null);
}
$('#ap').click(function(e)
{
checkScript();
});
This is a piece of code from my index.js file which I am using to load the React File, but the file isn't getting rendered.
However, if I use the following code, the rendering works just fine.
function checkScript()
{
var tab_content = document.getElementById('tab-content');
var a = '<div id="notifications" class="tab-pane fade">'+
'<h2 class="notify">Notify</h2>'+
'<div id="NotifyComponent">'+
'Waiting to load notify'+
'</div>'+
'</div>';
tab_content.innerHTML = tab_content.innerHTML + a;
loadScript('/components/notifications.js', null);
}
checkScript();
This script loads the react component just fine, the only difference is that it's called directly when the Javascript file is loaded, not when a event is triggered.
So, what changes do I make to load the react component on click event.!!
You might want to wrap it up in document.ready
$(document).ready(function() {
$('#ap').click(function() {
checkScript();
});
});

using multiple templates on the same popover button

I'm trying to user multiple templates for bootstrap popover , the scenario I follow is click on button on load page, first template will be shown with a link to change class f popover button. So it should display the second template when I click on the same button again ! but it seems popover save the class for button and binding the popover on it. I tried to destroy it and bind popover again on the new class but not work. find example on fiddle here.
I've a solution by replace the button html with the same button but with the new class. and It worked. see here working example I made. link
but I'm trying to find another or better solution .
var popoverTemplate = ['<div class="first-pop popover" role="tooltip">',
'<div class="arrow"></div>',
'<button type="button" class="close" onclick="$(\'.popover\').popover(\'hide\')" aria-hidden="true">×</button>',
'<h3 class="popover-title">test</h3>',
'<div class="popover-content">ONE',
'</div>',
'</div>'].join('');
var firstTemplate = ['<div class="firstTmp-pop popover" role="tooltip">',
'<div class="arrow"></div>',
'<button type="button" class="close" onclick="$(\'.popover\').popover(\'hide\')" aria-hidden="true">×</button>',
'<div class="popover-content">',
'</div>',
'</div>'].join('');
var firstTmpContent = ['<div class="firstTmpContent-post clearfix"><a class="changetemp" href="#">Change template</a>',
'</div>',].join('');
var content = ['<div>Content</div>',].join('');
var secondOptions = {
trigger: "click"
, html: true
, template: popoverTemplate
, content: content
};
var firstOptions = {
trigger: "click"
, html: true
, template: firstTemplate
, content: firstTmpContent
};
$('.box').popover(firstOptions);
$(document).on('click','.box2',function(e){
$(this).popover(secondOptions);
});
$(document).on('click','.changetemp',function(e){
e.preventDefault();
$('[rel="popover"]').popover('hide');
$('.box').removeClass('box').addClass('box2');
});
var obj = '';
$('.box').click(function(){
obj = $(this).clone();
});
$(document).on('click','.changetemp',function(e){
e.preventDefault();
$('[rel="popover"]').popover('hide');
obj.addClass('box2').removeClass('box');
$('.box').replaceWith(obj);
$('.box2').popover(secondOptions);
});

click() for ClassName

UPDATE: A commenter told me to change some codes, this is the new code and its not working neither.
I'm creating a Facebook-Like chat. It gets the latest messages "Not Read" from a JSON file and it appends the text to an "UL" element vía "LI" into a box. If the box doesn't exist, it creates and attach the text. I want that when I click that div, it hides using margin-bottom negative, and when I click it again it shows by Margin-Bottom:0. Please help me since it's just not working.
function showChat(id){
$(this).animate({marginBottom : "0"}).removeClass("hidden_box").addClass("active_box").removeAttr('onclick').click(function(){
hideChat(Id);
});
}
function hideChat(id){
$(this).animate({marginBottom : "-270px"}).removeClass("active_box").addClass("hidden_box").click(function(){
showChat(Id);
});
}
function getOnJSON(){
//Creating Variables that will be used
var from;var to;var msg_id;var msg_txt;
//Getting the data from the json file
$.getJSON("/ajax/chat.json.php",function(data){
//Repeat for each result
$.each(data.notif, function(i,data){
//Getting a var to info
from = data.from;to = data.to;msg_id = data.id;msg_txt = data.text;
//check if div exists
if ($("#chat_"+from+"_lp").length === 0){
//If not, create the div
$("#boxes").append('<div id="chat_'+from+'_lp" class="chat_box hidden_box clickable_box"></div>');
//Add the senders name
$("#chat_"+from+"_lp").append('<div id="'chat_+from+'_nick" class="chat_name">'+from+'</div>');
//Add the chats UL
$("#chat_"+from+"_lp").append('<ul id="chat_'+from+'_txt" class="chat_txt"></ul>');
//Add the message text
$("#chat_"+from+"_lp").append('<li id="' + msg_id + '">'+ msg_txt+'</li>');
//Add event handler for each div
$('#chat_'+from+'_lp').click(function() {showChat(this);});
//If div exists just add the text
}else{
//Add the message text
$("#chat_"+from+"_txt").append('<li id="' + msg_id + '">'+ msg_txt+'</li>');
//Add event handler for each document
$('#chat_'+from+'_lp').click(function() {showChat(this);});
//Close If
}
//Close data for each item
});
//Close JSON
});
//Close Function
}
UPDATE 2: in order to stop making and appending things, I made an unique HTML string that is going to be appended.
new_chat_string = '<div id="chat_'+from+'_lp" class="chat_box hidden_box clickable_box"><div id="'chat_+from+'_nick" class="chat_name">'+from+'</div><ul id="chat_'+from+'_txt" class="chat_txt"><li id="' + msg_id + '">'+ msg_txt+'</li></ul></div>';
$("#boxes").append(new_chat_string);
use class instead of id
<div id="chat_sender_lp" class="chat_box hidden_box clickable_box sender-click"
then
$('.hidden_box.sender-click').live('click', function(){
$(this).slideToggle(500);
});
After:
$("#boxes").append('<div id="chat_'+from+'_lp" class="chat_box hidden_box clickable_box" ><div id="name">'+from+'</div><ul id="chat_'+from+'_txt" class="chat_txt"><li id="' + msg_id + '">'+ msg_txt+'</li></ul></div>');
Add the event handler for the inserted element:
$('#chat_'+from+'_lp').click(function() { showChat(this) })
"this" passes a DOM reference to itself.
Keep in mind that you're adding: <div id="name"> every time. IDs must be unique. Use a class name instead.
EDIT:
Appending to the DOM is really quite slow. It's actually more efficient to build up your HTML as a string and just insert it in one go. Also, you only really need to stick and ID on the wrapping element. Everything else can be derived from that using a jQuery selector. It helps you write much cleaner code.
Here's the string you need to append:
'<div id="chat_'+msg_id+'" class="chat_box hidden_box clickable_box">
<div class="chat_name">'+from+'</div><ul class="chat_txt"><li>
'+msg_txt+'</li></ul></div>'
If you wanted to select chat name later, you'd use: $('chat_1 .chat_name').html()
It also makes more semantic sense to hook up your click handler to an A tag. So you'd use:
$('#chat_'+msg_id).find('a').click(function() {showChat(this);});
The code is a lot cleaner and easier to follow this way. I hope this helps.

Categories

Resources