Schneimi’s Dev Weblog


Update multiple fields with one ajax request response

Posted in Ajax,CakePHP by schneimi on October 27, 2007
Tags: , , ,

I searched for a possibility to update multiple fields with each ajax request made by a remoteTimer, but didn’t find any satisfying explanation on the web. To get that right, each field should get updated with the same response of a request.

So I had a look closer into the ajax helper and the prototype framework and came up with a little hack that suffice my needs and might be also helpful for others.

In the ajax helper (cake/libs/helpers/ajax.php) we first have to look into what happens when the options[update] parameter is set to an array with the different fields we want to update. That leads us to the ‘remoteFunction’ where following happens in that case:

$func = "new Ajax.Updater(document.createElement('div'),";

I have no clue what the creation of the div is really good for, but anyway we have to replace it with a JavaScript array holding the id’s of our fields:

$update = '[';

foreach($options['update'] as $option) {
  $update .= "'" . $option . "',";
}            

$update .= ']';                

$func = "new Ajax.Updater({$update},";

Now we must have a look into the prototype framework (app/webroot/js/prototype.js) and make sure the function Ajax.Updater can handle that array. The important function there is called updateContent:

Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {

  [...]

  updateContent: function() {

    [...]

    if (receiver = $(receiver)) {
      if (this.options.insertion)
        new this.options.insertion(receiver, response);
      else
        receiver.update(response);
    }

    [...]
  }
});

Because the receiver is now our array, we must step through it and send a response to each of it:

Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {

  [...]

  updateContent: function() {

    [...]

    if (receiver.constructor.toString().indexOf("Array") != -1) {
      for(var i = 0; i < receiver.length; i++) {
        if(r = $(receiver&#91;i&#93;)) {
      if (this.options.insertion)
        new this.options.insertion(r, response);
      else
        r.update(response);
    }
      }
    } else {
      if (receiver = $(receiver)) {
        if (this.options.insertion)
          new this.options.insertion(receiver, response);
        else
          receiver.update(response);
      }
    }

    &#91;...&#93;
  }
});&#91;/sourcecode&#93;
After checking if the receiver is actually an array, we step through it and send the response to every our fields.

Finished!

You can now use it like:
&#91;sourcecode language="php"&#93;
<?php echo $ajax->remoteTimer(array('url' => 'controller/action', 'update' => array('field1', 'field2', 'field3'), 'frequency' => '5')); ?>

Sortable table rows with ajax helper

Posted in Ajax,CakePHP by schneimi on October 25, 2007
Tags: , ,

Most examples for drag&drop sorting with the ajax helper use lists (<ul>, <ol>) to demonstrate, but if you have several columns each row, you really would like to use a table and drag&drop it’s rows.

There is a solution mentioned at script.aculo.us, where you just have to use the HTML 4.0 specified table looking like:

<table>
  <thead><tr><td></td></tr></thead>
  <tfoot><tr><td></td></tr></tfoot>
  <tbody><tr><td></td></tr></tbody>
</table>

Now you can use the tbody as parent in the ajax sortable function and set the ‘tag’-option to ‘tr’.Here is a small example in cakePHP:

<table>
  <thead>
 <tr><th>Sortable Table</th></tr>
  </thead>
  <tbody id="sortable_table">
 <tr><td>row 1</td></tr>
 <tr><td>row 2</td></tr>
 <tr><td>row 3</td></tr>
  </tbody>
</table>

<?php echo $ajax->sortable('sortable_table', array('tag' => 'tr')); ?>

Because the table rows are not set to float, you don’t see any moving effect while dragging a row. I found no way to make it float without the table beeing messed up.

Eclipse Code Completion for cakePHP

Posted in CakePHP,Eclipse by schneimi on October 12, 2007
Tags: , , , , , ,

Code Completion in Controllers
Add this to your app_controller.php for every Component and Model you want to have completed by eclipse:

/**
 * @var CookieComponent
 */
var $Cookie;
.
.
.
/**
 * @var Yourmodel
 */
var $Yourmodel;
.
.
.

Eclipse will use the PHPdoc for code completion.

Code Completion in Views
Add this to an extra file e.g. eclipse_cc.php:

$html = new HtmlHelper();
$javascript = new JavascriptHelper();
.
.
.

There is no need to include this file, just put it in your app folder and it will fool eclipse.

Init Weblog

Posted in CakePHP by schneimi on October 12, 2007

Because I recently started to bake a Website with cakePHP, I now want to write down my experiences with that very cool piece of Framework during the further development.