views:

292

answers:

2

I have a view where ill have 3 divs:

Div 1: List of Brands with checkboxs. Div 2: List of Categories with checkboxs.

Div 3: List of Items.

This last div will be refreshed with the all the items according to what is selected in the first two divs. At beginning it shows all the items, after we select some of the brands and/or categories and press refresh i'll want to refresh the div 3.

In Javascript I can get which of the categories/brands are selected and my biggest doubt is on how to refresh the last div...

Heres what I was trying:

function refresh() {
var brands= /*<code where i get all the brands selected (this will be a js array)>*/
var categories = /*<code where i get all the categories selected (this will be a js array)>*/
<?php echo $ajax->remoteFunction(array('url' => array('controller' => 'items', 
                                                      'action' => 'men', brands, categories),
                                                      'update' => 'itemsContent')); ?>
}

My problems are: - How do I pass the js vars into the php method? - How do I receive an js array in a cakephp action? Because brands and categories will be used to filter the query that produce results for the div 3...

+2  A: 

You won't be able to use the $ajax helper here, since it just outputs a static script which can't be changed/influenced at "run-time" in the browser. It just wasn't made for something more complex than it is.

So, you'll have to roll your own JS, which shouldn't be that hard though. All you need is:

  1. a Cake action that outputs a list of items based on the data it receives (shouldn't be hard)
  2. a bit of JS that figures out which brands and categories are selected (which you already have)
  3. another bit of JS that packages that data and sends it to the Cake action
  4. another bit of JS that updates the site with the list of items you received back

I'd take a look at jQuery's AJAX functions to accomplish #3. If you POST the data in a format like this, it's very easily accessible in $this->data in Cake:

{
    'data[ModelName][categories]' : categories,
    'data[ModelName][brands]'     : brands
}

Regarding your question:

"How do I pass the js vars into the php method?"

You don't. PHP runs on the server and is already finished by the time the Javascript runs in the browser. The only "communication" between JS and PHP is via standard HTTP GET and POST requests, and there it doesn't matter whether the request comes from a standard browser or JS or Flash or whatnot.

The $ajax helper just has a bunch of pre-fabricated Javascript snippets it can put into your page, but your JS will not be able to "talk to" the $ajax helper in any way.

deceze
Here is what I have so far: http://bin.cakephp.org/saved/55267. How can I exactly see how is the $this->data record? tried print_r and debug but got nothing :S. And second the php response im geting to my post is the full page, isnt that going to be bad to just update div #3? Btw thanks for your answer, this (JS -> PHP) was something I never had explained so well!
NoOne
Log stuff on the Cake site with `CakeLog::write('debug', $something)` (goes into `app/tmp/logs/`) and/or `console.log(something)` in Javascript, which you can see in Firefox using Firebug or Safari's or Chrome's Web Inspector's Javascript Console. To avoid the whole layout being rendered, you need to set `$this->layout = 'ajax'` in Cake.
deceze
If I use $this->layout ='ajax' then it won't render full page at first load, so I tried to create a function (menRefresh) only for the refresh of this page... but i get 404 @ firebug console with: jQuery.post("../items/menRefresh"). I think its because I don't have a view for that action (I'm really noob lol).
NoOne
Well yes, you'll either need to create a separate action (with view, or using `$this->render()`), or you need to switch the layout dynamically depending on whether it's an AJAX request or a normal one. I'd recommend you read a few tutorials to get the basics straight first. These look decent enough for the beginning: http://marcgrabanski.com/article/cakephp-ajax-quick-save-jquery http://bakery.cakephp.org/articles/view/serving-up-actions-as-ajax-with-jquery-in-a-few-simple-steps
deceze
I've got this last issued worked out and the result I get its only the content of the div I want... My last problem is that I'm not getting the arguments in the controller... i did CakeLog::write('debug', $this->data); and my test invocation is: jQuery.post("/store/items/refresh", { name: "John", time: "2pm" } ); but the debug prints nothing at the logs :S
NoOne
Then you should read the part of my answer that talks about the data format again. :)
deceze
Oh LOL, ya that was pretty simple... I just thought that all the data I send from ajax would be store at $this->data so I wasnt formating the params as you said... Working now... thks :D
NoOne
+1  A: 

I had a similar scenario to yours, and I found a few methods on the Javascript helper that are applicable. I used codeBlock() to wrap a chunk of javascript, and event() to wire up the click event, but I'm not sure how much clearer this is than just writing the raw Javascript.

I found the AJAX section of the CakePHP manual to be really helpful for getting the basic set up. Then I took the generated Javascript and made it more dynamic.

In this example, I'm calling the add_topic action whenever the user clicks the link. Every time it gets called, I increment the topicIndex variable and pass it as a parameter in the AJAX call. The AJAX call returns a few rows that are inserted in the table above the link that the user clicked.

        <tr id="add_topic_row"><td colspan="3">
            <a id="add_topic_link" href="javascript:void(0);">New Topic 
                <?php echo $html->image('icons/add32.png');?></a></td></tr>
        </table>
    </fieldset>
<?php 
    echo $form->end('Submit');
    $addTopicUrl = $html->url(array('action' => 'add_topic')) . '/';
    $script = <<<EOS
var topicIndex = $index;
var addTopicUrl = '$addTopicUrl';
addTopic = function()
{
    new Ajax.Updater(
        'add_topic_row', 
        addTopicUrl + topicIndex, 
        {
            asynchronous:true, 
            evalScripts:true, 
            insertion:Insertion.Before, 
            requestHeaders:['X-Update', 'add_topic']
        });
    topicIndex++; 
}
EOS;
    echo $javascript->codeBlock($script);
    echo $javascript->event('add_topic_link', 'click', 'addTopic();')
?>
Don Kirkby