This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.

wilirius15434
wilirius15434

Full scenario:

You have a Grade form.

The Grade form has a semester field.

In the Semester record that it relates to, that Semester has a "is grading open" boolean field.

How can you prevent grades from being edited/created in the Grade form while it is related to a Semester that has "is grading open" set to false?

Last updated

wilirius15434
wilirius15434

Pretty sure I got this.

First off, disable the field in the form from inside the controller's formExtendFields method.

public function formExtendFields($form)
{
    if( isset( $form->data->attributes['semester_id']) ) {
        $isGradingOpen = Semester::find($form->data->attributes['semester_id'])->is_grading_open;

        // Disable grade based on Semester            
        if( !$this->user->hasAccess('example.plugin.edit_all_fields_grades') && !$isGradingOpen ) {
            $form->removeField('student_grade');

            $form->addFields([
                'student_grade' => [
                    'label' => 'Grade',
                    'span' => 'auto',
                    'type' => 'text',
                    'attributes' => [
                        'disabled' => true
                    ]
                ]
            ]);   
        }
    }
}

Then give them a nice message telling them nah you can't do that by overriding the update_onSave method.

public function update_onSave($recordId, $context = null)
{
    $thisForm = post('Grade');
    $thisRecord = Grade::find($recordId);

    // If trying to change the grade, and the new grade is not equal to the old grade
    if( isset($thisForm['student_grade']) && $thisForm['student_grade'] !== $thisRecord->student_grade ) {

        $isGradingOpen = $thisRecord->semester->is_grading_open;

        // If this user does not have the permission to make this change currently    
        if( !$this->user->hasAccess('example.plugin.edit_all_fields_grades') && !$isGradingOpen ) {

            // Then deny
            Flash::error('You do not have permission to change the grade at this time.');
        }else {

            // Otherwise proceed, call the original update_onSave method
            return $this->asExtension('FormController')->update_onSave($recordId, $context);
        }
    }else {
        // Otherwise proceed, call the original update_onSave method
        return $this->asExtension('FormController')->update_onSave($recordId, $context);
    }
}

And then finally, now that all the visual stuff is set up, guarantee that the model won't update when it shouldn't. This is in the model's beforeSave method.

public function beforeSave()
{
    /**
    * Cancel if attempting to input grade when grading isn't open
    */
    if( isset( $this->semester_id ) && isset( $this->student_grade )  ) {
        $isGradingOpen = Semester::find($this->semester_id)->is_grading_open;

        // Disable grade based on Semester            
        if( !$user->hasAccess('example.plugin.edit_all_fields_grades') && !$isGradingOpen ) {
            return false;
        }
    }         

I don't believe there's any way to get around this, but I do not know if there exists a simpler way to accomplish this.

Last updated

daftspunky
daftspunky

Take a look at the filterFields method in the model, see the docs on how to use it.

wilirius15434
wilirius15434

That's awesome, thanks.

Switched almost everything from extendFields into filterFields. Works great for changing a field to type=text, change value, and disabling it so to show a locked out RecordFinder.

One thing I ran into is that while I could change the scope parameter from within the filterFields, it would not actually apply the scope.

Last updated

1-4 of 4

You cannot edit posts or make replies: the forum has moved to talk.octobercms.com.