Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

noblemfd's avatar

How to make students not to score beyond the max mark

I am using Laravel-5.8 for a web application project. In the project I have these tables:

class SubjectCategory extends Model
{   
  protected $table = 'subject_categories';
  protected $fillable = [
              'name',
              'parent_id',
              'max_mark',
          ];

   public function children()
   {
     return $this->hasMany('App\Models\SubjectCategory', 'parent_id');
   }

  public function exams()
  {
    return $this->hasMany('App\Models\Exam');
  }
}

class Exam extends Model
{
  protected $table = 'exams';
  protected $fillable = [
              'subject_category_id',
              'student_id',
              'student_mark',
              'subject_name',
          ];

  public function subjectcategory()
  {
    return $this->belongsTo('App\Models\SubjectCategory','subject_category_id');
  }  
}

SubjectCategory is an hierarchical table. Only the parent have the max_mark

Here is the Controller

public function create()
{
 $categories = SubjectCategory::with('children')->whereNull('parent_id')->get();

return view('exams.create')
        ->with('categories', $categories);
}
public function store(StoreExamRequest $request)
{

    $exam = new Exam();
    $exam->stubject_category_id     = $request->stubject_category_id;
    $exam->student_id              = $student_id;
    $exam->student_mark             = $request->student_mark;
    $exam->save();
        return redirect()->route('exams.index');
}

view blade

<div class="row">
        <div class="col-md-12">
        <!-- general form elements -->
         <div class="card card-secondary">
          <form  method="POST" action="{{route('exams.store')}}">
          @csrf
       <div class="card-body">
        <div class="form-body">
        <div class="row">
            
          <div class="col-12 col-sm-6">
            <div class="form-group">
              <label class="control-label"> Subject Category:<span style="color:red;">*</span></label>
              <select id="subject_category" class="form-control" name="subject_category_id">
                <option value="">Select Subject Category</option>

                @foreach ($categories as $category)
                  <option disabled="disabled" value="{{ $category->id }}" {{ $category->id == old('category_id') ? 'selected' : '' }}>{{ $category->name }}</option>

                  @if ($category->children)
                    @foreach ($category->children as $child)
                      <option value="{{ $child->id }}" {{ $child->id == old('category_id') ? 'selected' : '' }}>&nbsp;&nbsp;{{ $child->name }}</option>
                    @endforeach
                  @endif
                @endforeach
              </select>
            </div>
          </div>    
            
          <div class="col-12 col-sm-6">
            <div class="form-group">
              <label class="control-label"> Subject Name:<span style="color:red;">*</span></label>
              <input  type="text" name="subject_name" placeholder="Enter Subject Name here" class="form-control">
            </div>
          </div>

          <div class="col-12 col-sm-4">
            <div class="form-group">
              <label class="control-label"> Mark Obtained:</label>
              <input  type="number" name="student_mark" placeholder="Enter Mark Obtained here" class="form-control">
            </div>
          </div>  


       </div>
     </div>
    </div>          
    <!-- /.card-body -->
    <div class="card-footer">
      <button type="submit" class="btn btn-primary">Save</button>
    </div>           
       
    </form>
    </div>
    <!-- /.card -->
   </div>
   <!--/.col (left) -->
  </div>

Subjects are categorized. From SubjectCategory, the parent subject have sub subjects as children. Only the Parent Subject Category have the Maximum Obtainable Score (Max Mark).

From the Exam (subject_category_id) dropdownlist contains all the children fields from subject_categories. What I want to achieve is this:

When Subject Category is selected from the dropdownlist, the system goes to the exams table. It displays total student_mark based on student_id and subject_category_id.

In each subject, the student accumulated mark cannot be more than the max_mark in the parent subject_category.

When the user tries to enter data into student_mark text field, the application adds the value in the text field to the student aggregate. If the result is more than the max_mark in subject_categories (SubjectCategory) based on the parent max_mark, then an error message is displayed.

How do I achieve this?

0 likes
11 replies
willvincent's avatar

How do I achieve this?

In a word... Javascript.

Make a request whenever the category is changed, to gather requisite child form element data, then build the form accordingly.

Sounds like you'll also need client side validation (more javascript).

Implementing this form as a vue component would probably be your best bet, but regardless, you'll not accomplish it with blade alone.

onetwothreeneth's avatar

in your controller

public function store(Request $request)
{
    $validatedData = $request->validate([
        'score' => 'required|max:100' 
    ]);
}

noblemfd's avatar

Its not the issue of validation. I think its to write some Javascript

iristechph's avatar

if you are using jquery you can do this.

<body>
    <input name="student_mark" type="number" id="student_mark">
    <script
              src="https://code.jquery.com/jquery-3.4.1.min.js"
              integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
              crossorigin="anonymous"></script>
    <script>
        $(() => {
            $('#stundent_mark').keyup(function() {
                let number = parseInt($(this).val())
                               if(number <= 100) {
                    $(this).removeAttr('readonly')
                } else {
                    $(this).attr('readonly', true)
                }
            })
        })
    </script>
</body>
bugsysha's avatar

No need for Javascript. Just on that input tag add attribute <input type="number" max="100">.

noblemfd's avatar

It will need compare what the user entered to the setting in the database.

noblemfd's avatar

I think I'm getting some some clue from what you posted. The only thing is that the max score is not fixed. Based on my question the application will validate all the scores of the student (obtained score) based on the subject_group score with the subject_group score (obtainable score) in the database.

iristechph's avatar

you can do this also <input type="number" max="{{ default.max }}">

Please or to participate in this conversation.