So, I'm a php/html noob....
I have a php script that queries a database and returns a whole host of information which I've formatted into a long HTML page. The script is invoked by a dropdown box on a main page. The main page's contents refresh depending on what is selected in the dropdown box.
The php script dynamically grabs whatever data is in the various database tables, and makes one large HTML page, containing 6 formatted tables.
On the main page, I have a <div class="content"></div> that contains this block of html.
My question is this:
How can I make it so that my php script still returns the same information, but instead of returning it as 1 big chunk of html in "content", return it in 6 smaller pieces of html which I can then indivdually place on the page in different places (actually, I want to place them in tab fragments)?
Basically, I want each dynamic table to be created by the php, and then stored in some variable which I can then assign as the content of the tab fragment.
PS - I thought about doing this the long winded way and splitting my php function into smaller ones, with one php script being responsible for drawing each table; but I ran into problems trying to work out how to invoke the php (since I use AJAX calls atm - the javascript fires off the php when my selection menu is changed)
Posts
When you need to return the query, put it in php tags and use:
the closing tag 'html' has to be completely left justified otherwise it wont work, so no indenting it.
also the 'html' part can be anything, its works like a variable
echo <<< block1
html;
echo <<< block2
html;
and then on my main page, instead of using <div class="content"></div>, I just put
<php>block1</php>
What is the limit of what you can do inside the html blocks? Can you only use this to return pure html? I actually do some dynamic grabbing of data in my script.
so
<form>
<select><option value="whatever">Whaever</option></select>
</form>
<div class="content">
<?php include('phpscript.php');?>
</div>
is this correct?
If so, what you want to do is remove the div class="content" wrapper around the script and have your phpscript format the HTML.
I personally dont use html blocks like that in my code. I prefere to simply throw the html into a variable as a string and then echo it out. But to each their own. Either way, your PHP script would do all the formatting at once, and be simply called from your main page.
so it would do
<?php
//whatever logic you need to get the POST data and query your mysqlDB with it...
$out='';
$out.='<div class="block1">'.$database_var1.'</div>';
$out.='<div class="block2">'.$database_var2.'</div>';
$out.='<div class="block3">.'$database_var3.'</div>';
echo($out);
?>
You have a few options - make 6 calls (not good in terms of http requests), or take your one call and insert "separators" between the different parts, such that when your JS gets the content back, it can explode the string on the separator to get an array containing the seperate bits of content (tables).
Note that I've wrapped the separating character in html comment tags (means that if you're just getting back the content and shoving it in, the characters won't show up). When you do the string explode, include the <!-- --> parts as well.
The 3rd option is to just return your data for the 6 tables in XML or JSON, then get the JS to write out the table.
BUT thats a bit beyond what we are discussing here I think. Best keep it to simple SERVER->CLIENT instead of using JS and ajax calls to dynamically change the page.
Yes, this is what I already have.
My ajax script is returning 'content' which is a whole block of html. In my php script (where I create the 6 different tables) i've put <div> tags around each section, so I have a load of HTML that comes out the far end of this, with 6 distinct named 'div' sections.
What I was then hoping to do is add each section into my main page, but it doesn't work. Each tab shows no info, because of course I no longer have a container that is showing the content returned by the ajax call.
I see then, what I need to do is as you suggested Disruptor - somehow create a php variable with each of the seperate divs as elements, and then in my main page, call the php variable indexed to whichever variable I need...?
(Technically JS is part of the Client :P)
EDIT: Oh damn, didn't realise I was beat in my first reply, and again now!
Disruptor: your original probably only works if his html is structurally like that (for all we know, the divs are housed all over the place?)
cmsamo: you don't already have the JSON stuff, probably just the onchange event.
Can you provide us the html you're trying to put things into?
Ya, I found that in a google search
Ok... the relevant snippet of my main php page is below (couldnt include all of it for privacy reasons):
Note that in this example all 6 tables are drawn on the first tab, because I can't split up the content.
When the menu is changed, a javascript does some ajax stuff, which calls my php script to create the HTML that is returned into the content div...
So what I need to do is somehow put variables in my php script that store the different tables individually, and then on this main page, reference the PHP
In my php script I do this:
Obviously I have 5 other distinct blocks that grab data in a similar way. So how do I "variablize" this in PHP and make it visible at the other end of the Ajax call?
Basically, you will want to return your code in a way that javascript can easily break apart and then put into the divs.
Reading up and using JSON is probably the best way to go, as it is very easy once you understand it, and is really best suited for this type of thing.
Beyond that, you can simply return a string with your variables, deliminated by some character you know you wont use.
So, your PHP script can just do
echo($var1.'**'.$var2.'**'.$var3) etc.
then in your javascript on the return call you would do
response=xmlHttpvar.responseText;
responses=response.split('**');
document.getElementById("fragment-1").innerHTML=responses[0];
document.getElementById("fragment-2").innerHTML=responses[1];
document.getElementById("fragment-3").innerHTML=responses[2];
Again, JSON is a much better way to do it then passing a deliminated string, but this is easier to grasp at first. Hopefully I didnt mis-interpret what you are doing, and you are in fact using ajax already. Otherwise I probably just confused you. Its hard to know what other folks already know. Id be a terrible teacher
Like so:
[PHP]
<?php
$div1 = "<div id=\"something\">Oh hi this is div 1</div>"
$div2 = "<div id=\"something2\">Oh hi this is div 2</div>"
?>
<html>
<body>
<?php echo $div1; ?>
<?php echo $div2; ?>
</body>
</html>
[/PHP]
I apologize for anyone nerdraging that that's not valid HTML, or there's no doctype, or whatever. Get that part working, then move onto the AJAX and whatever other fancy fluff you want.
bowen: Oh god, my eyes.
cmsamo: are you using a javascript framework at all (I suggest jQuery)? bowen makes a good point - get it working without ajax first, (google progressive enhancement), once you've got what you need working you can add the ajax later to make things spiffy.
When you fire the onchange on the select to call your ajax, what data are you getting back? Are you always getting new data for each fragment, and how different is the data depending on which option?
When I run my onchange - I get back a response which is a big chunk of html. Prior to starting this thread, it didn't have any divs in it.
Now, having added some divs in my back end PHP (the script that grabs the 6 tables from the database) I now have a big chunk of HTML but with each section encased in:
<div id="section1"> a table</div>
<div id="section2"> a second table</div>
... etc
The problem is that in my main page (see code above) I can't get the data to display on the page because when I try and reference those sections, nothing appears. I'm not 100% on why.
Your best bet at the moment is still probably to use my/Disruptor's idea about the separator in the html, so you explode the string.
So I can see that .content is the problem...because it's this element that is being filled by the HTML. I'll need to change getHardwareTable.php to add a character between chunks then split them in javascript.
Headed to bed now, so I figured I'd save us both some trouble
Note: in the for loop it might need to be i <= length, not sure off the top of my head.
You may also want to hide('fast') the fragments if they already had html in them, otherwise it's going to look pretty weird.
Second note: my code will update as many fragments as exists in the new array from the split html. This means if you add more tables in the php file, you just need to add the extra divs, and not touch the JS.
How do you access it once you've got it out of the javascript? (i.e. on the main page)
PHP:
Put your HTML into an array (I suggest an associative array, so that you end up with something like this)...
return json_encode($thisArrayOfFragmentData)
Then in your JS, you would continue to use the same call for the AJAX, but in your success callback the html would be stored in
data.fragments (array)
whereby you can $.each(data.fragments) or for loop, etc
The rest is going to be identical to the rest of my code from last time.
Below is the array that I get into the javascript.
So the final part is to split this into the seperate divs and assign them to the fragments (like your loop above). I couldn't seem to make this loop work. - I was getting single characters from the array - each tab took the value of 1 character - but I'm almost there!
Using the JSON method you shouldn't have to split things up as you already did it in PHP.
You'd access them by going data.d1, data.d2....
The alert pops up, and shows me the HTML strings that I expect to see, but for some reason I can't get the fragments in the tabs to work... Nothing is displayed. What am I doing wrong in here?
Why'd you put [ ] around it?
I rechecked and noticed the hashes were also missing
Now, it runs, but I get a javascript error about too much recursion in JSON.Stringify <- muy json.js was out of date.
*EDIT*
OK - SOLVED my test code is now working perfectly! Thanks a whole lot Segeur and everyone else for the help! Now I'll try and port it all across to my main code