PrashantS Posted March 22, 2023 Share Posted March 22, 2023 (edited) I have a form which allows the user to select ASC center and add students data for each time. The scenario is a user selects ASC center from the drop down list. Upon selecting the ASC center, a function called StudentList returns the students for the selected ASC center. Now these students should be populated for each row. I have assigned a class for the Student input field and used each function of the jquery to populate all the students field with the data returned by the StudentList function. But the problem is the data gets populated for the very first row correctly. But as soon as the user clicks on Add Student to add more student for a particular time or clicks on Add Time to add new time then the previously populated data gets cleared. The expected is that the once the ASC center is selected from the drop down by the user, then no matter how many new students or new time is added by the user on the form by clicking Add Student or Add Time button then the previously populated data should not be cleared. The below image shows the students populated for the first student row on selecting the ASC center https://pasteboard.co/PDm9UwYMK4CI.png Below is the image which shows the Students input field gets cleared when a user adds new student or adds new time https://pasteboard.co/fzUipa4ZYtCO.png Below is the function StudentList which returns the list of students for specific ASC center. public function actionStudentLists($id) { $countstudents = Student::find()->where(['ASCId' => $id])->count();//Counts number of students $Students = Student::find()->where(['ASCId' => $id])->all(); // Execute students for ASCId if ($countstudents > 0) { echo "<option value>Select Students</option>"; foreach ($Students as $Student) { ob_start(); echo "<option value='" . $Student->StudentId . "'>" . $Student->StudentName . "</option>"; } } else { echo "<option> - </option>"; } } Below is the form <?php use yii\helpers\Html; use yii\bootstrap\ActiveForm; use yii\jui\DatePicker; use wbraganca\dynamicform\DynamicFormWidget; use app\models\Ascassignment; use app\models\Asccenter; use kartik\time\TimePicker; use yii\helpers\ArrayHelper; use app\models\Student; ?> <script> // When user clicks on Add Student button $(function () { $(".dynamicform_student").on("beforeInsert", function(e, item) { $.post("index.php?r=student/student-lists&id=' . '"+$("select#ascteacherreport-ascid").val(),function(data){ $(".i").html(data); }); }); }); //When user clicks on Add Time button $(function () { $(".dynamicform_wrapper").on("beforeInsert", function(e, item) { $.post("index.php?r=student/student-lists&id=' . '"+$("select#ascteacherreport-ascid").val(),function(data){ $(".i").html(data); }); }); }); </script> <div class="ascteacherreport-form"> <?php $form = ActiveForm::begin(['id' => 'dynamic-form', 'options' => ['class' => 'disable-submit-buttons'], ]);?> <div class="panel panel-primary " > <div class="panel panel-heading"><font size="3"><b>Teacher Report</b></font></div> <div class="row"> <div class="col-sm-4"> <?= $form->field($model, 'ASCId')->dropDownList(ArrayHelper::map(Asccenter::find()->leftJoin('ascassignment','`ascassignment`.`ASCId`=`asccenter`.`ASCId`')->where(['ascassignment.UserId' => \Yii::$app->user->identity->getonlyid()])->all(),'ASCId','ASCName'), ['prompt' => 'Select ASC Center','class'=>'form-control ascid','onChange' => ' $.post("index.php?r=student/student-lists&id=' . '"+$(this).val(),function(data){ $(".i").each(function(k,v) { $(".i").html(data); // Populates the Student control having class .i with the data from the StudentList function } ); }); ' ]) ?> </div> <div class="col-sm-4"> <?= $form->field($model, 'DateofReport')->widget(DatePicker::classname(), [ //'language' => 'ru', 'dateFormat' => 'yyyy-MM-dd', 'options' => ['class' => 'form-control picker','readOnly'=>'readOnly'], 'clientOptions'=>['changeMonth'=>true, 'changeYear'=>true, 'readOnly'=>true] ]) ?> </div> </div> </div> <div class="panel panel-primary"> <div class="panel-heading"><font size="3"><b>Time and Student Details</b></font></div> <?php DynamicFormWidget::begin([ 'widgetContainer' => 'dynamicform_wrapper', 'widgetBody' => '.container-items', 'widgetItem' => '.time-item', 'limit' =>10, 'min' => 1, 'insertButton' => '.add-time', 'deleteButton' => '.remove-time', 'model' => $modelsTime[0], 'formId' => 'dynamic-form', 'formFields' => [ 'FromTime', 'ToTime' ], ]); ?> <table class="table table-bordered"> <thead> <tr bgcolor='#B8B8B8'> <th style='border: 1px solid black;'></th> <th class ="text-center" style='border: 1px solid black;'>Time</th> <th class ="text-center" style='border: 1px solid black;'>Student Details</th> <th class="text-center" style='border: 1px solid black;'> <button type="button" class="add-time btn btn-success btn-xs"><span class="fa fa-plus"></span> Add Time</button> </th> </tr> </thead> <tbody class="container-items"> <?php foreach ($modelsTime as $indexTime => $modelTime): ?> <tr class="time-item"> <td class="vcenter" style='border: 1px solid black;'> <?php // necessary for update action. if (! $modelTime->isNewRecord) { echo Html::activeHiddenInput($modelTime, "[{$indexTime}]ASCReportDetailsId"); } ?> </td> <td style='border: 1px solid black;width:15%'> <?= $form->field($modelTime, "[{$indexTime}]FromTime")->label(true)->widget(TimePicker::classname(),[ 'pluginOptions' => [ 'readOnly' => true, 'minuteStep' => 1, ],])?> <br> <?=$form->field($modelTime, "[{$indexTime}]ToTime")->label(true)->widget(TimePicker::classname(),[ 'pluginOptions' => [ 'readOnly' => true, 'minuteStep' => 1, ], ])?> </td> <td style='border: 1px solid black;'> <?= $this->render('_form-studentdata', [ 'form' => $form, 'indexTime' => $indexTime, 'modelsStudentdata' => $modelsStudentdata[$indexTime], ]) ?> </td> <td class="text-center vcenter" style='border: 1px solid black;'> <button type="button" class="remove-time btn btn-danger btn-xs"><span class="fa fa-minus"></span></button> </td> </tr> <?php endforeach; ?> </tbody> </table> <?php DynamicFormWidget::end(); ?> </div> <div class="form-group"> <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?> </div> Below is the nested inner form Student form <?php use yii\helpers\Html; use yii\helpers\ArrayHelper; use yii\bootstrap\ActiveForm; //use nex\datepicker\DatePicker; use yii\web\UploadedFile; use wbraganca\dynamicform\DynamicFormWidget; use app\models\Student; ?> <?php DynamicFormWidget::begin([ 'widgetContainer' => 'dynamicform_student', 'widgetBody' => '.container-student', 'widgetItem' => '.student-item', 'limit' => 50, 'min' => 1, 'insertButton' => '.add-student', 'deleteButton' => '.remove-student', 'model' => $modelsStudentdata[0], 'formId' => 'dynamic-form', 'formFields' => [ 'StudentId', 'Subject', 'Topic', 'Confidence', ], ]); ?> <table class="table table-bordered"> <thead> <tr bgcolor='#B8B8B8'> <th style='border: 1px solid black;'></th> <th class ="text-center" style='border: 1px solid black;'>Student</th> <th class ="text-center" style='border: 1px solid black;'>Subject</th> <th class ="text-center" style='border: 1px solid black;'>Topic</th> <th class ="text-center" style='border: 1px solid black;'>Confidence</th> <th class="text-center" style='border: 1px solid black;'> <button type="button" class="add-student btn btn-success btn-xs"><span class="glyphicon glyphicon-plus"></span> Add Student</button> </th> </tr> </thead> <tbody class="container-student"> <?php foreach ($modelsStudentdata as $indexStudent => $modelStudentdata): ?> <tr class="student-item"> <td class="vcenter" style='border: 1px solid black;'> <?php // necessary for update action. if (! $modelStudentdata->isNewRecord) { echo Html::activeHiddenInput($modelStudentdata, "[{$indexTime}][{$indexStudent}]ASCTeacherReportTimeDetailsId"); } ?> </td> <td style='border: 1px solid black; width:30%'><?= $form->field($modelStudentdata, "[{$indexTime}][{$indexStudent}]StudentId")->label(false)->dropDownList(ArrayHelper::map(Student::find()->all(),'StudentId','StudentName'), ['prompt' => 'Select Student','class'=>'form-control i']) ?> //class .i assigned to the Student </td> <td style='border: 1px solid black; width:30%'> <?= $form->field($modelStudentdata, "[{$indexTime}][{$indexStudent}]Subject")->label(false)->textInput(['maxlength' => true]) ?> </td> <td style='border: 1px solid black; width:30%'> <?= $form->field($modelStudentdata, "[{$indexTime}][{$indexStudent}]Topic")->label(false)->textInput(['maxlength' => true]) ?> </td> <td style='border: 1px solid black; width:30%'> <?= $form->field($modelStudentdata, "[{$indexTime}][{$indexStudent}]Confidence")->label(false)->textInput(['maxlength' => true]) ?> </td> <td class="text-center vcenter" style=" border: 1px solid black;width: 90px;"> <button type="button" class="remove-student btn btn-danger btn-xs"><span class="glyphicon glyphicon-minus"></span></button> </td> </tr> <?php endforeach; ?> </tbody> </table> <?php DynamicFormWidget::end(); ?> Edited March 22, 2023 by PrashantS Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/ Share on other sites More sharing options...
kicken Posted March 22, 2023 Share Posted March 22, 2023 I can't tell for sure, but it seems like maybe you're using JavaScript to populate the select list after a new student/time is added. The problem I think is that you're re-populating all the select lists with your code. You have: $('.i').html(data); Which will find ALL elements with class i and replace their content. What you want to do instead is find only the newly added .i element and replace it's content, not any others. Something like this probably: $(".dynamicform_student").on("beforeInsert", function(e, item) { const $i = $(this).find('.i'); $.post("index.php?r=student/student-lists&id=' . '"+$("select#ascteacherreport-ascid").val(),function(data){ $i.html(data); }); }); In the beforeInsert callback, this should be the .dynamicform_student element that triggered the event, so use that to create a new jQuery instance and then find a child of it with class i. Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606732 Share on other sites More sharing options...
PrashantS Posted March 23, 2023 Author Share Posted March 23, 2023 Yes it works, but there is an issue where a user selects an ASC center from the drop down then all the students belonging to that ASC center gets populated on the first row correctly but when the user clicks on Add Student button to add students or clicks on Add Time button to add time then all students are displayed (All ASC centers students are displayed). Only selected ASC centers students should be populated every time the user clicks on Add Student or Add Time button. Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606752 Share on other sites More sharing options...
kicken Posted March 23, 2023 Share Posted March 23, 2023 Your URL is probably wrong. On 3/22/2023 at 9:32 AM, PrashantS said: "index.php?r=student/student-lists&id=' . '"+$("select#ascteacherreport-ascid").val() Seems like you tried to mix PHP style and JS style concatenation there. As such, you're PHP script probably isn't getting the correct ID and just loading everything. Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606758 Share on other sites More sharing options...
PrashantS Posted March 25, 2023 Author Share Posted March 25, 2023 The URL is getting the correct ASC Id. Following is the code where I am alerting the ASC Id $(function(){ $(".dynamicform_student").on("afterInsert", function(e, item) { const $i = $(this).find('.i'); $.post("index.php?r=student/student-lists&id=' . '"+$("select#ascteacherreport-ascid").val(),function(data){ alert($("select#ascteacherreport-ascid").val()); }); }); }); If I remove $(function(){ }); block then alert is not working Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606811 Share on other sites More sharing options...
maxxd Posted March 25, 2023 Share Posted March 25, 2023 kicken's point is that you need to remove the ' . ' from the URL. take this line: $.post("index.php?r=student/student-lists&id=' . '"+$("select#ascteacherreport-ascid").val(),function(data){ and change it to this: $.post("index.php?r=student/student-lists&id="+$("select#ascteacherreport-ascid").val(),function(data){ Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606813 Share on other sites More sharing options...
PrashantS Posted March 25, 2023 Author Share Posted March 25, 2023 I tried the line of code, but the problem still exists. All students are displayed Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606815 Share on other sites More sharing options...
kicken Posted March 25, 2023 Share Posted March 25, 2023 Use the browser's dev tools (networking tab) to inspect the URL and response of your ajax request. If the URL has the correct ID, but it's response includes all students then there is a problem in your PHP code somewhere. You'll have to start debugging that to determine why the ID filter is not being applied. Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606821 Share on other sites More sharing options...
PrashantS Posted March 27, 2023 Author Share Posted March 27, 2023 I change the code to below, but it has issue like previously selected students are getting cleared. $(document).ready(function(){ $(".dynamicform_student").on("afterInsert", function(e, item) { const $i = $(this).find('.i'); $.post("index.php?r=student/student-lists&id="+$("select#ascteacherreport-ascid").val(),function(data){ $i.html(data); }); }); }); When I inspect using Network tab, then first time when the user selects the ASC center, the URL gets the correct Id and response is also correct.(Only those students are getting displayed in response as well as in the field belonging to that ASC center) Image 1 : URL getting correct ID and response is also correct (ASC Center of Id 6 is getting correctly to the URL) Image 2: When user clicks on Add Student button to add new students, then also URL is getting correct ID as well as the response is also correct as shown in below image, but the previously selected students are getting cleared from the form. Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606862 Share on other sites More sharing options...
kicken Posted March 27, 2023 Share Posted March 27, 2023 If the selects are getting cleared, then const $i = $(this).find('.i'); probably is selecting too many items. You can check how many inputs it's selecting by logging it. console.log($i.length, $i); If it's selecting too much, you'll need to either find a way to narrow the selection or save and restore the selected item when changing the option list. Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606869 Share on other sites More sharing options...
PrashantS Posted March 27, 2023 Author Share Posted March 27, 2023 It is selecting too many items. By default one student row is present, and if user clicks on Add Student button then the length is 2 console.log($i.length, $i); Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606872 Share on other sites More sharing options...
kicken Posted March 27, 2023 Share Posted March 27, 2023 Log both e and item. console.log(e, item); See if either of those will help you narrow down the selection to just the newly added row. Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606874 Share on other sites More sharing options...
PrashantS Posted March 27, 2023 Author Share Posted March 27, 2023 $(document).ready(function(){ $(".dynamicform_student").on("afterInsert", function(e, item) { const $i = $(this).find('.i'); $.post("index.php?r=student/student-lists&id="+$("select#ascteacherreport-ascid").val(),function(data){ console.log(e,item); }); }); }); Doesn't logs anything on the console Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606875 Share on other sites More sharing options...
kicken Posted March 27, 2023 Share Posted March 27, 2023 35 minutes ago, PrashantS said: const $i = $(this).find('.i'); try const $i = $(item).find('.i'); Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606876 Share on other sites More sharing options...
PrashantS Posted March 27, 2023 Author Share Posted March 27, 2023 Yes it works correctly for the first time row. But when the user clicks on Add Time button to add students then the first student row of second time gets cleared and second student row of second time shows all the students. // When the user clicks on Add Student button $(document).ready(function(){ $(".dynamicform_student").on("afterInsert", function(e, item) { const $i = $(item).find('.i'); $.post("index.php?r=student/student-lists&id="+$("select#ascteacherreport-ascid").val(),function(data){ $i.html(data); }); }); }); //When the user clicks on Add Time button $(document).ready(function(){ $(".dynamicform_wrapper").on("afterInsert", function(e, item) { const $i = $(item).find('.i'); $.post("index.php?r=student/student-lists&id=' . '"+$("select#ascteacherreport-ascid").val(),function(data){ $i.html(data); }); }); }); Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606878 Share on other sites More sharing options...
PrashantS Posted March 28, 2023 Author Share Posted March 28, 2023 I made changes to the code and now it is working correctly. But on the update page it causes issue like all students are displayed for loaded fields. As shown in the image, it is the update page and student data is loaded but when the user clicks on the drop down of loaded student data then all students are displayed. // When the user clicks on Add Student button $(document).ready(function(){ $(".dynamicform_student").on("afterInsert", function(e, item) { const $i = $(item).find('.i'); $.post("index.php?r=student/student-lists&id="+$("select#ascteacherreport-ascid").val(),function(data){ $i.html(data); }); }); }); //When the user clicks on Add Time button $(document).ready(function(){ $(".dynamicform_wrapper").on("afterInsert", function(e, item) { const $i = $(item).find('.i'); $.post("index.php?r=student/student-lists&id="+$("select#ascteacherreport-ascid").val(),function(data){ $i.html(data); }); // When the user clicks on Add Student button $(".dynamicform_student").on("afterInsert", function(e, item) { const $i = $(item).find('.i'); $.post("index.php?r=student/student-lists&id="+$("select#ascteacherreport-ascid").val(),function(data){ $i.html(data); }); }); }); }); Quote Link to comment https://forums.phpfreaks.com/topic/316030-how-to-populate-nested-dynamic-form-inputs-with-data-from-server/#findComment-1606898 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.