问题
I want to create dynamic field with jquery without using any library. I have two filed in form but one filed label
i want to create multiple time which is actually question option it can be more then one time.
In below form.php you see that label field
i create with jquery in multiple time. I can save them but i am not understand how i will show those filed which was more then one time in update case
. Really sorry for my english.
Controller
public function actionCreate()
{
$model = new QuestionsOptions();
if ($model->load(Yii::$app->request->post())) {
if(sizeof(array_filter($_POST['QuestionsOptions']['label'])) > 0){
foreach($_POST['QuestionsOptions']['label'] as $key => $row){
$model->setIsNewRecord(true);
$model->option_id = null;
$model->label = $row;
$model->save();
}
}
// exit;
return $this->redirect(['view', 'id' => $model->option_id]);
} else {
return $this->renderAjax('create', [
'model' => $model,
]);
}
}
Model
namespace app\models;
use Yii;
class QuestionsOptions extends \yii\db\ActiveRecord
{
public static function tableName()
{
return 'questions_options';
}
public function rules()
{
return [
[['question_id', 'label', 'type'], 'required'],
[['question_id'], 'integer'],
[['type'], 'string'],
[['dated', 'updated'], 'safe'],
[['label'], 'string', 'max' => 255],
[['question_id'], 'exist', 'skipOnError' => true, 'targetClass' => SurveysQuestions::className(), 'targetAttribute' => ['question_id' => 'question_id']],
];
}
public function attributeLabels()
{
return [
'option_id' => 'Option ID',
'question_id' => 'Question ID',
'label' => 'Label',
'type' => 'Type',
'dated' => 'Dated',
'updated' => 'Updated',
];
}
public function getQuestionsAnswers()
{
return $this->hasMany(QuestionsAnswers::className(), ['option_id' => 'option_id']);
}
public function getQuestion()
{
return $this->hasOne(SurveysQuestions::className(), ['question_id' => 'question_id']);
}
}
form.php
<?php
use yii\helpers\Html;
use yii\widgets\ActiveForm;
?>
<div class="surveys-questions-form">
<?php $form = ActiveForm::begin(); ?>
<?php
if(isset($_GET['option_id']) and $_GET['option_id'] > 0)
$id= $_GET['option_id'];
else
$id= $model->option_id;
echo $form->field($model, 'question_id')->hiddenInput(['value' => $id])->label(false);
?>
<div class="col-md-6">
<div id="question_wrapper">
<?= $form->field($model, 'type')->dropDownList([ 'text' => 'Text', 'numbers' => 'Numbers', 'date' => 'Date', 'texarea' => 'Texarea', 'checkbox' => 'Checkbox', 'radio' => 'Radio', 'rating' => 'Rating', ], ['prompt' => '']) ?>
<div id="add_more_field">
<?= $form->field($model, 'label[]')->textInput(['maxlength' => true]) ?>
</div>
<div class="form-group">
<?php
echo Html::a('Add more', 'javascript:void(0);', [
'id' => 'surveys-questions-new-button',
'class' => 'pull-right btn btn-primary btn-xs'
])
?>
</div>
</div>
</div>
<div class="col-md-12">
<div class="form-group">
<?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
</div>
</div>
<?php ActiveForm::end(); ?>
</div>
<?php
$script = <<< JS
$(document).ready(function(){
$('#surveys-questions-new-button').on('click', function () {
$("#add_more_field").clone().appendTo("#question_wrapper");
});
});
JS;
$this->registerJs($script);
?>
Maybe other thing is also not right in my code please can suggest me I am really want help.
回答1:
I have few comments to improve and rework your code:
Create
QuestionOptionsForm
that may load your dynamically added options/labels. Use this model for iteration the options (that may be loaded from request or DB). Don't use statements like$_GET['option_id']
(especially in a view).When you add new options (dynamically) on the form, add integer-index for the field names. For example
label[45]
. I used usually special html template with replacements. Use this way instead clone of existing rows. For example:<div class="js-new-option-template"> <input type="text" name="option[{{OPTION_ID}}][label]"/> <input type="hidden" name="option[{{OPTION_ID}}][is_new_option]"/> </div>
NOTE: you need to separate existing option IDs from the dynamically generated in a JS code. You can use
is_new_option
hidden field for this.When you restore the existing options, index them using their IDs.
Then when you iterate options, load models for existing options, and create new models for the dynamically generated.
// ... foreach ($modelForm->options as $optionId => $optionData) { // Prepare data $isNewModel = \yii\helpers\ArrayHelper::getValue($optionData, 'is_new_option', true); $optionLabel = \yii\helpers\ArrayHelper::getValue($optionData, 'label'); $optionQuestion = \yii\helpers\ArrayHelper::getValue($optionData, 'question_id'); // Create or find options model $modelOption = $isNewModel ? new QuestionsOptions() : QuestionsOptions::findOne($optionId); if (!$modelOption) { throw new \yii\web\NotFoundHttpException('Cannot be found option record with the id = ' . $optionId); } // Populate and save model $modelOption->label = $optionLabel; $modelOption->question_id = $optionQuestion; // foreign key if (!$modelOption->save()) { throw new \yii\base\Exception('Cannot be saved new option record.'); } }
If necessary, you can delete from DB options, that has been deleted on the form.
来源:https://stackoverflow.com/questions/42417814/how-to-update-dynamic-field-in-yii2