cssyphus
cssyphus

Reputation: 40038

complex jqueryui dialog

Okay, that's a presumptuous title - it's complex to me.

Overview: (See screenshots and UPDATE at bottom.)
a. On $(document).ready, jQuery/AJAX builds table with one contact per row
b. Each table row, 3rd cell, is: <a id="edit_83">edit</a> tag -- "83" is example and represents the contact_id from db, so each a tag will have a unique id number that is used in step (d)
c. As table being built, construct jqueryui dialog (autoOpen=false) for each contact in AJAX callback
d. when any edit anchor is clicked, jquery splits off the contact_id and uses that to display the appropriate jQueryUI dialog.

Objective: Clicking on edit link in any table row opens a jqueryui dialog with edit form for that contact.

Problem: The form opens, but there are no form fields inside. In fact, in the DOM the injected form/div is missing for each table row. ???


HTML:

<div id="contact_table"></div>

Javascript/jQuery - AJAX call:

$(document).ready(function() {
$.ajax({
    type: "POST",
    url: "ax_all_ajax_fns.php",
    data: 'request=index_list_contacts_for_client&user_id=' + user_id,
    success: function(data) {
        $('#contact_table').html(data);
        var tbl = $('#injected_table_of_contacts');
        tbl.find("div").each(function() {
            $(this).dialog({
                autoOpen: false,
                height: 400,
                width: 600,
                modal: true,
                buttons: 
                    {
                        Okay: function() {
                            $( this ).dialog( "close" );
                        },
                        Cancel: function() {
                            $( this ).dialog( "close" );
                        }
                    }
            })
        });
    }
});
});

AJAX/PHP 1 - ax_all_ajax_fns.php:

}else if ($_POST['request'] == 'index_list_contacts_for_client') {
    $user_id = $_POST['user_id'];
    $r = build_contact_table_for_client($user_id);
    echo $r;
}

AJAX/PHP 2: - functions.php

function build_contact_table_for_client($user_id) {
    $aContact_info = get_contact_data_ARRAY_user_id($user_id, 'first_name','last_name','email1','cell_phone', 'contact_id');
    $r = '<table id="injected_table_of_contacts">
            <tr>
                <th width="120">Name</th>
                <th width="200">Email Address</th>
                <th width="100">Cell Phone</th>
                <th>Action</th>
            </tr>
        ';
    while ($rrow = mysql_fetch_array($aContact_info)) {
        $r .= '
            <tr>
                <td>'.$rrow['first_name'].' '.$rrow['last_name'].'</td>
                <td>'.$rrow['email1'].'</td>
                <td>'.$rrow['cell_phone'].'</td>
                <td>
                    <a class="editcontact" id="edit_'.$rrow['contact_id'].'" href="#">edit</a>
                     / 
                    <a class="delcontact" id="del_'.$rrow['contact_id'].'" href="#">del</a>
                    <div id="editThisContact_'.$rrow['contact_id'].'" style="display:none">
                        <form name="editForm" onsubmit="return false;">
                            <p class="instructions">Edit contact information:</p>
                            First Name:<span style="padding:0 20px;">Last Name:</span><br />
                            <input type="hidden" id="fn_'.$rrow['contact_id'].'" value="'.$rrow['first_name'].'">
                            <input type="hidden" id="ln_'.$rrow['contact_id'].'" value="'.$rrow['last_name'].'">
                            Email:<span style="padding:0 20px;">Cell Phone:</span><br />
                            <input type="hidden" id="em_'.$rrow['contact_id'].'" value="'.$rrow['email1'].'">
                            <input type="hidden" id="cp_'.$rrow['contact_id'].'" value="'.$rrow['cell_phone'].'">
                        </form>
                    </div>
                </td>
            </tr>
        ';
    }

    $r .= '</table>';
    return $r;
}

jQuery - document.click event - if injected code missing, how is it able to find the selector??

$(document).on('click', '.editcontact', function(event) {
    var contact_id = this.id.split( 'edit_' )[1];
    var etc = $( '#editThisContact_' + contact_id );
    etc.dialog("open");
});

UPDATE - PARTIAL SOLUTION:

The dialog is now appearing - the cancel button was out of place, per this post. However, the injected code has vanished. Nothing else changed - just got the dialog code working by fixing syntax error in placement of cancel button.

Upvotes: 0

Views: 472

Answers (2)

Thom Porter
Thom Porter

Reputation: 2609

In response to the question on my comment on the original post: You really already know JSON, it stands for JavaScript Object Notation. This is a JSON object:

{"a":1,"b":2,"c":3}

look familiar? JSON is just a fancy name for something we've been using a long time (that may not be 100% true, but it's how I see it.)

The idea is to have the server pass back JSON objects and have your JavaScript create/update HTML based on them. In your scenario, you were having your PHP build multiple HTML dialogs. Instead, you would have your PHP pass back an array of objects each one representing a single row from your table, like so:

{
  "records": 
  [
    { 
      "field a":"value a",
      "field b":"value b"
    },
    // record 2
    { 
      "field a":"value a",
      "field b":"value b"
    }
  ]
}

If you were to request that from the server using .getJSON(), jQuery would automatically read that and give you a an object with a .records property that is an array of objects! Now you can use JavaScript to update a single dialog/form on the screen when they click one of the corresponding records.

Note: You could have PHP just pass back an array of objects, but it is best practice to wrap it in an object above. Many times you'll want other info too, for example, when you are doing paginated search results you're going to need to know the total number of records and what page you're on and maybe other data points.

An added benefit of this is that the server is done much faster. You push all of the display logic onto the client's computer, and hence, can server more pages from the same server.

That's a real brief explanation. There are tutorials and examples ALL OVER the web. Any good Ajax app you use online (GMail for example) uses JSON objects instead of passing huge blocks of HTML around. Here are a few links, Google has quite a few more:

There are also some really good frameworks out there to help out with this process. I'm a huge fan of both backbone.js and spine.js. Both use jQuery, both help you use best practices when building apps (like MVC.)

Upvotes: 2

cssyphus
cssyphus

Reputation: 40038

It's nice when you solve your own question. Not so nice when the answer is a ID-ten-T error.

In the injected HTML, note the type of the input fields (screenshot 1). Change type to type="text", and all works as desired.

When concepts are new, Occam's Razor moves almost beyond reach.

I still don't understand why I can't see the injected markup, though..!

Upvotes: 0

Related Questions