The new forums will be named Coin Return (based on the most recent vote)! You can check on the status and timeline of the transition to the new forums here.
The Guiding Principles and New Rules document is now in effect.

[Programming] php and div-content

cmsamocmsamo Registered User regular
edited September 2010 in Help / Advice Forum
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)

steam_sig.png
cmsamo on

Posts

  • rfaliasrfalias Registered User regular
    edited September 2010
    Usually you can put your static HTML in the php page, with out <?php tags.

    When you need to return the query, put it in php tags and use:
    
    echo <<<html
    
    TONS OF HTML THAT YOU DON'T HAVE TO FORMAT OR ADDSLASHES!
    
    html;
    
    

    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

    rfalias on
  • cmsamocmsamo Registered User regular
    edited September 2010
    so in my PHP, I surround each "block" of html with

    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.

    cmsamo on
    steam_sig.png
  • DisrupterDisrupter Registered User regular
    edited September 2010
    Not exactly. Your main page, I assume it is a simple html form which then includes a PHP script below it?

    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);
    ?>

    Disrupter on
    616610-1.png
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    cmsamo: rfalias's reply doesn't help you return what you want in separate pieces.

    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).
    <table id="table-1">...</table>
    <!-- [some sort of character string you can seperate/explode on] -->
    <table id="table-2">...</table>
    <!-- [some sort of character string you can seperate/explode on] -->
    <table id="table-3">...</table>
    

    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.

    Seguer on
  • DisrupterDisrupter Registered User regular
    edited September 2010
    Yeah using ajax to return the content as JSON then throwing the content into each div would be the best way to do it, as you would be able to have your dropdown trigger the ajax call onchange...

    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.

    Disrupter on
    616610-1.png
  • cmsamocmsamo Registered User regular
    edited September 2010
    Yeah using ajax to return the content as JSON then throwing the content into each div would be the best way to do it, as you would be able to have your dropdown trigger the ajax call onchange...

    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...?

    cmsamo on
    steam_sig.png
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    Yeah it's probably the "best" option, but it may be beyond what he wants to do.

    (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?

    Seguer on
  • rfaliasrfalias Registered User regular
    edited September 2010
    Oh sorry, yeah misinterpreted his post...

    rfalias on
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    FYI: rfalias' response is 'heredoc'

    Seguer on
  • cmsamocmsamo Registered User regular
    edited September 2010
    QUOTE=Seguer;16511751]FYI: rfalias' response is 'heredoc'[/QUOTE]

    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):
    
    <select id="placeDropdown" class="userInput">
              <?php
                include("../support/getInstallationDBConnection.php");
                $query="SELECT \"code\", id FROM place ORDER BY \"placecode\";";
                
                $result = pg_query($query) or die("Query failed: " . pg_last_error() . "</error>");
    
                while ($line = pg_fetch_array($result, null, PGSQL_ASSOC))
                {
                  echo "<option value='".$line["id"]."'>".$line["placecode"]."</option>";
                }
    
                pg_free_result($result);
              ?>
            </select>
            <br/>
            <br/>
            <div id="tabs">
        <ul>
            <li><a href="#fragment-1"><span>Table1</span></a></li>
            <li><a href="#fragment-2"><span>Table2</span></a></li>
            <li><a href="#fragment-3"><span>Table3</span></a></li>
            <li><a href="#fragment-4"><span>Table4</span></a></li>
            <li><a href="#fragment-5"><span>Table5</span></a></li>
            <li><a href="#fragment-6"><span>Table6</span></a></li>
        </ul>
        <div id="fragment-1">
            <div class="content"></div> 
            
        </div>
            <div id="fragment-2">
            
        </div>
            <div id="fragment-3">
            
        </div>
            <div id="fragment-4">
            
        </div>
            <div id="fragment-5">
            
        </div>
            <div id="fragment-6">
        </div>
    </div>
    </body>
    

    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:
    
    // draw the hardware table
      while($row=pg_fetch_array($result, null, PGSQL_ASSOC))
      {
    
        if(!$written_header)
        {
          echo "<table class=\"fancy\" id=\"ticket_list_table\"><thead><tr><th>ID</th><th>Hardware Name</th><th>Serial No.</th><th>IP Address</th><th>Username</th><th>Password</th></tr></thead><tbody>";
          $written_header = true;
        }
    
        echo "<tr><td>",$row['id'],"</td><td>",$row['hardwarename'],"</td><td>",$row['serialnumber'],"</td><td>",$row['ipAddress'],"</td><td>",$row['username'],"</td><td>",$row['password'],"</td></tr>";  
    
      }
    
      pg_free_result($result);
    

    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?

    cmsamo on
    steam_sig.png
  • DisrupterDisrupter Registered User regular
    edited September 2010
    I didnt realize you were already doing JS and ajax call with your dropdown. I assumed it was a straight up form submission to the same page. If you are calling a JS script with your dropdown which does an httprequest to your PHP script, that opens up some easier, better doors.

    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 :)

    Disrupter on
    616610-1.png
  • bowenbowen Sup? Registered User regular
    edited September 2010
    IMO, get the page working without AJAX first. It's not difficult at all to do something like this. Store the HTML pieces as strings, then, place the strings throughout your page.

    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 on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    Disruptor: Hey that's what I said, but with examples! :P

    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?

    Seguer on
  • bowenbowen Sup? Registered User regular
    edited September 2010
    Yeah the PHP code background is kind of intense. People go too crazy with AJAX and JS right from the get go. Plus, someone new to both PHP and HTML probably should hold off on it. Doesn't really add too much to a page anyways.

    bowen on
    not a doctor, not a lawyer, examples I use may not be fully researched so don't take out of context plz, don't @ me
  • cmsamocmsamo Registered User regular
    edited September 2010
    Someone else (who has left my company) build an entire site that runs with ajax and jquery. I've just created a page to display a bunch of data from a server. I have got as far on my own as populating this page using Ajax.

    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.

    cmsamo on
    steam_sig.png
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    How about posting the JS you're using to run the AJAX/receive the response etc?

    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.

    Seguer on
  • cmsamocmsamo Registered User regular
    edited September 2010
    Here's my js:
    $(function (){
      
       $("#placeDropdown").change(function()
      {
        reload();
      });
      
    }); // end of document.ready
    
    function reload()
    {
    
      var selected_airport = $("#placeDropdown").val();
      //console.log("selected place:", selected_place);
      filter(selected_place);
    }
    
    function filter(selected_place)
    {
      if($("#subtitle") != null || $("#subtitle").length > 0)
      {
        var subtitle_string = "Showing Installation Details for "+
                  $("#placeDropdown option:selected").text();
    
        $("#subtitle").text(subtitle_string);
      }
    
      $.ajax({
        method: "get",
        url: "getHardwareTable.php",
        data: "&airport="+selected_airport,
        beforeSend: function(){
          $("#loading").show("fast");
        }, //show loading just when link is clicked
        complete: function(){
          $("#loading").hide("fast");
        }, //stop showing loading when the process is complete
        success: function(html){ //so, if data is retrieved, store it in html
          $(".content").show("slow"); //animation
          $(".content").html(html); //show the html inside .content div
    
        }
      });
    }
    

    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.

    cmsamo on
    steam_sig.png
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    function filter(selected_place)
    {
      if($("#subtitle") != null || $("#subtitle").length > 0)
      {
        var subtitle_string = "Showing Installation Details for "+
                  $("#placeDropdown option:selected").text();
    
        $("#subtitle").text(subtitle_string);
      }
    
      $.ajax({
        method: "get",
        url: "getHardwareTable.php",
        data: "&airport="+selected_airport,
        beforeSend: function(){
          $("#loading").show("fast");
        }, //show loading just when link is clicked
        complete: function(){
          $("#loading").hide("fast");
        }, //stop showing loading when the process is complete
        success: function(data){ //so, if data is retrieved, store it in html
          //$(".content").show("slow"); //animation
          //$(".content").html(html); //show the html inside .content div
    
    //note: indenting is going to be screwy
    data = data.split('separator'); //data is now an array of strings split by your sep
    var length = data.length+1;
    for (var i = 1; i < length; i++)
    {
      $('#fragment-'+i).html(data[i-1]).show('slow');
    }
    
        }
      });
    }
    

    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.

    Seguer on
  • DeathPrawnDeathPrawn Registered User regular
    edited September 2010
    There's no need to mess around with splitting strings. Instead of having a single variable contain multiple HTML objects with manually injected separators, you can just store each HTML chunk as its own variable in PHP and then return a JSON response object containing all of the chunks as distinct variables instead of plaintext HTML.

    DeathPrawn on
    Signature not found.
  • cmsamocmsamo Registered User regular
    edited September 2010
    So I should be looking at json_encode or something like that? and assign the json object to data: in the javascript?

    How do you access it once you've got it out of the javascript? (i.e. on the main page)

    cmsamo on
    steam_sig.png
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    If you want to go the JSON route:

    PHP:

    Put your HTML into an array (I suggest an associative array, so that you end up with something like this)...
    Array (
      [fragments] => Array (
        0 => 'some html',
        1 => 'some html',
        2 => 'some html',
        //etc
      )
    )
    

    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.

    Seguer on
  • cmsamocmsamo Registered User regular
    edited September 2010
    I've got as far as having a JSON object in the javascript but I can't seem to decode it into the final HTML blocks.

    Below is the array that I get into the javascript.
    {"d1":"<div id='d1'><br\/><b>Message 1<\/b><br\/><\/div>","d2":"<div id='d2''><b>Message 2<\/b><br\/><\/div>","d3":"<div id='d3'><br\/><b>Message 3<\/b><br\/><\/div>","d4":"<div id='d4''><b>Message 4<\/b><br\/><\/div>","d5":"<div id='d5'><br\/><b>Message 5<\/b><br\/><\/div>","d6":"<div id='d6''><b>Message 6<\/b><br\/><\/div>"}
    

    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!

    cmsamo on
    steam_sig.png
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    Umm... take a look at the docs for $.ajax/$.get and change the type to JSON, so that you get back a result.

    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....

    Seguer on
  • cmsamocmsamo Registered User regular
    edited September 2010
    Ok... Almost there...
    $.ajax({
        method: "get",
        url: "getDetails.php",
        data: "&airport="+selected_airport,
        dataType: 'json',
        beforeSend: function(){
          $("#loading").show("fast");
        }, //show loading just when link is clicked
        complete: function(){
          $("#loading").hide("fast");
        }, //stop showing loading when the process is complete
        success: function(json){ //so, if data is retrieved, store it in html
    
          alert("It worked!: " + json.f1 + ", " + json.f2); 
          $('fragment-1').html([json.f1]).show('slow');
          $('fragment-2').html([json.f2]).show('slow');
          $('fragment-3').html([json.f3]).show('slow');
          
          
        }
    

    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?

    cmsamo on
    steam_sig.png
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    cmsamo wrote: »
    Ok... Almost there...
    $.ajax({
        method: "get",
        url: "getDetails.php",
        data: "&airport="+selected_airport,
        dataType: 'json',
        beforeSend: function(){
          $("#loading").show("fast");
        }, //show loading just when link is clicked
        complete: function(){
          $("#loading").hide("fast");
        }, //stop showing loading when the process is complete
        success: function(json){ //so, if data is retrieved, store it in html
    
          alert("It worked!: " + json.f1 + ", " + json.f2); 
          $('fragment-1').html([json.f1]).show('slow');
          $('fragment-2').html([json.f2]).show('slow');
          $('fragment-3').html([json.f3]).show('slow');
          
          
        }
    

    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?
    $('fragment-1').html(json.f1).show('slow');
    $('fragment-2').html(json.f2).show('slow');
    $('fragment-3').html(json.f3).show('slow');
    

    Why'd you put [ ] around it?

    Seguer on
  • cmsamocmsamo Registered User regular
    edited September 2010
    OK.. brackets were a noob mistake. It still doesn't work without the brackets though. Do I need to explicitly decode the json object? I thought that because it worked ok with the Alert, it should work just fine in the assignment to the fragment but I guess not.

    cmsamo on
    steam_sig.png
  • cmsamocmsamo Registered User regular
    edited September 2010
    $('#fragment-1').html(json.f1).show('slow');
    $('#fragment-2').html(json.f2).show('slow');
    $('#fragment-3').html(json.f3).show('slow');
    

    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 :)

    cmsamo on
    steam_sig.png
  • SeguerSeguer of the Void Sydney, AustraliaRegistered User regular
    edited September 2010
    No worries cmsamo.

    Seguer on
Sign In or Register to comment.