Jump to content

PHP can only modify divs declared before the modifier


fmohrmann

Recommended Posts

Dear all,

 

I am new to the forums, with a hope that somebody can point me in the right direction. I am coding a new photo website, and am doing it with PHP to maximize my flexibility. In essence I want to have a set of gallery folder on the server, and the site reads off these folders and automatically generates the required galleries.

 

My PHP code is below, along with a detail of the exact problem:

 

  <?php


$main 	= "Collections/"; 	# Location of galleries
$big    = "Large/"; 		# Location of big versions (subdir within each gallery)
$i 		= 0;				#Gallery Iterator


#Searching for galleries & Checking only for directories (save them im $galleries array)
$tempgalleries = scandir($main);	
    foreach ($tempgalleries as $gallery_iterate)
    { 
	if (!is_dir($gallery_iterate))
	{
		$galleries[]=$gallery_iterate;
	}
}


#Iterating galleries. Collecting each gallery's images (saving in $GalleryImages.$i). This creates an image array for each $galleries[$i]
for($i=0; $i<=sizeof($galleries)-1; $i++) 
{	
#Making the title nice (from the the directory names)			
$GalleryTitles[$i] = str_replace('_',' ', $galleries[$i]);;			
$temp_gallery = opendir($main.$galleries[$i]);
#Checking for Images and storing in array if valid
while (false !== ($image = readdir($temp_gallery))) 
{
	  if ($image != "." && $image != ".." && $image != rtrim($big,"/") && strstr($image,'.jpg')) 
	  {
			${$GalleryImages_.$i}[] = $image;							
	  }
}
#Sorting the images numerically
natsort(${$GalleryImages_.$i});
closedir($temp_gallery);
}


#Better location for the buttons!!

#Printing the galleries and all the html required for naming, separation, etc.. This is also an iteration
for($i=0; $i<=sizeof($galleries)-1; $i++) 
{
echo('<div class="galleries_hidden" id="gallery_'.$i.'"><hr><br><div class="Gallery_Title"><b><i><big>'.$GalleryTitles[$i].'</big></i></b></div><br>');
$folder=$galleries[$i];
foreach(${$GalleryImages_.$i} as $thumb_image)	
{
	echo  '<a href="'.$main . $folder .'/'. $big . 'large_'. $thumb_image . '" rel="lightbox['.$folder.']" title="'.$folder.'"><img src="' . $main . $folder .'/'. $thumb_image. '" alt="'.$folder.'" class="Gallery_Image" /></a>';
}
echo('</div>');
}

#Making the buttons to cycle the galleries
for($i=0; $i<sizeof($galleries); $i++) 
{	
echo('<input type="button" id="gallery_'.$i.'" value="Show '.$GalleryTitles[$i].'" onclick="showgallery(');echo("'gallery_".$i."');");echo('" /><br><br>');
}

?> 

 

I have managed to make each aspect work, exept one. The last portion, as commented:

 

#Making the buttons to cycle the galleries
for($i=0; $i<sizeof($galleries); $i++) 
{	
echo('<input type="button" id="gallery_'.$i.'" value="Show '.$GalleryTitles[$i].'" onclick="showgallery(');echo("'gallery_".$i."');");echo('" /><br><br>');
}

 

This piece of code generates buttons which shows one gallery, and hides the rest. This is done by changing the classes of the divs from "galleries_visible" to "galleries_hidden", as applicable. This is done using a javascript declared in the header as follows:

 

<script type="text/javascript">
function showgallery(id) 
{
var divall = document.getElementsByTagName("div");
var i=0;

for (i=0;i<divall.length;i++)
{

	if(divall[i].className == "galleries_visible")
	{
		divall[i].className = "galleries_hidden"; 
	}

var showdiv = document.getElementById(id);
showdiv.className = "galleries_visible";

return false;
}
</script>

 

When I have the button-generating php code below the gallery-generating php code, then the javascript seems to work, by showing and hiding respective galleries. These galleries and their litebox viewer all work normally. However, when putting the button-creator php above the gallery-generator php, then the buttons appear as normal, and the javascript runs, but it cannot find the div with the id it searches for:

 

var showdiv = document.getElementById(id);
showdiv.className = "galleries_visible";

 

I am confused. The PHP code makes several arrays which stores all the file and folder information, and these arrays are read by the button-generator irrespective of its position (I know this because the buttons are generated based on the content of non-empty arrays).

 

Why can't the javascript change the gallery-containing divs when they are below the button-containing div?

 

Any help is greatly appreciated, I just cant seem to find whats wrong!

 

Kind regards,

 

Frederik

Link to comment
Share on other sites

Could be due to a JavaScript race condition.  JavaScript loads fast, faster than the generated HTML.  Placing the buttons above the gallery could be causing the error as your showgallery() functions are being hooked up to divs that may not exist when the script first loads.  Element position does matter to JavaScript.  That's why the first step for good script writing is to always wait for the entire DOM to load first.  Try placing your script at the bottom of your markup.

 

Barring that, show your generated HTML.

 

Also, as a general tip, I strongly suggest you clean up your overall code structure.  Mashing PHP processing with output and JavaScript generation is the road to heartbreak.  Well-formed PHP apps follow the general pattern of:

 

All PHP processing first, where results are stored in variables -> Markup, with a minimal amount of PHP to display those results (if/else statements and loops should be the extent of the logic used for display).  JavaScript should be written in an unobtrusive manner.  By separating back end logic from markup from presentation logic, you make your code easier to work with, maintain, edit, and debug.  It's how the pros do it.

 

It will certainly make the lives of those you ask for help from easier.

Link to comment
Share on other sites

hi fmohrmann,

I think Nightslyr is correct about the load order of the javascript and html.

You might be better using jquery to do this. You can check the dom has loaded before the javascript is read.

It is off-topic for a php forum to go into a lot of detail about javascript but here is an example of some jquery that will show and hide divs. You should be able to adapt this to your needs.

 

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
    "http://www.w3.org/TR/html4/strict.dtd"
    >
<html lang="en">
<head>
    <title>test</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js" type="text/javascript"></script>
    <script type="text/javascript">
    $(document).ready(function() {
        
        // by default show the first gallery
        $('div.gallery').hide();
        $('#div1').show();
       
      $('a.button').click(function() {
         // get the numeric id of the link
        var idNum = this.id.substr(6,this.id.length);
        // create the id for the gallery div
        var galleryDivId = 'div' + idNum;
        // add the hide class to all galleries
        $('div.gallery').hide();
        // show the chosen gallery
        $('#' + galleryDivId).show();
        
      })
    })
    </script>
    <style type="text/css">
    div.gallery {
        border: 1px solid #000;
        padding: 30px;
        width: 70px;
    }
    </style>
</head>
<body>
    <div class="gallery" id="div1">
        test 1
    </div>
    <div class="gallery" id="div2">
        test 2
    </div>
    <div class="gallery" id="div3">
        test 3
    </div>
    <div class="gallery" id="div4">
        test 4
    </div>
    <a href="#" class="button" id="button1">gallery 1</a>
    <a href="#" class="button" id="button2">gallery 2</a>
    <a href="#" class="button" id="button3">gallery 3</a>
    <a href="#" class="button" id="button4">gallery 4</a>
</body>
</html>

 

Hope this helps,

Fergal

Link to comment
Share on other sites

Hello Nightslyr, Fergal,

 

First of all many thanks for your help already! I have found Jquery elsewhere, but want to try this at first, unless it's deemed foolish....

 

Anyway, here is my whole HTML output:

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Lustrum LXXX Foto's - Sint Borrel</title>

<link rel="stylesheet" href="http://delft.corps.nl/onderverenigingen/aero/Litebox/css/lightbox.css" type="text/css" media="screen" />
<link rel="stylesheet" href="Layout.css" type="text/css" media="screen" />

<script type="text/javascript" src="http://delft.corps.nl/onderverenigingen/aero/Litebox/js/prototype.lite.js"></script>
<script type="text/javascript" src="http://delft.corps.nl/onderverenigingen/aero/Litebox/js/moo.fx.js"></script>
<script type="text/javascript" src="http://delft.corps.nl/onderverenigingen/aero/Litebox/js/litebox-1.0.js"></script>

<script type="text/javascript">
function showgallery(id) 
{
var divall = document.getElementsByTagName("div");
var i=0;

for (i=0;i<divall.length;i++)
{
	if(divall[i].className == "galleries_visible")
	{
		divall[i].className = "galleries_hidden"; 
	}
}

var showdiv = document.getElementById(id);
showdiv.className = "galleries_visible";

return false;
}
</script>

<script type="text/javascript">
function menu() 
{
var menudivs = document.getElementsByTagName("div");
var i=0;

var menu = '';
for (i=0;i<menudivs.length;i++)
{
	if(menudivs[i].className == "galleries_visible" || menudivs[i].className == "galleries_hidden")
	{
		var templink1='<input type="button" id="'+menudivs[i].id+'" value="Show '+menudivs[i].id+'" onclick="showgallery(';
		var templink2="'"+menudivs[i].id+"');";
		var templink3='" /><br><br>';

		menu+=(templink1+templink2+templink3);
	}
}
document.getElementById('Menu').innerHTML = menu;
return false;
}
</script>

</head>

<BODY onLoad="initLightbox()">

<div id="Banner">
<img src="Layout/Banner_Main.jpg" alt="Banner_Main"/>
</div>

<div id="Title">
<b><i><big>WEBSITE IN VERBOUWING!</big></i></b>
</div>

<div id="Menu">
<div>

<div id="Gallery">
<?php
$main	= "Collections/"; 	# Location of galleries
$big         = "Large/"; 		# Location of big versions (subdir within each gallery)
$i 		= 0;				#Gallery Iterator


#Searching for galleries & Checking only for directories (save them im $galleries array)
$tempgalleries = scandir($main);	
    foreach ($tempgalleries as $gallery_iterate)
    { 
	if (!is_dir($gallery_iterate))
	{
		$galleries[]=$gallery_iterate;
	}
}

#Iterating galleries. Collecting each gallery's images (saving in $GalleryImages.$i). This creates an image array for each $galleries[$i]
for($i=0; $i<=sizeof($galleries)-1; $i++) 
{	
#Making the title nice (from the the directory names)			
$GalleryTitles[$i] = str_replace('_',' ', $galleries[$i]);;			
$temp_gallery = opendir($main.$galleries[$i]);
#Checking for Images and storing in array if valid
while (false !== ($image = readdir($temp_gallery))) 
{
	  if ($image != "." && $image != ".." && $image != rtrim($big,"/") && strstr($image,'.jpg')) 
	  {
			${$GalleryImages_.$i}[] = $image;							
	  }
}
#Sorting the images numerically
natsort(${$GalleryImages_.$i});
closedir($temp_gallery);
}





#Making the buttons to cycle the galleries
for($i=0; $i<sizeof($galleries); $i++) 
{	
echo('<input type="button" id="gallery_'.$i.'" value="Show '.$GalleryTitles[$i].'" onclick="showgallery(');echo("'gallery_".$i."');");echo('" /><br><br>');
}

#Printing the galleries and all the html required for naming, separation, etc.. This is also an iteration
for($i=0; $i<=sizeof($galleries)-1; $i++) 
{
echo('<div class="galleries_hidden" id="gallery_'.$i.'"><hr><br><div class="Gallery_Title"><b><i><big>'.$GalleryTitles[$i].'</big></i></b></div><br>');
$folder=$galleries[$i];
foreach(${$GalleryImages_.$i} as $thumb_image)	
{
	echo  '<a href="'.$main . $folder .'/'. $big . 'large_'. $thumb_image . '" rel="lightbox['.$folder.']" title="'.$folder.'"><img src="' . $main . $folder .'/'. $thumb_image. '" alt="'.$folder.'" class="Gallery_Image" /></a>';
}
echo('</div>');
}

?> 
</div>

<script type="text/javascript">
menu();
</script>

</body>
</html>

 

As you may have seen, I have also tested a javascript menu, seeing if that would make a difference. This script writes the same button code into a menu div which I "should" be able to place anywhere. Strangely, similar to the PHP placement, only if the menu div (now before the php), is placed after the php, then the buttons generated into it (by the menu() function) work.

 

Summarized, if the menu div is placed before the php then the buttons are created, but the galleries don't show. This seems strange, because the buttons are based on the existing divs which have the "galleries_hidden" class, which means that they have been created, but somehow these gallery divs don't show....?

 

I have taken to your comments about my structure. I agree with you, and will restructure as soon as possible. I hope the code is followable to some extent. The scripts are in the header, and the php is split into the processing/array creation, and the two output sections.

 

I have tried to place the scripts I use below the PHP. However, I tried placing both in and below the body div, and this does not change anything. It works the same (menu buttons always appear, but only work when the menu div is below the php).

 

I hope this gives some clarification, and again I much appreciate your insights!

 

Kind regards,

 

Frederik

Link to comment
Share on other sites

AHA, I found the problem!!

 

Using a for loop I previously used to test the javascript, I managed to deduce that the divs were found, and existed. However, using dreamweaver I could view the "live code", and this showed that the buttons I was creating had the same ID as the galleries they were showing. Really stupid, as I back-then quickly set up the ID of the button to be equal to the ID of the gallery, in order to keep them separated.

 

This resulted in the the buttons being modified, however they were not a div so their class/visibility would not change. By changing the button ID's to something similar, I still keep them separated but modify the actual galleries. Great! This also explains why the higher placement of the buttons didn't work; the button divs were modified instead of the gallery divs. As I made the error in both the menu() function as the PHP buttons, both work well now after I fixed them.

 

One question though (this is a tad off topic); I have the divs created one after the other, I beleive they are next to eachother. When I show the first one and hide the second it looks fine. When hiding the first and showing the second, the shown gallery (#2) seems to move a tad to the right. Is this because the hidden gallery #1 still takes up some space to the left of #2? How could I reduce it (with CSS perhaps?).

 

You can see the progress and the small problem here:

 

http://gallery.dsalustrum.nl/index_2.php

 

As a note: these default buttons will be changed to clickable images to differentiate the galleries, buts that all markup, and will come soon!

 

Regards,

 

Frederik

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.