YII中的动态用户配置文件管理



我在数据库profile_fieldsprofile_fields_values中有两个表。

profile_fields具有列

  • id
  • fieldname
  • fieldtitle
  • fieldType
  • orderby
  • 必需
  • 出版

profile_field_values有列

  • id
  • field_id
  • user_id
  • field_value

在这里我必须创建一个动态的配置文件管理。

我如何在yii中显示动态形式?

您需要使用形式构建器,它有很多示例如何使用数组来构造表单。它还支持子形式。只需按照链接的教程中的示例,内容是在这里长期引用的。

更新:

class LoginForm extends CFormModel
{
    public $username;
    public $password;
}
$form = new LoginForm();
$form->validatorList->add(
    CValidator::createValidator('required', $form, 'username, password')
);

或另一个示例:

class SomeModel
{
 public $orders;
 public function rules()
 {
  return array(
   array('orders', 'validateOrders'),
  );
 }
 public function validateOrders($attribute, $params)
 {
  foreach($this->orders as $order)
   if (empty($order)) {
    $this->addError('orders', 'There is an empty order');
    break;
   }
 }
}

在论坛上是一个更广泛的例子。

I am trying to build this dynamic profile management let me know my approach is my approach is right?
firstly i have created a input form(_form) where user can input fieldtype,fieldname,fieldtitle and field default value and etc which can be save in database table (profile_fields).In this fieldtype is bydefault set and user choose it from dropdownlist As like in the below form.
<?php
/* @var $this ProfileManagerController */
/* @var $model ProfileFields */
/* @var $form CActiveForm */
?>
<div class="form">
<?php $form=$this->beginWidget('CActiveForm', array(
    'id'=>'profile-fields-form',
    'enableAjaxValidation'=>false,
)); ?>
    <p class="note">Fields with <span class="required">*</span> are required.</p>
    <?php echo $form->errorSummary($model); ?>
    <div class="row">
        <?php echo $form->labelEx($model,'location'); ?>
        <?php echo $form->dropDownList($model,'location',CHtml::listData(Countries::model()->findAll('',array('orderby' => 'countryName ASC')),'countryCode','countryName'), array('empty' => array("*" => 'For All Countries'))); ?>
        <?php echo $form->error($model,'location'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'profile_type'); ?>
        <?php echo $form->dropDownList($model,'profile_type',Yii::app()->params['userRoles'], array('empty' => array("*" => 'For All users')), array($model->profile_type)); ?>
        <?php //echo $form->dropDownList($model, 'profile_type', Yii::app()->params['userRoles'], array($model->profile_type)); ?>
        <?php echo $form->error($model,'profile_type'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'section'); ?>
        <?php echo $form->dropDownList($model,'section',array('profile'=>'profileSection','basicdetails'=>'BasicDetails','contactdetails'=>'ContactDetails','imagedetails'=>'ImageDetails','clientdetails'=>'ClientDetails','tagdetails'=>'TagDetails','otherdetails'=>'OtherDetails','alldetails'=>'AllDetails')); ?>
        <?php echo $form->error($model,'section'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'field_name'); ?>
        <?php echo $form->textField($model,'field_name',array('size'=>60,'maxlength'=>255)); ?>
        <?php echo $form->error($model,'field_name'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'field_title'); ?>
        <?php echo $form->textField($model,'field_title',array('size'=>60,'maxlength'=>255)); ?>
        <?php echo $form->error($model,'field_title'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'field_type'); ?>
        <?php echo $form->dropDownList($model,'field_type',array('text' => 'Text','date' => 'Date','email' => 'Email', 'radio' => 'Radio','multiselect' => 'Multi Select Dropdown List','file'=>'File','checkbox'=>'CheckBox','hidden'=>'Hidden','select'=>'Dropdownlist','password'=>'Password','checkboxlist'=>'Checkboxlist','radiolist'=>'Radiolist','textarea'=>'TextArea'),array('options' => array($model->field_type => array('selected' => true)))); ?>
        <?php echo $form->error($model,'field_type'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'field_default_value'); ?>
        <?php echo $form->textArea($model,'field_default_value',array('rows'=>6, 'cols'=>50)); ?>
        <?php echo $form->error($model,'field_default_value'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'required'); ?>
          <?php echo $form->dropDownList($model, 'required', array('1' => 'Yes', '0' => 'No')); ?>
        <?php echo $form->error($model,'required'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'published'); ?>
          <?php echo $form->dropDownList($model, 'published', array('1' => 'Yes', '0' => 'No')); ?>
        <?php echo $form->error($model,'published'); ?>
    </div>
    <div class="row">
        <?php echo $form->labelEx($model,'order_by'); ?>
        <?php echo $form->textField($model,'order_by'); ?>
        <?php echo $form->error($model,'order_by'); ?>
    </div>
    <div class="row buttons">
        <?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'); ?>
    </div>
<?php $this->endWidget(); ?>
</div><!-- form -->
secondly I have created a view index file which will show dynamically what type of fieldstypes and fieldsname and field title are set by the user in profile_field table and call the extension created by me and then another  user can input accordingly .and these values are save in profile_field_values table .
----------index file---------------

<div class="form">
    <?php
    $form = $this->beginWidget('CActiveForm', array(
        'id' => 'completeProfile-form',
        'htmlOptions' => array('enctype' => 'multipart/form-data'),
        'enableAjaxValidation' => false,
        'clientOptions' => array('validataOnSubmit' => true),
        'enableClientValidation' => true,        
    ));
    ?>
    <?php
    if (!empty($field_data)) {
        foreach ($field_data as $field) { 
            $selectedOptions = '';
            $def_value='';
            $field_name = $field->field_name; // required field
            $field_type = $field->field_type; // required field
            $field_id = $field->id; // required field
            //for validation 
            $req = $field->required == 1 ? 'required' : ''; // required if using validation
            $email = $field->field_type == 'email' ? 'email' : ''; // required if using validation
            $password = $field->field_type == 'password' ? 'password' : ''; // required if using validation
            $class = array($req, $email, $password); // class must be array type, if no class found, send empty array
            //values present in  ProfileFieldsValues to populate
            $value = ProfileFieldsValues::model()->findByAttributes(array('user_id' => Yii::app()->user->id, 'field_id' => $field->id));
            // set html options
            $htmlOptions = array();
            $htmlOptions['class'] = implode(" ", $class);
            $htmlOptions['value'] = $value ? $value->field_value : '';
            // field array - Must SET
            $fieldArray = array();
            $fieldArray['model'] = $field;
            $fieldArray['form'] = $form;
            $fieldArray['field_type'] = $field_type;
            $fieldArray['field_name'] = $field_name;
            $fieldArray['field_id'] = $field_id;
            $fieldArray['default_value'] = $value ? $value->field_value : $field->field_default_value;
            //If input type field is dropdowlist for selecttion
            if($field_type == 'select' ){
                if(!empty($field->field_default_value)){
                    $my_string = preg_replace(array('/n/'), '#PH#', $field->field_default_value );
                    $my_array = explode('#PH#', $my_string);
                    foreach($my_array as $my_arr){
                            $def=explode('|',$my_arr);
                            $def_value[$def[0]]=$def[1];
                    }
                     $fieldArray['select_box_array']=$def_value;
                }else{
                     $fieldArray['select_box_array'] =$country;
                }
                $htmlOptions['prompt'] = 'SELECT ANY';
                $value ? $htmlOptions['options']=array($value->field_value=>array('selected'=>'true')): $htmlOptions['prompt'] = 'SELECT ANY';
            }
            //if input type field is multiple select dropdownlist
            if( $field_type == 'multiselect'){
                if(!empty($field->field_default_value)){
                    $my_string = preg_replace(array('/n/'), '#PH#', $field->field_default_value );
                    $my_array = explode('#PH#', $my_string);
                    foreach($my_array as $my_arr){
                    $def=explode('|',$my_arr);
                    $def_value[$def[0]]=$def[1];
                    }
                    $fieldArray['select_box_array']=$def_value;
                }else{
                    $fieldArray['select_box_array'] =$country;
                }
                $htmlOptions['prompt'] = 'SELECT Multiple';
                if(!empty($value)){
                $field_valu= explode(',',$value->field_value); 
                foreach($field_valu as $eachValue){
                    $selectedOptions[$eachValue] = array('selected'=>'selected');
                 }
                $htmlOptions['options']= $selectedOptions;
                }
            }
            // if input type field is radio button
            if ($field_type == 'radiolist') {
                $fl = ProfileFieldsValues::model()->findByAttributes(array('field_id' => $field->id, 'user_id' => Yii::app()->user->id));                
                if(!empty($field->field_default_value)){
                $my_string = preg_replace(array('/n/'), '#PH#', $field->field_default_value );
                $my_array = explode('#PH#', $my_string);
                foreach($my_array as $my_arr){
                    $def=explode('|',$my_arr);
                    $def_value[$def[0]]=$def[1];
                }
                 $fieldArray['radio_box_array']=$def_value;
                }else{
                 $fieldArray['radio_box_array'] =array('hello','bye');
                }
                $value = $fl ? $fl->field_value : 0;
                $htmlOptions = array('labelOptions' => array('style' => 'display:inline'), 'separator' => ' ','value' => $value);
            }
            //if input type field is checkbox list
            if ($field_type == 'checkboxlist') {
                $fl = ProfileFieldsValues::model()->findByAttributes(array('field_id' => $field->id, 'user_id' => Yii::app()->user->id));
                if(!empty($field->field_default_value)){
                    $my_string = preg_replace(array('/n/'), '#PH#', $field->field_default_value );
                    $my_array = explode('#PH#', $my_string);
                    foreach($my_array as $my_arr){
                        $def=explode('|',$my_arr);
                        $def_value[$def[0]]=$def[1];
                    }
                    $fieldArray['check_box_array']=$def_value;
                }else{
                    $fieldArray['check_box_array'] =array('hello','bye');
                }
                $value = $fl ? (array)explode(",",$fl->field_value) : array(0);                                
                $htmlOptions = array('labelOptions' => array('style' => 'display:inline'), 'separator' => ' ','value' => $value );
            }
            //if input type field is file
            if ($field_type == 'file') {
                $files = ProfileFieldsValues::model()->findByAttributes(array('field_id' => $field->id, 'user_id' => Yii::app()->user->id));
                if(isset($files->field_value)){
                    echo CHtml::image(Yii::app()->request->baseUrl . '/images/user_images/' .$files->field_value, 'Image', array('class' => 'img-polaroid', 'width' => 200)); 
                }
            }
            $fieldArray['htmlOptions'] = $htmlOptions;
                if ($field->published == '1') { 
                        if($field->field_type == 'checkbox' || $field->field_type == 'radio' ){ ?>
                        <div class="row">   
                            <?php $this->widget('ext.dynamicFields.EDynamicFields', $fieldArray); ?>
                            <?php echo $field->field_title; ?>
                            <?php echo $form->error($field, $field->field_title); ?>
                        </div>
                        <?php }else{ ?>
                        <div class="row">   
                        <?php echo $form->labelEx($field, $field->field_title); ?>
                        <?php $this->widget('ext.dynamicFields.EDynamicFields', $fieldArray); ?>
                        <?php echo $form->error($field, $field->field_title); ?>
                        </div>
                        <?php } ?>
                <?php } ?>
            <?php } ?>
            <div class="row buttons">
                <?php echo CHtml::submitButton('Submit'); ?>
            </div>
        <?php
    }
     $this->endWidget();
    ?>
</div><!-- form -->
<?php Yii::app()->clientScript->registerScriptFile(Yii::app()->getBaseUrl(true) . '/js/jquery.validate.js'); ?>
<script type="text/javascript">
    $("#completeProfile-form").validate({
    });
</script>

I have created a extension for various input type fields like
1.text
2.email textbox
3.hidden input type field
4.textarea
5.dropdownlist 
6. multiple select dropdownlist
7.password textfield            
8.file
9.radiolist
10.radio button
11 checkbox
12checkboxlist
13 date field             
   <?php
/**
 * Description of EDynamicFields
 * It will show dynamic fields
 *
 * @author Gaurav Parashar
 */
class EDynamicFields extends CWidget {
    public $field_type;
    public $field_name;
    public $field_id;
    public $default_value;
    public $select_box_array = array();
    public $radio_box_array = array();
    public $check_box_array = array();
    public $htmlOptions = array();
    public $model;
    public $form;
    public $select;
    public function run() {
        switch ($this->field_type) {
            case 'text':
                echo $this->form->textField($this->model, "field_name[$this->field_type][$this->field_id]", $this->htmlOptions);
            break;
            case 'email':
                echo $this->form->textField($this->model, "field_name[$this->field_type][$this->field_id]", $this->htmlOptions);
            break;
            case 'hidden':
                echo $this->form->hiddenField($this->model, "field_name[$this->field_type][$this->field_id]", $this->default_value);
            break;
            case 'textarea':
                echo $this->form->textArea($this->model, "field_name[$this->field_type][$this->field_id]", $this->htmlOptions);
            break;
            case 'select':
                echo $this->form->dropDownList($this->model, "field_name[$this->field_type][$this->field_id]", $this->select_box_array, $this->htmlOptions);
            break;
            case 'password':
                echo $form->passwordField($model,'password',$this->htmlOptions);
                break;
            case 'multiselect':
                $newarr = array_merge($this->htmlOptions, array('multiple' => 'multiple'));
                echo $this->form->dropDownList($this->model, "field_name[$this->field_type][$this->field_id]", $this->select_box_array, $newarr);
            break;
            case 'file':
                echo $this->form->fileField($this->model, "field_name[$this->field_type][$this->field_id]" ,$this->htmlOptions);
            break;
            case 'radio':
                echo $this->form->radioButton($this->model, "field_name[$this->field_type][$this->field_id]", $this->htmlOptions);
            break;
            case 'radiolist':
                echo CHtml::radioButtonList("ProfileFields[field_name][$this->field_type][$this->field_id]",$this->htmlOptions['value'],$this->radio_box_array,$this->htmlOptions);
            break;
            case 'checkbox':
                echo $this->form->checkBox($this->model, "field_name[$this->field_type][$this->field_id]", $this->htmlOptions);
            break;
            case 'date':
                 $this->widget('zii.widgets.jui.CJuiDatePicker', array(
                                'attribute' => "field_name[$this->field_type][$this->field_id]",
                                'model' => $this->model,
                                'htmlOptions'=>array(
                                'class'=>'required',
                                ),    
                                'options' => array(
                                        'dateFormat' => 'yy-mm-dd',
                                        'maxDate' => 'new Date()', // One month ahead
                                        //'minDate' => '-50y', // Today
                                        'changeMonth' => true,
                                        'changeYear' => true,
                                        'yearRange'=>'2000:2099',
                                        'minDate' => '2000-01-01',      // minimum date
                                        'maxDate' => '2099-12-31',
                                )
                ));
            break;
            case 'checkboxlist':
                    echo CHtml::checkBoxList("ProfileFields[field_name][$this->field_type][$this->field_id]",$this->htmlOptions['value'],$this->check_box_array,$this->htmlOptions);
            break;
        }
    }
}

最新更新