Monday, September 27, 2010

JS helper

Hi,

I needed a simple Ajax feature to load box with additional info and
close it after reading. I am new to Ajax and seldom used JS scripts
till now. I need your opinion/help on optimizing following piece of
code. The JS helper documentation is terrible - I'll share my
experience on this at the end of this post for these interested.
Please advice on questions that follow the code.

1. I have 'ajaxInfoBox' element that is called with an ID of the
object I want to display. I have a need of few on the page hence
element - to keep unique div ids.
2. Element displays icons with arrows down (opens box when clicked)
and up (closes box when clicked). Additionally they hide/show
alternatively themselves. Also I have a hidden busy indicator on main
layout that is copied and displayed within the box while the box data
is being loaded.
3. The content of the box comes (Ajax request) from another
controller, which prepares set of data and renders it through
dedicated HTML view. To makes things simple (I am not efficient in JS)
I prefer using HTML views rather then JSON and JQuery loaded by
inclusions functions.

Here is the 'ajaxInfoBox' element code (bare functionality, no
exceptions):

echo '<div class="AjaxCommands">';
echo '<A href="#" id="OpenCommand'.$Id.'" alt="Info">'.$this->Html-
>image('icons/Colored/PNG/arrow_down.png').'</A>';
echo $this->Js->get('#OpenCommand'.$Id)->event('click',
$this->Js->request(array('controller' => 'Characters', 'action' =>
'displayCharacter', $Id), array (
'update' => '#InfoBox'.$Id,
'before' =>'$("#busy-indicator").clone().appendTo("#InfoBox'.
$Id.'").show();'
. '$("#InfoBox'.$Id.'").show();',
))
);
echo $this->Js->get('#OpenCommand'.$Id)->event('click', '$
("#OpenCommand'.$Id.'").hide();');
echo $this->Js->get('#OpenCommand'.$Id)->event('click', '$
("#CloseCommand'.$Id.'").show();');
echo '<A href="#" id="CloseCommand'.$Id.'" alt="Close"
style="display: none">'.$this->Html->image('icons/Colored/PNG/
arrow_top.png').'</A>';
echo $this->Js->get('#CloseCommand'.$Id)->event('click', '$
("#InfoBox'.$Id.'").empty();');
echo $this->Js->get('#CloseCommand'.$Id)->event('click', '$
("#CloseCommand'.$Id.'").hide();');
echo $this->Js->get('#CloseCommand'.$Id)->event('click', '$
("#InfoBox'.$Id.'").hide();');
echo $this->Js->get('#CloseCommand'.$Id)->event('click', '$
("#OpenCommand'.$Id.'").show();');

echo '</div>';
echo '<div class="InfoBox" id=InfoBox'.$Id.'></div>';

Few problems I faced with the above:
- I have not managed to deploy toggle() JQuery function through the JS
helper hence so many separate lines
- used many event JS helpers functions as concatenating actions after
one get() did not work as expected.
- did not use url attribute for HTML->img as id is tied to image not
the link therefore hiding id hides image but leaves a pixel of the
selected link
- not sure if copying and placing busy-indicator div into box and
replacing it with target content is a good idea

==
Now for interested, I will share how terrible experience CakePHP
serves its users with respect to JS Helper.

There is not so bad documentation on Ajax and Javascript but these
helpers are depreciated in 1.3. so I focused on JS Helper. I spent
over a week researching how to implement above Ajax info box using
this helper.

I started with JS Helper - this got me nowhere. Not a single simple
future (including Ajax Pagination) brought working examples
(Pagination tutorial fails to note that you need to include
RequestHandler helper for the Ajax layout to work properly). There are
no easily reachable (googled few hours) examples beside some advanced
troubleshooting discussions on this forum. Few 'know-hows' learned:
- simple ajax test for views:
echo '<Div>Text <A id="GoLink" href=#>Click</A></div>'.$this->Js-
>get('#GoLink')->event('click', 'alert("Works!")');
- one needs to use RequestHandler helper (overlooked in all JS helper
documentation) for Ajax layout to work properly
- if using other then default Ajax layout one needs to call 'echo $js-
>writeBuffer();' at the end of Ajax rendered view or Ajax custom
template
- any link created should have url or href=# - otherwise mouse pointer
will not detect this as a link (although it will work)

Above lessons helped me started but are bare working examples that
will not allow to do anything sensible without learning JQuery. Any
sensible feature needs to be implemented as a JQuery code embedded
into the cake-like JS helper code. Any more advanced JQuery code is a
hell to work with within short strings cake functions provide. Any
inclusions of additional files is fine if you want to start writing
extensive JQuery functions, but with somehow dilutes the strength of
CakePHP framework as a tool for weekend programmers. I am not into
inclusion of JS files and functions implemented there.

Check out the new CakePHP Questions site http://cakeqs.org and help others with their CakePHP related questions.

You received this message because you are subscribed to the Google Groups "CakePHP" group.
To post to this group, send email to cake-php@googlegroups.com
To unsubscribe from this group, send email to
cake-php+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/cake-php?hl=en

No comments: