Jump to content

How to identify each drop down uniquely of different rows of dynamic form


Go to solution Solved by mac_gyver,

Recommended Posts

I have a form allowing the user to enter students' attendance as shown in the image. The scenario is that the user selects the ASC center. Upon choosing the ASC center, students belonging to that ASC center get populated in the Student drop-down.

When the user selects Student, the student's standard should be displayed. I have a function called Standard that checks if the student's attendance record exists for the given academic year, ASC center, and student. If a record exists, then the standard of the student gets returned as shown below

public function actionStandard($aid,$ascid,$sid)
    {
		$count = \Yii::$app->db->createCommand("SELECT COUNT(*) from attendancereportdetails,attendancereport
					where attendancereportdetails.AttendanceReportId=attendancereport.AttendanceReportId
					and attendancereport.AcademicYearId=:ayear and attendancereport.ASCId=:acenter and attendancereportdetails.StudentId=:student and  
                    attendancereportdetails.Standard!=''")->bindValues([':ayear'=>$aid,':acenter'=>$ascid,':student'=>$sid])->queryAll();
		$count_result;
		foreach($count as $count_records)
		{
			$count_result = $count_records['COUNT(*)'];
		}

		$records = \Yii::$app->db->createCommand("SELECT * from attendancereportdetails,attendancereport
					where attendancereportdetails.AttendanceReportId=attendancereport.AttendanceReportId
					and attendancereport.AcademicYearId=:ayear and attendancereport.ASCId=:acenter and attendancereportdetails.StudentId=:student and 
                    attendancereportdetails.Standard!=''")->bindValues([':ayear'=>$aid,':acenter'=>$ascid,':student'=>$sid])->queryAll();

      if ($count_result > 0) {

			echo "<option value>Select Standard</option>";

            foreach ($records as $record) {
					ob_start();
				if($record['Standard']==0)
					echo "<option value=" . $record['Standard'] . ">" . 'Nursery' . "</option>";
				if($record['Standard']==1)
					echo "<option value=" . $record['Standard'] . ">" . '1st'. "</option>";
				if($record['Standard']==2)
					echo "<option value=" . $record['Standard'] . ">" . '2nd'. "</option>";
				if($record['Standard']==3)
					echo "<option value=" . $record['Standard'] . ">" . '3rd'. "</option>";
				if($record['Standard']==4)
					echo "<option value=" . $record['Standard'] . ">" . '4th'. "</option>";
				if($record['Standard']==5)
					echo "<option value=" . $record['Standard'] . ">" . '5th'. "</option>";
				if($record['Standard']==6)
					echo "<option value=" . $record['Standard'] . ">" . '6th'. "</option>";
				if($record['Standard']==7)
					echo "<option value=" . $record['Standard'] . ">" . '7th'. "</option>";
				if($record['Standard']==8)
					echo "<option value=" . $record['Standard'] . ">" . '8th'. "</option>";
				if($record['Standard']==9)
					echo "<option value=" . $record['Standard'] . ">" . '9th'. "</option>";
				if($record['Standard']==10)
					echo "<option value=" . $record['Standard'] . ">" . '10th'. "</option>";

            }
        } else {
			echo "<option value=''selected disabled>Select Standard</option>";
            echo "<option value=0>Nursery</option>";
			echo "<option value=1>1st</option>";
			echo "<option value=2>2nd</option>";
			echo "<option value=3>3rd</option>";
			echo "<option value=4>4th</option>";
			echo "<option value=5>5th</option>";
			echo "<option value=6>6th</option>";
			echo "<option value=7>7th</option>";
			echo "<option value=8>8th</option>";
			echo "<option value=9>9th</option>";
			echo "<option value=10>10th</option>";
        }
    }

 

Below is the image of the form. The problem occurring here is that the first student selected, his standard, is only getting populated in all other students' standards, as shown below. The requirement is that for each different student, their standard should only get populated in their corresponding Standard drop-down.

image.thumb.png.4a0bfd17e2ec5edaf0c1beafcb230e06.png

 

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 app\models\Academicyear;
use kartik\time\TimePicker;
use yii\helpers\ArrayHelper;
use app\models\Student;
?>
<script>
$(document).ready(function() {
$(".i").each(function(k,v){
$(".i").attr("disabled","true");
});
});

$(document).ready(function(){
  //When the user clicks on plus button
  
 $(".dynamicform_studentattendance").on("afterInsert", function(e, item) {
	const $i = $(item).find('.i');

   //Populates student names belonging to the selected ASC center
    $.post("index.php?r=student/student-lists&id="+$("select#attendancereport-ascid").val(),function(data){
 				$i.html(data);
					});
	});

	$(".dynamicform_studentattendance").on("afterInsert", function(e, item) {
	const $s = $(item).find('.s');
    
     //Populates standard for the selected student
      $.post("index.php?r=attendancereport/standard&aid="+$("select#attendancereport-academicyearid").val()+"&ascid="+$("select#attendancereport-ascid").val()+"&sid="+$(".s").val(),function(data){
			
        		$s.html(data);
					});
	});
});
</script>

<div class="attendancereport-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>Student Attendance Report</b></font></div>
<div class="row">
<div class="col-sm-4">

   <?=	$form->field($model, 'AcademicYearId')->dropDownList(ArrayHelper::map(Academicyear::find()->where(['DisplayStatus'=>'Enabled'])->all(),'Id','academicyear'), ['prompt' => 'Select Academic Year'])?>

	</div>

<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").attr("disabled",false);
						 $(".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'=>false,
											'changeYear'=>false,
											'maxDate'=>'today',
											 'stepMonths'=> false,
											],

]) ?>
</div>
</div>
</div>
<div class="panel panel-primary">
		<div class="panel-heading"><font size="3"><b>Student Attendance Details</b></font></div>
<?php DynamicFormWidget::begin([
		'widgetContainer' => 'dynamicform_studentattendance',
		'widgetBody' => '.container-studentattendance',
		'widgetItem' => '.studentattendance-item',
		'limit' =>500,
		'min' => 1,
		'insertButton' => '.add-studentattendance',
		'deleteButton' => '.remove-studentattendance',
		'model' => $modelsStudentattendance[0],
		'formId' => 'dynamic-form',
		'formFields' => [
			'StudentId',
			'Standard',
			'AttendanceStatus',
		],
	]); ?>
	<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;'>Standard</th>
				<th class ="text-center" style='border: 1px solid black;'>Attendance Status</th>
				<th class="text-center" style='border: 1px solid black;'>Action</th>
			</tr>
		</thead>
		<tbody class="container-studentattendance">
		<?php foreach ($modelsStudentattendance as $indexStudent => $modelStudentattendance): ?>
			<tr class="studentattendance-item">
				<td class="vcenter" style='border: 1px solid black;'>
					<?php
						// necessary for update action.
						if (! $modelStudentattendance->isNewRecord) {
							echo Html::activeHiddenInput($modelStudentattendance, "[{$indexStudent}]AttendanceReportDetailsId");
						}
					?>
					</td>
					<td style='border: 1px solid black;'>


				 <?= $form->field($modelStudentattendance, "[{$indexStudent}]StudentId")->label(false)->dropDownList(ArrayHelper::map(Student::find()->all(),'StudentId','StudentName'), ['prompt' => 'Select Student','class'=>'form-control i','onChange'=>'
			$.post("index.php?r=attendancereport/standard&aid=' . '"+$("select#attendancereport-academicyearid").val()+"&ascid=' . '"+$("select#attendancereport-ascid").val()+"&sid=' . '"+$(".i").val(),function(data){

                        $(".s").each(function(k,v)
						{
						 $(".s").html(data); //Populates the Standard drop-down having class .s with the data from the Standard function
						}
						);
                    });

	']) ?>
				</td>

				<td style='border: 1px solid black;'>

						<?= $form->field($modelStudentattendance, "[{$indexStudent}]Standard")->label(false)->dropDownList([], ['prompt'=>'Select Standard','class'=>'form-control s']) ?>

				</td>

				<td style='border: 1px solid black;'>


				 <?= $form->field($modelStudentattendance, "[{$indexStudent}]AttendanceStatus")->label(false)->dropDownList(['Present'=>'Present', 'Absent' => 'Absent'], ['prompt'=>'Select Attendance Status'])?>
				</td>

				<td class="text-center vcenter" style='border: 1px solid black;'>
				<button type="button" class="add-studentattendance btn btn-success btn-xs"><span class="fa fa-plus"></span></button>
					<button type="button" class="remove-studentattendance 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']) ?>
		 <?= Html::resetButton('Reset',['class' => 'btn btn-default'])?>
    </div>

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

</div>

 

the most immediate problem is that the onChange code for the Student select/option menu needs to get the correct sid value. by using $(".i") you are getting a collection of all the class = i elements, not the current one. using $(this) should work (all suggestions are untested unless indicated otherwise.)

next, requiring the user to select each student from a select/option menu is a poor User Interface (UI) and provides a bad User eXperience (UX). you should simply list out each Student, the Standard select/option menu with any existing choice pre-selected, and the Attendance select/option menu with the Present choice pre-selected (the most common case.) the user should only need to make the fewest number of changes to the choices and submit the form, so, only make any Standard changes and select which students are Absent.

I modified the code as you said, but now what is happening is that when the user selects the first student, then his Standard 3rd gets populated in the corresponding Standard drop-down, but when the user clicks on the plus button and selects the second student, then her Standard 4th gets populated in the first student Standard drop-down as well.

Modified code

<?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 app\models\Academicyear;
use kartik\time\TimePicker;
use yii\helpers\ArrayHelper;
use app\models\Student;
?>
<script>
$(document).ready(function() {
$(".i").each(function(k,v){
$(".i").attr("disabled","true");
});
});

$(document).ready(function(){
  //When the user clicks on plus button
  
 $(".dynamicform_studentattendance").on("afterInsert", function(e, item) {
	const $i = $(item).find('.i');

   //Populates student names belonging to the selected ASC center
    $.post("index.php?r=student/student-lists&id="+$("select#attendancereport-ascid").val(),function(data){
 				$i.html(data);
					});
	});

	$(".dynamicform_studentattendance").on("afterInsert", function(e, item) {
	const $s = $(item).find('.s');
    
     //Populates standard for the selected student
      $.post("index.php?r=attendancereport/standard&aid="+$("select#attendancereport-academicyearid").val()+"&ascid="+$("select#attendancereport-ascid").val()+"&sid="+$(this).val(),function(data){
			
        		$s.html(data);
					});
	});
});
</script>

<div class="attendancereport-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>Student Attendance Report</b></font></div>
<div class="row">
<div class="col-sm-4">

   <?=	$form->field($model, 'AcademicYearId')->dropDownList(ArrayHelper::map(Academicyear::find()->where(['DisplayStatus'=>'Enabled'])->all(),'Id','academicyear'), ['prompt' => 'Select Academic Year'])?>

	</div>

<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").attr("disabled",false);
						 $(".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'=>false,
											'changeYear'=>false,
											'maxDate'=>'today',
											 'stepMonths'=> false,
											],

]) ?>
</div>
</div>
</div>
<div class="panel panel-primary">
		<div class="panel-heading"><font size="3"><b>Student Attendance Details</b></font></div>
<?php DynamicFormWidget::begin([
		'widgetContainer' => 'dynamicform_studentattendance',
		'widgetBody' => '.container-studentattendance',
		'widgetItem' => '.studentattendance-item',
		'limit' =>500,
		'min' => 1,
		'insertButton' => '.add-studentattendance',
		'deleteButton' => '.remove-studentattendance',
		'model' => $modelsStudentattendance[0],
		'formId' => 'dynamic-form',
		'formFields' => [
			'StudentId',
			'Standard',
			'AttendanceStatus',
		],
	]); ?>
	<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;'>Standard</th>
				<th class ="text-center" style='border: 1px solid black;'>Attendance Status</th>
				<th class="text-center" style='border: 1px solid black;'>Action</th>
			</tr>
		</thead>
		<tbody class="container-studentattendance">
		<?php foreach ($modelsStudentattendance as $indexStudent => $modelStudentattendance): ?>
			<tr class="studentattendance-item">
				<td class="vcenter" style='border: 1px solid black;'>
					<?php
						// necessary for update action.
						if (! $modelStudentattendance->isNewRecord) {
							echo Html::activeHiddenInput($modelStudentattendance, "[{$indexStudent}]AttendanceReportDetailsId");
						}
					?>
					</td>
					<td style='border: 1px solid black;'>


				 <?= $form->field($modelStudentattendance, "[{$indexStudent}]StudentId")->label(false)->dropDownList(ArrayHelper::map(Student::find()->all(),'StudentId','StudentName'), ['prompt' => 'Select Student','class'=>'form-control i','onChange'=>'
			$.post("index.php?r=attendancereport/standard&aid=' . '"+$("select#attendancereport-academicyearid").val()+"&ascid=' . '"+$("select#attendancereport-ascid").val()+"&sid=' . '"+$(this).val(),function(data){

                       
						 $(".s").html(data); //Populates the Standard drop-down having class .s with the data from the Standard function
						
                    });

	']) ?>
				</td>

				<td style='border: 1px solid black;'>

						<?= $form->field($modelStudentattendance, "[{$indexStudent}]Standard")->label(false)->dropDownList([], ['prompt'=>'Select Standard','class'=>'form-control s']) ?>

				</td>

				<td style='border: 1px solid black;'>


				 <?= $form->field($modelStudentattendance, "[{$indexStudent}]AttendanceStatus")->label(false)->dropDownList(['Present'=>'Present', 'Absent' => 'Absent'], ['prompt'=>'Select Attendance Status'])?>
				</td>

				<td class="text-center vcenter" style='border: 1px solid black;'>
				<button type="button" class="add-studentattendance btn btn-success btn-xs"><span class="fa fa-plus"></span></button>
					<button type="button" class="remove-studentattendance 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']) ?>
		 <?= Html::resetButton('Reset',['class' => 'btn btn-default'])?>
    </div>

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

</div>

 

Edited by PrashantS
Modified code

that's because the current code is looping over the collection of class = s elements, and setting them all to the data that is returned -

$(".s").each(function(k,v)
	{
		$(".s").html(data); //Populates the Standard drop-down having class .s with the data from the Standard function
	}
);

you need to 'find' the correct class = s element and set it to the data that is returned. take a look at the jquery .parent() method to find a common parent container that all the related form fields are in, then use the jquery .find() method to find the element with class = s.

I tried using the below codes, but it still populates all the students' Standard drop-down 

 $(".container-studentattendance").find(".s").html(data);

 $(".container-studentattendance").find(".studentattendance-item").find(".s").html(data);


 $(".studentattendance-item").find(".s").html(data);

 

  • Solution

i don't know what this will look like incorporated into the yii syntax, but this is what i used with just jquery/javascript -

	// the element that was clicked on
	var e = $(this);
	$.post("index.php?r=attendancereport/standard&aid="+$("#academicyearid").val()+
		"&ascid="+$("#ascid").val()+"&sid="+e.val(),function(data){
		e.closest('tr').find('.s').html(data);
	});

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.