Dynamically Load a React Component using Javascript - 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();
});
});

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

lightgallery does not work with dynamically generated elements

I have implement lighgallery plugin to my local site... and this is not working with dom elements ...
for example
1.) append dom element created with js to html code..
if i create something like this in js "<span id='imgcon'><img src="image"></span>" and this all code is in a varialbe lets call galleryview (var galleryview) and this variable i append to a div that is in html file <html><head></head><bdy><div class="container"></div></bdy></html> and append like this from js file code $(".container").append(galleryview); and in end i use this $(".imgcon").lightGallery(); does not work...
Here is jsfiddle demo not working with dom
2.) images are in html code
i have html code smthing like this <html><head></head><bdy><div class="container"><span class="imgcont"><img src="image"></span></bdy></html>
This works fine as it.$(".imgcon").lightGallery();
Here is jsfiddle working demo without dom.
Question : why i cannot use dom with lightgallery ?
First demo is not working becasue i use js dom and second demo is working because i use html code in html file.. or there any problem with my code..
Simply put your $(".imagecontiner").lightGallery(); inside the click handler
http://jsfiddle.net/o0y70kv0/1/
The above will work only for the first dynamically created gellery.
To make it work for multiple elements: pre-create in-memory appendable elements and assign to each the .lightGallery() instance
http://jsfiddle.net/o0y70kv0/6/
$(document).ready(function() {
var imagesarray = [
"http://www.planwallpaper.com/static/images/Winter-Tiger-Wild-Cat-Images.jpg",
"http://www.gettyimages.ca/gi-resources/images/Homepage/Category-Creative/UK/UK_Creative_462809583.jpg",
"http://blog.jimdo.com/wp-content/uploads/2014/01/tree-247122.jpg",
"http://i765.photobucket.com/albums/xx291/just-meller/national%20geografic/Birds-national-geographic-6873734-1600-1200.jpg",
"http://www.gettyimages.com/gi-resources/images/CreativeImages/Hero-527920799.jpg"
];
var hiddenimages = "",
albumcover;
$("#appendnewcontainer").click(function() {
$("<span />", {
class : "container",
appendTo : $("#fotoappendarea"),
append : $("<span />", {
class : "imagecontiner",
html : "<a class='dfed' href=" + imagesarray[1] + "><img src='" + imagesarray[1] + "' class='_34'/></a>"
}).lightGallery()
});
});
});
when you generated gallery item after than you need to use below code in your project
var $methods = $('#gallery-container');
$methods.lightGallery();
$methods.data('lightGallery').destroy(true);
$methods.lightGallery({
thumbnail: true,
animateThumb: true,
showThumbByDefault: true,
});

Mixing Angular with MVC partial views

What I need
A chain of screens that each open the next screen on a button click. Each previous screen must be collapsed and the new screen must be added by loading a partial view from the MVC backend.
What I have
An AngularJS controller with the following function:
self.AddChild = function (uri, targetContainerId, collapseTitle, breadCrumbContainerId) {
var target = $("#" + targetContainerId);
if (target != 'undefined' && target != undefined && target.length > 0) {
apiService.Get(uri).then(function (viewData) {
self.CollapsePreviousChild(self.ChildCount);
// Increase childcount by 1
self.ChildCount += 1;
// Set HTML data
var html = '<div id="collapsibleScreen-"' + self.ChildCount + ' class="open">' + viewData + '</div>';
target.html(html);
// Update screens collapse status
self.UpdateScreenBreadCrumb(collapseTitle, breadCrumbContainerId);
});
};
}
The UpdateScreenBreadCrumb function works and is otherwise unrelated.
It is called (for instance) like this:
self.AddChild("/Partials/View1", "targetContainer", "View", "breadCrumbContainer");
What it does
The content of the View, a form, is loaded, the breadcrumb is updated correctly.
What I need fixed
On the partial view that was loaded, there is a button defined like this:
<button class="btn btn-primary" ng-click="AddPartialView()">Add partial view</button>
Clicking that button has no effect whatsoever. If I add a console.log('Code was here.') to the
AddPartialView(), it is not logged. Setting the ng-click value directly to alert('hello') has no effect either.
There are no errors of any kind visible.
Any suggestions on how to make this button work?
In regards to your question, you are adding HTML that isn't compiled by Angular. You need to use $compile on your newly added HTML element and then bind it to a scope. The $compile() function returns a link() function which you use to bind a scope to. Example:
$compile(new-element)(scope-to-bind-to)
NOTE: You should not be manipulating the DOM via a controller. This is considered bad practice. You should be using a custom directive or some combo of Angular directives (ngIf, ngSwitch, ngInclude). I recommend watching AngularJS best practices.
I've looked into $compile, as suggested by Itamar L. and got it to work. The samples I found were using Directives as well, so I implemented them anyway:
angular.module('directives.api').directive("PartialViewLoader", [
'$compile',
'chainedScreensService',
function (
$compile,
chainedScreensService) {
return {
restrict: 'A',
scope: {
view: '=',
parent: '='
},
controller: function() {
},
link: function (scope, element, attrs) {
chainedScreensService.GetPartialView(attrs.view).then(function (viewData) {
var linkFunc = $compile(viewData);
var content = linkFunc(scope);
element.append(content);
if (attrs.parent != 'undefined' && attrs.parent != undefined && attrs.parent.length > 0) {
chainedScreensService.CollapsePartialByIdentifier(attrs.parent);
}
});
}
}
}
]);
I use it like this:
<div ng-controller="collapseController">
<div id="breadCrumbContainer" style="display: inline"></div>
<div id="mainContainer">
<div id="personContainer" partial-view-loader view="persoon" parent="" class="open"></div>
</div>
</div>
That in itself displays the first page, which has a button to the next, as mentioned. The associated function, found in the collapseController, is this:
self.AddNextScreen = function (parentViewIdentifier, targetContainerId, breadCrumbContainerId) {
self.AddChildByDirective("NextScreen", parentViewIdentifier, targetContainerId, breadCrumbContainerId);
}
The code for AddChildByDirective:
self.AddChildByDirective = function (viewIdentifier, parentViewIdentifier, targetContainerId, breadCrumbContainerId) {
var html = '<div id="' + viewIdentifier + 'Container" fvl-partial-view-loader view="' + viewIdentifier + '" parent="' + parentViewIdentifier + '" class="open"></div>';
var target = $('#' + targetContainerId);
var linkFunc = $compile(html);
var content = linkFunc($scope);
target.append(content);
self.UpdateScreenBreadCrumb(viewIdentifier, breadCrumbContainerId);
}
At this point I still need to test actual chaining, but this works to load a new screen and collapse the previous.

Delegating click function to appended div

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.

Categories

Resources