I'm trying to insert a div into a HTML page using a for loop and the appendChild method in PHP. The issue I'm running into is that the first div always ends up stuck inside the second div, which always ends up stuck in the third div and so on and so forth. So how do I end the div at the end of the for loop?
///The PHP Side
// Create an insertion point for the Projects element
$projectInsert = $doc->getElementById("projects");
// Create a project Box
for ($x = $row_cnt; $x > 0; $x--) {
$sql2 = "SELECT * FROM `$prjct` WHERE id=$x";
$result2 = mysqli_query($db,$sql2);
$row2 = mysqli_fetch_array($result2,MYSQLI_ASSOC);
//Insert a project Box
$projectBox = $doc->createElement('div');
$projectBox->setAttribute("class","projectBox");
$project_element_title = $doc->createElement('p', $row2["title"]);
$project_element_description = $doc->createElement('p', $row2["description"]);
$projectInsert->appendChild($projectBox);
$projectInsert->appendChild($project_element_title);
$projectInsert->appendChild($project_element_description);
}
//Here's where it's inserting in the HTML
<div class="projectBar" id="projectsBar">
<h4 style="height: 30%; width: 100%; margin: auto;">Projects</h4>
<p id="projects"></p>
</div>
Here's photos of what's happening vs what I want to happen
https://docs.google.com/presentation/d/1OgthPueXHzGXyUi6L3DmgWTtOr6gHpfj8LgGh5OG85Y/edit?usp=sharing
Since I'm new I can't embed images.
Thanks for any and all help!
Instead of appending childs($project_element_title and $project_element_description) to parent($projectBox) you are appending it to super-parent($projectInsert), that's the problem.
So change:
$projectInsert->appendChild($project_element_title);
$projectInsert->appendChild($project_element_description);
To
$projectBox->appendChild($project_element_title);
$projectBox->appendChild($project_element_description);
Related
(This has now been resolved - thanks #ChelseaStats)
I have built a web page in PHP. users log in and upload photos and stories, and the page displays the stories and photos immediately.
The problem is that the photos that the MySQL query and PHP return from the database are being displayed all over the place. I have printed them out in an id’d div but the CSS is having no control over their positioning.
Currently the query is like this:
$q1 = "SELECT * from images ORDER BY date ASC";
and they are displayed like this...
row1 = #mysqli_query($dbc, $q1);
echo '<div id = "pictures">';
while ( $fix1 = mysqli_fetch_array($row1) ) {
echo '
<img style = "border: 1px solid black; padding: 10px;" height = "80" width = "80" src = "data:image;base64,'.$fix1['image'].'"><br>'.$fix1['image_id'].'
';}
echo '</div id = "pictures">';
What I would like to do is store all the 'while loop' programming in a variable, then print that variable out elsewhere on the HTML page away from php script so that when the database query is run, I can use the results to fill/initialize the variable (e.g. $displayPics) which will then be printed out on the html page where I want it to appear.
I realise this may be impossible and I am open to suggestions...
...or I might be willing to run a query with a limit of 20 giving results in descending date order and then assigning ‘loop-free’ PHP code to a variable which I can then print out on the page elsewhere.
Code could look something like this:
row1 = #mysqli_query($dbc, $q1);
$fix1 = mysqli_fetch_array($row1);
$displayPics = '
<img style = "border: 1px solid black; padding: 10px;" height = "40" width = "40" src = "data:image;base64,\'.$row1[$fix1[\'image\']].\'"><br>\'.$row1[$fix1[\'image\']].\'
';
(Above code is a shot at how I imagine it will look). (I think the img src code and html has been filtered out by the forum possibly).
But maybe this code will be repeated 20x in the variable with row number changing for each subsequent repetition perhaps?
(I basically want better control over the positioning of the pics coming back from the database).
in a foreach you can assign to a variable like this
$bob = ''; // set it
foreach($row as $image) {
// append to it
$bob .= '<div id=""><img src="" /></div>'.PHP_EOL;
}
print $bob;
similar would work for you.
if you use Bootstrap- you can assign a display class as it is rendered. The following will display each image as follows (4 across on a medium to large viewport, 3 across on a small viewport, and two across on a mobile sized viewport). Also note the use of figcaption to provide the caption on each image.
row1 = #mysqli_query($dbc, $q1);
while ( $fix1 = mysqli_fetch_array($row1) ) {
echo "<div class='col-md-3 col-sm-4 col-xs-6'>
<figure>
<img style = 'border: 1px solid black; padding: 10px;' height = '80' width = '80' src = 'data:image;base64,".$fix1['image']."'/>
<figcaption>".$fix1['image_id']."</figcaption>
</figure>
</div>
";}
Simply write a function that returns all of the rows into an array of assoc arrays and loop through them when you need them elsewhere in the code and use conditional tests on the rows to have better control over where they go!
function getImages(){
$imgs = array();
while(($next = mysqli_fetch_assoc(...)){
array_push($imgs, $next);
}
return $imgs; //array of assoc arrays
}
Okay so I have this portfolio page where I display a couple of thumbnails, and you can order it by tags, so for example like this:
year 1
And this works fine. However, my thumbnails display at three on a row, so only the first two should have a right margin, the third one no margin.
I used PHP to do this which works fine.
if ($result=$link->query($query)) {
for ($i=1; $i <= $result->num_rows; $i++) {
$row= $result->fetch_assoc();
$id = $row['number'];
$title = $row['title'];
$bgthumbnail = $row['thumbnail'];
if($i%3 == 0){
echo "
<div class=\"thumbnail\">
<a href=\"portfoliodetail.php?id=$id\">
<div class=\"thumbnailOverview noMargin\" style=\"background: url('images/portfolio/thumbnails/$bgthumbnail'); background-position: center center;\">
<div class=\"latestWorkTitle\">$title</div>
</div>
</a>
</div>
";
} else {
echo "
<div class=\"thumbnail\">
<a href=\"portfoliodetail.php?id=$id\">
<div class=\"thumbnailOverview\" style=\"background: url('images/portfolio/thumbnails/$bgthumbnail'); background-position: center center;\">
<div class=\"latestWorkTitle\">$title</div>
</div>
</a>
</div>
";
}
}
$result->close();
}
However, when I click a tag, the margin doesn't update. So when a thumbnail was given no margin in the overview because it was the third one in row, when it displays first because of a chosen tag, it also receives no margin.
Of course this is because nothing "refreshes" or something, but I was wondering if there is an "easy" way to fix this problem? To make the PHP loop run again or something?
You must to set/remove noMargin class name via javascript:
$('.year-clicker').click(function (event) {
event.preventDefault();
var year = $(event.currentTarget).data('year');
$('.thumb').hide().removeClass('noMargin').filter('.year' + year).show();
$('.thumb:visible').each(function (i, e) {
if ((i + 1) % 3 == 0) {
$(e).addClass('noMargin');
}
});
return false;
});
Try out this jsfiddle http://jsfiddle.net/xgE3K/1/
unless your "tags" are recalling the page - so that the php is re-executed - you probably want to look at javascript (or possibly ajax) to do the reformatting of the layout.
Depending on the quantity of thumbnails and the variety of tags, you might use the php to create a div (with a relevant id and a style="" attribute) for each of the different filter tags - containing the layout of the thumbnails for that tag (so you can ensure your layout is fine for each view).
i.e. repeat your code above enclosed by a unique div tag for each view.
Make the default view div visible (style="display: block") and the others hidden (style="dsplay: none").
Then have a javascript function that is executed on any tag click. This will make the relevant div visible and the rest hidden, by changing their style value as above.
Uses a bit more memory, but your switching between views will be quicker than doing a reload.
Despite all this, I think it's cleaner and more scalable to recall the page with the relative filter (depending on the tag) then you will have more control over the layout.
hi i wonder if anyone can help, not entirely sure this is possible but i have a div container called <div class="scroll">
inside div scroll is a sql query that echoes comments posted by users from the database. the div scroll is set to a width of 600px and so the comments will be arranged in this div left to right, theres two comment boxes on each line, each comment box is just under 300px each as to align next to each other.
the comments are listed like so:
<div class="scroll">
comment 1 | comment 2
comment 3 | comment 4
comment 5 | comment 6
</div>
the comments are encased in the div "comment_box"
now what i have done is put a background image to the div "comment_box" this image is a pointer arrow that points to the left and is positioned on the left hand side of the div, but i also want to have a second background image for the comment boxes that align on the right, so in this instance comments 2, 4 and 6 will have a different background image/an arrow that points to the right on the right hand side of the div.
is this possible?
thanks
comment box{
.wall_post_case_branch {
background-image:url(../img/effects/arrow_left.png);
background-repeat:no-repeat;
background-position: center;
height:90px;
width:290px;
position:relative;
border:#ccc 1px solid;
}
mysql:
<?php
if(mysql_num_rows($wallposts_set) > 0) {
while ($posts = mysql_fetch_array($wallposts_set)) {
$age = days_from_date($posts['date_added']);
?>
<div class="comment_box">
<?php echo "{$posts['content']}"; ?>
</div>
You can do it as below.
<?php
$i = 0;
while ($posts = mysql_fetch_array($wallposts_set))
{
$class = ' odd';
if ($i++ % 2 == 0)
{
$class = ' even';
}
echo '<div class="comment_box'.$class.'">';
}
?>
and in css
.odd { background-image:imageone.jpg; }
.even{ background-image:imagesecond.jpg; }
I would right before the while loop make the variable $i = 0;.
It would use that to define what background color it should use.
Then in the while loop I would use this code:
while ($posts = mysql_fetch_array($wallposts_set)) {
$i++;
$age = days_from_date($posts['date_added']);
echo "<div class=\"comment_box_$i\">
$posts['content']}
</div>";
if ($i == 2)
$i = 0;
}
Then the boxes will have 2 difference classes, the one of the left will have the class="comment_box_1" while the right box will have class="comment_box_2".
Then you can create your CSS for the difference boxes.
Enjoy
You can also do this simply with CSS by using:
:nth-child(even)
:nth-child(odd)
The fiddle illustrates with background colors instead of images.
http://jsfiddle.net/ingvi/CFMcA/
hope it helps
I have a bit of an issue...
Ive made a div, and normally, it expands to suit the height of its contents fine, however... Now i have a problem.
My content is being returned from a Sql statment, and its not expanding to suit its height, a working non dynamic version is
#commentblock {
min-height:50px;
width:90%;
margin:20px auto;
padding:10px;
border:1px solid #999;
}
My code is as follows (its in a for loop making a new div for each instance)
// Now lets query to grab the responses to this fault
$querytwo = "SELECT * FROM comments WHERE faultid=".$fid;
// execute query
$resulttwo = mysql_query($querytwo) or die ("Error in query: $querytwo. ".mysql_error());
// see if any rows were returned
if (mysql_num_rows($resulttwo) > 0) {
// print them one after another
while($row = mysql_fetch_row($resulttwo)) {
// lets make this render then
echo "<div id='commentblock'>";
echo "<div class='loggedby'>Logged By : <span>".$row[4]."</span><p class='contactno'>Entered : <span>".$row[3]."</span></p></div>";
echo "<div class='info'><span>".$row[2]."</span></div>";
echo "</div>";
}
}
// free result set memory
mysql_free_result($resulttwo);
// close connection
mysql_close($connection);
Thanks in advance :)
Got it, the content was in a span which was inheriting a floating attribute. Removed the float - now its all fine :)
It might not be to do with dynamic code, but invalid HTML.
You are using:
id='commentblock'
... in a loop, which create multiple, identical IDs on the same page, which is not valid.
You should change to:
class='commentblock'
and reference you CSS as:
.commentblock
... instead of:
#commentblock
I am trying to display a recursive list in PHP for a site I am working on.
I am really having trouble trying to get the second level to display. I have a function that displays the contents to the page as follows.
function get_menu_entries($content,$which=0)
{
global $tbl_prefix, $sys_explorer_vars, $sys_config_vars;
// INIT LIBRARIES
$db = new DB_Tpl();
$curr_time = time();
$db->query("SELECT * FROM ".$tbl_prefix."sys_explorer WHERE preid = '".$which."' && config_id = '".$sys_explorer_vars['config_id']."' && blocked = '0' && startdate < '".$curr_time."' && (enddate > '".$curr_time."' || enddate = '') ORDER BY preid,sorting");
while($db->next_record()){
$indent = $db->f("level") * 10 - 10;
$sitemap_vars['break'] = "";
$sitemap_vars['bold'] = "";
if($db->f("level") == 2) {
$sitemap_vars['ul_start'] = "";
$sitemap_vars['bold'] = "class='bold'";
$sitemap_vars['ul_end'] = "";
}
switch($db->f("link_type"))
{
case '1': // External Url
$sitemap_vars['hyperlink'] = $db->f("link_url");
$sitemap_vars['target'] = "";
if($db->f("link_target") != "") {
$sitemap_vars['target'] = "target=\"".$db->f("link_target")."\"";
}
break;
case '2': // Shortcut
$sitemap_vars['hyperlink'] = create_url($db->f("link_eid"),$db->f("name"),$sys_config_vars['mod_rewrite']);
$sitemap_vars['target'] = "";
break;
default:
$sitemap_vars['hyperlink'] = create_url($db->f("eid"),$db->f("name"),$sys_config_vars['mod_rewrite']);
$sitemap_vars['target'] = "";
break;
}
if($db->f("level") > 1) {
$content .= "<div style=\"text-indent: ".$indent."px;\" ".$sitemap_vars['bold'].">".$db->f("name")."</div>\n";
}
$content = get_menu_entries($content,$db->f("eid"));
}
return(''.$content.'');
}
At the moment the content displays properly, however I want to turn this function into a DHTML dropdown menu.
At present what happens with the level 2 elements is that using CSS the contents are indented using CSS. What I need to happen is to place the UL tag at the beginning and /UL tag at the end of the level 2 elements.
I hope this makes sense. Any help would be greatly appreciated.
Instead of using <div> tags with indentation, use an unordered list for each level, including the first one. Have your function output <ul> at the start and </ul> at the end, and change <div style="text-indent: ..."> to a simple <li>. Give the first level an ID so you can hook onto it. Then you can use CSS to remove bullet points and change the indentation, etc. You don't need to calculate the indentation or whether to bold the text in PHP—instead, use selectors and allow the browser to figure it out:
ul#menu { margin: 0; padding: 0; }
ul#menu > li { margin: 0; padding: 0; }
ul#menu > li > ul { margin-left: 10px; font-weight: bold; }
All this will allow you to use one standard algorithm for generating your list, instead of branching based on the level, as well as making the menu look like a menu to web crawlers, search engines and those with CSS-less browsers.
By the way, you should really be htmlspecialchars-ing all that dynamic text. You don't want a stray < to mess up your markup.
Correct me if I'm wrong, but it seems that your issue is not that you don't know when to print the first set of <ul> tags, but that you are trying to print the second set (for level 2) in every function call, and thus ending up with too many open/close tags.
I think what you should try to do is sort your array by level, first (see uasort() and then you can output your opening <ul> tag on the first loop of the second level (use a counter to keep track of which loop you're on and then do something like if ($i == 0) or if ($i == (count($array) - 1)). This will work no matter how many nested levels you have.