Yii Framework Forum: Dynamic Tabular Form - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Dynamic Tabular Form

#1 User is offline   folumike 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 169
  • Joined: 27-November 14

Posted 14 June 2018 - 07:13 AM

I have these two models

Questions

    public function attributeLabels()
    {
        return [
            'id' => Yii::t('course', 'Question'),
            'question_category_id' => Yii::t('course', 'Question Category'),
            'question_course_id' => Yii::t('course', 'Course'),
            'instructor_id' => Yii::t('course', 'Instructor'),
            'question_name' => Yii::t('course', 'Question Name'),
            'question_text' => Yii::t('course', 'Question Text'),
            'default_mark' => Yii::t('course', 'Default Mark'),
            'penalty' => Yii::t('course', 'Penalty'),
            'qtype' => Yii::t('course', 'Question Type'),
            'mcq_answer_option' => Yii::t('course', 'Mcq Answer Option'),
            'is_status' => Yii::t('course', 'Is Status'),
        ];
    }

    public function getQuestionAnswers()
    {
        return $this->hasMany(\app\modules\course\models\QuestionAnswers::className(), ['question_id' => 'id']);
    } 


QuestionAnswers

    const UPDATE_TYPE_CREATE = 'create';
    const UPDATE_TYPE_UPDATE = 'update';
    const UPDATE_TYPE_DELETE = 'delete';

    const SCENARIO_BATCH_UPDATE = 'batchUpdate';


    private $_updateType;

    public function getUpdateType()
    {
        if (empty($this->_updateType)) {
            if ($this->isNewRecord) {
                $this->_updateType = self::UPDATE_TYPE_CREATE;
            } else {
                $this->_updateType = self::UPDATE_TYPE_UPDATE;
            }
        }

        return $this->_updateType;
    }

    public function setUpdateType($value)
    {
        $this->_updateType = $value;
    }

    public function rules()
    {
        return [
            ['updateType', 'required', 'on' => self::SCENARIO_BATCH_UPDATE],
            ['updateType',
                'in',
                'range' => [self::UPDATE_TYPE_CREATE, self::UPDATE_TYPE_UPDATE, self::UPDATE_TYPE_DELETE],
                'on' => self::SCENARIO_BATCH_UPDATE]
            ,            
            [['question_id'], 'integer'],
            //allowing it to be empty because it will be filled by the QuestionController
            ['question_id', 'required', 'except' => self::SCENARIO_BATCH_UPDATE],            
            [['answer'], 'required', 'message' => ''],
            [['answer', 'feedback'], 'string'],
            [['fraction'], 'number'],
            [['question_id', 'answer'], 'unique', 'targetAttribute' => ['question_id', 'answer'], 'message' => yii::t('course', 'Answer already exist for this Question.')],
        ];
    }

    public function attributeLabels()
    {
        return [
            'id' => 'Question Answer',
            'question_id' => 'Question',
            'answer' => 'Answer',
            'fraction' => 'Fraction',
            'feedback' => 'Feedback',
        ];
    }

    public function getQuestions()
    {
        return $this->hasOne(\app\modules\course\models\Questions::className(), ['id' => 'question_id']);
    } 


I am working on a Dynamic Tabular Form without using any Yii2 Extension. All necessary actions are performed in QuestionsController and questions(View)


QuestionsController

    public function actionCreate()
    {        
        $model = new Questions();
        $modelAnswers = [];              
        
        $formAnswers = Yii::$app->request->post('QuestionAnswers', []);
        foreach ($formAnswers as $i => $formAnswer) {
            $modelAnswer = new QuestionAnswers(['scenario' => QuestionAnswers::SCENARIO_BATCH_UPDATE]);
            $modelAnswer->setAttributes($formAnswer);
            $modelAnswers[] = $modelAnswer;
        }
        //handling if the addRow button has been pressed
        if (Yii::$app->request->post('addRow') == 'true') {
            $model->load(Yii::$app->request->post());
            $modelAnswers[] = new QuestionAnswers(['scenario' => QuestionAnswers::SCENARIO_BATCH_UPDATE]);
            return $this->render('create', [
                'model' => $model,
                'modelAnswers' => $modelAnswers
            ]);
        }
        if ($model->load(Yii::$app->request->post())) {   
            $model->course_id = $answerasc_id;
            $model->instructor_id = $instructorid;                      
            $model->created_by = Yii::$app->getid->getId();
            $model->created_at = new \yii\db\Expression('NOW()');                     
            
            if (Model::validateMultiple($modelAnswers) && $model->validate()) {
                $model->save();
                foreach($modelAnswers as $modelAnswer) 
                {
                    $modelAnswer->question_id = $model->id;
                    $modelAnswer->save();
                }
                return $this->redirect(['view', 'id' => $model->id]);
            }
        }
        return $this->render('create', [
            'model' => $model,
            'modelAnswers' => $modelAnswers
        ]);
    }


1. When nothing is selected, we have
Attached File  tabular1.PNG (18.28K)
Number of downloads: 0


2. I want to use qtype(Question Type) Dropdownlist to control what will be displayed and save in the models.
If qtype is equal to "True/False", then we have:
Attached File  tabular2.PNG (15.08K)
Number of downloads: 0

Also, if count is greater than 1, the Add Answer Button should be disabled. The attribute answer should be a dropdownlist

3. I want to use qtype(Question Type) Dropdownlist to control what will be displayed and save in the models.
If qtype is equal to "Mutiple Choice Single Answer", then we have:
Attached File  tabular3.PNG (14.08K)
Number of downloads: 0

The attribute answer should be a textinput. The should be a field called "Correct Answer" in form of radiobutton, and only one should be selected.

4. I want to use qtype(Question Type) Dropdownlist to control what will be displayed and save in the models.
If qtype is equal to "Mutiple Choice Multiple Answers", then we have:


The attribute answer should be a textinput. The should be a field called "Correct Answer" in form of checkbox, and multiple can be selected.

View

<?php $this->registerJs("
    $('.delete-button').click(function() {
        var detail = $(this).closest('.question-answers');
        var updateType = detail.find('.update-type');
        if (updateType.val() === " . json_encode(QuestionAnswers::UPDATE_TYPE_UPDATE) . ") {
            //marking the row for deletion
            updateType.val(" . json_encode(QuestionAnswers::UPDATE_TYPE_DELETE) . ");
            detail.hide();
        } else {
            //if the row is a new row, delete the row
            detail.remove();
        }

    });
");
?>
<div class="col-xs-12 col-lg-12">
<div class="questions-form">
<div class="box-success box view-item col-xs-12 col-lg-12">
    <?php $form = ActiveForm::begin([
                                        'enableClientValidation' => false

                                    ]); ?>    
<!-- GENERAL DETAILS -->
<div class="box box-info">   
  <div class="box-header with-border">
    <h3 class="box-title">General</h3>
      <div class="box-tools pull-right">
        <button type="button" class="btn btn-info" data-widget="collapse"><i class="fa fa-minus"></i></button> 
<!--        <button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>-->
      </div>
  </div>
  <!-- /.box-header -->
  <div class="box-body">
    <div class="table-responsive">  
    <div class="col-xs-12 col-lg-12 no-padding">  
        <div class="col-xs-12 col-sm-6 col-lg-6">    
            <?php $courseid = Yii::$app->getRequest()->getQueryParam('acs_id');?>
                <?= $form->field($model, 'question_category_id')->widget(Select2::classname(), [
                    'data' => ArrayHelper::map(QuestionCategories::find()->where(['course_id' => $courseid, 'is_status'=>0])->all(),'question_category_id','name'),
                    'language' => 'en',
                    'options' => ['placeholder' => 'Select Question Category ...'],
                    'pluginOptions' => [
                    'allowClear' => true
                    ],
                ]);
                ?> 
        </div>
        <div class="col-xs-12 col-sm-6 col-lg-6">    
            <?= $form->field($model, 'question_name')->textInput(['maxlength' => 100]) ?>
        </div>        
    </div>    
    <div class="col-xs-12 col-lg-12 no-padding"> 
        <div class="col-xs-12 col-sm-12 col-lg-12">
                <?= $form->field($model, 'question_text')->textInput(['maxlength' => 100]) ?>      
        </div>
    </div> 
    <div class="col-xs-12 col-lg-12 no-padding">  
        <div class="col-xs-12 col-sm-6 col-lg-6"> 
            <?= $form->field($model, 'default_mark')->textInput(['maxlength' => 12, 'value' => '1']) ?>
        </div>
        <div class="col-xs-12 col-sm-6 col-lg-6">    
                <?= $form->field($model, 'qtype')->widget(Select2::classname(), [
                    'data' => $model->getQuestionType(),
                    'language' => 'en',
                    'options' => ['placeholder' => 'Select Question Type ...'],
                    'pluginOptions' => [
                    'allowClear' => true
                    ],
                ]);
                ?>               
        </div>        
    </div>         
    </div>
  </div>  
</div>    
<!-- FORMAT -->
<div class="box box-success">   
  <div class="box-header with-border">
    <h3 class="box-title"><i class="glyphicon glyphicon-user"></i> Question Answers</h3>
      <div class="box-tools pull-right">    
        <button type="button" class="btn btn-success" data-widget="collapse"><i class="fa fa-minus"></i></button> 
        <!--<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>-->
      </div>
  </div>   
<!--   /.box-header -->
  <div class="box-body">
    <div class="table-responsive">     
    <div class="padding-v-md">
        <div class="line line-dashed"></div>
    </div>  
        
    <div class="panel panel-default">
        <div class="panel-heading">
            <i class="fa fa-envelope"></i> Question Answers
            <button type="button" class="pull-right add-item btn btn-success btn-xs"></button>
            <div class="clearfix"></div>
        </div>  
        
        <div class="panel-body container-items truefalse-data"><!-- widgetContainer -->        
            <?php foreach ($modelAnswers as $i => $modelAnswer) : ?>
<!--                <div class="item panel panel-default"> widgetBody -->
            <div class="row question-answers question-answers-<?= $i ?>">
                    <div class="panel-heading">
                        <span class="panel-title-address">Question Answers: <?= ($i + 1) ?></span>
                        
                        <div class="clearfix"></div>
                    </div>
                    <div class="panel-body">
                        <?= Html::activeHiddenInput($modelAnswer, "[$i]id") ?>
                        <?= Html::activeHiddenInput($modelAnswer, "[$i]updateType", ['class' => 'update-type']) ?>

                        <div class="row">
                            <div class="col-sm-11">
                                <?= $form->field($modelAnswer, "[{$i}]answer")->widget(Select2::classname(), [
                                 'data' => $modelAnswer->getTrueFalse(),
                                 'language' => 'en',
                                 'options' => ['placeholder' => 'Select Question Type ...'],
                                 'pluginOptions' => [
                                 'allowClear' => true
                                 ],
                             ]);
                             ?>                                
                        </div>                                
                            <div class="col-md-1">
                                <?= Html::button('x', ['class' => 'delete-button btn btn-danger', 'data-target' => "question-answers-$i"]) ?>
                            </div>  
                            <div class="col-sm-12">
                                <?= $form->field($modelAnswer, "[$i]feedback")->textInput(['maxlength' => 100]) ?>                                 
                            </div>                            
                        </div><!-- end:row -->
                    </div>
                </div>
            <?php endforeach; ?>
        </div>
        
        <div class="panel-body container-items mcsa-data"><!-- widgetContainer -->        
            <?php foreach ($modelAnswers as $i => $modelAnswer) : ?>
<!--                <div class="item panel panel-default"> widgetBody -->
            <div class="row question-answers question-answers-<?= $i ?>">
                    <div class="panel-heading">
                        <span class="panel-title-address">Question Answers: <?= ($i + 1) ?></span>
                        
                        <div class="clearfix"></div>
                    </div>
                    <div class="panel-body">
                        <?= Html::activeHiddenInput($modelAnswer, "[$i]id") ?>
                        <?= Html::activeHiddenInput($modelAnswer, "[$i]updateType", ['class' => 'update-type']) ?>

                        <div class="row">
                            <div class="col-sm-11">
                                <?= $form->field($modelAnswer, "[$i]answer")->textInput(['maxlength' => 100]) ?>
                        </div>                                
                            <div class="col-md-1">
                                <?= Html::button('x', ['class' => 'delete-button btn btn-danger', 'data-target' => "question-answers-$i"]) ?>
                            </div>  
                            <div class="col-sm-12">
                                 <?= $form->field($modelAnswer, "[$i]feedback")->textInput(['maxlength' => 100]) ?>
                            </div>                            
                        </div><!-- end:row -->
                    </div>
                </div>
            <?php endforeach; ?>
        </div>
        
        <div class="panel-body container-items mcma-data"><!-- widgetContainer -->        
            <?php foreach ($modelAnswers as $i => $modelAnswer) : ?>
<!--                <div class="item panel panel-default"> widgetBody -->
            <div class="row question-answers question-answers-<?= $i ?>">
                    <div class="panel-heading">
                        <span class="panel-title-address">Question Answers: <?= ($i + 1) ?></span>
                        
                        <div class="clearfix"></div>
                    </div>
                    <div class="panel-body">
                        <?= Html::activeHiddenInput($modelAnswer, "[$i]id") ?>
                        <?= Html::activeHiddenInput($modelAnswer, "[$i]updateType", ['class' => 'update-type']) ?>

                        <div class="row">
                            <div class="col-sm-11">
                                <?= $form->field($modelAnswer, "[$i]answer")->textInput(['maxlength' => 100]) ?>
                        </div>                                
                            <div class="col-md-1">
                                <?= Html::button('x', ['class' => 'delete-button btn btn-danger', 'data-target' => "question-answers-$i"]) ?>
                            </div>  
                            <div class="col-sm-12">
                                 <?= $form->field($modelAnswer, "[$i]feedback")->textInput(['maxlength' => 100]) ?>
                            </div>                            
                        </div><!-- end:row -->
                    </div>
                </div>
            <?php endforeach; ?>
        </div>        

    </div>
    
    </div>
  </div>  
</div>
<!--</div>-->  

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
         <?= Html::submitButton('Add Answer', ['name' => 'addRow', 'value' => 'true', 'class' => 'btn btn-info']) ?>
    </div>

    <?php ActiveForm::end(); ?>

</div>
</div>
</div>

<script>
$(document).ready(function(){
	var chkvalue = $('#questions-qtype').val();
	if(chkvalue=='True/False') {
		$(".mcsa-data").hide();
                $(".mcma-data").hide();
		$(".truefalse-data").show();
	}
	else if(chkvalue=='Multiple Choice Single Answer') {
		//$("#cheque-data").css("display","block");
		$(".mcsa-data").show();
                $(".mcma-data").hide();
		$(".truefalse-data").hide();
	}
        
	else if(chkvalue=='Multiple Choice Multiple Answers') {
		//$("#cheque-data").css("display","block");
		$(".mcsa-data").hide();
                $(".mcma-data").show();
		$(".truefalse-data").hide();
	}        
	else {
		//$("#cheque-data").css("display","block");
		$(".mcsa-data").hide();
                $(".mcma-data").hide();
		$(".truefalse-data").hide();
	}        
	$("#questions-qtype").change(function(){
	var chkvalue = $('#questions-qtype').val();
	if(chkvalue=='True/False') {
		$(".mcsa-data").hide();
                $(".mcma-data").hide();
		$(".truefalse-data").show();
	}
	else if(chkvalue=='Multiple Choice Single Answer') {
		//$("#cheque-data").css("display","block");
		$(".mcsa-data").show();
                $(".mcma-data").hide();
		$(".truefalse-data").hide();
	}
        
	else if(chkvalue=='Multiple Choice Multiple Answers') {
		//$("#cheque-data").css("display","block");
		$(".mcsa-data").hide();
                $(".mcma-data").show();
		$(".truefalse-data").hide();
	}        
	else {
		//$("#cheque-data").css("display","block");
		$(".mcsa-data").hide();
                $(".mcma-data").hide();
		$(".truefalse-data").hide();
	}  
	});
});
</script>


0

Share this topic:


Page 1 of 1
  • 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