jmultiselect2side

Hi there.

I have just uploaded an extension for using jmultiselect2side.

I was looking for a transfer select plugin and I guess this one is pretty good.

Regards,

Raul

can you tell me how to extract the selected values ??

Hi there.

I have updated the extension with version 1.1

The selected values are at ‘name’ property. In the example, Model[]

Regards.

Raul

Version 1.2 released.

The list parameter is not an array(array,array) anymore. It is just an array so you can mix this with models from DB.

Check the documentation for an example.

Raul

This is a nice start on something quite useful. I have a couple of questions/suggestions…

  1. The parent::init() is being called from within the run() method. Is there a reason that you have moved it there rather than within the overridden init() method?

  2. Have you considered loading the scripts a little differently?

IMO, you should consider moving the block that exports the script directly in the form to a CClientScript::POS_READY addition and use the default Yii::app()->clientScript->registerCoreScript(‘jquery’) rather than include jquery directly.

So:


	

protected function registerClientScript(){


  // add core jquery

  Yii::app()->clientScript->registerCoreScript('jquery');


  // Strike this and use the core jquery

  //$file=dirname(__FILE__).DIRECTORY_SEPARATOR.'jquery.js';


  $file2=dirname(__FILE__).DIRECTORY_SEPARATOR.'jquery.multiselect2side.js';


  $file3=dirname(__FILE__).DIRECTORY_SEPARATOR.'jquery.multiselect2side.css';


  // use core jquery

  //$jsFile=Yii::app()->getAssetManager()->publish($file);


  $jsFile2=Yii::app()->getAssetManager()->publish($file2);


  $cssFile=Yii::app()->getAssetManager()->publish($file3);


  $cs=Yii::app()->clientScript;


  // use core jquery

  //$cs->registerScriptFile($jsFile);


  $cs->registerScriptFile($jsFile2);


  $cs->registerCssFile($cssFile);


}



And the block that does the echo out, that would be …

Existing:




	echo "<script type=\"text/javascript\">\n";

		echo "\$().ready(function() {\n";

		echo "\$('#seleccion').multiselect2side({\n";

                if (isset($this->selectedPosition)){

                    echo "selectedPosition: '{$this->selectedPosition}',\n";

                }

                if (isset($this->moveOptions) && ! $this->moveOptions){

                    echo "moveOptions: false,\n";

                }

                if (isset($this->labelTop)){

                    echo "labelTop: '{$this->labelTop}',\n";

                }

                if (isset($this->labelBottom)){

                    echo "labelBottom: '{$this->labelBottom}',\n";

                }

                if (isset($this->labelUp)){

                    echo "labelUp: '{$this->labelUp}',\n";

                }

                if (isset($this->labelDown)){

                    echo "labelDown: '{$this->labelDown}',\n";

                }

                if (isset($this->labelSort)){

                    echo "labelSort: '{$this->labelSort}',\n";

                }

                if (isset($this->maxSelected)){

                    echo "maxSelected: {$this->maxSelected},\n";

                }

                if (isset($this->labelsx)){

                    echo "labelsx: '{$this->labelsx}',\n";

                }

                if (isset($this->labeldx)){

                    echo "labeldx: '{$this->labeldx}',\n";

                }

                if (isset($this->autoSort)){

                    echo "autoSort: '{$this->autoSort}',\n";

                }

                echo "});\n";

                echo "});\n";

                echo "</script>\n";



Revised:





$str = " $('#seleccion').multiselect2side({".PHP_EOL;


if (isset($this->selectedPosition)){

  $str.= "selectedPosition: '{$this->selectedPosition}',".PHP_EOL;

}

if (isset($this->moveOptions) && ! $this->moveOptions){

    $str.= "moveOptions: false,".PHP_EOL;

}

if (isset($this->labelTop)){

    $str.= "labelTop: '{$this->labelTop}',".PHP_EOL;

}

if (isset($this->labelBottom)){

    $str.= "labelBottom: '{$this->labelBottom}',".PHP_EOL;

}

if (isset($this->labelUp)){

    $str.= "labelUp: '{$this->labelUp}',".PHP_EOL;

}

if (isset($this->labelDown)){

    $str.= "labelDown: '{$this->labelDown}',".PHP_EOL;

}

if (isset($this->labelSort)){

    $str.= "labelSort: '{$this->labelSort}',".PHP_EOL;

}

if (isset($this->maxSelected)){

    $str.= "maxSelected: {$this->maxSelected},".PHP_EOL;

}

if (isset($this->labelsx)){

    $str.= "labelsx: '{$this->labelsx}',".PHP_EOL;

}

if (isset($this->labeldx)){

    $str.= "labeldx: '{$this->labeldx}',".PHP_EOL;

}

if (isset($this->autoSort)){

    $str.= "autoSort: '{$this->autoSort}',".PHP_EOL;

}


$str.= "});".PHP_EOL;


Yii::app()->clientScript->registerScript('seleccion', $str, CClientScript::POS_READY);




This way it will be in the same ready block placed at the end of the page with the other Yii client scripts rather than drawn out in the middle of the page.

  1. Refine it just slightly and enable multiple multi-select items on the same page by adding a static identifier to the widget and updating the ‘seleccion’ name and registerScript identifier to include the static ID as well.

  2. Allow to pass in ‘model’ and ‘attribute’ params (optionally) so that the name can be built automatically by the widget (if they are provided) as:




$this->name = get_class( $this->model )."[".$this->attribute."][]";



Hope that’s helpful =) Thanks for your work on this extension!

Attached is my proposed revision of the extension, including the enhancements listed above, and utilizing the CHtml::listBox and CHtml::activeListBox (if model is provided).

This revision allows for multiple instances of the multi-select form to be present on the same page and function independently.

Edit – hm file didn’t attach?

Here is the code:




<?php


class Jmultiselect2side extends CWidget{


    /**

     * Extension for jmultiselect2side

     * Options:

     * Parameters:

     * selectedPosition - position of selected elements - default 'right'

     * moveOptions - show move options - default true

     * labelTop - label of top buttom - default 'Top'

     * labelBottom - label of bottom buttom - default 'Bottom'

     * labelUp - label of up buttom - default 'Up'

     * labelDown - label of down buttom - default 'Down'

     * labelSort - label of sort buttom - default 'Sort'

     * maxSelected - number of max selectable options

     * labelsx: Left label - default '* Selected *'

     * labeldx: Right label - default '* Available *'

     * autoSort: Automatic sort of selected options - default true

     */


	/**

	 * position of selected elements - default 'right'

	 * @var string

	 */

	public $selectedPosition;


        /**

	 * show move options - default true

	 * @var boolean

	 */

	public $moveOptions;


        /**

	 * label of top buttom - default 'Top'

	 * @var string

	 */

	public $labelTop;


        /**

	 * label of bottom buttom - default 'Bottom'

	 * @var string

	 */

	public $labelBottom;


        /**

	 * label of up buttom - default 'Up'

	 * @var string

	 */

	public $labelUp;


        /**

	 * label of down buttom - default 'Down'

	 * @var string

	 */

	public $labelDown;


        /**

	 * label of sort buttom - default 'Sort'

	 * @var string

	 */

	public $labelSort;


        /**

	 * number of max selectable options

	 * @var int

	 */

	public $maxSelected;


        /**

	 * Left label - default '* Selected *'

	 * @var string

	 */

	public $labelsx;


        /**

	 * label of sort buttom - default 'Sort'

	 * @var string

	 */

	public $labeldx;


        /**

	 * Automatic sort of selected options - default true

	 * @var boolean

	 */

	public $autoSort;


        /**

	 * name for the selected select

	 * @var string

	 */

	public $name;


	/**

	 * data for generating the first list options .suport  (value=>display) and string.

	 * require

	 * @var array

	 */

	public $list;

	

	/**

	 * DHL - add unique count so that multiple instances can exist on one form

	 * @staticvar unique identifier 

	 */

	public static $idCount = 0;

	

	/**

	 * DHL - automatically format the name properly for the model and attribute

	 * @var CModel 

	 */

	public $model;

	

	/**

	 * DHL -automatically format the name properly for the model and attribute

	 * @var string The attribute of the model in question

	 */

	public $attribute;

	

	//***************************************************************************

	// register clientside widget files

	//***************************************************************************

	protected function registerClientScript(){

		$file2=dirname(__FILE__).DIRECTORY_SEPARATOR.'jquery.multiselect2side.js';

                $file3=dirname(__FILE__).DIRECTORY_SEPARATOR.'jquery.multiselect2side.css';

		$jsFile2=Yii::app()->getAssetManager()->publish($file2);

                $cssFile=Yii::app()->getAssetManager()->publish($file3);


		$cs=Yii::app()->clientScript;

		$cs->registerCoreScript('jquery');

		$cs->registerScriptFile($jsFile2);

                $cs->registerCssFile($cssFile);

	}


	//***************************************************************************

	// Initializes the widget

	//***************************************************************************

	public function init(){

		if(!isset($this->name)){

   		    if (!isset($this->model) && !isset($this->attribute))

			throw new CHttpException(500,'"name" have to be set!');

   		    else

			$this->name = get_class($this->model)."[".$this->attribute."][]";

		}

		if(!isset($this->list)){

  		  throw new CHttpException(500,'"list" have to be set!');

		}

		parent::init();

	}


	//***************************************************************************

	// Run the widget

	//***************************************************************************

	public function run(){

	    $id = "seleccion".self::$idCount++;

		

		if ( $this->model !== null )

		    echo CHtml::activeListBox($this->model, $this->attribute,

			  $this->list,

			  array('multiple'=>true, 'id'=>$id));

                else

                    echo CHtml::listBox($this->name, null, $this->list, array('multiple'=>true, 'id'=>$id));


        $this->registerClientScript();

        $str = " $('#{$id}').multiselect2side({".PHP_EOL;		


	if (isset($this->moveOptions) && ! $this->moveOptions){

	     $str.= "moveOptions: false,".PHP_EOL;

	}

       foreach(array('selectedPosition','labelTop','labelBottom','labelUp','labelDown','labelSort','maxSelected','labelsx','autoSort') as $p)

       {

	    if(isset($this->$p)) $str.="{$p}:'{$this->$p}',".PHP_EOL;

       } 


       $str.= "});".PHP_EOL;


		Yii::app()->clientScript->registerScript('multiselect'.$id, $str, CClientScript::POS_READY);

	}


	protected function renderContent(){

	}


}


?>



IMHO this could narrow your code:




                if (isset($this->selectedPosition)){

                    $str.= "selectedPosition: '{$this->selectedPosition}',".PHP_EOL;

                }

                if (isset($this->moveOptions) && ! $this->moveOptions){

                    $str.= "moveOptions: false,".PHP_EOL;

                }

                if (isset($this->labelTop)){

                    $str.= "labelTop: '{$this->labelTop}',".PHP_EOL;

                }

                if (isset($this->labelBottom)){

                    $str.= "labelBottom: '{$this->labelBottom}',".PHP_EOL;

                }

                if (isset($this->labelUp)){

                    $str.= "labelUp: '{$this->labelUp}',".PHP_EOL;

                }

                if (isset($this->labelDown)){

                    $str.= "labelDown: '{$this->labelDown}',".PHP_EOL;

                }

                if (isset($this->labelSort)){

                    $str.= "labelSort: '{$this->labelSort}',".PHP_EOL;

                }

                if (isset($this->maxSelected)){

                    $str.= "maxSelected: {$this->maxSelected},".PHP_EOL;

                }

                if (isset($this->labelsx)){

                    $str.= "labelsx: '{$this->labelsx}',".PHP_EOL;

                }

                if (isset($this->labeldx)){

                    $str.= "labeldx: '{$this->labeldx}',".PHP_EOL;

                }

                if (isset($this->autoSort)){

                    $str.= "autoSort: '{$this->autoSort}',".PHP_EOL;

                } 



I would change it to:




if (isset($this->moveOptions) && ! $this->moveOptions){

         $str.= "moveOptions: false,".PHP_EOL;

}

foreach(array('selectedPosition','labelTop','labelBottom','labelUp','labelDown','labelSort','maxSelected','labelsx','autoSort') as $p)

{

      if(isset($this->$p) $str.="{$p}:'{$this->$p}',".PHP_EOL;

 

 } 



-not tested :)

Love that! It works perfectly with the addition of the closing ) on the if statement. Updating above code to reflect the change.

Hi Dana. I was looking for transfer select extension and then I found the jmultiselect2side. I liked it and then I decided to make an extension for that. Like I’m starting to learn on Yii, I made my extension based on other extension I had downloaded before. So any improvement is really appreciated. I will include any suggestions/improvements you or anyone make. I’ll wait a couple of days in case any other suggestions and then I’ll update the version with the code you published on this post.

Thanks!

Raul

Hello people.

I need advice:

I want to update this extension with a new "search" parameter (just introduced by the jquery plugin).

It introduces 2 images inside the css file on this way:

jquery.multiselect2side.css file contains:

.ms2side__header a {

font-size: 10pt;


padding: 0 8px;


width: 20px;


color: black;


text-align: center;


text-decoration: none;


border: 1px solid grey;


[b]background: #FFFFFF url(&#46;&#46;/img/close.gif) no-repeat center center;[/b]


margin: 0 0 0 3px;

}

The fact is that the extension is under an asset directory when deployed so cannot find url(../img/close.gif)

Is there a way without changing the original css file to make accessible these images to the extension?

Any idea?

Thanks in advance

Raul

Hi ,

there’s no default value

why don’t you give public variable




/**

 * value selected

 * @var array

*/

public $selected;



and when you call listbox function like this


   echo CHtml::listBox($this->name, isset($this->selected) ? $this->selected : null, $this->list, array('multiple'=>true, 'id'=>$id));



Just advice thanks

Lateph

everything goes fine, but one thing not done

this estension is awesome, and powerfull , this ekstension make me dizzy for two day, how to use this ( extract the value, get selected from database )… last i didnt success is

i need to use findAllbyAttributes, if use findbyattributes there is just single row that show up… here my code





$models= Relatedproductsview::model()->findAllbyAttributes(array('products_id'=>'1') );  // complete user list to be shown at multiselect order by username $users= Products::model()->findAll(                  array('order' => 'id'));         	$this->widget('application.extensions.jmultiselect2side.Jmultiselect2side',array(                 	'name'=>'relatedproducts[]',                    'model'=>$models,                 	'attribute'=>'id', //selected items                 	'labelsx'=>'Available',                 	'labeldx'=>'Selected',                    'list'=>CHtml::listData(Products::model()->findAll(),'id', 'title') ,             	));

need help for show multiple row selected, asp… thx, if i use findallbyattributes it show error -> get_class() expects parameter 1 to be object, array given…

Hi Freddo,

I’m also getting the same error as you. Did you manage to get a solution. I didn’t find any related materials on the Internet.

Please find the Best solution here to save the selected values in jmultiselect2side widget

[html]http://www.yiiframework.com/forum/index.php/topic/54429-use-of-jmultiselect2side-widget-in-yii/ [/html]

Thanks

Srikanth