I am very new to PHP and I am trying to get a piece of PHP code to run inside of my HTML file.
I have a drop down menu. If users select one item, it should display additional fields. So, I want them to only display if they select that item from the drop down menu. I am trying to select it based on the value for that drop down item. I have not declared any PHP values in a PHP script. This is all in HTML.
I know that with jquery you have to pull in the jquery library before running the script. Do I need to do this with PHP also?
Here is the code that I am trying to run:
Thank you in advance!
html file
<?php
if ($dropmenuValue == specificDropDownOption) {
?>
<div>
-conditional content-
</div>
<?php
}
?>
One of the main things about PHP and other server-side languages is that once they render the page, they shut down, and that's it. There's nothing they can do after.
You need to resort to a client-side here, probably the simplest way being adding the values of PHP variables to the appropriate JavaScript variables and then taking it from there. You would also need to render all possible contents and only show what you need.
So, in your case, you could make a CSS class to denote hidden content and then use JavaScript to hide/show different parts of the markup. Please note that all the hidden code (rendered by PHP, but hidden by CSS) is still visible in the page source, so if you have anything sensitive in there you should definitely do it by either making AJAX calls to load partial content, or regular page redirection/navigation.
EDIT
Here is a super-simple example I made for you, to see how you can show/hide content:
HTML (parts can be rendered by PHP, of course)
<div id="content1" class="content">Hey</div>
<div id="content2" class="content hidden">There</div>
<div id="content3" class="content hidden">World</div>
<hr />
<button onclick="show(1)">Show 1</button>
<button onclick="show(2)">Show 2</button>
<button onclick="show(3)">Show 3</button>
JS
function show(id) {
// select all the content divs
var allDivs = document.getElementsByClassName('content');
// iterate over them and add a hidden class to each
for (var i = 0; i < allDivs.length; i++){
allDivs[i].classList.add('hidden');
}
// finally, remove the hidden class from the one we referenced
document.getElementById('content' + id).classList.remove('hidden');
}
See it in action here: http://jsfiddle.net/f0onk7bk/
You can try something out with this... While using HTML inside of the PHP
#item { display: block;}
#itme.active { display:none }
Something like this would work when the page was loaded/reloaded...
<?php
if(isset($_POST['dropdown_name_here']) && $_POST['dropdown_name_here'] == "specificParameter")
{
echo("<div id='condition_one_div'> ... </div>");
}
else
{
echo("<div id='condition_two_div'> ... </div>");
}
?>
... but JavaScript is what you would want to use for dynamic content I would think.
var div = document.getElementById('div_name_here');
var dropdown = document.getElementById('dropdown_name_here');
if(dropdown.value == "specificParameter")
{
//add/show content for div here
}
else
{
//hide content for div here
}
is this what you are looking for?
<select id='dropdown_name' onchange='if(this.value == "parameter"){ document.getElementById("div_name").style.display = "block"; }else{ document.getElementById("div_name").style.display = "none"; }' >
</select>
So I have several divs that i assigned a class to. Each div has a header. The contents underneath each header are dynamically generated via php. Certain times of the year these divs contain no information but the header still displays. I want to hide the divs that do not have any paragraphs inside of them I cannot quite get them to work and I have a feeling it has to do with the paragraphs being generated by php.
EXAMPLE:
<div class="technology_connected article_headers">
<h3>TECHNOLOGY CONNECTED</h3>
<?php echo $tools->article_formatter($articles, 'Technology Connected'); ?>
</div>
Here is my Jquery code.
$(document).ready(function() {
$(".article_headers").each(function() {
if ($(this).find("p").length > 0) {
$('.article_headers').show();
}
});
});
Try this:
$(document).ready(function() {
$(".article_headers").each(function() {
if ($(this).find("p").length > 0) {
$(this).show();
}else{
$(this).hide();
}
});
});
DEMO
As noted by #JasonP above, this really should be done server side. However, since you do want it done server side, you can simplify the process greatly. Generate the data server side as you're doing. Make sure all <div> tags are visible. Then in your JavaScript use the following selector:
// Shorthand for $(document).ready(function() { ... });
$(function () {
$('.article-headers:not(:has(p))').hide();
});
The selector above targets all elements with the class .article-headers that do not contain a <p> tag and hides them.
JSFiddle demoing the above as a toggle button to show or hide the no paragraph sections.
So my PHP webiste generates DHTML output that looks like the following:
<div class="toggle-ctrl" onclick="toggleMenu();">
click me to toggle menu
</div>
<div id="site-menu">
<ul>
<li>opt 1</li>
<li>opt 2</li>
</ul>
</div>
<p>Link to Myself</p>
And of course, when clicked, the first div calls some JavaScript which toggles the visibility of the site-menu
function toggleMenu() {
var navigation_pane = document.getElementById('site-menu').style;
if ( navigation_pane.display == 'none' )
navigation_pane.display = 'block';
else
navigation_pane.display = 'none';
}
All this works fine. It's clicking on the link which is bothering me right now. Clicking it (of course) creates a new http request, and my PHP engine re-generates the page again.
The problem occurs when the visibility of the site-menu is 'none'. The PHP engine doesn't know that the menu is hidden, so it generates the same-html again, and the browser places the menu back in front of the surprised-looking user.
The question therefore, is how do I inform PHP (or how can PHP go to check) what the status of the site-menu's visibility is, before it goes to re-generate the page?
There are at least two options other than sending the menu state to the PHP script.
Use AJAX to load just part of the page. If you don't reload the menu, you don't need to re-initialize its style. Before going down this path, examine whether AJAX is suitable. If you implement this solution, don't break browser functionality.
Modern browsers support a storage mechanism. Store the menu state in localStorage when it changes, and set the menu state when the page loads. To support older browsers, you can create an API that uses web storage when available and cookies when not (jQuery.Storage does this).
Menu.js:
/* implementation of Storage, Class and addEventListenerTo left as
an exercise for the reader.
*/
var Menu = {
init: function(id, toggleId) {
if (! toggleId) {
toggleId = id + '-toggle';
}
var toggler = document.getElementById(toggleId),
menu = document.getElementById(id);
menu.toggler = toggler;
/* addEventListenerTo should call the browser-supplied event subscriber
method (e.g. addEventListener or attachEvent)
*/
addEventListenerTo(toggler, 'click',
function(evt) {
Menu.toggle(id);
});
if (! Storage.exists(id+'-open')) {
Storage.set(id+'-open', true);
}
if (Storage.get(id+'-open')) {
Menu.open(id);
} else {
Menu.close(id);
}
},
toggle: function(id) {
var menu = document.getElementById(id);
Class.toggle(menu, 'open closed');
if (Class.has(menu, 'open')) {
menu.toggler.firstChild.nodeValue = 'close menu';
Storage.set(id + '-open', true);
} else {
menu.toggler.firstChild.nodeValue = 'open menu';
Storage.set(id + '-open', false);
}
},
setState: function (id, toAdd, toRemove) {
var menu = document.getElementById(id);
Class.remove(menu, toRemove);
Class.add(menu, toAdd);
},
open: function(id) {
this.setState(id, 'open', 'closed');
},
close: function(id) {
this.setState(id, 'closed', 'open');
}
};
some CSS file:
.closed { display: none; }
page:
<div id="site-menu-toggle" class="toggle-ctrl">close menu</div>
<div id="site-menu" class="open">
<ul>
<li>opt 1</li>
<li>opt 2</li>
</ul>
</div>
<p>Link to Myself</p>
<script type="text/javascript">
Menu.init('site-menu');
</script>
You can play with a live version of the Menu.js approach on jsFiddle. Using jQuery, you can do away with Menu.js, resulting in a much more succinct implementation:
<script type="text/javascript">
$('#site-menu-toggle').click(function (evt) {
var $menu = $('#site-menu');
$menu.toggleClass('open close');
$.Storage.set('site-menu-state', $menu.attr('class'));
if ($menu.hasClass('open')) {
$('#site-menu-toggle').text('close menu');
} else {
$('#site-menu-toggle').text('open menu');
}
});
$(function() {
var state = $.Storage.get('site-menu-state');
if (! state) {
$.Storage.set('site-menu-state', $('#site-menu').attr('class'));
} else {
$('#site-menu').attr('class', state);
}
});
</script>
There's a jFiddle for the jQuery menu state implementation that you can play with.
Since differences in the menu state don't conceptually make for different resources, it doesn't matter whether having the menu open or closed is bookmarkable or affected by history.
NB. don't use the text "click me", it's too verbose and redundant (what other action is there? Affordances should be implicit.). Instead, you can use a graphic to indicate open/close, or simply say "open menu"/"close menu".
The question therefore, is how do I inform PHP (or how can PHP go to
check) what the status of the site-menu's visibility is, before it
goes to re-generate the page?
It can't. By the time the HTML is delivered to the browser, PHP is no longer in the picture. The only way you could make PHP aware of this would be to send a parameter in the URL indicating the menu is hidden, or set a cookie and have the cookie indicate visibility of the object. Then PHP can check for the presence of this value and set the visibility of the div when it renders it.
You could accomplish this in a number of ways, for example:
Use document.cookie to set the cookie in your toggleMenu function.
Use ajax to notify PHP in the toggleMenu function and have PHP set a cookie or session value
Append a flag to the link indicating the visibility of the menu from the toggleMenu function.
Actually, there are several types of answers to your question.
While it may sound there's no way to do what you want, there are, in fact, many ways.
Cookies
The obvious. Cookies can be accessed by javascript as well as PHP. Just modify the cookie whenever the menu is shown/hidden through javascript (there's the excellent jQuery cookie plugin).
Form input
If you are submitting a form, simply have a hidden input keep the value of the menu's visibility:
<input type="hidden" name="menu-visibility" value="0"/>
Again, you need javascript to keep this input updated.
Update relevant parts of the page
This is the hip & leet new trend. Well, actually, it's been there for some 6 years or so. Basically, don't submit anything and don't reload the page. Update the parts of the page that actually need updating, through AJAX.
Local Storage
As #outis mentioned, today browsers have something similar to cookies, except they keep it for themselves (hence locally). It's a pretty new feature, to be honest, I wouldn't trust it considering there are better ways to accomplish what you need.
In addition to drew010's suggestions: You could also create a form with a hidden input element named, let's say, 'menu_status' whose value gets set by toggleMenu(). Then when you click on your link, use javascript to POST or GET the form. Then you read the value server-side with php using either $_POST["menu_status"] or $_GET["menu_status"], depending on the form method.
UPDATE: Something like this:
<form name="session_form" action="" method="POST">
<input type="hidden" name="menu_state" value="block">
</form>
<?php $menu_state = isset($_POST["menu_state"]) ? $_POST["menu_state"] : "block"; ?>
<div id="site-menu" style="display:<?php echo $menu_state; ?>">
<ul>
<li>opt 1</li>
<li>opt 2</li>
</ul>
</div>
<p>Link to Myself</p>
function toggleMenu() {
var navigation_pane = document.getElementById('site-menu').style;
if ( navigation_pane.display == 'none' )
navigation_pane.display = 'block';
else
navigation_pane.display = 'none';
document.forms.session_form.menu_state.value = navigation_pane.display;
}
EDIT: Using jQuery ajax could involve something like this:
<div class="toggle-ctrl">click me to toggle menu</div>
<?php $menu_state = isset($_POST["menu_state"]) ? $_POST["menu_state"] : "block"; ?>
<div id="site-menu" style="display:<?php echo $menu_state; ?>">
<ul>
<li>opt 1</li>
<li>opt 2</li>
</ul>
</div>
<p>Link to Myself</p>
$("div.toggle-ctrl").click(function(){
$("#site-menu").toggle();
});
$("#go").click(function(e) {
e.preventDefault();
var menu_state = $("#site-menu").css("display");
$.post("", {menu_state:menu_state}, function (response) {
$("html").html(response);
});
});
Or without using ajax or a form, just append a parameter to the link and use $_GET instead of $_POST in your php:
$("#go").click(function(e) {
e.preventDefault();
var menu_state = $("#site-menu").css("display");
document.location.href = "index.php?menu_state=" + menu_state;
});
This seems to me the simplest solution.
I know it's not cool to answer your own question, but another possible solution occurred to me last night, and it only requires 1 new line of code to be written (sort of).
The first part of the solution has already been implicitly suggested by many of you. Modify the JavaScript to write to a cookie:
function toggleMenu() {
var navigation_pane = document.getElementById('site-menu').style;
if ( navigation_pane.display == 'none' )
navigation_pane.display = 'block';
else
navigation_pane.display = 'none';
document.cookie = "menu_vis=" + navigation_pane.display; // +1 line of code
}
Now, what are the possibilities if your CSS file just so happens to be a PHP file in disguise? my_css.php would look something like this:
<?php
header("Content-type: text/css");
?>
#site-menu {
display: <?php echo isset($_COOKIE['menu_vis']) ? $_COOKIE['menu_vis'] : 'block'; ?>; /* line of code modified, but not added! */
}
Tested this morning, and it works.
I find it a neat solution, because it means that I don't have to bend my PHP or HTML design around any presentational concerns.
--
I appreciate that there are more "encompassing" solutions out there. If I was a better JavaScript developer, (or made use of jQuery or the like), I could build more complicated classes which could then be applied more generally to other HTML elements. I may come back to investigate such solutions later, but that's just not where my project is at the moment.
Thank you everyone for all your replies. I wouldn't have found this solution without bouncing these ideas off you guys.
I list a lot of users on my page and I use a php function to pass the user's id and return a div pop up that displays their online status, avatar, stats etc. The problem is that the code is currently set to show the layer onmouseover and hide the layer onmouseout. I would like the code to be onclick show, and second click (either toggle on the same link or click anywhere else on the page) hide the layer but I'm not sure how to accomplish that.
The current code I'm using I got from Dynamic Drive. (sorry my tab key won't work in this text box, not sure how to fix that. feel free to edit)
SKIP TO BOTTOM
Original Method:
Javascript part
<div id="dhtmltooltip"></div>
<script type="text/javascript">
/***********************************************
* Cool DHTML tooltip script- Dynamic Drive DHTML code library (www.dynamicdrive.com)
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/
var offsetxpoint=-60 //Customize x offset of tooltip
var offsetypoint=20 //Customize y offset of tooltip
var ie=document.all
var ns6=document.getElementById && !document.all
var enabletip=false
if (ie||ns6)
var tipobj=document.all? document.all["dhtmltooltip"] : document.getElementById? document.getElementById("dhtmltooltip") : ""
function ietruebody(){
return (document.compatMode && document.compatMode!="BackCompat")? document.documentElement : document.body
}
function ddrivetip(thetext, thecolor, thewidth){
if (ns6||ie){
if (typeof thewidth!="undefined") tipobj.style.width=thewidth+"px"
if (typeof thecolor!="undefined" && thecolor!="") tipobj.style.backgroundColor=thecolor
tipobj.innerHTML=thetext
enabletip=true
return false
}
}
function positiontip(e){
if (enabletip){
var curX=(ns6)?e.pageX : event.clientX+ietruebody().scrollLeft;
var curY=(ns6)?e.pageY : event.clientY+ietruebody().scrollTop;
//Find out how close the mouse is to the corner of the window
var rightedge=ie&&!window.opera? ietruebody().clientWidth-event.clientX-offsetxpoint : window.innerWidth-e.clientX-offsetxpoint-20
var bottomedge=ie&&!window.opera? ietruebody().clientHeight-event.clientY-offsetypoint : window.innerHeight-e.clientY-offsetypoint-20
var leftedge=(offsetxpoint<0)? offsetxpoint*(-1) : -1000
//if the horizontal distance isn't enough to accomodate the width of the context menu
if (rightedge<tipobj.offsetWidth)
//move the horizontal position of the menu to the left by it's width
tipobj.style.left=ie? ietruebody().scrollLeft+event.clientX-tipobj.offsetWidth+"px" : window.pageXOffset+e.clientX-tipobj.offsetWidth+"px"
else if (curX<leftedge)
tipobj.style.left="5px"
else
//position the horizontal position of the menu where the mouse is positioned
tipobj.style.left=curX+offsetxpoint+"px"
//same concept with the vertical position
if (bottomedge<tipobj.offsetHeight)
tipobj.style.top=ie? ietruebody().scrollTop+event.clientY-tipobj.offsetHeight-offsetypoint+"px" : window.pageYOffset+e.clientY-tipobj.offsetHeight-offsetypoint+"px"
else
tipobj.style.top=curY+offsetypoint+"px"
tipobj.style.visibility="visible"
}
}
function hideddrivetip(){
if (ns6||ie){
enabletip=false
tipobj.style.visibility="hidden"
tipobj.style.left="-1000px"
tipobj.style.backgroundColor=''
tipobj.style.width=''
}
}
document.onmousemove=positiontip
</script>
PHP part
$username = "<a onMouseover=\"ddrivetip('<Center><font class=f2>$username</font><BR>$avatarl</center>
<table align=center><Tr><Td><b>Points:</b> <font class=alttext>$user_points</font>
<BR><B>Posts:</b> <font class=alttext>$user_posts</font><BR>$user_status</td></tr></table>
<BR><img src=$icons/add-user.png height=12> <a href=$cs_url/friends/add/$user>Send Friend Request</a>
<BR><img src=$icons/user_message2.png height=12> <a href=$cs_url/messages/compose/$user>Send Message</a>
<BR><img src=$icons/user_im2.png height=12> Instant Message')\"
onMouseout=\"hideddrivetip()\">$username</a>";
My primary reason for wanting the toggle/blur as opposed to mouseout is so that users have the chance to actually click the links inside of the div layer.
The reason why I am trying to stick to this script as opposed to other ones out there I've found is because it doesn't rely on unique ids or alot of css styles. With other scripts, when I click on one username, they all of the hidden divs on the page pop up, or at least all of them for that user. This seemed to be the best for showing just one at a time.
I decided to scrap the method above. I have a script that I also got elsewhere that I use to toggle a twitter-like login in. I was wondering how I could use it to toggle the user information layer.
Second Method:
Javascript
$(".users").click(function(e) {
e.preventDefault();
$("fieldset#users_menu").toggle();
$(".users").toggleClass("menu-open");
});
$("fieldset#users_menu").mouseup(function() {
return false
});
$(document).mouseup(function(e) {
if($(e.target).parent("a.users").length==0) {
$(".users").removeClass("menu-open");
$("fieldset#users_menu").hide();
}
});
PHP part
<div id='container' class='users_container'>
<div id='usersnav' class='usersnav'> <a href='<?php echo $cs_url; ?>/users/all' class='users'><span>Fans</span></a> </div>
<fieldset id='users_menu'>
content
</fieldset>
</div>
The problem with this method as I mentioned before is that when I click on the username link, ALL of the layers for ALL of the users display on the page appear. How can I make it so that only the child layer of the parent link is displayed? Also, is there a way to toggle the layer hidden when anywhere else on the page is clicked?
Starting from your old code I assume you had something like:
elem.onmouseover = showCard;
elem.onmouseout = hideCard;
Well, from there you just need to do something along the lines of:
elem.isShown = false;
elem.onclick = function() {
if( elem.isShown) hideCard();
else showCard();
elem.isShown = !elem.isShown;
}
This ended up being the best solution though there is still one thing I wish was different about it.
This is built upon Dan's response. The reason why it wasn't working before Dan was because the user information was inside tags, I switcher username to span and the content display. The problem after that was when I clicked on one username the layer would popup but it would remain until I clicked on the same link again. So multiple layers would sometimes be on at once.
The following closes the layer when a user clicks on the layer, outside the layer or on the original link. The one little snag is that when clicking on the original link to close the layer you must click twice.
Javascript
<script type="text/javascript">
$(document).ready(function () {
$(".username").click(function () {
$(this).children().toggle();
$('.tooltip_container').hover(function(){
mouse_is_inside=true;
}, function(){
mouse_is_inside=false;
});
$(".username").click(function () {
$(this).children().toggle();
});
});
$("body").mouseup(function(){
if(! mouse_is_inside) $('.tooltip_container').hide();
});
});
</script>
PHP
<span class='username'>$username
<div class='tooltip_container'>
<div class='tooltip'>
Content goes here
</div>
</div>
</span>
I'm looking to make a page wherein a user will make a selection for eg: "How old is your computer?" - "One year", "Two years" etc etc and the page will remove and add 'options' (which at the moment only need to be informative sections of text)
Is there any way to do something like that?
The technologies I'm using are PHP and of course, HTML and CSS to style the pages.
Thanks in advance!
PHP cannot detect if changes has been made to the page, you will have to use Javascript for that.
If you are using a HTML select element and you want to create the content dynamically it could look something like this:
HTML
<select id="computerAge">
<option>2 years</option>
<option>3 years</option>
</select>
<div id="dynamicContent">
</div>
Javascript
var computerAge = document.getElementById('computerAge');
var dynamicContent = document.getElementById('dynamicContent');
computerAge.onchange = function()
{
// Get a list of the current dynamic content
var contents = document.getElementById('content').document.getElementsByTagname('p');
// Remove current dynamic content
for(i = 0; i < contents.length; i++)
{
dynamicContent.removeChild(contents[i]);
}
// Create new dynamic content
var dynamicP = document.createElement('p');
if(computerAge.value == '2 years')
{
dynamicP.innerHTML = 'Content for 2 year old computer';
dynamicContent.appendChild(dynamicP);
}
elseif(computerAge.value == '3 years')
{
dynamicP.innerHTML = 'Content for 3 year old computer';
dyanmicContent.appendChild(dynamicP);
}
}
Or if you're not creating elements dynamically:
HTML
<select id="computerAge">
<option>2_years</option>
<option>3_years</option>
</select>
<div id="content">
<div id="2_years" style="display: none">
<p>Content for 2 year old computer</p>
</div>
<div id="3_years" style="display: none">
<p>Content for 3 year old computer</p>
</div>
</div>
Javascript
function init()
{
// Get the select element
var select = document.getElementById('computerAge');
select.onchange = function()
{
// Get the elements which could be the dynamic content
var content = document.getElementById('content')
var contents = content.getElementsByTagName('div');
// Iterate over contents; make selected visible and hide others
for(i = 0; i < contents.length; i++)
{
if(contents[i].id == select.value)
{
contents[i].style.display = 'block';
}
else
{
contents[i].style.display = 'none';
}
}
}
}
window.onload = init;
I think you're mixing some stuff together. From what I understand is you want to show or hide portions of the page depending on what the user selected in a dropdown.
PHP makes "dynamic webpages" that's true. But what's ment by this is that the page can serve different content on each request. But once the content is served it's rendered on the client side and not in PHP hands anymore.
If you want to change the content without reloading the whole page you should use javascript.
You could also server new content using ajax, but I think you just want to put some div's display propertie to none or something like that.