-1

I have a small website that using a basic MVC structure. I have some code that inserts two values into a database, the insertion works fine without any issues, however, if i want to see the new data i usually have to refresh the page or navigate to another page and then back. I understand that i need to use JQuery/Ajax to make this work but dont really understand how to do it with PHP functions.

The code in question is below:

PHP Function:

<?php
session_start();
require_once('../Config/config.php');

class Readings 
{
    public $dbconn;

    public function __construct()
    {
        $database = new Database();
        $db = $database->dbConnection();
        $this->dbconn = $db;
    }

    public function enterElecReadings($eUsage)
    {
        try
        {       
            $estmt = $this->dbconn->prepare("
                INSERT INTO elec_readings
                    (ElecUsage, DateAdded, AccountNumber) 
                VALUES
                    (:eUsage, NOW(), :accNum)");
            $estmt->bindparam(":eUsage", $eUsage);
            $estmt->bindparam(":accNum", $_SESSION['user_session']);
            $estmt->execute();  
            return $estmt;
        }
        catch(PDOException $e)
        {
            echo $e->getMessage();
        }   
    }

    public function getElecReadings(){
        try {
            $stmt = $this->dbconn->prepare("SELECT ElecUsage, DateAdded FROM elec_readings WHERE AccountNumber = '" . $_SESSION['user_session'] . "'");
            $stmt->execute();
            return $stmt;
        } catch (Exception $e) {

        }
    }
}

?>

Page that the user will see:

    if(isset($_POST['btn-submitElecUsage']))
    {
        $eUsage = strip_tags($_POST['txtElecUsage']);

        try {
            if($newReading->enterElecReadings($eUsage)){    
                $elecNotif[] = "Reading successfully entered.";
            }
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }

<div class="elecUsage">
        <form id="elecRead" method="POST">
            <h2>Electricity Usage</h2>

            <?php
            if(isset($elecError))
            {
                foreach($elecError as $elecError)
                {
                    ?>
                    <div class="alert alert-danger">
                        <?php echo $elecError; ?>
                    </div>
                    <?php
                }
            }

            if(isset($elecNotif))
            {
                foreach($elecNotif as $elecNotif)
                {
                    ?>
                    <div class="alert alert-danger">
                        <?php echo $elecNotif; ?>
                    </div>
                    <?php
                }
            }
            ?>

            Please enter your latest electricity meter reading:
            <br>
            <input type="text" name="txtElecUsage" required/>
            <br>
            <input type="submit" name="btn-submitElecUsage" value="Submit"/>

        </form>


        <br>
        Your previous Electricity meter readings:
        <br>

        <div id="previousElecReadings">
            <br>

            <table class="tableElec" >
                <thead>
                    <tr>
                        <th>Usage</th>
                        <th>Date Added</th>     
                    </tr>
                </thead>
                <?php
                foreach ($elec_readings as $elec_reading): ?>
                <tbody>
                    <tr>
                        <td><?php echo $elec_reading['ElecUsage']; ?></td>
                        <td><?php echo $elec_reading['DateAdded']; ?></td>
                    </tr>
                    <?php
                    endforeach;
                    ?>
                </tbody>
            </table>
        </div>
    </div>

Controller class:

<?php
require_once('../Model/readingsModel.php');
require_once('../Tool/DrawTool.php'); 

$newReading = new Readings();
// instantiate drawing tool
$draw = new DrawTool();
// parse (render) appliance view
$renderedView = $draw->render('../View/meterReadings.php', array('elec_readings' => $newReading->getElecReadings()), 
    array('gas_readings' => $newReading->getGasReadings()));

echo $renderedView;

?>

As i said above. Insertion works fine. But i want to see the data appear instantly instead of having to refresh.

Any ideas?

Thanks

resontant81
  • 39
  • 2
  • 3
  • 8
  • Have you looked up any examples of ajax (jQuery or otherwise)? There are a lot out there. – Rasclatt Mar 28 '16 at 19:32
  • @Rasclatt I have but either cant understand it or cant get it to work with the function – resontant81 Mar 28 '16 at 19:33
  • Post what you have tried, there may have been something simple you missed. – Rasclatt Mar 28 '16 at 19:34
  • @Rasclatt the main one i looked at was this: http://stackoverflow.com/questions/16616250/form-submit-with-ajax-passing-form-data-to-php-without-page-refresh – resontant81 Mar 28 '16 at 19:37
  • Well, you have to post your version of it, to figure it out, we'd need to see how it fit's into your page (are you submitting a form, pressing a button, etc. ) to fire it. – Rasclatt Mar 28 '16 at 19:38
  • @Rasclatt Sorry i dont have that version anymore i got rid of it. I edited my original code as i forgot to add the full form code that im using. I have a submit button that inserts the code into the database – resontant81 Mar 28 '16 at 19:41
  • You will want to use the `on('submit')` or `$('#elecRead').submit(function(e){` then add `e.preventDefault();` to stop form submission, then you can grab the data from your form using `$(this).serialize()`. After that you can receive back JSON to parse or HTML that you can drop into a container. – Rasclatt Mar 28 '16 at 19:47
  • Also, you put your php that does the inserting on a new page and reference that in the `url:` portion of the ajax – Rasclatt Mar 28 '16 at 19:48
  • You will need two pages to do this. Page 1 ( your controller page where you render the initial ui) and page 2 where you process in the insertion. Page 2 just contains your class that you use to process the update. It will return to Page 1 the ajax response, either html (your error formatted) or a JSON string that your `success` response in your ajax will post to a container on Page 1 – Rasclatt Mar 28 '16 at 20:10

2 Answers2

1

All it really does it act like a browser and in the background hit that page. You can either choose to call back data or not, but it's as if your browser has gone to that page, so you treat it like any other page. This is just a hack cut and paste but this is probably close:

index.php (whatever your initial page is called):

    <!-- use the id to target the form -->
    <form id="elecRead" method="POST">
        <h2>Electricity Usage</h2>
        <!-- You just have an empty container where your ajax will return -->
        <div id="errors"></div>
        Please enter your latest electricity meter reading:
        <br>
        <input type="text" name="txtElecUsage" required/>
        <br>
        <input type="submit" name="btn-submitElecUsage" value="Submit"/>

    </form>
    ...etc...

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>

    <script>
    // When page is done loading
    $(document).ready(function(){
        // When this particular form is submitted
        $('#elecRead').submit(function(e){
            // Stop normal refresh of page
            e.preventDefault();
            // Use ajax
            $.ajax({
                // Send via post
                type: 'post',
                // This is your page that will process the update 
                // and return the errors/success messages
                url: "page2.php",
                // This is what compiles the form data
                data: $(this).serialize(),
                // This is what the ajax will do if successfully executed
                success: function(response){
                    // It will write the html from page2.php into an 
                    // element with the id of "errors", in our case
                    // it's a div
                    $('#errors').html(response);
                },
                //  If the ajax is a failure, this will pop up in the console.
                error: function(response){
                    console.log(response);
                }
            });
        });
    });
    </script>

page2.php (processing page):

<?php
// Page two just contains the processing of the update
// so include everything that you need to do that
session_start();
require_once(__DIR__.'/../Config/config.php');
require_once(__DIR__.'/../Model/readingsModel.php');
// Check for the post
if(isset($_POST['btn-submitElecUsage'])){
        // Create the instance of your class that does the update and error
        // handling/rendering
        $newReading = new Readings();
        $eUsage = strip_tags($_POST['txtElecUsage']);

        try {
            if($newReading->enterElecReadings($eUsage)){    
                $elecNotif[] = "Reading successfully entered.";
            }
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }
// I am just using a buffer, but you don't need it
ob_start();
    // I presume this variable is on an included page, I don't see it 
    // anywhere but if you include the same stuff as your initial page,
    // it should show up here fine
    if(isset($elecError)){
        foreach($elecError as $elecError){
            ?>
            <div class="alert alert-danger">
                <?php echo $elecError; ?>
            </div>
            <?php
        }
    }

    if(isset($elecNotif)){
        foreach($elecNotif as $elecNotif){
            ?>
            <div class="alert alert-danger">
                <?php echo $elecNotif; ?>
            </div>
            <?php
        }
    }

$data = ob_get_contents();
ob_end_clean();
// Just print the contents of the page and your ajax on page 1
// will take this content and place it in the <div id="errors"><div>
die($data);
Rasclatt
  • 12,498
  • 3
  • 25
  • 33
0

With pure php you can't do it without refreshing the page. So use AJAX!

Here's a little example

<html>
    <head>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
    </head>
    <body>
        <input type="text" id="name"/>
        <input type="submit" id="submit" value="Send"><br/><br/>
        <div id="response"><div>

        <script>
        $(document).ready(function(){
            $('#submit').click(function(e){
                e.preventDefault();
                var value = $('#name').val();
                if (value != ''){
                    $.ajax({
                        type: "POST",
                        url: "your_process_file.php",
                        data: { name:value },
                        success: function(data){
                            $('#response').html(data);
                        },
                        fail: function(data){
                            $('#response').html('There is an error!');
                        }
                    });
                }
            });
        });
        </script>
    </body>
</html>

And your_process_file.php could look like:

$name = $_POST['name'];
$stmt = $db->prepare('SELECT * FROM tblName WHERE name=?');
$stmt->execute([$name]);
while ($row = $stmt->fetch()){
    echo $row['col1'],' ',$row['col2'],' ',$row['colN'];
}

And assuming you have some data in a db table:

id name address

1 abc address1

2 def address2

Then, when you write in the textbox, fe, abc the whole row from the table will be returned inside the <div id="response"></div> without refreshing the page.

OBS: I assume there might be some errors in the code, as I didn't test it.

Dan Costinel
  • 1,716
  • 1
  • 15
  • 23
  • Thanks for the answer but im using a model class with a function. How would i call that in the Ajax file? – resontant81 Mar 28 '16 at 19:46
  • Edited my original post to include the full class for inserting and selecting the data – resontant81 Mar 28 '16 at 19:50
  • In my example, I've send the request to a simple php file, but you can send it to a php class file too. Like: url: "app/classes/Process.php". Then inside any method of that class make the db stuff and return the row of db you need. – Dan Costinel Mar 28 '16 at 19:51
  • Sorry im kinda confused. So i could do : `url: "../Model/readingsModel.php"` – resontant81 Mar 28 '16 at 19:52
  • Yes. You can do like that too. – Dan Costinel Mar 28 '16 at 19:53
  • But then how to i access the specific function? or would it do that automatically? – resontant81 Mar 28 '16 at 19:54
  • @resontant81 You put the `if(isset($_POST['btn-submitElecUsage']))` portion on a separate page that you reference in the `url:` spot of the ajax – Rasclatt Mar 28 '16 at 19:57
  • Access the specific function? What do you mean? All you need to do, is to process the information that AJAX send to that file ( `../Model/readingsModel.php` ). In whatever method of that class you want, you can do like I did in `your_process_file.php`. Just that instead of echoing, you will `return`. – Dan Costinel Mar 28 '16 at 19:57
  • And don't mix php code with HTML code in the same page. Make some separate files: the html code and AJAX code in, let's say, `index.html`, and the AJAX code sends requests to php files, which are located as you have that `../Model/readingsModel.php`. – Dan Costinel Mar 28 '16 at 20:02
  • Sorry guys still really confused. Ive added my "controller" class if it makes things clearer. – resontant81 Mar 28 '16 at 20:06
  • Sorry if you are confused! But you have here all the things you need. Just adapt this code to your needs. I really can't make your project from the scratch. First try out my code, understand what's happening, then proceed to modify it according to your needs. – Dan Costinel Mar 28 '16 at 20:09