Yii Framework Forum: EchMultiSelect Widget - Yii Framework Forum

Jump to content

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • 4
  • You cannot start a new topic
  • You cannot reply to this topic

EchMultiSelect Widget Simple Wrapper Widget for the jQuery UI MultiSelect Widget by Eric Hyn Rate Topic: -----

#21 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 28 March 2012 - 06:27 PM

View Postwaitforit, on 28 March 2012 - 05:04 PM, said:

How do you show your preselected data in the list?

On my update action I want to show what related data I have already selected. But it shows '0 selected'.

I am using my relation name as the dropdownAttribute. I have tried HAS_MANY and MANY_MANY and I cant get it to preselect my list for me.


When you use the relation name as the dropDownAttribute, that is not enough to make the dropDownList know which elements should be preselected. That's because dropDownList needs an array of elements/values, not an array of objects.

If 'categories' is a relation in the model Post for example, then:
$model = Post::model()->findByPk($id);
$pcs = $model->categories; // This is an array of objects. Not a array of values.

returns an array of objects, which cannot be utilized by dropDownList.

You need to do something like this:
$model = Post::model()->findByPk($id);
$postCategories = PostCategories::model()->findAll(array('select'=>'category_id','condition'=>'post_id='.$id);
$categories = array();
foreach($postCategories as $pcs) {
   $categories[] = $pcs->category_id;
}
$model->categories = $categories;

After that, '$model->categories' is an array of ids/values, that dropDownList can utilize, and the values will be preselected.

Note that after clicking 'update' in the form, the newly selected values will not be automatically saved in the relation table PostCategories. You have to take care of it in your actionUpdate() method of your Post model.

I recommend this article: Handling Related Models in Yii Forms from Larry Ullman.
0

#22 User is offline   jcny 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 14
  • Joined: 23-September 11

Posted 28 March 2012 - 11:31 PM

View Postc@cba, on 28 March 2012 - 05:58 PM, said:

One possibility is the following:
you define a new attribute/variable in the model file, at the beggining, directly after the class starts:
class Car extends CActiveRecord {
   $colors = array();
   ...
}

The name of the variable should not be equal to a column name. Here, your model/table should not have a column named 'colors'. You then use this new attribute in the widget:
$this->widget('ext.widgets.EchMultiselect', array(
    'model' => $model,
    'dropDownAttribute' => 'colors',     
    'data' => $data,
});

In the controller file, you then have the array
$_POST['Cars']['colors']

that provides the id's of the clicked/selected colors for further use.

To handle the field_1,...,field_N columns:
You could build an array, like
$data = array('field_1',...,'field_N');

and use it as the data source in the widget above.
Then in the controller you can loop from 1 to N and check for each, if the correspondig box was selected and set the field_X accordingly. Something like:
if( in_array(X,$_POST['Cars']['colors']) ) $model->field_X = 1;
else $model->field_X = 0;


Otherwise, you would have to provide a separate checkbox for each of the field_X columns in your form. And to combine a set of checkboxes into a dropdown of checkboxes, I think we would need a different widget.

Best regards...


This worked perfectly, thanks so much!
0

#23 User is offline   jcny 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 14
  • Joined: 23-September 11

Posted 28 March 2012 - 11:49 PM

View Postc@cba, on 28 March 2012 - 06:27 PM, said:

When you use the relation name as the dropDownAttribute, that is not enough to make the dropDownList know which elements should be preselected. That's because dropDownList needs an array of elements/values, not an array of objects.

If 'categories' is a relation in the model Post for example, then:
$model = Post::model()->findByPk($id);
$pcs = $model->categories; // This is an array of objects. Not a array of values.

returns an array of objects, which cannot be utilized by dropDownList.

You need to do something like this:
$model = Post::model()->findByPk($id);
$postCategories = PostCategories::model()->findAll(array('select'=>'category_id','condition'=>'post_id='.$id);
$categories = array();
foreach($postCategories as $pcs) {
   $categories[] = $pcs->category_id;
}
$model->categories = $categories;

After that, '$model->categories' is an array of ids/values, that dropDownList can utilize, and the values will be preselected.

Note that after clicking 'update' in the form, the newly selected values will not be automatically saved in the relation table PostCategories. You have to take care of it in your actionUpdate() method of your Post model.

I recommend this article: Handling Related Models in Yii Forms from Larry Ullman.


This was actually my next question - what if I want to do it simpler (without relations)? I currently have in my model:

        public static $TypeArray
          = array(
                 1=>'TYPE1',
                 2=>'TYPE2',
                 3=>'TYPE3',
                 4=>'TYPE4',              
                 5=>'TYPE5',);


and my view file has
                $types = Model::$TypeArray;                                 
                $this->widget('ext.widgets.EchMultiselect', array(
                'model'=>$TypeModel,
                'dropDownAttribute'=>'type',  //I did as you said and created new array $type in controller    
                'data'=>$types, 


And my table has field_1, field_2, field_3, field_4, field_5, each which gets set to 0 or 1 depending on whether they get checked (working thanks to your code suggestion!).

So how do I get it to now show the already checked values after POST? Thanks so much.
0

#24 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 29 March 2012 - 04:31 AM

View Postjcny, on 28 March 2012 - 11:49 PM, said:

This was actually my next question - what if I want to do it simpler (without relations)? I currently have in my model:

        public static $TypeArray
          = array(
                 1=>'TYPE1',
                 2=>'TYPE2',
                 3=>'TYPE3',
                 4=>'TYPE4',              
                 5=>'TYPE5',);


and my view file has
                $types = Model::$TypeArray;                                 
                $this->widget('ext.widgets.EchMultiselect', array(
                'model'=>$TypeModel,
                'dropDownAttribute'=>'type',  //I did as you said and created new array $type in controller    
                'data'=>$types, 


And my table has field_1, field_2, field_3, field_4, field_5, each which gets set to 0 or 1 depending on whether they get checked (working thanks to your code suggestion!).

So how do I get it to now show the already checked values after POST? Thanks so much.


Hi jcny, glad it worked so far...

Now, in the actionUpdate() method of your controller, you could do something like this:
$TypeModel = TypeModel::model()->findByPk($id);
for($i=1;$i<=N;$i++) {
    if($TypeModel->field_$i == 1) $TypeModel->type[$i] = 1;
    else $TypeModel->type[$i] = 0;
}

This way, you fill the new variable/array type of your model according to the values in your table, before your render the form.

Since the widget in your view file has type as its dropDownAttribute, and type is an array with values, the widget will/can use these values to preselect the options.

Best regards...
0

#25 User is offline   jcny 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 14
  • Joined: 23-September 11

Posted 29 March 2012 - 10:45 AM

View Postc@cba, on 29 March 2012 - 04:31 AM, said:

Hi jcny, glad it worked so far...

Now, in the actionUpdate() method of your controller, you could do something like this:
$TypeModel = TypeModel::model()->findByPk($id);
for($i=1;$i<=N;$i++) {
    if($TypeModel->field_$i == 1) $TypeModel->type[$i] = 1;
    else $TypeModel->type[$i] = 0;
}

This way, you fill the new variable/array type of your model according to the values in your table, before your render the form.

Since the widget in your view file has type as its dropDownAttribute, and type is an array with values, the widget will/can use these values to preselect the options.

Best regards...

This makes sense - I am running into an error though with $TypeModel->field_$i - my editor is saying that doesn't work (the field_$i). I tried it with field_.$i but that doesn't work either. Any thoughts?
0

#26 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 29 March 2012 - 11:36 AM

View Postjcny, on 29 March 2012 - 10:45 AM, said:

This makes sense - I am running into an error though with $TypeModel->field_$i - my editor is saying that doesn't work (the field_$i). I tried it with field_.$i but that doesn't work either. Any thoughts?



sorry, I was fast-typing some kind of pseudocode.
The following works (this time I tested):

// To get the value of the model-attribute
$fieldname = 'field_'.$i;
$type[$i] = $TypeModel->attributes[$fieldname];

// And if you want to set the value of the model-attribute at some point:
$TypeModel->setAttribute($fieldname, $tpye[$i]);

0

#27 User is offline   jcny 

  • Newbie
  • Yii
  • Group: Members
  • Posts: 14
  • Joined: 23-September 11

Posted 29 March 2012 - 12:44 PM

View Postc@cba, on 29 March 2012 - 11:36 AM, said:

sorry, I was fast-typing some kind of pseudocode.
The following works (this time I tested):

// To get the value of the model-attribute
$fieldname = 'field_'.$i;
$type[$i] = $TypeModel->attributes[$fieldname];

// And if you want to set the value of the model-attribute at some point:
$TypeModel->setAttribute($fieldname, $tpye[$i]);



Great, this worked perfect. I ended up using something like this:
for($i=1;$i<=5; $i++) {
$fieldName = 'field_'.$i;    
if ($TypeModel->$fieldName == 1) //check model for 1 or 0                           
 $TypeModel->type[$i] = $i;  //using $i instead of 1 since we need checkbox value, but model only stores 0 or 1 
    else $TypeModel->type[$i] = 0;


Again, really appreciate your help and instruction!
0

#28 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 29 March 2012 - 01:02 PM

View Postjcny, on 29 March 2012 - 12:44 PM, said:

Great, this worked perfect. I ended up using something like this:
for($i=1;$i<=5; $i++) {
$fieldName = 'field_'.$i;    
if ($TypeModel->$fieldName == 1) //check model for 1 or 0                           
 $TypeModel->type[$i] = $i;  //using $i instead of 1 since we need checkbox value, but model only stores 0 or 1 
    else $TypeModel->type[$i] = 0;


Again, really appreciate your help and instruction!


I'm glad if I could help.

When I think about it, the '0' values are probably not needed.
So the following should also work:
if ($TypeModel->$fieldName == 1) $TypeModel->type[] = $i;  //just add the index that should be checked into the array $type
// else do nothing.


Doesn't make much difference if there are not so many fields. But for optimization freaks like me, it's the principle that counts :)
0

#29 User is offline   Denis Roussel 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 28-October 11

Posted 24 May 2012 - 10:48 AM

Hi,


A great extension!

I tested it but I can't get the options take the whole width of the widget. They are left-aligned (about on the 100 first px I think) even if I increase the width of the widget.

Do you have a solution for me?

Many Thanks
0

#30 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 28 May 2012 - 05:58 AM

View PostDenis Roussel, on 24 May 2012 - 10:48 AM, said:

Hi,


A great extension!

I tested it but I can't get the options take the whole width of the widget. They are left-aligned (about on the 100 first px I think) even if I increase the width of the widget.

Do you have a solution for me?

Many Thanks


Hi Denis,

I use the extension like the following, and the width of the options-box is the same as the widget (drop-down-button) itself:
$this->widget('ext.widgets.EchMultiselect', array(
	'model'=>$model,
	'data' => $idata,
	'dropDownAttribute' => 'itypes',
	'dropDownHtmlOptions'=> array(
		//'class'=>'span-10',
		'style'=>'width:450px',
	),
	'options' => array( 
		'selectedList'=>5,
		'multiselect'=>true,
		'header'=>true,
		'filter'=>true,
	),
)); ?>


It works both when I specify the 'style' in the 'dropDownHtmlOptions', or the 'class'.
Can you try this code and see if it works for you?

If not, can you post your code; or the URL of the site, if it is online?

Best regards...
0

#31 User is offline   Denis Roussel 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 28-October 11

Posted 29 May 2012 - 04:02 AM

View Postc@cba, on 28 May 2012 - 05:58 AM, said:

Hi Denis,

I use the extension like the following, and the width of the options-box is the same as the widget (drop-down-button) itself:
$this->widget('ext.widgets.EchMultiselect', array(
	'model'=>$model,
	'data' => $idata,
	'dropDownAttribute' => 'itypes',
	'dropDownHtmlOptions'=> array(
		//'class'=>'span-10',
		'style'=>'width:450px',
	),
	'options' => array( 
		'selectedList'=>5,
		'multiselect'=>true,
		'header'=>true,
		'filter'=>true,
	),
)); ?>


It works both when I specify the 'style' in the 'dropDownHtmlOptions', or the 'class'.
Can you try this code and see if it works for you?

If not, can you post your code; or the URL of the site, if it is online?

Best regards...



Hi c@cba,

I tried your code but it does not work.

Here is an example of the result and my code :

$this->widget('ext.widgets.EchMultiselect', array(
	        'name'=>'test',
	        'data' => array('Test1','Test2'),
	        
	        'dropDownHtmlOptions'=> array(
	'class'=>'span-10',
	                //'style'=>'width:450px',
	),
	        'options' => array( 
	                'selectedList'=>5,
	                'multiselect'=>true,
	                'header'=>true,
	                'filter'=>true,
	),
	));

0

#32 User is offline   Denis Roussel 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 28-October 11

Posted 29 May 2012 - 04:03 AM

Here is the file Attached File  test_echmultiselect.png (4.54K)
Number of downloads: 29
0

#33 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 29 May 2012 - 09:10 AM

View PostDenis Roussel, on 29 May 2012 - 04:03 AM, said:

Here is the file Attachment test_echmultiselect.png


I assume that the same problem exists when you define the width via 'width:450px' instead of span-10?

It seems to me, that there are other style-declarations (like width, or float:right etc.) that affect the checkboxes and make them appear that way...

Do you use Firebug (the add-on for firefox)?
With firebug you could determine what styles exactly are applied to the checkboxes.

Sometime css-styles do behave unexpectedly and if there are more than one css-file, something overrides the other and there is no way to know what happpens without some tool like firebug...

Best regards...
0

#34 User is offline   Denis Roussel 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 28-October 11

Posted 29 May 2012 - 09:41 AM

View Postc@cba, on 29 May 2012 - 09:10 AM, said:

I assume that the same problem exists when you define the width via 'width:450px' instead of span-10?

It seems to me, that there are other style-declarations (like width, or float:right etc.) that affect the checkboxes and make them appear that way...

Do you use Firebug (the add-on for firefox)?
With firebug you could determine what styles exactly are applied to the checkboxes.

Sometime css-styles do behave unexpectedly and if there are more than one css-file, something overrides the other and there is no way to know what happpens without some tool like firebug...

Best regards...



I've juste tested this and it appears that the 'ui-corner-all' style is applied to the label tag. Is that correct?
0

#35 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 29 May 2012 - 10:42 AM

View PostDenis Roussel, on 29 May 2012 - 09:41 AM, said:

I've juste tested this and it appears that the 'ui-corner-all' style is applied to the label tag. Is that correct?


Yes, the labels have the class 'ci-corner-all', that only has the effect of rounding the corners of the label (the gray area).

the <ul> element has the class 'ui-multiselect-checkboxes', so it looks like this:
<ul class="ui-multiselect-checkboxes">
  <li>
    <label class="ui-corner-all"> ... </label>
  </li>
</ul>


It is really difficult to say something without seeing the code, but I have the suspicion that somewhere in your css files there is a style declaration for the 'label' element that sets a fixed width for it and makes the text within right aligend, i.e. something like this:

label {
   width:100px;
   text-align:right;
}


This is often done to style form elements, where a label is followed by a text-field for example, to produce forms like here: http://jeffhowden.com/code/css/forms/

Note that the labels are right aligned and how they are styled further below:
form div label {
  display: block;
  float: left;
  width: 130px;
  padding: 3px 5px;
  margin: 0 0 5px 0;
  text-align: right;
}


More than likely something like this is happening in your case...

Best regards...
0

#36 User is offline   Denis Roussel 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 28-October 11

Posted 30 May 2012 - 05:33 AM

View Postc@cba, on 29 May 2012 - 10:42 AM, said:

Yes, the labels have the class 'ci-corner-all', that only has the effect of rounding the corners of the label (the gray area).

the <ul> element has the class 'ui-multiselect-checkboxes', so it looks like this:
<ul class="ui-multiselect-checkboxes">
  <li>
    <label class="ui-corner-all"> ... </label>
  </li>
</ul>


It is really difficult to say something without seeing the code, but I have the suspicion that somewhere in your css files there is a style declaration for the 'label' element that sets a fixed width for it and makes the text within right aligend, i.e. something like this:

label {
   width:100px;
   text-align:right;
}


This is often done to style form elements, where a label is followed by a text-field for example, to produce forms like here: http://jeffhowden.com/code/css/forms/

Note that the labels are right aligned and how they are styled further below:
form div label {
  display: block;
  float: left;
  width: 130px;
  padding: 3px 5px;
  margin: 0 0 5px 0;
  text-align: right;
}


More than likely something like this is happening in your case...

Best regards...



I found the problem.

I think there is a conflict with the Bootstrap extension (it overwrite indeed the label tag).

I'm not an expert in css, do you have a workaround for me?

Many thanks
0

#37 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 30 May 2012 - 06:04 AM

View PostDenis Roussel, on 30 May 2012 - 05:33 AM, said:

I found the problem.

I think there is a conflict with the Bootstrap extension (it overwrite indeed the label tag).

I'm not an expert in css, do you have a workaround for me?

Many thanks


In the assets folder of the extension, there is the file "jquery.multiselect.css"

Add the following code into that file should work:
.ui-multiselect-checkboxes label  { width:auto !important; text-align:left !important; }


Best regards...
0

#38 User is offline   Denis Roussel 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 28-October 11

Posted 30 May 2012 - 06:13 AM

View Postc@cba, on 30 May 2012 - 06:04 AM, said:

In the assets folder of the extension, there is the file "jquery.multiselect.css"

Add the following code into that file should work:
.ui-multiselect-checkboxes label  { width:auto !important; text-align:left !important; }


Best regards...


Ok, works like a charm. I change the width:auto (the cornered box width takes just the label characters length) to 98% (the scroll bar hides the end)
0

#39 User is offline   Denis Roussel 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 36
  • Joined: 28-October 11

Posted 30 May 2012 - 06:18 AM

Hi,

I want to tune the component to fit my needs.

I want to display it like a multiple checkbox list but without the user to click on the scroller => always display the entire list (and abusing : is it possible in that case that the checkboxes take the entire height before the next component? - css? my weakness)

Is it possible?
0

#40 User is offline   c@cba 

  • Junior Member
  • Pip
  • Yii
  • Group: Members
  • Posts: 43
  • Joined: 02-December 11

Posted 30 May 2012 - 06:54 AM

View PostDenis Roussel, on 30 May 2012 - 06:18 AM, said:

Hi,

I want to tune the component to fit my needs.

I want to display it like a multiple checkbox list but without the user to click on the scroller => always display the entire list (and abusing : is it possible in that case that the checkboxes take the entire height before the next component? - css? my weakness)

Is it possible?


So you don't want a "drop-down-checkbox-list"?
You want a list of checkboxes that are always visible?

EchMultiSelect is a JQuery widget, there is a lot of javascript-code behind its behavior ((dis)appearing of the boxes etc.).
It will not be easy to make it behave like you want it to, it is not just a matter of css.

So if you don't need/want a drop-down element, I would recommend for example the CheckBoxList of Yii:
http://www.yiiframew...kBoxList-detail

Best regards...
0

Share this topic:


  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • 4
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users