The Relation widget is used in forms, where the User can choose between a selection of related elements.
It automatically renders a Selectbox or Listbox. Every Type of Relation is supported (even MANY_MANY since 0.8).
Resources ¶
Documentation ¶
The Relation widget is used in forms, where the User can choose between a selection of model elements, that this models belongs to.
Since version 0.8 it is able to handle BELONGS_TO, HAS_ONE and MANY_MANY Relations. The Relation type is detected automatically from the Model 'relations()' section.
The following example shows how to use Relation with a minimal config, assuming we have a Model "Post" and "User", where one User belongs to a Post:
$this->widget('application.components.Relation', array(
'model' => 'Post',
'relation' => 'user'
'fields' => 'username' // show the field "username" of the parent element
));
Results in a selectbox in which the user can choose between all available Users in the Database. The shown field of the Table "User" is "username" in this example.
You can choose the Style of your Widget in the 'style' option. Note that a Many_Many Relation always gets rendered as a Listbox, since you can select multiple Elements.
'fields' can be an array or an string. If you pass an array to 'fields', the Widget will display every field in this array. If you want to show further sub-relations, separate the values with '.', for example: 'fields' => 'array('parent.grandparent.description')
Optional Parameters:
You can use 'field' => 'post_userid' if the field in the model that represents the foreign model is called different than in the relation
Use 'foreignField' => 'id_of_user' if the primary Key of the Foreign Model differs from the one given in the relation.
Normally you shouldn´t use this fields cause the Widget get the relations automatically from the relation.
Use 'allowEmpty' to let the user be able to choose no parent. The string assigned to 'emptyString' will be displayed.
With 'hideAddButton' => 'true' you can hide the 'create new Foreignkey' Button generated beside the Selectbox.
Define the AddButtonString with 'addButtonString' => 'Add...'. This string is set default to '+'
When using the '+' button you most likely want to return to where you came. To accomplish this, we pass a 'returnTo' parameter by $_GET. The Controller can send the user back to where he came from this way:
if($model->save())
if(isset($_GET['returnTo']))
$this->redirect(array(urldecode($_GET['returnTo'])));
Using the 'style' option we can configure if we want our widget to be rendered as a 'Selectbox' (default) or a 'ListBox'.
Use the option 'createAction' if the action to add additional foreign Model options differs from 'create'.
With 'parentObjects' you can limit the Parent Elements that are being shown. It takes an array of elements that could be returned from an scope or an SQL Query.
The parentObjects can be grouped, for example, with 'groupParentBy' => 'city'
Use the option 'htmlOptions' to pass any html Options to the Selectbox/Listbox form element.
hint: ManyMany Records can easily be saved by using the CAdvancedArBehavior Behavior.
Full Example:
$this->widget('application.components.Relation', array(
'model' => 'Post',
'field' => 'Userid',
'style' => 'ListBox',
'parentObjects' => Parentmodel::model()->findAll('userid = 17'),
'groupParentsBy' => 'city',
'relation' => 'user',
'foreignField' => 'id_of_user',
'fields' => array( 'username', 'username.group.groupid' ),
'delimiter' => ' -> ', // default: ' | '
'returnTo' => 'model/create',
'createAction' => 'add', // default: 'create'
'addButtonString' => 'click here to add a new User', // default: ''
'htmlOptions' => array('style' => 'width: 100px;')
));
Change Log ¶
February, 21, 2010 ¶
- Version 0.9
- Better Name generation for MANY_MANY Field
February, 21, 2010 ¶
- Version 0.8
- Fixed Bug: get_class($this->foreignModel) instead of tableschema->className
- Added support for MANY_MANY Relations which gets rendered in a multiple-selectable ListBox
February, 07, 2010 ¶
- Version 0.7
- added parentGroupBy and parentObjects
February, 02, 2010 ¶
- Version 0.6
- minor bugfix (get_class instead tableSchema->name)
- added allowEmpty
- added emptyString
January 25, 2010 ¶
- Uploaded Version 0.4
- added getModelData() function for translating . to ->
January 25, 2010 ¶
- Uploaded Version 0.3.
- Bugfixes
- htmlOptions
- 'fields' (array or string)
- 'style' (Listbox or Selectbox)
- further Enhancements
January 21, 2010 ¶
- Uploaded Version 0.2.
- Bugfixes and now support 'returnTo' link (see Documentation)
January 19, 2010 ¶
- Initial release.
relation still active
it is interesting that people still find and use the relation widget.
there is a much-newer version available here:
http://code.google.com/p/gii-template-collection/source/browse/trunk/gtc/components/Relation.php
maybe i find the time and package this some time
Using with Many Many and tables with PK other than 'id'
Hi,
thank for the great widget
I have encountered a problem with a relation to a Model which table has a PK which is not 'id'.
I have changed line 405 :
to
$objects[$relobj->{$relobj->getMetadata()->tableSchema->primaryKey}] = $relobj;
It seems to do the trick, would the author comment on this ?
Thanks
great extension
would be nice to see the documentation of this updated - i only found the bug mentioned by #1383 after some own research (:
but the code is very clear and so that was ok
another bug: the "add new" button assumes the controller sounds the same as the relation-table.. would be nice to have this configurable
@#1545 if you want your selected data displayed then set 'model'=>$model this feature isn't documented (:
and here my code which i use to save my many_many relation.. perhaps this can be done easier
<code<?php
//before save():
if(isset($_POST['Entrytype']))
{ $model->attributes=$_POST['Entrytype']; $model->categories = $this->getListOfManyMany('Category');
$model->save()
}
public function getListOfManyMany($otherClass) { $thisClass = 'Entrytype'; $i = 0; $arr = array(); while(true) { $i++; $str = 'rel-'.$i.'-'.$thisClass; if (isset($_POST[$str][$otherClass])) { $val = $_POST[$str][$otherClass]; if (!empty($val)) $arr[] = $val; } else break; } return $arr; }
sorry for the bad code intendention :s
and perhaps someone has a better idea to do this - would be nice to see one here
Saves some time
This in conjunction with the CAdvancedarbehavior extension definitely saves some time.
Would like to see both of them extended further and added to the trunk.
My only issue currently is that I can't get it to use the saved data to display what has been previously selected on update.
Like the concept
helps to simplify using many-many on display. great features such as returnTo. Overall like where this extension is headed. It will be a time saver as it improves.
minor issues:
in documentation returnTo option is actually returnLink and creates a returnTo parameter for _GET
in documentation addButtonString does not exist: showAddButton contains the text to display or false to not display
data is not showing as selected in my listbox.
PK name problem.
Hi!
You have a little bug at line 303
It takes “id” as model's PK
if(!$this->_model->$id) return array();
and this code fails if schema has different PK name.
I made a little fix:
$id = $this->_model->tableSchema->primaryKey; if(!$this->_model->$id) return array();
Now it works.
Listbox selected issue
Thanks for this extension but it may help someone
School Model
'owners' => array(self::MANY_MANY, 'User', 'tbl_users_schools(school_id,user_id)')
So listbox will not set already assigned object as selected until I add space between fields in many to many table definition
So it works right this way
'owners' => array(self::MANY_MANY, 'User', 'tbl_users_schools(school_id, user_id)')
Outdated doc about foreignKey
It's now called relatedPk but the author did not update the page, only the code.
MANY to MANY question
Hi, I'm testing this widget, And I found that the list box doesn't show all the values spected.
I have the typical many-to-many relation, from table_a, Table_b, Table_rel_ab.
I'm updating or creating a record in table_a, and the listo box of the relation is empty.
If I add a record on table_reb_ab, I start seeing data.
Any suggest?
Best regards
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.