I have a rather long code, so i think the best is I post it here with some additional comments as questions inside of it:
<div class="contentRow">
<h2>Title</h2>
<div id="frame">
<?php
//Get files
$sql->query("SELECT * FROM files WHERE job = 'true'");
$count = count($sql->get());
//No files to display
if ($count == "0"){
echo "<div class='box red'><p>No jobs found.</p></div>";
} else{
$sql->query("SELECT * FROM files WHERE job = 'true'");
$i=0;
foreach($sql->get() as $result){
$i++;
?>
<!-- Here I start printing the results and here the problems begin -->
<!-- My goal here: Print n .jobsContainer with exactly 4 .jobContainer inside -->
<?php if ($i % 4 == 0){ ?>
</div><!-- CLOSE jobsContainer -->
<?php } ?>
<?php if ($i % 4 == 0 OR $i == 1){ ?>
<div class="jobsContainer"><!-- OPEN jobsContainer -->
<?php } ?>
<!-- Print the .jobContainer -->
<div class="jobContainer">
content + table + form
</div>
<!-- My goal here: Print .jobSeperator after every 2nd .jobContainer -->
<?php if ($i % 2 == 0){ ?>
<div class="jobSeperator"> </div>
<?php } ?>
<!-- CLOSE loop -->
<?php } }?>
</div><!-- jobsFrame -->
<div class="clear"></div>
</div><!-- contentRow -->
The desired output should look like this:
My problem is following:
It seems that there are only 3 elements included in the first container, but after that there are 4. Therefore also the seperators are kinda messed up and it looks like this:
It seems that the problem is not applying to the .jobSeperator, as it does always get included after every 2th container, however it gets messed up too, because of the fact that in the first .jobsContainer there are just 3 sub containers.
I dont get why in the first .jobsContainer there are just 3 sub containers, but from than on there are, as desired, 4, but probably it is obvious and I just dont see it...
p.s. If I set the code to print 5 .jobContainer inside one .jobsContainer, than there are printed 4 in the first .jobsContainer and from than on 5 in every following .jobsContainer
First of all, you should not keep your SQL logic mixed with HTML.
Anyway. The idea is that you need to output a separator after each second item. The testcase i would look at would be like this.
1 2
---
3 4
***
5 6
---
7
And the code for writing it would be:
$i = 0;
foreach( /* some array */ as $data ){
$i++;
if ( ($i - 1) % 2 === 0 ){
if ( ($i - 1) % 4 === 0 ){
echo '<br />***<br />';
} else {
echo '<br />---<br />';
}
}
echo $i, ' ';
}
This would reproduce the structure above (never tested).
As for the separation of layout and rest of application logic, you might look in to this article. It will show a quite simple way, without a need of additional 3rd party libraries.
try to change these lines:
<?php if ($i % 4 == 0 OR $i == 1){ ?>
<div class="jobsContainer"><!-- OPEN jobsContainer -->
<?php } ?>
to
<?php if ( ($i-1) % 4 == 0 ){ ?>
<div class="jobsContainer"><!-- OPEN jobsContainer -->
<?php } ?>
Now you open container at the begginning of 1st, 4th, 8th, 12th,... iteration, after this change you should open container before 1st, 5th, 9th, 13th,... iteration which should fix the problem. And you will get rid of ugly or. It seems this is the only bug, just try it.
I also suggest separating application logic and presentation.
I believe You're making one small mistake.
<!-- My goal here: Print n .jobsContainer with exactly 4 .jobContainer inside -->
<?php if ( ($i+1) % 4 == 0){ ?>
</div><!-- CLOSE jobsContainer -->
<?php } ?>
<?php if ( ($i+1) % 4 == 0 OR $i == 1){ ?>
<div class="jobsContainer"><!-- OPEN jobsContainer -->
<?php } ?>
Use ($i+1) instead of $i in this bit.
If you inspect the generated HTML output, you'll see that when $i == 4, you first close the jobsContainer div before outputting the 4th jobContainer. You need to change the order of output to something like this:
EDIT: seems like you should split up the start of the first jobsContainer ($i == 1)
<div class="contentRow">
<h2>Title</h2>
<div id="frame">
<?php
$i = 0;
for($j = 0; $j < 12; $j++)
{
$i++;
?>
<?php if ($i == 1) { ?>
<div class="jobsContainer">
<?php } ?>
<div class="jobContainer">job</div>
<?php if ($i % 4 == 2) { ?>
<div class="jobSeperator"> </div>
<?php } ?>
<?php if ($i % 4 == 0) { ?>
</div>
<div class="jobsContainer">
<?php } ?>
<?php
}
?>
<?php if ($i > 0) { ?>
</div>
<?php } ?>
</div>
<div class="clear"></div>
</div>
Related
I am developing a template for a WordPress page. Users have levels (beginner, amateur, intermediate, and advanced). My need was to load a % of content based on the level, with each higher level increasing the % of content shown.
As a novice, I wanted to work only in page-template.php. Alternative syntax lets you put HTML markup (without include and external .html files) between php tags. Next, the switch statement has fallthrough functionality to "load" content based on their level.
After reading more on switch, comparison operators in switch, heredoc, and alternative syntax, I still wasn't able to find what worked for me, so I wanted to share this to future novice programmers some time :p
Here is a functional piece of code that achieves what I want:
<?php $level = 1; // enter user level here ?>
<?php switch(true): ?>
<?php case ($level >= 1): ?>
<div>
1 <!-- represents 25% of content -->
</div>
<?php if($level == 1){break;} ?>
<?php case ($level >= 2): ?> // ugly code
<div>
2 <!-- represents 25% of content -->
</div>
<?php if($level == 2){break;} ?> // ugly code
<?php case ($level >= 3): ?>
<div>
3 <!-- represents 25% of content -->
</div>
<?php if($level == 3){break;} ?> // ugly code
<?php case ($level >= 4): ?>
<div>
4 <!-- represents 25% of content -->
</div>
<?php if($level == 4){break;} ?> // ugly code
<?php endswitch; ?>
That is, with each level, you get 25% more content until level 4... where all content is available. You will notice I have conditional breaks. This is because the conditionals in the cases don't seem to work alone as you one would hope -- I wasn't able to figure out why, but the break with the conditional help. It's redundant but it's the only thing I got to work.
For future readers, be wary of the spacing and tabination. Alternative syntax is very particular about it, and it may frustrate you if you neglect it.
So my question is if there is another way to improve this code or a cleaner way to write it? While writing this, I realize I can probably use alternative syntax for the breaks.
Maybe you can consider using a for loop?
<?php
$content[1] = "Content A";
$content[2] = "Content B";
$content[3] = "Content C";
$content[4] = "Content D";
$level = 3; // enter user level here
for ($lvl = 1; $lvl <= $level; $lvl++) { ?>
<div>
<?php echo $content[$lvl]; ?> <!-- represents 25% of content -->
</div>
<?php } ?>
I wouldn't use switch for this, but just a series of if statements:
<?php $level = 2; // enter user level here ?>
<?php if ($level >= 1) { ?>
<div> 1 <!-- represents 25% of content --> </div>
<?php } if ($level >= 2) { ?>
<div> 2 <!-- represents 25% of content --> </div>
<?php } if ($level >= 3) { ?>
<div> 3 <!-- represents 25% of content --> </div>
<?php } if ($level >= 4) { ?>
<div> 4 <!-- represents 25% of content --> </div>
<?php } ?>
An alternative is to first store all the content in an array, and then output a slice of that array:
<?php
$level = 2;
$content = [
<<<TEXT
<div> 1 <!-- represents 25% of content --> </div>
TEXT
,
<<<TEXT
<div> 2 <!-- represents 25% of content --> </div>
TEXT
,
<<<TEXT
<div> 3 <!-- represents 25% of content --> </div>
TEXT
,
<<<TEXT
<div> 4 <!-- represents 25% of content --> </div>
TEXT
];
echo implode("\n", array_slice($content, 0, $level));
?>
For parsing a list of articles, i have this code to parse all the articles:
while($article = $articles->fetch())
{
$date = strtotime($article['createdAt']);
$formatted_date = date("F Y",$date);
?>
<br />
<div class="news-content">
<div class="news-image">
<?php echo $article['title']; ?>
</div>
<div class="news-article">
<h3>
<span><?php $date = strtotime($article['createdAt']); echo /*date("F j",$date);*/ strftime('%e %B',$date) ?></span>
<br />
<?php echo $article['title']; ?>
</h3>
</div>
</div>
<?php
} //end while loop
?>
What i want to achieve: only the first 5 <div class="news-content">...</div> should be shown.
I know i have to do something with a for loop
but i do not know exactly how to use the for loop for this situation...
Can someone help me with that?
There are a lot of different ways to limit a loop. One possibility is to use a for loop instead of a while loop. for is often a good option if you want something to happen a specific number of times. Adding something else like fetch into the continuation condition will mean it happens up to a specific number of times.
for ($i = 0; $i < 5 && $article = $articles->fetch(); $i++) {
// output article
}
I want to fetch some data from database in the form of list. Following is my loop:
<div class="col-sm-4">
<ul>
<?php
foreach($subjects as $s)
{
echo "<li>$s->subject_title</li>";
}
?>
</u>
</div>
Now this loop prints data in one column and the user have to scroll down to view the last elements. I want to control the loop in such a way that after printing first 10 elements, it must start again from the div tag and print the next 10 elements and so on. I want to show the data in such a way that the user don't have to scroll down.
For example, I want to print the data in the following way:
I write the following code but it is not working. The div tag is only applied to the first 10 elements, and not on the rest of the data.
<div class="col-sm-6">
<ul class="filter-list">
<?php
$i = 0;
foreach($main_subjs as $i=>$ms)
{
if($i == 10) {
echo "</ul></div><div class='col-sm-6'><ul>";
$i++;
continue;
}
echo "<li><a href='#'>$ms->mains_title</a></li>";
}
?>
</ul>
</div>
Please Help.
As an arugment for a loop you can also use the key of array
foreach($subjects as $i=>$s)
When you will be able to "control" your loop, e.g.:
<div>
<?php
foreach($subjects as $i=>$s) {
if($i> 0 && $i % 5 == 0) {
echo "</div><div>";
}
echo "<li>$s->subject_title</li>";
}
?>
</div>
Im having a problem with a php script. I want to make it work so when under 5 hits it shows a locked button and greater than 5 hits it shows a unlocked button.
<?
if($hits < 5){
?>
<div id="status-button-locked"></div>
<?
}
?>
<?
if($hits > 5){
?>
<div id="status-button-unlocked"></div>
<?
}
?>
I have tried the code above but it didn't work, when it is greater than 5 it just wont show anything.
It won't show anything, when 5 hits exactly. Try:
<?
if($hits < 5){
?>
<div id="status-button-locked"></div>
<?
} else {
?>
<div id="status-button-unlocked"></div>
<?
}
?>
Like David said it now doesn't react when it hits exactly 5.
Try this:
<?php
if($hits >= 5){ // this part happens if $hits is 5 or higher.
?>
<div id="status-button-unlocked"></div>
<?php
} else {
?>
<div id="status-button-locked"></div>
<?php
}
?>
this way you handle errors like when $hits is empty.
I had 14 li elements with various information in and thought it's be better to wrap it all up into a php loop and use variables and arrays to fill in the gaps.
I've encountered two problems. The first of which is that I'm not returning any elements from the array description or title.
The next problem is in the filename $iFINAL.pdf - it should just be the variable $i with FINAL appended to it.
I wouldn't normally use EOT but in this case it seemed far quicker than escaping all the various quotes.
any help is appreciated, thanks!
<?php
$description = array("Decription 1 here","description 2 here");
$title = array("title 1","titlesfdfs ","sdfsdsd","wqeqe","","");
for($i=1; $i <= 14; $i++){
if($i < 10){
$i = "0".$i;
}
$body = <<<EOT
<h3>Chapter $i - $title[$i]</h3>
<div class=trainingItemListContainer>
<div class="mainDetails">
<p><strong>Introduction:</strong> $description[$i]</p>
</div>
<div class="subDetails">
<div class="viewAndDownload">
<p>Click to view the chapter</p>
</div>
<div class="viewAndDownload">
Click to download the PDF file <img src="../images/disk.png" alt="downloadIcon" border="0"/>
</div>
</div>
</div>
EOT;
echo $body;
}
There are two major issues with your code:
You're setting the value of $i to 01, 02 etc. This will cause the script to produce Undefined Index errors because there's no such index in your array.
You're not enclosing the variables in { }. If you enclose it, the actual variable values will be used. For example: {$i}
Example:
$body = <<<EOT
<h3>Chapter {$i} - {$title[$i]}</h3>
<div class=trainingItemListContainer>
<div class="mainDetails">
<p><strong>Introduction:</strong> {$description[$i]}</p>
</div>
<div class="subDetails">
<div class="viewAndDownload">
<p>Click to view the chapter</p>
</div>
<div class="viewAndDownload">
Click to download the PDF file <img src="../images/disk.png" alt="downloadIcon" border="0"/>
</div>
</div>
</div>
EOT;
Several issues here:
(1) This code is causing problems:
if($i < 10){
$i = "0".$i;
}
WHY? if you did a var_dump($i) (= simple debugging), you'd realize that
$title[1] is different from $title['01']
solution: delete the above code.
(2) an array in PHP will start with index 0, not 1.
echo $description[1];
will output "description 2 here".
solution:
for ($i = 0; $i < 14; $i++) {
$number = str_pad(($i + 1), 2, "00", STR_PAD_LEFT);
...
<h3>Chapter $number - $title[$i]</h3>
see it working here: http://codepad.viper-7.com/489laJ
There is a problem within your code, you are changing the value of $i (reassigning another value with it here):
if($i < 10){
$i = "0".$i;
}
You can alternatively use another variable such as $j
if($i < 10){
$j = "0".$i;
}else{
$j = $i;
}
This might not be your exact problem, but it might help you to improve your code.
Why not try this?
<?php
$description = array("Decription 1 here","description 2 here");
$title = array("title 1","titlesfdfs ","sdfsdsd","wqeqe","","");
for($i=1; $i <= 14; $i++){
if($i < 10){
$i = "0".$i;
}
?>
<h3>Chapter <?php print($i." - ".$title[$i]); ?></h3>
<div class=trainingItemListContainer>
<div class="mainDetails">
<p><strong>Introduction:</strong> <?php print($description[$i]); ?></p>
</div>
<div class="subDetails">
<div class="viewAndDownload">
<p>Click to view the chapter</p>
</div>
<div class="viewAndDownload">
Click to download the PDF file <img src="../images/disk.png" alt="downloadIcon" border="0"/>
</div>
</div>
</div>
If you have PHP code later on, just open the <? tag again!