Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums Back End Editable form fields?

  • This topic is empty.
Viewing 13 posts - 31 through 43 (of 43 total)
  • Author
    Posts
  • #171423
    chrisburton
    Participant

    @traq

    Is this what you’re trying to relay to me about using functions?:

    https://www.youtube.com/watch?v=YuLcBF1GVls

    #171451
    __
    Participant

    Yeah, kinda. His example misses a big point, however. It’s more than moving everything into a function definition; it’s about making the code more flexible and usable is more situations. In his example, the function makes a nav bar and prints it. This means that you can’t use the function unless you actually want to print the nav bar, too. If you wanted to get the nav bar HTML without printing it, then you’d have to create a whole second function that duplicates most of that code. (There’s also the issue of this being no better for error handling than the original code, but we’ll set that aside for now.)

    Here’s the basic PHP function syntax:

    • function keyword
    • function label (name)
    • opening paren
    • argument list
    • closing paren
    • opening curly brace
    • function body (i.e., the code)
    • closing curly brace

    So, you have:

    function name_of_function( $arg1,$arg2 ){
        /* code goes here */
        /* <code>return</code> statement goes here */
    }
    

    Arguments are optional. Most functions have args, but some don’t need any. You define arguments by putting varibale names inside the parens, as above. You can give arguments default values to make them optional: $arg2="default value".

    return statements are also optional. If you don’t have one, the function returns “void” (i.e., nothing) when it’s done. As a general rule, most functions you write should have return values. Also as a general rule, “side effects” (things done inside a function that also change things outside the function, e.g., printing the html for a nav bar) should not happen.

    Rewriting the function in that vid:

    <?php
    function nav_main( $dbc, $pageId ){
    
        $q = "select <code>id</code>,<code>label</code> from <code>pages</code>";
        $r = mysqli_query( $dbc,$q );
    
        $html = '<ul class="nav navbar-nav">';
    
        while( $nav = mysqli_fetch_assoc( $r ) ){
    
            $html .= ($nav['id'] === $pageId)?
                '<li class="active"><a href="'.$nav['id'].'">'.$nav['label'].'</a></li>':
                '<li><a href="'.$nav['id'].'">'.$nav['label'].'</a></li>';
        }
        $html .= '</ul>';
    
        return $html;
    }
    

    Instead of printing the HTML as it is generated, it is collected in the $html variable. Then, when we are done, we return that variable. Instead of having uncontrollable side effects, you simply get a string back from the function:

    $nav_html = nav_main( $dbc,$pageId );
    

    …which you can print, use to do other things, whatever.

    #171478
    __
    Participant

    So, let’s start with your page, and break down what it does. It:

    • checks for form submissions and redirects them to avoid duplicate submissions
    • inserts new records
    • reads existing records
    • displays existing records in a table for editing
    • shows a form for creating new records.

    We’ll write functions that do each of those things.

    • redirect_POST
    • client_insert
    • client_select
    • client_table
    • client_insert_form

    Then, we’ll make one more function for templating. When you make an ajax request, HTML output will ruin the JSON response, so you don’t want your php page to have any output by default.

    • client_page_HTMLtemplate

    With all the work being done inside of functions, your script becomes a “controller.” It’s much cleaner and easier to see what’s going on:

    <?php
    session_start();
    
    // check for form submission & do session redirect if necessary
    redirect_POST();
    
    // prepare the database connection
    $DB = new mysqli( 'host','username','password','dbname' );
    
    // if a new record was submitted, insert it
    if( $_POST ){ 
        client_insert( $DB,$_POST ); 
    }
    
    // select client records from db
    $records = client_select( $DB );
    
    // display records in a <table>
    $table = client_table( $records );
    
    // display table and new record <form> in html page template
    print client_page_HTMLtemplate( $table.client_insert_form() );
    
    // all done
    exit;
    

    Here’s a gist with everything.

    #171601
    chrisburton
    Participant

    @traq Hey, sorry for not responding! I’ve been quite busy lately. Thank you so much for helping me on this. I’ll take a look as soon as I can.

    Thanks again.

    #171602
    __
    Participant

    no prob.

    #171917
    chrisburton
    Participant

    @traq Thanks for sticking around. I keep getting an error on the following line:

    return $result->fetch_all();
    

    Error

    Fatal error:  Call to a member function fetch_all() on a non-object
    
    #171948
    __
    Participant

    Call to a member function fetch_all() on a non-object

    Meaning $result is not an object. $result came from $result = $db->query( $sql ). mysqli::query returns an object on success and false on failure, so we can assume that $result is false.

    Normally, we would check if the query succeeded before trying to read the results. But since you’re using try…catch blocks, we should have them catch the errors for us—that’s the whole point, right? : )

    Errors in PHP, unfortunately, are not the same as Exceptions. You can make them the same, though, using the ErrorException class.

    <?php
    set_error_handler(
        function( $errno,$errstr,$errfile,$errline ){
            throw new ErrorException( $errstr,0,$errno,$errfile,$errline );
        }
    );
    

    This will take every PHP error, turn it into an Exception, and throw it. That way, your catch blocks can catch them with no extra effort.

    Put this at the beginning of your script (or, require_once it in the class definition file).

    Then, let’s add some debugging stuff to the catch block:

    //  . . .
    catch( Exception $e ){
        print "{$db->error}<br>$sql";
        return false;
    }
    

    This will show us MySQL’s error message, and the SQL statement we built.

    #172189
    chrisburton
    Participant

    @traq

    First, I really apologize for disappearing. I’ve been helping people with an unexpected renovation and it has been hell.

    Anyway, I ended up having to manipulate your code a bit to get it to work. The only thing I believe is missing is the update function so that I am able to call it via jQuery on .blur().

    I’ll let you know as soon as I can get back to what we started without interruptions.

    #172192
    __
    Participant

    Well, what I’ve written so far basically only abstracts it from your original code. You would need to add a way to check if the form (POST) submission is coming from your “new record” form, or is an update. You’d also need to know if it’s a regular page request or via ajax (so you know whether to respond with HTML or JSON).

    Don’t worry about disappearing. It happens, and I’m in no hurry.

    #172311
    chrisburton
    Participant

    @traq I’m a little confused. Why would I check if the submission is coming from my form? At this point, wouldn’t I just need to update the record in my table with the .blur() function?

    For a logic example:

    click on textarea and change a value in my HTML table =>
    click out of the textarea (.blur()) =>
    update the new value to the database.

    #172312
    __
    Participant

    Why would I check if the submission is coming from my form?

    Because the form (the actual <form>) represents a new record; whereas your table represents records to be updated. If it’s an actual form submission (or the original page request), your response would be a full HTML page, whereas your submissions on blur need JSON responses.

    I’ll make some changes to illustrate my meaning.

    #172324
    chrisburton
    Participant

    I’ll make some changes to illustrate my meaning.

    I appreciate that. I’m still a bit confused.

    #172342
    __
    Participant

    Before I start, note that I completely rewrote the redirect_POST function. Now, we give it a variable that we want to be available after the redirect. I also added a client_update function, which -you guessed it- updates the database. (I thought I had already written this, but I guess not.) Before trying this, download everything fresh from the gist.

    Okay:

    When a request comes in, we need to decide a few things: First, if there is anything in POST (a database insert or update); second, if so, whether it posted via AJAX (i.e., do we respond with HTML or JSON)?

    Here’s the rewritten page controller:

    <?php
    # start session
    session_start();
        
    # decide on response type.
    # use POST "ajax=1" to distinguish AJAX requests and send JSON responses;
    # will default to HTML otherwise.
    $ajax = isset( $_POST["ajax"] );
     
    # prepare the database connection.
    $DB = new mysqli( 'host','username','password','dbname' );
     
    # check POST and process any form submission first.
    # this is a change from our previous approach: we will redirect later if needed.
    if( $_POST ){
        
        # if an ID exists, this is an update; otherwise, it's a new record.
        $update = isset( $_POST["id"] );
        
        # process form submission & query DB
        $success = $update?
            client_update( $DB,$_POST ):
            client_insert( $DB,$_POST );
            
        # prepare response data.
        # you could assign other parts to the response as desired,
        # for example, you might provided a more helpful message,
        # or we might return the ID for new inserted records.
        $response = [
            "success" => (int)$success,
            "message" => ($update? "update": "insert").($success? " successful": " failed")
        ];
        
        # if this is an ajax request, we send the response as json and stop here.
        if( $ajax ){
            echo json_encode( $response );
            exit;
        }
        # otherwise, we redirect (the whole browser history workaround).
        # only difference is, instead of passing POST through the session,
        # we'll pass the response data.
        redirect_POST( $response );
        exit;
    }
     
    # if we get to this point, it's a normal page request and we send HTML.
     
    # get records from DB
    $records = client_select( $DB );
     
    # look for a "response" from insert/update
    $response = isset( $_SESSION["redirect_POST_data"] )?
        "<div class=notice>{$_SESSION["redirect_POST_data"]["message"]}</div>":
        "";
     
    # the content of the HTML response will have three parts:
    # - the response from inserting/updating records (if any, in SESSION)
    # - the records, displayed in a <table>
    # - the <form> for submitting new records
    $content = $response
        .client_table( $records )
        .client_insert_form();
     
    # display content as HTML
    print client_page_HTMLtemplate( $content );
    exit;
    

    The javascript that will allow you to update the records displayed in the table is what we need to write next.

Viewing 13 posts - 31 through 43 (of 43 total)
  • The forum ‘Back End’ is closed to new topics and replies.