RSS
 

Posts Tagged ‘jquery’

CakePHP, draggable/droppable in jQuery

27 Mar

Working on bunch of CRUD routines in CakePHP, I finally got tired of multiple checkboxes and decided to write a small helper for jQuery UI drag-n-drop functionality.

In response to Teknoid post, I’ve made couple of additional tweaks to dynamic select boxes, and got quite nice combination of selectboxes and dynamic lists.

The main requirement of the script was:

  1. On Selectbox value changed, return the list of related items (in #base-list div-element)
  2. Add drag/drop functionality to the base-list ul elements as well as add arrow-west/arrow-east addition/deletion of the elements
  3. After all the movements are over, to be able to save dragged values in CakePHP form to be saved.
  4. Result: here.
  5. Sample MySQL DB file: Here

The view/helpers/droppable.php looks like:

 tag
    */
    function droppableElements($outside = false) {
        $js_code = "";
 
        $js_code = '
                    var $baseDiv = $(\'#base-list\');
                    var $targetDiv = $(\'#target-list\');
 
                    $(\'li\', \'#baseUl\' ).draggable({
                        accept: \'#baseUl > li\',
                        revert: \'invalid\',
                        helper: \'clone\',
                        cursor: \'move\'
                    }); 
 
                    $(\'li\', \'#targetUl\' ).draggable({
                        accept: \'#targetUl > li\',
                        revert: \'invalid\',
                        helper: \'clone\',
                        cursor: \'move\'
                    }); 
 
                    $targetDiv.droppable({
                        accept: \'#baseUl > li\',
                        activeClass: \'ui-state-highlight\',
                        drop: function(ev, ui) {
                            moveItem(ui.draggable, $targetDiv);
                        }
                    });
 
                    $baseDiv.droppable({
                        accept: \'#targetUl > li\',
                        activeClass: \'ui-state-highlight\',
                        drop: function(ev,ui) {
                            moveItem(ui.draggable, $baseDiv);
                        }
                    });
 
                    $(\'#baseUl > li\').click(function(ev){
                        moveItemClicked($(this), $(this).parent());
                    });
 
                    $(\'#targetUl > li\').click(function(ev){
                        moveItemClicked($(this), $(this).parent());
                    });';
 
            if($outside) {
                $this->out .= $this->Javascript->codeBlock($js_code);
                return $this->out;
            } else {
                return $js_code;
            }
 
    }
 
    /*
    *   @var string $boxId - observed selectBox id element
    *   @var string $eventType - default 'change'
    *   @var string $jsonAction - method call, i.e '/departments/ajax_get_list/departments/company_id/'
    */
 
    function observeSelectBox($boxId, $eventType = 'change', $jsonAction) {
        $js_script = "";
 
        $js_script ='
          $(\'#'.$boxId.'\').live(\''.$eventType.'\', function(){
            if($(this).val().length != 0) {
            $.getJSON(\''.$jsonAction.'\',
                {searchParam: $(this).val() }, 
 
                function(items) {
                    $(\'.jq_list\').remove();
                    generateBaseList(items);
 
                '.$this->droppableElements().'
                }
            );
        }
        } );';
 
        $this->out .= $this->Javascript->codeBlock($js_script);
 
        return $this->out;
    }
 
}?>

For using so-called ajax_get_list method, I’ve written a small function in app/app_controller.php that get all the id,name list array based on couple of arguments:

In order to use this method, you should have a small layout in related views folder, that looks like:

<?php
    // somewhere in views/departments/ajax_get_list.ctp
   if(isset($items)) {
        echo $javascript->object($items);
 }?>

The view of ajax_get_list method will output serialized array of the method. For the initial view, you need to add 2 div-elements and one select box. Div elements have static id’s which are used by jQuery script to look-up (base-list, and target-list).
In our view, it should look like:

<?php  echo $droppable->observeSelectBox('company-id','change','/departments/ajax_get_list/departments/company_id/');?>
 
        <label> Load company departments: </label>
        <?php print $form->select('Company.id', $companies, null, array('id'=>'company-id'), 'Company Departments);?>
 
        <?php print $html->div('right block', $html->div('target-title', 'Container', array(), false),array('id'=>'target-list'),false);?> 
 
        <?php print $html->div(null,null, array('id'=>'base-list'));
?>

And that’s about it, once you finish dragging the li-elements to the target-list, and save the form, its values will appear in ['Container']['item_ids'] array where you can do whatever you want with it.
To make things simple, you can download a small sample of code of these files here, as well as database sample file.

 

CakePHP: jQuery styling of flash messages

30 Jan

CakePHP session flash messages is one of the most useful things for usability, and user notification. Trying to make it more fancy, I came to jQuery framework with its HighlightFade plugin.

Adding just a couple of lines, we can get nice effects, looking the same as WordPress messages in Posting/Editing:

      var $j = jQuery.noConflict(); //I'm using Prototype as well, so we don't need conflicts
$j(document).ready(function() {
       if( $j("#flashMessage") ){ 
          $j("#flashMessage").highlightFade({color:'#24F273',speed:2000, iterator:'exponential'});
       }
});

Thus, next time you will pass $this->Session->setFlash('Foo');, your flash message with default

<div id="flashMessage"><?php $session->flash();?></div>

will be used with above HighLight effect.