Astrotomic / laravel-translatable

A Laravel package for multilingual models
https://docs.astrotomic.info/laravel-translatable/
MIT License
1.25k stars 157 forks source link

Validation for multiple fields #191

Closed ArtMin96 closed 4 years ago

ArtMin96 commented 4 years ago

Hi.

There are fields that are subject to cloning and should be validated and display messages for each field. Can you help me to figure out this?

edit.blade.php

@foreach(config('app.locales') as $key => $locale)
    <div class="card-body switch-translatable-fields p-0 d-none {{ $locale }}-form @if($key == 0) d-block @endif">
        <div class="form-group">
            <label class="required" for="{{ $locale }}_title">{{ trans('Page content title') }} ({{ \Illuminate\Support\Str::upper($locale) }})</label>
            <input class="form-control @error($locale.'.title') is-invalid @enderror" type="text" name="{{ $locale }}[title][{{ $key }}]" id="{{ $locale }}_title" value="{{ old($locale.'.title', !empty($pageContent->translate($locale)->title)? $pageContent->translate($locale)->title : '') }}">

            @error($locale.'.title')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror

        </div>

        <div class="form-group">
            <label class="required" for="{{ $locale }}_description">{{ trans('Page content description') }} ({{ \Illuminate\Support\Str::upper($locale) }})</label>
            <input class="form-control @error($locale.'.description') is-invalid @enderror" type="text" name="{{ $locale }}[description][{{ $key }}]" id="{{ $locale }}_description" value="{{ old($locale.'.description', !empty($pageContent->translate($locale)->description)? $pageContent->translate($locale)->description : '') }}">

            @error($locale.'.description')
                <span class="invalid-feedback" role="alert">
                    <strong>{{ $message }}</strong>
                </span>
            @enderror

        </div>
    </div>
@endforeach

PageContentRequest.php

public function rules()
{
    $rules = [
        '%title%' => 'required|string',
        '%description%' => 'required|string',
        'image' => 'file|max:5000|mimes:png,jpg,jpeg,gif',
    ];

    foreach(['en', 'ru', 'hy'] as $key => $locale)
    {
        $rules['%title%.'.$key] = 'required';
        $rules['%description%.'.$key] = 'required';
    }

    if ($this->request->get('has_link')) {
        foreach($this->request->get('has_link') as $key => $val)
        {
            $rules['button_type.'.$key] = 'required_if:has_link,0|required_if:has_link,1';
            $rules['link_title.'.$key] = 'required_if:has_link,0|required_if:has_link,1';
            $rules['image.'.$key] = 'file|max:5000|mimes:png,jpg,jpeg,gif';
        }
    }

    return RuleFactory::make($rules);
}

PageContentController.php

public function update(PageContentRequest $request, $id)
{

    $request->validated();

}
Gummibeer commented 4 years ago

Hey,

the easiest approach should be something like this:

view

@foreach(app(\Astrotomic\Translatable\Locales::class)->all() as $locale)
    <input type="text" name="title[{{ $locale }}]"/>
    <input type="text" name="description[{{ $locale }}]"/>
@endforeach

rules

return RuleFactory::make([
    '%title%' => 'required|string',
    '%description%' => 'required|string',
    'image' => 'file|max:5000|mimes:png,jpg,jpeg,gif',
]);

That's it - with this you should get title and description as an array with the locales as key and translations as value in your request which the packagesfill()method can handle so you just have to do$model->fill($request->validated())`.

The rules returned by the rule factory will mirror this as an array with the title and description listed for every locale in dot.notation - like title.en.

https://docs.astrotomic.info/laravel-translatable/package/validation-rule-factory

ArtMin96 commented 4 years ago

Thanks for the quick response. I tried the option you suggested but again some problems arise. In your package, everything is good. I have another problem right now. Maybe I'll try again later and use your answer. I close the question.