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

duddy67's avatar

Validation rule: add extra parameters ?

Hi, I use AJAX to update the user comments, and I need to pass an extra parameter (the comment id) whenever the validation fails (error 422).

Here is what I have so far:

class UpdateCommentRequest extends FormRequest
{
    /** 
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {   
        return true;
    }   

    /** 
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {   
        return [
            'comment-'.$this->comment->id => 'required',
        ];  
    }   

    public function messages()
    {   
        return [
            'comment-'.$this->comment->id.'.required' => 'Your comment cannot be empty.'
        ];  
    }   
}

The HTML

@foreach ($post->comments as $comment)
    <div class="card mb-4">
        <div class="card-header">
            {{ __('labels.post.posted_by', ['author' => $comment->author]) }} at @date ($comment->created_at->tz($timezone))

            @if (auth()->check() && Auth::user()->id == $comment->owned_by)
                <button type="button" id="delete-btn-{{ $comment->id }}" data-comment-id="{{ $comment->id }}" class="btn btn-space btn-danger float-end">@lang ('labels.button.delete')</button>
                <span class="float-end">&nbsp;</span>
                <button type="button" id="edit-btn-{{ $comment->id }}" data-comment-id="{{ $comment->id }}" class="btn btn-space btn-primary float-end">@lang ('labels.button.edit')</button>

                <div class="alert alert-success alert-block flash-message d-none" id="ajax-message-alert-{{ $comment->id }}">
                    <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
                    <strong id="ajax-message-{{ $comment->id }}"></strong>
                </div>

                <form id="updateComment-{{ $comment->id }}" action="{{ route('post.comment.update', ['comment' => $comment]) }}" style="display:none;" method="post">
                    @method('put')
                    @csrf

                    <textarea name="comment-{{ $comment->id }}" id="tiny-comment-{{ $comment->id }}" data-comment-id="{{ $comment->id }}" class="tinymce-texteditor">{{ $comment->text }}</textarea>
                    <button type="button" id="update-btn-{{ $comment->id }}" data-comment-id="{{ $comment->id }}" class="btn btn-space btn-success mt-2">@lang ('labels.button.update')</button>
                    <button type="button" id="cancel-btn-{{ $comment->id }}" data-comment-id="{{ $comment->id }}" class="btn btn-space btn-info mt-2">@lang ('labels.button.cancel')</button>
                    <div class="text-danger mt-2" id="comment-{{ $comment->id }}Error"></div>
                </form>

                <form id="deleteComment-{{ $comment->id }}" action="{{ route('post.comment.delete', ['id' => $comment->id]) }}" method="post">
                    @method('delete')
                    @csrf
                </form>
            @endif
        </div>
        <div id="comment-{{ $comment->id }}" class="card-body">
            {!! $comment->text !!} 
        </div>
    </div>
@endforeach

Is there any trick or specific method for that (I haven't seen any in the documentation) ?

Thanks

0 likes
11 replies
tykus's avatar

Why is the input named like this at all - you are updating a single Comment; why does the input need a dynamic, numeric suffix?

duddy67's avatar

@tykus It's a convenient way to spot the comment that is currently updating as each comment has its own error placeholder. Variables are indexed with the comment id: eg: comment-5, comment-8 etc...

tykus's avatar

@duddy67 what does the HTML look like for this?

I would maybe consider using named error bags instead

tykus's avatar

@duddy67 are you sending an AJAX request; I don't see where the validation errors are being output?

duddy67's avatar

@tykus The errors are output in the following div: <div class="text-danger mt-2" id="comment-{{ $comment->id }}Error">

duddy67's avatar

@tykus Through the AJAX result variable:

for (const [name, message] of Object.entries(result.errors)) { document.getElementById(name+'Error').innerHTML = message; }

tykus's avatar

@duddy67 as I supposed. If you are using JS, then you know the form element that triggered the request; so why not use that information to set the correct error message from the Response rather than messing with dynamically named form elements?

Just use comment as the textarea name.

duddy67's avatar

@tykus There are many comments, thus many textarea tags and just as the id attribute, the name attribute has to be unique or troubles might occur.

Extracting the id from the name variable with a regex might be the best option here.

duddy67's avatar
duddy67
OP
Best Answer
Level 1

Ok I got it. I added the failedValidation method in my FormRequest class:

use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Contracts\Validation\Validator;

class UpdateCommentRequest extends FormRequest
{

       ...

    protected function failedValidation(Validator $validator)
    {   
        throw new HttpResponseException(response()->json(['errors' => $validator->errors(), 'status' => true, 'commentId' => $this->comment->id], 422));
    }  
}

Now I can pass as many parameters as I want through the array argument.

Hope it helps.

1 like

Please or to participate in this conversation.