This is not very useful for me. I know how to do html markup, and how to receive and process data from forms, this question is about CActiveForm::dropDownList
$form->dropDownList() automatically selects the attribute value from your model. So first check wether the ‘location’ attribute in your model has the correct value. If not, make sure you’ve declared it as a “safe attribute”. If the value is o.k. make sure, that your data list ($locations) really has a key with this value.
<?php
/**
* Form used for User profile edit
*/
class ProfileForm extends CFormModel
{
public $username;
public $email;
public $location;
public $infoText;
public function rules() {
return array();
}
public function attributeLabels() {
return array(
'username' => 'Korisničko ime',
'email' => 'Email adresa',
'location' => 'Lokacija',
'infoText' => 'Kratki info',
);
}
}
It’s very simple, and with just few fields.
This is controller that gathers data, and renders view:
<?php
class ProfileController extends Controller
{
public function actionIndex() {
$data['user'] = Users::model()->find("username='" . Yii::app()->user->id . "'");
$data['model'] = new ProfileForm();
//priprema podataka za listu lokacija
$criteria = new CDbCriteria;
$criteria->order = 'name ASC';
$locations = Locations::model()->findAll($criteria);
$data['locations'] = CHtml::listData($locations, 'id', 'name');
$this->render('index', $data);
}
public function actionUpdate() {
if (isset($_POST['ProfileForm'])) {
$user = Users::model()->find("username='".Yii::app()->user->id."'");
$user->attributes = $_POST['ProfileForm'];
if ($user->validate()) {
$user->save();
$this->redirect($this->createUrl('profile/index'));
}
}
}
}
This is Users model:
<?php
/**
* This is the model class for table "users".
*/
class Users extends CActiveRecord
{
public $password2;
public $rememberMe;
public $verifyCode;
private $_identity;
/**
* The followings are the available columns in table 'users':
* @var integer $id
* @var string $username
* @var string $password
* @var string $salt
* @var string $email
* @var integer $location
* @var boolean $accEnabled
*/
/**
* Returns the static model of the specified AR class.
* @return Users the static model class
*/
public static function model($className=__CLASS__) {
return parent::model($className);
}
/**
* @return string the associated database table name
*/
public function tableName() {
return 'users';
}
/**
* @return array validation rules for model attributes.
*/
public function rules() {
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('username, password, password2, email', 'required', 'on' => 'register'),
array('password', 'compare', 'compareAttribute' => 'password2', 'on' => 'register'),
array('username, email', 'unique', 'on' => 'register'),
array('username, password, email', 'length', 'min' => 4, 'max' => 255, 'on' => 'register'),
array('email', 'email', 'on' => 'register'),
array('verifyCode', 'captcha', 'on' => 'register', 'allowEmpty' => !extension_loaded('gd')),
array('username, password', 'required', 'on' => 'login'),
array('accEnabled', 'accEnabled', 'on' => 'login'),
array('rememberMe', 'boolean', 'on' => 'login'),
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('id, username, email', 'safe', 'on' => 'AdminSearch'),
array('username, location', 'safe', 'on' => 'UserSearch'),
// password needs to be authenticated
array('password', 'authenticate', 'on' => 'login'),
);
}
/**
* @return array relational rules.
*/
public function relations() {
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'location' => array(self::BELONGS_TO, 'Locations', 'id'), // this is experiment, maybe I can get that damn selected="selected" with this??? NO, I can't
);
}
}
I’ve stripped out some functions from this post (eg. search functions, attributeLabels, login, accEnabled and so on, that I’ve think that is not important for this problem)
Table ‘locations’ is some kind of lookup table with prepopulated values
I’ve posted my models, controller and view above, now I will try to explain what happens when I’m using that.
I’m logged in, and I’m go to My Profile, I can see my form with prepopulated field (eg. username, email etc), I have dropdown list wit all correct values from ‘locations’ table:
I can select one of these options and click Submit, after that in ‘users’ table location field will be updated to correct value (eg. 1 if I select <option value=“1”>Bjelovarsko-bilogorska županija</option>)
after that, if I refresh page I will see <option value="">(Odaberite lokaciju)</option> as selected option in drop down list, and list markup will be exactly the same as above, and I want it to be like this:
make sure you have $_GET[id] in profile update page. it will be invoke loadModel() action in controller
you can echo $_GET[‘id’];
public function loadModel()
{
if($this->_model===null)
{
if(isset($_GET['id']))
$this->_model=profile::model()->findbyPk($_GET['id']);
if($this->_model===null)
throw new CHttpException(404,'The requested page does not exist.');
}
return $this->_model;
}
i dont see this method in you profilecontoller. ??
when you click submit,this method will be invoke.(Profileconttroller)
public function actionUpdate() {
$model=$this->loadModel();
if (isset($_POST['ProfileForm'])) {
/* uncomment this to see array data form after submit
print_r($model->attributes=$_POST['ProfileForm']);
die();
*/
$model->attributes=$_POST['ProfileForm'];
if($model->save())
$this->redirect($this->createUrl('profile/index'));
}
}
}
if your form is in index page you can try this
public function actionIndex() {
$data['user'] = Users::model()->find("username='" . Yii::app()->user->id . "'");
$data['model'] = new ProfileForm();
//priprema podataka za listu lokacija
$criteria = new CDbCriteria;
$criteria->order = 'name ASC';
$locations = Locations::model()->findAll($criteria);
$data['locations'] = CHtml::listData($locations, 'id', 'name');
if(isset($_GET['id'])){
$this->actionUpdate();
}else{
$this->actionCreate();
}
$this->render('index', $data);
}
Hmm. Maybe then you should read the guide first? Most is described there. You might read it a second or third time, as it’s very compact.
The problem with your code is:
You’ve declared the attribute location to be safe in scenario UserMode (see your rules). But you don’t set this scenario in your actionUpdate, when you query for the user model. So: either make it safe in any scenario (remove ‘on’=>‘UserSearch’ from that rule) or set this scenario after you queried $user in your controller.
Well, for other people who may also been looking for this solution, there are several methods to solve this, the first two of which I don’t recommend:
Assign the model’s attribute a default value. It has the problem of not being the best solution if the dropdownlist is multiselect. Besides, it is a model level solution for an interface issue: unless we are talking about a very sensitive decision, sometimes the default-selection is a matter of visualization only, sometimes it is a programmer’s whim to leave a default selection, but it doesn’t deeply affect the database, nor the model itself, nor the application gravely, so I think that the solution should be in the views layer.
Creating a default value in the table. This is worse, I think: it uses a database-level solution for something that is a matter of visualization (read the argument of point 1).
A more feasible and clearer solution is using the "options" entry in the array of htmloptions, I read it in the CHtml Dropdownlist documentation, but I applied it for an ActiveForm Dropdownlist. So in this example, if the reader wants the item with key value "3" tobe selected by default, she/he should use:
The solution for my issue was to make sure I had declared a validation rule in the model. Once that was done, Yii worked it’s magic, and the correct value is auto-selected.