Javascript - replacing content in divs, issues with click handler - javascript

I have been wrangling with my code all day with no luck in solving the problem.
My website has a series of images acting as navigation:
<div id="thumbs">
<img src="images/edwardsthumb1.jpg" class="thumb" border="0"/>
<img src="images/sample1thumb.jpg" class="thumb" border="0"/>
</div>
when these are clicked, content is added to blank divs:
<div id="image"> <!-- main image container -->
</div>
<div id="gallerytext"> <!-- text box -->
</div>
<div id="thumbset"> <!-- series of sub images/navigation -->
</div>
with this javascript:
$(function() {
var text = $('#gallerytext1').html(); <!-- blank divs are filled with content on page load -->
$('#gallerytext').html(text);
var thumbset = $('#thumbset1').html();
$('#thumbset').html(thumbset);
$('#image').html('<img src="images/edwards1.jpg" border="0"/>');
<!-- click handler -->
$(".image").click(function() { <!-- image variable is set when an image with class "image" is clicked -->
var image = $(this).attr("rel"); <!-- each image has appropriate rel attribute to fill variable -->
if (image == 'images/edwards1.jpg'){ <!-- different text and gallery loaded on click of specific image -->
var text = $('#gallerytext1').html();
$('#gallerytext').html(text);
var thumbset = $('#thumbset1').html();
$('#thumbset').html(thumbset);
$('#thumbset').hide();
$('#thumbset').fadeIn('slow');
}
if (image == 'images/sample1.jpg'){ <!-- different text and sub-gallery loaded on click of specific image -->
var text = $('#gallerytext2').html();
$('#gallerytext').html(text);
var thumbset = $('#thumbset2').html();
$('#thumbset').html(thumbset);
$('#thumbset').hide();
$('#thumbset').fadeIn('slow');
}
$('#image').hide(); <!-- main image changed -->
$('#image').fadeIn('slow');
$('#image').html('<img src="' + image + '"/>');
return false;
});
});
It works fine after the intial load, however if one of the "if" statements is triggered and the content is changed, images with the class .image within the div "thumbset" are now unclickable and the main image no longer changes. Images within the main navigation div: "thumbs" still work fine, and the "if" statements still go off.
all images are tagged and formatted as per the top code box in my post, and I cannot figure out why only images within "thumbset" decide to stop working.
I am very very green to Javascript, so any assistance will be greatly appreciated!
UPDATE: here is my updated code. Much cleaner now but the function is not working at all. I'm thinking the problem may be with the variable setting of "image" variable?
$(document).ready(function() {
var $doc = $(document.body);
var text = $('#gallerytext1').html(); //blank divs are filled with content on page load
$('#gallerytext').html(text);
var thumbset = $('#thumbset1').html();
$('#thumbset').html(thumbset);
$('#image').html('<img src="images/edwards1.jpg" border="0"/>');
//click handler
$doc.on("click",".image",function(){
var image=$(this).attr("rel");
var imid=$(this).attr("data");
var text=$('#gallerytext'+imid).html();
var thumbset=('#thumbset'+imid).html();
$('#debug').html(imid);
$('#gallerytext').fadeIn('slow');
$('#gallerytext').html(text);
$('#thumbset').fadeIn('slow');
$('#thumbset').html(thumbset);
$('#image').hide();
$('#image').fadeIn('slow');
$('#image').html('<img src="' + image + '"/>');
return false;
});
});

use
$(document).ready(function() {
var $doc = $(document.body);
$doc.on("click",".image", function() {//...
then bind all events from the $doc (chain them if different selectors
$doc.on(event,selector,function).on(ev,sel,fn)...
or if multiple events on same selector
$doc.on({
ev : function(e) {},
ev2 : function(e) {}
//...
},selector).on()...
to comment out in javascript use, it'll comment what's after in same line
//
instead of <!-- which is more meant to comment out html
your code in spaghetti like with many repeated instructions,
take out the common instructions in the if
define a pattern so to avoid using if(stg=='sthg')
for example you could do
<a ... data-idtoload="*id*">...
then
var imid=$(this).data("idtoload");
var text = $('#gallerytext'+imid).html();
$('#gallerytext').html(text);
var thumbset = $('#thumbset'+imid).html();
//...
no more if & your code is cut by 66%

Related

How to replace content area with an iframe when a button is clicked, via javascript?

I have a content area in which I want to display certain text when the page loads and the same text when a button is clicked (biography). When a different button is clicked (AFT), I want the text in the content area to be replaced with the content of a URL via an iframe.
I have managed to get the right text to display when the page loads, but when I click the 'AFT' button the text is replaced with "[object HTMLIFrameElement]" instead of displaying the iframe. Does anyone know whats going wrong?
HTML code:
<div id="content" >
<script src="myJS.js"></script>
<script> displayBiography(); </script>
<iframe src="cwExample.pdf" name="iframe" id="iframe1"></iframe>
</div>
<div id="leftBar">
<br><br>
<button class="button" type="button" onclick="displayBiography();">
Biography </button>
<h3> Samples of Work </h3>
<button class="button" type="button" onclick="toShow();"
target="#iframe1"> AFT </button>
JS Code:
var content = document.getElementById("content");
var biography = "<p> Text here </p>"
;
function displayBiography() {
"use strict";
content.innerHTML = biography;
}
window.onload = function() {
var iframe = document.getElementById('iframe1');
iframe.style.display = 'none';
}
function toShow() {
var iframe1 = document.getElementById('iframe1');
content.innerHTML = iframe1
biography.style.display = 'none';
iframe1.style.display = 'block';
}
There are different solutions, depending on what your future aim could be. But in general, using an iFrame is not recommended at all.
Hard coded text
If the text is static and doesn't need to be changed after coding, you can simply set the text with JS, without jQuery.
HTML
<div id="content">
</div>
JavaScript
window.onload = function() {
showBio();
// add event listeners to the buttons
}
function showBio() {
var bio = "blabla";
setContent(bio);
}
function showSmthElse() {
var txt = "other blabla";
setContent(txt);
}
function setContent(newContent) {
var div = document.getElementById("content");
if( div != null ) {
div.innerHTML = '';
div.insertAdjacentHTML = content;
}
}
Load text from database
If you want to change the text, give others the opportunity to change it or want to save multiple bios, think about storing them in a database on your server (if this is possible with your structure). In this case you should think about using AJAX. It's a technique to load data from a server without refreshing the page. There are a lot of tutorials on the web and many questions are already answered here. It's really not that difficult :)

addEventListener to array of images - modal in infinite scroll gallery

I want to add a modal to an "infinite" scroll image gallery I'm trying to create, so that when you click on each image the modal pops up linking to their respective source. I'm also trying to generate my images purely through my javascript without including any markup for the images in the HTML doc itself. I tried doing both "files[i].addEventListener" and "img.addEventListener" (to add it to all the images that have the ".myImg" class) but I got this error for files[i] in the console and only got it to work for the very first image and none of the images after that using the img variable.
"Uncaught TypeError: files[i].addEventListener is not a function
at XMLHttpRequest.putImages (main.js:32)"
Could anyone help me solve this, please? It would be really appreciated!
Note: I'm trying to do this without jquery, if that's possible.
JAVASCRIPT
// INFINITE SCROLL
// height of initial gallery, the original 13 images
var contentHeight = 600;
// height of visible page in browser
var pageHeight = document.documentElement.clientHeight;
// scrollbar position
var scrollPosition;
// next image
var n = 14;
// ajax
var ajaxCall = new XMLHttpRequest();
function putImages(){
if (ajaxCall.readyState==4)
{
if(ajaxCall.responseText){
// to separate the file names, with semicolons
var files = ajaxCall.responseText.split(";");
// check if string isn't empty and add a thumbnail
for(var i=0; i<files.length; i++){
if(files[i] != ""){
document.getElementById("gallery").innerHTML += '<img class="myImg" src="/img/'+files[i]+'" width="198" height="198"/>';
// Get the modal
var modal = document.querySelector('.modal');
// Get the image and insert it inside the modal - use its "alt" text as a caption
var img = document.querySelector('.myImg');
var modalImg = document.querySelector(".modalContent");
img.addEventListener('click', function() {
modal.style.display = "block";
modalImg.src = this.src;
})
// Get the <span> element that closes the modal
var span = document.querySelector(".close")[0];
}
}
}
}
}
//SCROLL
function scroll(){
if(navigator.appName == "")
scrollPosition = document.documentElement.scrollTop;
else
scrollPosition = window.pageYOffset;
if((contentHeight - pageHeight - scrollPosition) < 600){
// reference to the php file
var url="getImages.php?n="+n;
// send ajax request
ajaxCall.open("GET",url,true);
ajaxCall.send();
// put the images on the page
n += 13;
ajaxCall.onreadystatechange=putImages;
contentHeight += 600;
}
}
HTML
<!-- Header -->
<div class ="container">
<div class = "row">
<div class="col-md-12 header">
<h1>Image Gallery</h1>
</div>
</div>
</div>
<!-- The Modal -->
<div class="modal">
<!-- The Close Button -->
<span class="close" onclick="document.querySelector('.modal').style.display='none'">×</span>
<!-- Modal Content (The Image) -->
<img class="modalContent">
</div>
<div class="container">
<!-- Image Gallery -->
<div class="row">
<div class="col-xs-12" id="gallery">
</div>
</div>
<hr>
</div>
PHP
<?php
/* get directory for thumbnail images */
$dir = "img";
/* check if directory exists */
if(is_dir($dir)){
/* open directory if directory exists */
if($dd = opendir($dir)){
while (($f = readdir($dd)) !== false)
if($f != "." && $f != "..")
$files[] = $f;
closedir($dd);
}
/* to create infinite effect, b/c of lack of infinite images cycle must restart */
$n = $_GET["n"];
$response = "";
for($i = $n; $i<$n+13; $i++){
$response = $response.$files[$i%count($files)].';';
}
echo $response;
}
?>
I think that your problem is because when attaching it to files[i] that is something that isn't part of your DOM, it is the text of the src location of your image. So it can't attach there. And the img will only ever return the first one because you aren't looping through all of those. So you need to actually add the event listener to the <img>s.
You could add an id to each img as you add it:
document.getElementById("gallery").innerHTML += '<img class="myImg" src="/img/'+files[i]+'" width="198" height="198" id="file'+i+'" />';
and then add the listener to that, like:
var img = document.getElementById("file"+i);
img.addEventListener()

Bootstrap on-the-fly responsive height for elements appended with Javascript

For a prototype website, I have downloadded the free bootstrap template that can be found on this website : http://themes.3rdwavemedia.com/demo/prettydocs/index.html
As you can see on the index page of the template, the six item boxes all have the same size, despite the lenght of their content. If we inspect the DOM with Firebug, we can see that every item box is defined as a div :
<div class="item item-green col-md-4 col-sm-6 col-xs-6">
<div class=item-inner" style="height: 237px;">
...
</div>
</div>
Now, when I edit the index.html page downloadded with the template package, I see that those item div have no predefined height. The property seems to be added once the page is loadded.
What I want to do is to make the box list dynamic according to a parameter. Depending on the value of this parameter, there might be 2, 3, 7, 15 boxes, each with a specific icon, color, title, content and link.
In the index.html file, I have added the following onLoad method linked to a personnal Javascript file :
<body class="landing-page" onload="addItemBoxes()">
Then, in my Javascript file, i have a few fonctions to define the list of boxes to add, and then I use a loop calling a function like this :
function addBox(boxId) {
var boxDetails = getBoxDetails(boxId);
/*
Example of boxDetails content :
{
boxId : "1",
boxTitle : "Cars",
boxDescription : "This is a page that talks about cars",
boxIcon : "fa-automobile",
boxIconSource : "font-awesome",
boxLink : "cars.html"
}
*/
if (boxDetails) {
//Main div
var cardsWrapperDiv = document.getElementById("cards-wrapper");
//Get color from the global var
var nbrOfItems = cardsWrapperDiv.getElementsByClassName("item").length;
var nbrOfColors = COLORS.length;
var colorIndex = nbrOfItems % nbrOfColors;
var color = COLORS[colorIndex];
//Create the box
var itemDiv = document.createElement("div");
itemDiv.className = "item " + color + " col-md-4 col-sm-6 col-xs-6";
//Content of the box
var innerItemDiv = document.createElement("div");
innerItemDiv.className = "item-inner";
//Icon
var iconHolderDiv = document.createElement("div");
iconHolderDiv.className = "icon-holder";
if (boxDetails.boxIconSource == 'font-awesome') {
var i = document.createElement("i");
i.className = "icon fa " + boxDetails.boxIcon;
iconHolderDiv.appendChild(i);
} else if (boxDetails.boxIconSource == 'elegant_font') {
var iconSpan = document.createElement("span");
iconSpan.setAttribute("aria-hidden", "true");
iconSpan.className = "icon " + boxDetails.boxIcon;
iconHolderDiv.appendChild(iconSpan);
} else {
console.log("No icon!");
}
innerItemDiv.appendChild(iconHolderDiv);
//Title
var h3 = document.createElement("h3");
h3.className = "title";
h3.innerText = boxDetails.boxTitle;
innerItemDiv.appendChild(h3);
//Description
var p = document.createElement("p");
p.className = "intro";
p.innerText = boxDetails.boxDescription;
innerItemDiv.appendChild(p);
//Link
var a = document.createElement("a");
a.className = "link";
a.href = boxDetails.boxLink;
var span = document.createElement("span");
a.appendChild(span);
innerItemDiv.appendChild(a);
itemDiv.appendChild(innerItemDiv);
cardsWrapperDiv.appendChild(itemDiv);
}
}
The code works fine, except that the boxes have no style height assigned. When I inspect them with Firebug, I see their definition such as :
<div class="item item-green col-md-4 col-sm-6 col-xs-6">
<div class=item-inner">
...
</div>
</div>
Therefore, their height depends on the lenght of the content, and this is not pretty at all...
I suspect that the height is assigned with one of the scripts referenced at the bottom of the index.html code :
<script type="text/javascript" src="assets/plugins/jquery-1.12.3.min.js"></script>
<script type="text/javascript" src="assets/plugins/bootstrap/js/bootstrap.min.js"></script>
<script type="text/javascript" src="assets/plugins/jquery-match-height/jquery.matchHeight-min.js"></script>
<script type="text/javascript" src="assets/js/main.js"></script>
But I have no idea how to call them so that the height problem is fixed. Thank you very much for your help!
If you want to add style into the div using javascript, you can use:
//Content of the box
var innerItemDiv = document.createElement("div");
innerItemDiv.className = "item-inner";
innerItemDiv.style.height="237px"; // This is the line to add
Did not test the code, but I think it should work.
You can try doing overflow auto, or use the bootstrap elements class names/ids to adjust size. There is also the option to do nedia queries
I found in the main.js script associated with the template those few lines :
/* ======= jQuery Responsive equal heights plugin ======= */
/* Ref: https://github.com/liabru/jquery-match-height */
$('#cards-wrapper .item-inner').matchHeight();
$('#showcase .card').matchHeight();
If I add the two jquery calls at the end of my personal addBox function, it works. All the new boxes have a similar size, properly adjusted if the screen size changes.
Thank you all for your help.

Bootstrap Light Box not working properly

Edited:
Below js code generate a modal like this
but sometime it fails.And it look like this
So i want a solution for that problem
This is the html structure
<div class="col-sm-4">
<div class="gallery-item shad" style="height : 100px; width:143px;">
<a href="#">
#if(empty($service->image)))
{{HTML::image('image/no-image.png',null,array('style'=>'height : 100px;'))}}
#else
{{HTML::image('image/'.$service->image,null,array('style'=>'height : 100px;'))}}
#endif
</a>
</div>
file.js
/* copy loaded thumbnails into carousel */
$('.gallery-image img').on('load', function() {
/*this section execute when i reload the page*/
console.log('not working');
}).each(function(i) {
if(this.complete) {
var item = $('<div class="item"></div>');
var itemDiv = $(this).parent();
$(itemDiv.html()).appendTo(item);
item.appendTo('.carousel-inner');
if (i==0){ // set first item active
item.addClass('active');
}
}
});
/* activate the carousel */
$('#modalCarousel').carousel({interval:false});
/* when clicking a thumbnail */
$('.gallery-image').click(function(e){
e.preventDefault();
var idx = $(this).parents().parents().index();
var id = parseInt(idx);
$('#myModal').modal('show'); // show the modal
$('#modalCarousel').carousel(id); // slide carousel to selected
});
this code works when i load the page for very first time but when i reload the page and click on the image this code is not work working
I can understand that you are setting the contents of the modal window on the first few lines of the JavaScript. Try to set it in the click event:
$('.gallery-image').click(function(e){
e.preventDefault();
var idx = $(this).parents().parents().index();
var id = parseInt(idx);
$('#myModal').modal('show'); // show the modal
$('#modalCarousel').carousel(id); // slide carousel to selected
// Update the modal window contents here.
});
Finally i have find a solution
$('.carousel-inner').find('.item').first().addClass('active');
/* when clicking a thumbnail */
$('.gallery-image').click(function(e){
e.preventDefault();
var idx = $(this).parents().parents().index();
var id = parseInt(idx);
$("#myModal").modal("show");
$('#modalCarousel').carousel(id);
});

How to change the title of an Iframe dynamically?

I am trying to show some video files in an Iframe for our company web site. Whenever the user clicks on a video link it will be shown inside an Iframe. I used a Javascript file to perform this action. If I host my videos on you tube, you tube show the title of video.But the javascript I used only change the content of the iframe. I need to show the title of the video files somewhere above the Iframe.
The javascript file I use is this :
<script type="text/javascript">
function ChangeVideoUrl(url)
{
document.getElementById("video_iframe").src = url;
}
</script>
and in I wrote this :
<a class="links" href="JavaScript:ChangeVideoUrl('https://..something.');"> text</a>
Any Ideas?
You can change the actual title of the iframe with iframeReference.contentDocument.title = 'some title'. If you want to change an html title like a h1 tag, you can get the reference to it and set its textContent. See below.
Sample Markup:
<button id="myBtn">Change Iframe</button>
<h1 id="h1Title">Iframe Title</h1>
<iframe id="myIframe"></iframe>
Sample JavaScript:
var myBtn = document.getElementById('myBtn');
var myIframe = document.getElementById('myIframe');
var h1Title = document.getElementById('h1Title');
myBtn.addEventListener('click', changeIframe);
function changeIframe() {
myIframe.contentDocument.title = 'New title!';
h1Title.textContent = 'New Title!';
}
Live demo (click).
As you have now updated your question with your code, there is more to say.
First, inline js (JavaScript inside your html elements) is bad. Read some of these results: https://www.google.com/search?q=Why+is+inline+js+bad%3F
Instead, follow my example and get element references and attach event listeners to them. You can store your data on the element and pull it from there if you want to.
Live demo (click).
Markup:
<div class="links">
<a data-src="a/video" data-title="A video!">Click to Play: A video!</a>
<a data-src="some/title" data-title="Some Title!">Click to Play: Some Title!</a>
<a data-src="another/title" data-title="Another Title!">Click to Play: Another Title!</a>
</div>
<h1 id="h1Title">Iframe Title</h1>
<iframe id="myIframe"></iframe>
JavaScript:
var myIframe = document.getElementById('myIframe');
var h1Title = document.getElementById('h1Title');
var links = document.querySelectorAll('.links a');
for (var i=0; i<links.length; ++i) {
addClickFunc(links[i], i);
}
function addClickFunc(elem, i) {
elem.addEventListener('click', function() {
var title = elem.getAttribute('data-title');
var src = elem.getAttribute('data-src');
changeIframe(title, src);
});
}
function changeIframe(title, src) {
myIframe.src = src;
myIframe.contentDocument.title = title;
h1Title.textContent = title;
}
Assuming some heading for title. You can do this also by javascript.
Give the id for the tag that holding the title of iframe.
Using javascript change the text in that when user click's on video link(chnage innerHTML).

Categories

Resources