Asked  7 Months ago    Answers:  5   Viewed   31 times

I've built an online community in Drupal with a homepage that is kind of like the Facebook wall. You see the 25 most recent posts, with the two most recent comments below those posts. There is also a textarea right below those comments so that you can quickly post a new comment on a particular post.

These Facebook-style posts have a lot of functionality built into them via JavaScript. Clicking a "view all comments" link directly below a post makes an AJAX call that grabs all the comments for that post and displays them right below it. You can also mark posts as helpful, as the solution to your question, edit comments inline, etc. All of these actions require AJAX requests, which means that the JavaScript making the request needs to know essential information such as the Node ID (the unique identifier of the post), the comment ID (unique identifier of the comment), etc.

My initial implementation had these pieces of essential data sprinkled all over the posts, making it more complicated to write the JS that needed to find it. So my second implementation simply output all this data into a JSON-compatible string in the main wrapping element of each post. While this made it much easier for the JS to find the data it needed, writing JSON as a string is a pain (escaping quotes, no line breaks).

So now I have a third idea, and I'm looking for feedback on it prior to implementation. The idea is to create a single global JS Array for all these posts that contains within it objects that hold the data for each post. Each element in that array would hold the necessary data needed for the AJAX calls. So it would look something like this:

Facebook-style post template

<div class="post" data-postindex="<?php echo $post->index; ?>">
    <!-- lots of other HTML for the post -->
</div>
<script type="text/javascript">
    globalPostArray.push({
        nid: <?php echo $post->nid; ?>,
        authorID: <?php $post->authorID; ?>,
        //etc. etc. etc.
    });
</script>

The result of the above code is that when a link gets clicked that requires an AJAX request, the JS would simply traverse the DOM upwards from that link until it finds the main .post element. It would then grab the value of data-postindex in order to know which element in globalPostArray holds the data it needs.

Thoughts? I feel like there must be some standard, accepted way of accomplishing something like this.

 Answers

30

I've never heard of a standard way to "pass" information between PHP and Javascript, as they are a server-side and client-side language, respectively. I would personally use a hybrid of your second and third solutions.

Store the post id in a data-postindex attribute (data attributes are newish, and the "right" way to store small amounts of data). But I would still just use a JSON array for the rest, as storing lots of data in data-attributes (and escaping them!) is potentially problematic. PHP has a json_encode function that takes care of all the escaping and such for you - just build a PHP array (say, $postdata) like you normally would, and then throw this in your post template:

<script type="text/javascript">
    globalPostArray.push(<?php echo json_encode($postdata) ?>);
</script>

Where $postdata is something like the following:

$postdata = array(
    'nid' => 5,
    'authorId' => 45
    ...etc...
);

It should be easy enough to generate such an array from your existing code.

I wrote a blog post a while back about my implementation of this kind of thing, but it sounds like all you need is a pointer at json_encode.

Wednesday, March 31, 2021
 
fardjad
answered 7 Months ago
72

ok,from what i understand, you need a javascript function binded on the onclick event of the generated links that sends you back to a different page the link content. if that's what you need, i recommend using a library such as jquery (it's more easy ti use) and paste this code into the page:
$('a').click(function(){
$.post("url_of_the_page_you_want_to_send",
{data : $(this).html()}); });

hope this helps :|

Saturday, May 29, 2021
 
van_folmert
answered 5 Months ago
51

Secure for 08/15 website: yes
Secure for online banking: no

The method you use is equivalent to an unencrypted everyday login <form>. Albeit you should really not rely on a "user_id" cookie. Rather save the verified user_id in the session store only.

Also you might try to simply return the session cookie on the JSON result for the AJAX call. It usually sticks to all further HTTP requests, so you don't need (3) to set the cookie via Javascript additionally.

Saturday, May 29, 2021
 
Norgul
answered 5 Months ago
47

You can also use Prototype's function toJSON() to convert an array into a JSON object. After passing it to server via Ajax call, simply use PHP's function json_decode() to decode the object.

Saturday, May 29, 2021
 
viper
answered 5 Months ago
60

In my MVC URLs look like: index.php?c=Controller&m=ControllerMethod&d=slash/sepparated/list/of/stuff

Data (d=) is exploded on the slashes and passed as an array to every controller method. Autoloading (via spl_autoload_register()) is used to call the class (c=) and then the method in that class (m=).

Also, it sounds like you're either not setting the ACTION on your form or you're deliberately setting the ACTION to GET. As a general rule, ACTION should be POST to keep the URLs sane. Except search forms. Those can be GET with various advantages.

Re-directing to prevent a resubmitted form on refresh is your best option (probably only option). But in my MVC index.php?c=user&m=login handles both the login page and the login action.

Example

class login extends Controller {

    public function login($data) {

        if(empty($_POST)) {

            $this->view = "login.tpl";

            return TRUE;

        }


        $res = $this->model->auth();

        if($res !== TRUE) {

            $_POST = NULL;

            $this->errorState = 1;
            $this->errorMsg = "Invalid login details";

            $this->login();

            return FALSE;

        }

        Core::setMessage('success', 'user', 'login', '2', 'Logged in successfully');

        $home = new home(); //whatever the main controller is
        $home->index($data);

        //alternatively you can redirect

        header("Location: index.php?c=home&m=index);

        return TRUE;

    }

}

Does this make sense or have I completely missed the mark?

Saturday, May 29, 2021
 
muncherelli
answered 5 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :