2

I am confused with one problem from couple of days and i could not solve it. I have a form which has different classes and when user clicks on add button i want to generate couple of fields. I can generate the fields but i am not able to pass that particular class_id with those dynamic generated fields. I am using this widget And here is how i am generating the dynamic fields.

Only involved model is Registration form. Other than that i am just firing query and displaying the data.One class can have multiple Registrations

Class      Registration
is         id
name       class_id
           firstname
           lastname

This is my view code

 <?php if (!empty($data)) {
    foreach($data as $event){

        $modelsRegistration = [new Registration()];

        DynamicFormWidget::begin([
            'widgetContainer' => 'dynamicform_wrapper', // required: only alphanumeric characters plus "_" [A-Za-z0-9_]
                        'widgetBody' => '.container-items'.$model['id'], // required: css class selector
                        'widgetItem' => '.item'.$model['id'], // required: css class
                        'limit' => 4, // the maximum times, an element can be added (default 999)
                        'min' => 0, // 0 or 1 (default 1)
                        'insertButton' => '.add-item'.$model['id'], // css class
                        'deleteButton' => '.remove-item'.$model['id'], // css class
                        'model' => $modelsRegistration[0],
                        'formId' => 'registration-form',
                        'formFields' => [
                            'firstname',
                            'lastname',
                        ],
        ]);

        ?>
        <div class="container">
            <div class="row">
                <div class="col-lg-9 col-md-9 col-sm-12 col-xs-12">
                    <table class="table table-striped table-bordered">
                        <thead>
                        <tr>
                            <th class="col-lg-4 col-md-4 col-sm-4 col-xs-4">Class Name</th>
                            <th class="col-lg-2 col-md-2 col-sm-2 col-xs-2">Rounds</th>
                        </tr>
                        </thead>
                        <tbody>
                        <tr>
                            <td><?= $event['name'] ?></td>
                            <td><button type="button" id="<?= $event['id'] ?>"  class="add-item<?=$model['id'] ?> btn btn-success btn-xs">Add Rounds <i
                                        class="glyphicon glyphicon-plus"></i></button></td>
                        </tr>
                        </tbody>
                    </table>
                    <div class="row">
                        <div class="container-items<?=$model['id'] ?>"><!-- widgetBody -->
                            <?php foreach ($modelsRegistration as $i => $modelRegistration){

                                ?>
                                <div class="item<?=$model['id'] ?>"><!-- widgetItem -->
                                    <?php
                                    // necessary for update action.
                                    if (!$modelRegistration->isNewRecord) {
                                        echo Html::activeHiddenInput($modelRegistration, "[{$i}]id");
                                    }
                                    ?>
                                    <div class="row">
                                        <div class="col-sm-5">
                                            <?= $form->field($modelRegistration, "[{$i}]firstname")->textInput(['maxlength' => true]) ?>
                                        </div>
                                        <div class="col-sm-5">
                                            <?= $form->field($modelRegistration, "[{$i}]lastname")->textInput(['maxlength' => true]) ?>
                                            <?= $form->field($modelRegistration, "[{$i}]class_id")->hiddenInput(['maxlength' => true])->label(false) ?>
                                        </div>
                                        <div class="col-sm-2">
                                            <button type="button" class="remove-item<?=$model['id'] ?> btn btn-danger btn-xs"><i
                                                    class="glyphicon glyphicon-minus"></i></button>
                                        </div>
                                    </div>
                                    <!-- .row -->
                                </div>
                            <?php } ?>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <?php
        DynamicFormWidget::end();
    } } ?>
4
  • Can you show us the attributes of the models involved and the relation of your models? Commented Dec 4, 2015 at 0:57
  • @Clyff i have updated the code Commented Dec 4, 2015 at 2:53
  • I can't see why your lastname field shows correctly and the class_id don't. I made a teste here and you are calling the hidden input right, it should work. Just to be sure i'm understanding the correct scenario: You enter in the upload action and this dynamic form is generated correctly but just the class_id field is showing with blank values or the page is triggering some sort of error (wich one)? If not, can you please explain with more details the scenario in your question? Commented Dec 4, 2015 at 14:02
  • @Clyff the problem is class id is different for every class and the problem is when i click on the + button to add dynamic field for asking names it cant differentiate under which class new field was generated. thats why its not returning the class_id Commented Dec 7, 2015 at 3:54

1 Answer 1

1

If you have a view showing only people of one class (therefore, adding more people means they all are the same class) you can use in your dynamicform only the first/last name fields and add this id_class later in the controller just before saving it.

Example:

// load and validation of the model
// ...


foreach ($modelsRegistration as $modelRegistration) {
    $modelRegistration->class_id = $myClassId;
    if (! ($flag = $modelRegistration->save(false))) {
        $transaction->rollBack();
        break;
    }
}

Now, if in your view you have people of all class divided by sections and each section have this add button, i strongly recommend you remove this add buttons from there and make a new section just for add people (with a select for choose a class).

Steps:

  • Remove the option insertButton in the DynamicFormWidget class in all those sections. And remove the html button also (won't work anymore).
  • Add the new section, something like this:

    <?php
    $newModelsRegistration = [new Registration()];
    
    DynamicFormWidget::begin([
        'widgetContainer' => 'dynamicform_wrapper_registration', // required: [A-z0-9_]
                    'widgetBody' => '.container-items-registration', // required: css class selector
                    'widgetItem' => '.item-registration', // required: css class
                    'limit' => 1, // the maximum times, an element can be added (default 999)
                    'min' => 0, // 0 or 1 (default 1)
                    'insertButton' => '.add-item-registration', // css class
                    'deleteButton' => '.remove-item-registration', // css class
                    'model' => $newModelsRegistration[0], // 
                    'formId' => 'registration-form',
                    'formFields' => [
                        'firstname',
                        'lastname',
                        'class_id'
                    ],
    ]);
    
    ?>
    <div class="panel-body">
        <button type="button" class="add-item-registration btn btn-success btn-sm pull-right margin-b-base">
            <i class="glyphicon glyphicon-plus"></i> Add
        </button>
        <div class="clearfix"></div>
        <div class="container-items-registration"><!-- widgetBody -->
    
        <?php foreach ($newModelsRegistration as $i => $newModelRegistration): ?>
    
            <div class="item-registration panel panel-default"><!-- widgetItem -->
                <div class="panel-heading">
                    <h3 class="panel-title pull-left">Registration</h3>
                    <div class="pull-right">
                        <button type="button" class="remove-item-registration btn btn-danger btn-xs"><i class="glyphicon glyphicon-minus"></i></button>
                    </div>
                    <div class="clearfix"></div>
                </div>
    
                <div class="panel-body">
                    <div class="form-group row">
                        <div class="col-md-12">
                            <?= $form->field($newModelRegistration, "[{$i}]firstname")->textInput(['maxlength' => true]) ?>
                            <?= $form->field($newModelRegistration, "[{$i}]lastname")->textInput(['maxlength' => true]) ?>
                            <?= $form->field($newModelRegistration, "[{$i}]class_id")->dropDownList(
                                ArrayHelper::map(Class::find()->all(), 'id', 'name'),
                                ['prompt' => 'Select']
                            ) ?>
                        </div>
                    </div>
                </div>
            </div>
    
        <?php endforeach; ?>
    
        </div>
    </div>
    
    <?php DynamicFormWidget::end(); ?>
    
  • Make sure the limit option is set to 1. So, will be easy to avoid people trying to add too much registrations in the same class (if i understood correctly each class have a limit amount of registrations). You can add a new rule in your Registration model and check if it already reached the limit of that class. Same thing for that find() method used in the dropDownList.

But if you still want to have all this add button in the same view, you can always use js to add that value for you.

Example:

// begin of form
// ...

<?= $form->field($modelRegistration, "[{$i}]class_id")->hiddenInput(['maxlength' => true, 'class' => 'form-control add-class-id', 'data-event' => $event['id']])->label(false) ?>

// end of form


<?php
$js = <<<JS
$('#registration-form').on('submit', function (e) {
    $('.add-class-id').each(function() {
        $(this).val($(this).attr('data-event'));
    });
});
JS;
$this->registerJs($js);
?>

Let me know if any of this ideas works for you.

Sign up to request clarification or add additional context in comments.

2 Comments

thank you for your help. Actually your code helped me a lot and i was able to find another solution so thank you for your help. I could not use the same code and javascript because i dont have same class id for each form but i figured out what to do.
Cool, i tried to check all possibilities. And feel free to accept (or not) this answer if was helpful in finding your solution.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.