Hide / Show divs from url string in php - php

A complete beginners question.
I have a large number of divs (>80) on a page (page2.php) and what I would like to do is open page1.php, click on a link to open page2.php and show only one of these divs depending on which link was clicked.
I have a basic working version of this by adding an if else to the divs. I've only done this on 5 of the divs so far and it works but it also seems a fairly in-eloquent way of doing things.
Page 1:
this is a link
Page 2:
<?php
$divID = $_GET['id'];
?>
<div id="r0101" <? if($divID == r0101): ?>class="show"<? else: ?>class="hidden"<? endif; ?> >
This then applies a css class to hide or show the div.
Would it be possible to have a function or whatever at the top of the page that takes the id from the url, figures out that there is a div with that id also, show it and hide all the others? This is probably an easy thing to do but it has me stumped.
Any help greatly appreciated.
Thanks.

Let alone the divs and work on css (as you relay on that to hide/show the divs).
You can generate not only markup but css stylesheet too. Use a similar one (put it at
the end of your head section). And let the browser do the work for you ;)
<style type="text/css">
div {
display: none;
}
div#<?php echo $_GET['id']; ?>:{
display: block;
}
</style>

$divs = array('r0101', 'r0102', 'r0103');
$divID = $_GET['id'];
foreach($divs as $div)
{
echo '<div id="'.$div.'" class="';
if ($div == $divID)
{
echo 'show';
}
else
{
echo 'hidden';
}
echo '">';
}
Assuming I have read the question correctly, you have a set of divs (r0101, r0102, etc.) and wish to show only one of these depending on the page you are on. The code above creates an array of these divs, loops through and creates the div. The class of the div is 'show' if the div matches the div from the page url, and 'hidden' otherwise.

First of all, you should consider a way of making your divs to be printed dynamically. Something like:
<?php
for($i = 1; $i <= 80; $i++):
?>
<div id="r<?php print $i; ?>">div contents</div>
<?php
endfor;
?>
Also, if you find a way of doing what's stated above, you can also do something like:
<?php
for($i = 1; $i <= 80; $i++):
if($i == $_GET['id']){
$class = 'show';
} else {
$class = 'hidden';
}
?>
<div id="r<?php print $i; ?>" class="<?php print $class; ?>">div contents</div>
<?php
endfor;
?>
or
<?php
for($i = 1; $i <= 80; $i++):
$class = ($i == $_GET['id']) ? 'show' : 'hidden';
?>
<div id="r<?php print $i; ?>" class="<?php print $class; ?>">div contents</div>
<?php
endfor;
?>
which is exactly the same but (using the ternary operator) spares a few lines and (some people think) it decreases readability.

If you want to make your download faster, you should output only the div you want to show. You could do something like this:
$divs = array('r0101', 'r0102', 'r0103');
$divID = $_GET['id'];
foreach($divs as $div)
{
if($div == $divID){ echo '<div> /* CONTENT HERE */ </div> };
}
Hope this helps.

Related

Overriding CSS code trough visual composer

I have the following line of html code which i don't have access to.
Since i wanted to hide a TAB which is the first <a href='#all' ...>, I used the custom css options of visual composer which allows me to override an existing code. To do that I simply used
.testing, a[href='#all'] {
visibility: hidden; }
I'm fine with this as long as that TAB is not visible. But next problem here is this particular TAB is always selected when i refresh the page, simply because the class=selected is applied to it. Can i somehow override it using css to apply the class selected to one of the other 2 <li>'s ?
Edit
I managed to find an access to the following line of php code which stands behind these TABs
<li>
<ul class="tabs">
<?php
$obj = new stdClass();
$obj->id = 0;
$obj->title = esc_html__('All', 'arcane');
$obj->abbr = esc_html__('All', 'arcane');
$obj->icon = 0;
array_unshift($games, $obj);
for($i = 0; $i < sizeof($games); $i++) :
$game = $games[$i];
$link = ($game->id == 0) ? 'all' : 'game-' . $game->id;
$p = array( 'game_id' => $game->id,'status' => array('active', 'done'));
$matches_tab = $ArcaneWpTeamWars->get_match($p, false, true);
if(!empty($matches_tab)){
?>
<li<?php if($i == 0) echo ' class="selected"'; ?>><?php echo esc_attr($game->abbr); ?><div class="clear"></div></li>
<?php } endfor; ?>
</ul>
<div class="clear"></div>
</li>
You can assign the selected class to the second li by changing the 0 to 1 and also use your own css to hide the first one:
<li<?php if($i == 1) echo ' class="selected"'; ?>>
or you can totally remove the first option which refers to all by starting the loop from 1 instead of 0 and ignore hiding first one using css:
for($i = 1; $i < sizeof($games); $i++) : // Start loop from 1 instead of 0
You can try to change the php code and instead of
$link = ($game->id == 0) ? 'all' : 'game-' . $game->id;
to have
$link = ($game->id == 2) ? 'game-2' : 'game-' . $game->id;
In this way the CS:GO should be the first. Im not 100% sure but try it :)

JQUERY next () img in li? multiple imgs in li

<div id = "listwrapper">
<ul id = "mylist">
<?php
$images = glob("sorted/2017/*.jpg");
$i = 0;
foreach((array_reverse($images)) as $image){
if ($i == 0){
echo "<li>";
}
$i++;
echo'<img id="BR" src="'.$image.'">;
if($i==4){
echo"</li>";
$i = 0;
}
}
?>
</ul>
<div>
The above script works fine and outputs a <li> tag with 4 images in each one. with about 80 images in total.
Now I'm trying to use next() and closest() to display the next <img> in the <li> tag when the image is clicked. or if it is the last <img> in the <li>, then skip to the next <li>? seems like it would be easier to change the script and just put each image in its own <li> tag..
$('#mylist li img').click(function(){
var el = document.getElementById('BR');
var big = document.getElementById('BRBIG');
var img = document.getElementById('mylist li img');
imageClicked = $(this).closest('li');
big.src = imageClicked.find('img').next().next().attr('src');
$('#brbigcon').show('fadein');
$('#BRBIG').show(300);
$('#fs').show(300);
});
Is there someway to implement closest('img') instead of closest ('li')?
Try this:
<div id = "listwrapper">
<ul id = "mylist">
<?php
$images = glob("sorted/2017/*.jpg");
$i = 0;
foreach((array_reverse($images)) as $image){
if ($i == 0){
echo "<li>";
}
$i++;
echo '<img class="BR" src="'.$image.'">';
if($i==4){
echo "</li>";
$i = 0;
}
}
?>
</ul>
<div>
Jquery:
$('#mylist .BR').click(function(){
var src = $(this).attr('src');
var big = $('BRBIG');
big.attr('src', src);
$('#brbigcon').show('fadein');
$('#BRBIG').show(300);
$('#fs').show(300);
});
A piece of advice. In your html, if the amount of images is not a multiple of 4, the last li never gets closed. Here you have another approach to solve it...
<div id = "listwrapper">
<ul id = "mylist">
<?php
// Get the array of image urls.
$images = array_reverse(glob("sorted/2017/*.jpg"));
// Create the html `img` element of each image.
$imgs = array_map(function($v) { return "<img class=\"BR\" src=\"".$v."\">"; },$images);
// Chumk the array in groups of 4 and put each group inside of a `li` element.
$imgsli = array_map(function($v) { return "<li>".implode("",$v)."</li>"; },array_chunk($imgs,4));
// Print all the `li` elements.
echo implode("",$imgsli);
?>
</ul>
<div>
About the jquery, this would be my approach...
$('#mylist li img').click(function() {
var $nextImg;
if ($(this).next('img').length > 0) { // There's more img in current li, get the next one.
$nextImg = $(this).next('img');
}
else {
if ($(this).closest('li').next('li').length > 0) // There's more li's, go to the first image of the next one.
$nextImg = $(this).closest('li').next('li').find('img:first');
else // We are in the last div, go to the first image.
$nextImg = $('ul#mylist li:first img:first');
}
// Now $nextImg is the jQuery object of the right next image. Do what you need to show it.
...
});
With this you get the right next image according to your indications. Just add the code you want to show the image, etc.
I hope it helps

Show/Hide Div Based on URL using PHP

I want to show a DIV ONLY when on /../mahjong.php. So even if I go to /../mahjong.php?layout it should hide the div (since it's not the same url)
I have tried the following:
// We're NOT on the home page
if (strpos($_SERVER['REQUEST_URI'], "/games/mahjong/mahjong.php") >= 0) {
$style = "display: none";
}
else {
$style = "display: inline";
}
And my div ofcourse:
<div class="menu" id="menu" style="<?php echo $style; ?>">
But if I go to /games/mahjong/mahjong.php?layout it doesn't change the style. I've echoed:
echo $_SERVER['REQUEST_URI'];
and it changes to /games/mahjong/mahjong.php?layout, so why isn't the style set to inline?
if (strpos($_SERVER['REQUEST_URI'], "/games/mahjong/mahjong.php") === false) {
Didn't work either. (this wil show the div and never hide it) What am I missing?
Many thanks,
Maurice
Check if the $_GET array has been populated or not:
<?php if (empty($_GET)): ?>
<div>
...
</div>
<?php endif; ?>
Should be sufficient if you're not manually adding to the $_GET array, which would be very silly.
Change your condition to:
strrpos($_SERVER['REQUEST_URI'], '/games/mahjong/mahjong.php') === strlen($_SERVER['REQUEST_URI']) - strlen('/games/mahjong/mahjong.php')
This will make sure the request uri ends with that string.
strpos(); only search for that string, and in both cases, string is found
strpos(); isn'T exact search !
// We're NOT on the home page
if (strpos($_SERVER['REQUEST_URI'], "/games/mahjong/mahjong.php?layout") >= 0) {
$style = "display: inline";
}
else {
$style = "display: none";
}
or you can use
// We're NOT on the home page
if (isset($_GET['layout'])) {
$style = "display: inline";
}
else {
$style = "display: none";
}
this might help
Check whether PATH_INFO AND QUERY_STRING are empty...if not, then it's not the page you want.

How to make this code more readable

This is a part fo php code, which use the contentArray, which is a JSON, and generate the UI to the user, it generate html tags, also, it generate js code too.... It works, but I think the code is pretty difficult to read and maintain, any ideas??? thank you.
for($i = 0; $i < count($contentArray); $i++){
if($i %2 == 0){
echo ("<li class='even_row'>");
}else{
echo ("<li class='odd_row'>");
}
$content = $contentArray[$i];
echo("<textarea class='userdata' id='user_data_textarea_".$content->{'m_sId'}."'>");
echo($content->{'m_sDataContent'});
echo("</textarea>");
echo("</li>");
echo("<script type='text/javascript'>");
echo("$('#user_data_textarea_".$content->{'m_sId'}."').bind('keydown', function(e){");
echo(" TypingHandler.handleTypingInUserDataTextArea(".$content->{'m_sId'}.", e);");
echo(" });");
echo("</script>");
}
first for your odd and even styling there is not need for a class just use css
here is info on that
then in php only echo what you need in one line
$count = count($contentArray);
for($i = 0; $i < $count; $i++){
$content = $contentArray[$i];
echo('<li><textarea class="userdata" id="user_data_textarea_"'.$content->{'m_sId'}.'">'.$content->{'m_sDataContent'}.'</textarea></li>');
}
and lets put the jquery in the html page away from php
we get can get every item by using starts with selector
$('[id^=user_data_textarea_]').bind('keydown', function(e){
var id = this.id.str_replace("user_data_textarea","");
TypingHandler.handleTypingInUserDataTextArea(id, e);
});
One tip on your "for" loop, you should calculate the count of $contentArray before the loop. Every time the loop executes, it has to call that function.
$count = count($contentArray);
for ($i=0; $i<count; $i++) {
// ...
}
You could try real HTML:
<?php
for($i = 0; $i < count($contentArray); $i++){
$rowClass = $i %2 == 0 ?'even_row' : 'odd_row';
?>
<li class='<?= $rowClass ?>'>
<textarea class='userdata' id='user_data_textarea_<?=$content->{'m_sId'}?>'>
<?= $content->{'m_sDataContent'} ?>
</textarea>
</li>
<script type='text/javascript'>
//etc...
</script>
<?php } ?>
It should look something like this, for better readability in the IDE.
<?php
foreach($contentArray as $content){
?>
<li>
<textarea class="userdata" id="user_data_textarea<?php echo htmlentities($content['m_sId']); ?>">
<?php echo htmlspecialchars($content['m_sDataContent']); ?>
</textarea>
<script type="text/javascript">
$('#user_data_textarea_<?php echo htmlspecialchars($content['m_sId']); ?>').bind('keydown',function(e){
TypingHandler.handleTypingInUserDataTextArea('<?php echo htmlspecialchars($content['m_sId']); ?>',e);
});
</script>
</li>
<?php
}
You could remove the ( ) from the echo statements, they're not necessarily needed and might help make it look a little neater...
That actually looks pretty understandable to me; I could figure out what you're doing without difficulty. The only difference I would suggest would be the use of ternary operators for the row class:
echo "<li class='".( ($i%2 == 0) ? "even" : "odd" )."_row'>";
...but that's just me, some would find that MORE confusing, rather than less. I personally like putting it all in one line.
Personnaly, I like to use printf to write html code in php. It could look like:
for($i = 0; $i < count($contentArray); $i++){
printf("<li class='%s'>", $i % 2 ? "odd_row" : "even_row");
$content = $contentArray[$i];
printf("<textarea class='userdata' id='user_data_textarea_%s'>%s</textarea>",
$content->{'m_sId'},
$content->{'m_sDataContent'});
echo("</li>");
echo("<script type='text/javascript'>");
printf("$('#user_data_textarea_%1$s').bind('keydown', function(e){
TypingHandler.handleTypingInUserDataTextArea(%1$s, e);
});",
$content->{'m_sId'});
echo("</script>");
}
<?php
foreach($contentArray as $content){
$class = ($i %2 == 0) ? "even_row": "odd_row"; ?>
<li class="<?php echo $class ?>">
<textarea class='userdata' id='user_data_textarea_<? echo $content['m_sId'] ?>'>
<? php echo $content['m_sDataContent'] ?>
</textarea>
</li>
<script type='text/javascript'>
$('#user_data_textarea_<?php echo content['m_sId'] ?>').bind('keydown', function(e){
TypingHandler.handleTypingInUserDataTextArea(<?php $content['m_sId'] ?>, e);
});
</script>
<?php } // end foreach ?>
jQuery code should be already in the HTML, using some main selector and not binding elements one by one, it not makes sense for me. That should clarify your code.
for($i = 0; $i < count($contentArray); $i++){
$content = $contentArray[$i];
echo "<li class='" . (($i %2 == 0) ? "even_row" : "odd_row") . ">";
echo "<textarea class='userdata' id='user_data_textarea_".$content->{'m_sId'}."'>";
echo $content->{'m_sDataContent'};
echo "</textarea>";
echo "</li>";
}
ADDED
A generic case:
$(function() {
$('.userdata').click(function() {
some_function($(this).attr('id');
});
})
That is, bind using a class selector and late use some unique identifier for doing the job.
Put everything in arrays, then echo them at the END of your loop.
// Put each item in the array, then echo at the end
$items = array();
$js = array();
// I'm assuming that your content array has numeric keys
// if not, use the for statement from your original code
foreach ($contentArray as $i => $content)
{
// using sprintf
$items[] = sprintf('<li class="%s_row"><textarea class="userdata" id="user_data_textarea_%s">%s</textarea></li>'
, ($i % 2) ? 'even' : 'odd'
, $content->m_sId
, $content->m_sDataContent
);
// or just plain old concatenation
$js[] = "$('#user_data_textarea_{$content->m_sId}').bind('keydown', function(e){TypingHandler.handleTypingInUserDataTextArea({$content->m_sId}, e);});";
}
echo "<ul>" . join("\n", $items) . "</ul>\n"
. '<script type="text/javascript">' . join("\n", $js) . "</script>\n";
Separate your content and code using for example smarty. It requires some infrastructure investment in the short term, but improves maintenance in the long run.
Reflecting the comments, let's then treat PHP as a real templating language.
$contentCount = count($contentArray);
for($i = 0; $i < $contentCount; $i++)
{
$rowType = ( $i % 2 ) ? 'even' : 'odd';
$content = $contentArray[$i];
echo <<<EOT
<li class='{$rowType}_row'>
<textarea class='userdata' id='user_data_textarea_{$content->m_sId}'>
{$content->m_sDataContent}
</textarea>
</li>
<script type="text/javascript">
$('#user_data_textarea_{$content->m_sId}').bind('keydown', function(e)
{
TypingHandler.handleTypingInUserDataTextArea({$content->m_sId}, e);
}
</script>
EOT;
}

Easiest way to alternate row colors in PHP/HTML?

Here's a PHP example of mine. Can anyone find a shorter/easier way to do this?
<? foreach($posts as $post){?>
<div class="<?=($c++%2==1)?‘odd’:NULL?>">
<?=$post?>
</div>
<? }?>
<style>
.odd{background-color:red;}
</style>
Examples in other languages would be fun to see as well.
Fundamentally - no. That's about as easy as it gets. You might rewrite it a bit shorter/cleaner, but the idea will be the same. This is how I would write it:
$c = true; // Let's not forget to initialize our variables, shall we?
foreach($posts as $post)
echo '<div'.(($c = !$c)?' class="odd"':'').">$post</div>";
If you'd like to have less in-line PHP, a great way of doing it is via JavaScript.
Using jQuery, it's simply:
<script type="text/javascript">
$('div:odd').css('background-color', 'red');
</script>
Using CSS3 you can do something like this:
div:nth-child(odd)
{
background-color: red
}
But better not use that for a few years if you actually want your users to see the color...
Smarty has it inbuilt:
{section name=rows loop=$data}
<tr class="{cycle values="odd,even"}">
<td>{$data[rows]}</td>
</tr>
{/section}
So does Django:
{% for o in some_list %}
<tr class="{% cycle 'row1' 'row2' %}">
...
</tr>
{% endfor %}
i always name my zebra rows "row0" and "row1" - this makes the code a bit simpler.
<?php // you should always use the full opening tag for compatibility
$i = 0;
foreach ($rows as $row) {
echo '<tr class="row' . ($i++ % 2) . '">...</tr>';
}
?>
Maybe a function with a static variable?
<?php
function alternate_row_color($css_class) {
static $show = true;
$show = !$show;
if ($show) {
return $css_class;
} else {
return NULL;
}
}
?>
Then to use it (using your example):
<?php foreach($posts as $post) { ?>
<div class="<?=alternate_row_color('odd')?>">
<?=$post?>
</div>
<?php } ?>
<?php $alt = true; foreach ($posts as $post): $alt = !$alt; ?>
<div<?php echo $alt ? ' class="odd"' : ''; ?>>
<!-- Content -->
</div>
<?php endforeach ?>
Would be the simplest and clearest way to do it.
You can encapsulate the logic as follows:
<?php
class ListCycler {
private $cols, $offs, $len;
// expects two or more string parameters
public function __construct() {
$this->offs = -1;
$this->len = func_num_args();
$this->cols = func_get_args();
foreach($this->cols as &$c)
$c = trim(strval($c));
}
// the object auto-increments every time it is read
public function __toString() {
$this->offs = ($this->offs+1) % $this->len;
return $this->cols[ $this->offs ];
}
}
?>
<html>
<head>
<style>
ul#posts li.odd { background-color:red; }
ul#posts li.even { background-color:white; }
</style>
</head>
<body>
<div>
<h3>Posts:</h3>
<ul id="posts"><?php
$rc = new ListCycler('odd','even');
foreach($posts as $p)
echo "<li class='$rc'>$p</li>";
?></ul>
</div>
</body>
</html>
Just for fun
Assuming you can use CSS3 selectors you can do something like
<div class="posts">
<? foreach($posts as $post){?>
<div>
<?=$post?>
</div>
<? }?>
</div>
<style>
div.posts div:odd{background-color:red;}
</style>
Even with CSS2 support and mootools (javascript library) you can substitute the style with this javascript
<script type="text/javascript">
// obviously this script line should go in a js file in a onload (or onDomReady) function
$$('div.posts div:odd').setStyle('background-color','red');
</script>
If you don't have anything but php a it you can simplify a bit yous code using an array
<? $isodd=array('','odd');
$c=0;
foreach($posts as $post){?>
<div class="<?=$isodd[$c++%2]?>">
<?=$post?>
</div>
<? }?>
It's short enough as it is, but I would probably wrap it into some helper function with a clear name. That way it's more obvious what's going on and you won't have to repeat that logic in all templates where you need it.
If you want to do it on the display end and are comfortable with or otherwise already using javascript, libraries like jQuery will often have :odd and :even selectors, which you can then hook up to adding specific style properties or hooking into CSS more generally by adding classes.
On a side noe, to alternate between two values a and b, a nice way of doing it in a loop is this:
x = a;
while ( true ) {
x = a + b - x;
}
You can also do this without addition and subtraction:
x = a ^ b ^ x;
where ^ is the XOR operation.
If you just want to alternate between 0 and 1, you can do this:
x = 0;
while ( true ) {
x = !x;
}
You could of course use x as an index of colors, CSS style classes and so on.
function row_color($cnt,$even,$odd) {
echo ($cnt%2) ? "<tr bgcolor=\"$odd\">" : "<tr bgcolor=\"$even\">";
}
How to use:
$cnt=0;
while ($row = mysql_fetch_array ($result)) {
row_color($cnt++,"e0e0e0","FFFFFF");
}
You can abuse the $GLOBAL scope to store the current selected class state, see below table_row_toggle() function. Yes, I know its dirty to abuse the $GLOBAL scope, but hey, we're here to fix problems ain't we? :)
Calling the table row toggle function in HTML:
<tr <? table_row_toggle(); ?>>
The function in PHP:
/* function to toggle row colors in tables */
function table_row_toggle() {
/* check if $trclass is defined in caller */
if(array_key_exists('trclass', $GLOBALS)) {
$trclass = $GLOBALS['trclass'];
}
/* toggle between row1 and row2 */
if(!isset($trclass) || $trclass == 'row2') {
$trclass = 'row1';
} else {
$trclass = 'row2';
}
/* set $trclass in caller */
$GLOBALS['trclass'] = $trclass;
/* write the desired class to the caller */
echo ' class="' . $trclass . '"';
}
<?php ($i%2==1) ? $bgc='#999999' : $bgc='#FFFFFF'; ?>
'<div bgcolor=" bgcolor='.$bgc.'">';
Spot on Vilx but, always go minimal for speed (page weight)
<tr class="'.(($c = !$c)?'odd':'even').'">
Been using something like this:
<?php
function cycle(&$arr) {
$arr[] = array_shift($arr);
return end($arr);
}
$oddEven = array('odd', 'even');
echo cycle($oddEven)."\n";
echo cycle($oddEven)."\n";
echo cycle($oddEven)."\n";
A simple little function that works well for me.
<?php
class alternating_rows()
{
private $cycler = true;
//------------------------------------------------------------------------------
function rowclass($row0,$row1)
{
$this->cycler = !$this->cycler;//toggle the cycler
$class=($this->cycler)?$row0:$row1;
return $class;
}// end function rowclass
//------------------------------------------------------------------------------
}//end class alternating rows
?>
<?php $tablerows= new alternating_rows();?>
<table>
<tr>
<th scope="col">Heading 1</th>
<th scope="col">Heading 2</th>
</tr>
<?php foreach ($dataset as $row){?>
<tr class="<?php echo $tablerows->rowclass("oddrow","evenrow"); ?>">
<td>some data</td>
<td>some more data</td>
</tr>
<?php } //end foreach?>
</table>
In PHP I am using this code:
function alternate($sEven = "even", $sOdd = "odd")
{
static $iCount;
return ($iCount++ & 1) ? $sOdd :$sEven;
}
for($i = 0; $i< 5; $i++)
echo alternate();
/*output:
even
odd
even
odd
even
*/
Source: http://sklueh.de/2013/11/einfache-alternierung-mit-php/

Categories