This is driving me mad. I am using jquery and ajax to run the php to update my database and that all works fine, but after the update (specifically adding records) I want to re-run the query to get all records so that the new one is displayed but nothing happens and in my error log I am getting an error regarding my class instantiation and objects (this is partly a jquery/ajax problem I suppose as well).

The main page (form shortened for ease of reading):

<?php
    require_once('../../inc/core.php');
    require_once('../../inc/class.faqs.php');

    $objFAQ = new Faqs;
    $cats = $objFAQ->get_faq_categories();

    include('../../assets/layout/header.php');

?>

    <div class="container">
        <div class="success-notice"></div>
        <div class="add-record">
            <form action="admin-faq.php" method="post" id="add-faq">
                <label for="question">Question</label>
                <input type="text" name="question" id="question" value="">.
                .
                .
                <input type="submit" name="do_add" value="Submit">
                <button class="close-form" value="Cancel">Cancel</button>
            </form>
            <hr>
        </div>
        <div id="faq-records">
            <?php include('faq-records.php'); ?>
        </div>
    </div>
<?php
    include('../../assets/layout/footer.php');
?>

The faq-records.php file (form shortened for ease of reading - this all works fine on page load):

<?php
    $faqs = $objFAQ->get_admin_faqs();
    foreach ($faqs as $faq) {
?>
    <div class="faq">
        <p><?php echo $faq['question']; ?></p>
        <div class="edit-record">
            <form action="admin-faq.php" method="post" id="edit-faq">
                <input type="hidden" name="id" value="<?php echo $faq['id']; ?>">
                <label for="question">Question</label>
                <input type="text" name="question" id="question" value="<?php echo htmlentities(stripslashes($faq['question'])); ?>">
                .
                .
                <input type="submit" name="do_edit" value="Submit">
                <button class="close-form" value="Cancel">Cancel</button>
            </form>
        </div>
        <hr>
    </div>
<?php } ?>

And the jquery / ajax (as I say this all works apart from the load function, however if I load a basic html file with a line of text that does work):

$("#add-faq").submit(function(e){

        e.preventDefault();
        var dataString = $("#add-faq").serialize();
        var theDiv = $(this);

        $.ajax({
            type: "POST",
            url: "admin-faq.php",
            data: dataString,
            success: function(data){
                $('.success-notice').html('<p>'+data+'</p>');
                theDiv.closest('.add-record').hide();
                $('#faq-records').load('faq-records.php');
            }
        });

        return false;

    });

The errors I get are:
Undefined variable: objFAQ
And therefore
PHP Fatal error: Call to a member function get_admin_faqs() on a non-object

I don't want to have to call the include files and reinstantiate the object again within the faq-records.php file if I can help it but I am not sure if it is load function or the php that is causing the problem.

Any ideas please??

Recommended Answers

All 9 Replies

Member Avatar for diafol

I don't want to have to call the include files and reinstantiate the object again

I ran into this when starting OOP. As you know PHP doesn't keep state, so your options are pretty limited. I played around with persistance, like placing objects into sessions etc - but this quickly turned out to be a nightmare. If you need to store intermediate data - you can use a DB maybe? I had the idea that a simple ajax update shouldn't need a complete reinstantiation of all those classes again. I think I was wrong (still learning).
You can use sessions as hooks to cut down on some methods I suppose or store serialized versions of objects in a DB. But PHP is build up, tear down.

I'll come back and have a look at the code later, if nobody else has posted.

The faq-records.php file (form shortened for ease of reading - this all works fine on page load):

<?php
    $faqs = $objFAQ->get_admin_faqs();
    foreach ($faqs as $faq) {
?>

Looks like you are calling a class function, but have not included nor declared.

I am still very new to OOP. You have declared $objFAQ = new Faqs; in the main page code, this, as far as i understand, will not carry over unless as Diafol suggested, using sessions.

Hope it helps

Member Avatar for diafol

If you send a parameter to the ajax loader, like a $_POST var and you add this tothe top of the faq-records.php:

if(isset($_POST['ajax_request'])){
    require_once('../../inc/core.php');
    require_once('../../inc/class.faqs.php');
    $objFAQ = new Faqs;
}

BTW - to set the record straight, I'm not suggesting keeping objects in sessions. I tried it and it was a bad idea. :)

Member Avatar for diafol

Darn, can't seem to edit at the moment - so here's the ajax bit:

    $.ajax({
        type: "POST",
        url: "admin-faq.php",
        data: dataString,
        success: function(data){
            $('.success-notice').html('<p>'+data+'</p>');
            theDiv.closest('.add-record').hide();
            $('#faq-records').load('faq-records.php', {ajax_request: 1});
        }
    });

Thank you diafol, unfortuantley you have confirmed my worst fears :) I just hoped someone might have an answer without me having to re-instantiate the class but hey ho.

I do like your idea of only reloading the include files and re-instantiating if the data returned shows an ajax request and will at the very least implement that.

Squidge - that was my question, can I re-call the class method without having to re-include and re-instantiate.

All working nicely :) Just got to work out how to get the click function for the dit button working again after re-loading the div (will post in Javascript forum). Thanks diafol for the idea :)

Member Avatar for diafol

No worries - dynamic 'edit' buttons - you can use '.on':

For example:

$('#containerDiv').on("click", ".editbutton", function (e) {
    e.preventDefault();
    //e.g. get identifier record related to edit button if set 
    var id = $(this).attr('data-id');
    //run rest of code
});

Your updatable part of the page needs to be within <div id="containerDiv">. And the classname for the edit button should be 'editbutton'. The container doesn't have to be directly before the updatable part, just that it encloses it.

Thanks diafol, I used .live('click', function......) instead on the edit button which has worked (already done before I saw your post).

Member Avatar for diafol

Thank you diafol, unfortuantley you have confirmed my worst fears :) I just hoped someone might have an answer without me having to re-instantiate the class but hey ho.

There is an approach you could research, now I think of it - the 'Registry Pattern' which could have a sessionRegistry subclass. I haven't used it, but read about it the other day. May be worth a look.

Here's an example: http://www.devshed.com/c/a/PHP/Session-Handler-with-the-Registry-Design-Pattern/
It's not the one I read (mine was in a book), so I can't comment on the quality.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.