Validation not working correctly in Laravel Livewire - laravel

I dont know what I am doing wrong. I have some fields with images, I want to do an update to the database only if there is an image. I have tried setting to nullable but I keep on getting error the photo must be of type image.
This is my code in Livewire class:
$this->validate([
'photo1'=>'sometimes|image',
'photo2'=>'nullable|image',
'photo3'=>'nullable|image'
]);
In the blade
<div class="col-md-6">
<label>Front Right</label>
<input type="file" wire:model="photo1" accept="image/*">
<span class="text-danger">#error('photo1'){{ $message }}#enderror</span>
</div>
<div class="col-md-6">
<label>Flont Left</label>
<input type="file" wire:model="photo2" accept="image/*">
<span class="text-danger">#error('photo2'){{ $message }}#enderror</span>
</div>
</div>

Probably it's bit late for it, but I had the same issue and this is the solution:
If you are using updated instead of updating it will work. The problem when using updating is that the property does not have the file assigned, so it's still null during validation.
Let's say your are using updating() and your property name is $logo:
You would need to assign the $value to the property ($logo) before validation, e.g.:
function updating($key,$value) {
$this-logo = $value; // This line you need to add to make it work
$this-validateOnly($key);
}
I do simply use updated() instead.

Have you added enctype="multipart/form-data" in form element?
Add mimes in validation: 'photo2'=>'nullable|image|mimes:jpg,jpeg,png,svg,gif' and then check if it works.

Related

how to pass callback function in component? (laravel alpine.js)

I make a draft implementation for my reusable input component.
The code below obviously throws an error.
Question is how to pass the $event back to register blade to get or log the value of the input?
register.blade.php
<div>
<x-input onChange="(value) => {console.log('value', value)}"></x-input>
<div/>
input.blade.php
#props(['onChange' => 'null'])
<input x-on:change="{{ $onChange($event) }}">
A few things here.
First off, your markup is wrong. You have a the closing slash at the wrong end of the closing div. Should be </div> not <div/>.
Then you're using x-on without x-data. Alpine only picks up components with the x-data attribute.
Finally, events propagate automatically, so you could just listen on the parent instead:
{{-- register.blade.php --}}
<div x-data>
<x-input x-on:change="console.log('value', $event.target.value)" />
</div>
{{-- input.blade.php --}}
<input {{ $attributes }}>
I learned we could just achieve this through Alpine.Js dispatch. I don't need to pass onClick props via Laravel component. I just simply use dispatch to listen the event (x-on).
What I like in this implementation is that,
aside of event information, passing of extra data is easy
you don't have to use Laravel props and assigned unnecessary props in the tag.
register.blade.php
<div>
<x-input x-on:custom-input="console.log('your values =', $event.target.newValue)"
></x-input>
<div/>
input.blade.php
<input x-on:change="$dispatch('custom-input', { newValue: $event.target.value })">
you can pass "key" prop to distinguish each component.

Validation on checkbox where one one checkbox must be checked in laravel

I have the following Checkboxes now a want put validation in checkbox that one checkbox must be checked . But i dont't know how to do that.
CheckBox
<div class="form-group clearfix">
<label for="" class="col-sm-2 col-form-label">Arch (es) </label>
<div class="col-sm-10">
<label class="control-label" for="inputError" style="color: red"><i
id="arch_upper_error"></i></label>
<div class="demo-checkbox">
<input id="md_checkbox_1" name="arch_upper" value="41" class="chk-col-black"
type="checkbox">
<label for="md_checkbox_1">Upper</label>
<input id="md_checkbox_2" name="arch_lower" value="41" class="chk-col-black"
type="checkbox">
<label for="md_checkbox_2">Lower</label>
</div>
</div>
</div>
I tried this in laravel validation but i know its wrong because it required for both but i want at least one checkbox is checked.
public function rules()
{
return [
'arch_lower' => 'required',
'agarch_upper' => 'required',
,
];
}
I think you could use Laravel's required-without method:
The field under validation must be present and not empty only when any
of the other specified fields are not present.
Implementation would look something like this:
'arch_upper' => 'required_without: arch_lower',
If, by any chance, you have more checkboxes, you could use required-without-all:
The field under validation must be present and not empty only when all
of the other specified fields are not present.
Implementation:
'arch_upper' => 'required_without_all: arch_lower,another_checkbox',
Note: Code is not tested, if you encounter any errors, let me know.
You can read more on Laravel's official documentantion.

:value="form.name | slugify" conflicts with v-model on the same element because the latter already expands to a value binding internally

I have a value i want to save to the database as a slug generated from the name. The problem is I cannot use both v-model and :value in the same input field. what is the solution to this? I am using laravel and vuejs. How can i solve this error?
<div class="modal-body">
<div class="form-group">
<label>Slug</label>
<input v-model="form.slug" :value="form.name | slugify" type="text" name="slug"
placeholder="downtown-dubai"
class="form-control" :class="{ 'is-invalid': form.errors.has('slug') }">
<has-error :form="form" field="slug"></has-error>
</div>
</div>
Just generate slug from the name on the backend.
From the Frontend, you only send name and other needed fields, while on the backend you use that name to create a slug.
The easiest and most direct way would by to use v-model="form.name" and get rid of the :value attribute, then just update form.slug using the data from form.name in the function that submits the form. Example:
submitForm() {
this.form.slug = this.$options.filters.slugify(this.form.name)
// Submit the form...
},
If the form.slug field is actually displayed on the page and needs to immediately be reactive, you could also update it using a watcher for form.name like this.
watch: {
'form.name'() {
this.form.slug = this.$options.filters.slugify(this.form.name)
},
},

laravel 5.5 | old() empty in view unless $request->flash() used

I've run into an odd issue where the helper function old() always returns null in a blade view unless $request->flash() is used prior to loading the view. I have never had to do this when using laravel in the past. Did something change or is there something that I have forgotten to set/configure. Below is a simple example of the behavior:
web.php
Route::get('/test', function(){
return view('testView');
});
Route::post('/test', function(Illuminate\Http\Request $request){
$request->flash(); // if uncommented old() works, if commented old() does not work
return view('testView');
});
form in testView.blade.php
<form action="/test" method="POST">
{{csrf_field()}}
<input type="hidden" name="test001" value="001"/>
<input type="hidden" name="test002" value="002"/>
<div class="">
{{old('test001')}}
<br/>
{{old('test002')}}
</div>
<button type="submit">GO</button>
</form>
after form submitted without $request->flash()
after form submitted with $request->flash()
EDIT
Thinking this might have something to do with using a single route name for both post and get methods, the form was changed so to submit via get, and the issue persists. For example:
web.php
Route::get('/test', function(function(Illuminate\Http\Request $request){
return view('testView');
});
form in testView.blade.php
<form action="/test" method="GET">
<input type="hidden" name="test001" value="001"/>
<input type="hidden" name="test002" value="002"/>
<div class="">
{{old('test001')}}
<br/>
{{old('test002')}}
</div>
<button type="submit">GO</button>
</form>
Use redirect back() instead of loading view directly in a post method.
return redirect()->back()->withInput();
You need to flash request data to put old input into session, otherwise old() will return empty result. See official doc here.

How do I use an Angular.JS generated form to upload a file (and other fields) through AJAX to Symfony2?

I'm trying to send a form generated by Angular.js through an AJAX call to a Symfony controller action in order to be saved. The form is generated in an ng-repeat after receiving some JSON data (including an entry ID). The code looks as follows.
<div ng-repeat="job in sc.careers">
<div>
<h2>{[{job.title}]}</h2>
<span ng-if="job.super">{[{job.super}]}</span>
<div>
<h4>Role</h4>
<span ng-bind-html="job.role"></span>
</div>
<div class="col-md-4">
<h4>Required Skills</h4>
<span ng-bind-html="job.skills"></span>
</div>
<div class="col-md-4">
<h4>Media</h4>
Some other content \ media
</div>
</div>
<hr/>
<div class="join-us">
<button ng-click="sc.joinUs[$index] = true" ng-hide="sc.joinUs[$index]">Apply for this position</button>
<div ng-show="sc.joinUs[$index]">
<h4>Join Us</h4>
<span>Some random text</span>
<form>
<input type="hidden" name="job_id" value="{[{job.id}]}" />
<label for="email">E-Mail</label>
<input type="email" id="email" name="email" />
<label for="motivation">Cover Letter & CV link</label>
<textarea id="motivation" name="motivation"></textarea>
<label for="resume">Upload your resume</label>
<input type="file" name="resume">
<button type="submit">Send your application</button>
</form>
</div>
</div>
</div>
* most class names have been redacted to keep the code as relevant to the question as possible
I have not yet placed an ng-click -> submit directive. Also, my Angular is configured for the use of the "{[{" and "}]}" delimiters so as not to interfere with TWIG.
I have searched the internet for possible answers but they all pertain to Symfony generated forms (which include validation tokens). Other answers (such as this one) don't quite describe the Angular side of things or don't describe sending the entire form.
In the end, I'm not exactly sure how to approach this. If it's too complicated I'd even settle for not using AJAX at all and submitting directly to Symfony. (actually, the only reason I want to use AJAX is to make the site feel more "snappy").
For what it's worth I'm using the latest stable versions of PHP, Symfony and Angular.JS at the time of writing.
Update
So i managed to send the data back to the controller by using an Agular JS module that enables the use of ng-model on file inputs and by using FormData like so:
var formObject = new FormData;
formObject.append('email', self.careers[index].application.email);
formObject.append('motivation', self.careers[index].application.motivation);
formObject.append('resume', self.careers[index].application.file);
formObject.append('jobID', self.careers[index].id);
$http.post('/app_dev.php/jobs/apply', formObject, {
transformRequest: angular.identity,
headers: { 'Content-Type': undefined } // Allows angular to choose the proper Content-Type
})
The only problem left now is that Symfony does not recognize my form data as being valid. The controller action looks like this (for now).
public function applyAction(Request $request) {
$jobApplication = new JobApplications(); // This is the entity I use to store everything.
$form = $this->createFormBuilder($jobApplication)
->add('jobId')
->add('email')
->add('coverLetter')
->add('file')
->getForm();
$form->handleRequest($request);
$response = array (
'isValid' => $form->isValid(), // false
'isSubmitted' => $form->isSubmitted(), // false < that's why the form is invalid
'isErrors' => $form->getErrorsAsString() // empty array
);
if ($form->isValid()) { // is not valid so the following section is not complete
$em = $this->getDoctrine()->getManager();
$jobApplication->upload();
$em->persist($jobApplication);
$em->flush();
//return $this->redirect($this->generateUrl('idea_presentation_careers'));
}
return new JsonResponse($response);
}

Resources