I have a form with some inputs and one file input.Everything works well but there is a weird problem!
Here is my validations code:
$validator = \Validator::make($request->all(), [
'name' => 'required|max:25|min:3',
'email' => 'required|email|max:35|min:5',
'phone' => 'required|max:15|min:7',
'file' => 'max:2000|mimes:jpeg,png,doc,docs,pdf',
]);
The problem is that I don't set required for file but I don't know why when I submit the form it said:
The file must be a file of type: jpeg, png, doc, docs, pdf
Actually I want to file be optional.
I have tried sometimes:
'file' => 'sometimes|max:2000|mimes:jpeg,png,doc,docs,pdf',
But it didn't work.
Thanks for any suggestion.
Update:
my Ajax request:
$(document).ready(function () {
$("#submit").click(function (event) {
event.preventDefault();
var formData = new FormData();
formData.append('name', $('#name').val());
formData.append('email', $('#email').val());
formData.append('phone', $('#phone').val());
formData.append('telegram', $('#telegram').val());
formData.append('contactWith', $('#contactWith').val());
formData.append('orderType', $('#orderType').val());
formData.append('price', $('#price').val());
formData.append('uiLevel', $('#uiLevel').val());
formData.append('codingType', $('#codingType').val());
formData.append('maxTime', $('#maxTime').val());
formData.append('file', $('#file')[0].files[0]);
formData.append('message', $('#message').val());
$.ajax({
type: "POST",
url: "{{route('orders.store')}}",
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
},
data: formData,
contentType: false,
processData: false,
success: function (msg) {
},
}, "json")
})
});
And my file input:
<div class="form-group">
<label for="file">send file</label>
<br>
<label id="browse-label" for="file"><i class="fa fa-upload" aria-hidden="true"></i>browse
<input type="file" id="file">
</label>
<span id="filename">no file chosen</span>
</div>
Use the nullable rule
Docs: https://laravel.com/docs/8.x/validation#a-note-on-optional-fields
Which gives you:
'file' => 'nullable|max:2000|mimes:jpeg,png,doc,docs,pdf',
You can do it as follows
$validator = \Validator::make($request->all(), [
'name' => 'required|max:25|min:3',
'email' => 'required|email|max:35|min:5',
'phone' => 'required|max:15|min:7',
]);
if($request->file){
$validator = \Validator::make($request->all(), [
'file' => 'max:2000|mimes:jpeg,png,doc,docs,pdf',
]);
}
Related
Hello I am trying to post data via ajax but i face this error and i am sure that i called CSRF_TOKEN in header section
Header Section :
meta name="csrf-token" content="{{ csrf_token() }}"
Route Section :
Route::post('cart/data/store/{id}', [CartController::class, 'AddToCart']);
Ajax Code :
function addToCart() {
var product_name = $('#pname').text();
var id = $('#product_id').val();
var color = $('#color option:selected').text();
var size = $('#size option:selected').text();
var quantity = $('#qty').val();
$.ajax({
type:"POST",
dataType:"JSON",
data:{
color:color,
size:size,
quantity:quantity,
product_name:product_name,
},
url: "cart/data/store/"+id,
success:function(data) {
$('#closeModal').click();
console.log(data)
}
})
}
Controller :
class CartController extends Controller
{
public function AddToCart(Request $request, $id) {
$product = Product::findOrFail($id);
if ($product->discount_price == NULL) {
Cart::add([
'id' => $id,
'name' => $request->product_name,
'qty' => $request->quantity,
'price' => $product->selling_price,
'weight' => 1,
'options' => [
'image' => $product->product_thumbnail,
'size' => $request->size,
'color' => $request->color,
],
]);
return response()->json(['success' => 'Item Added To Your Cart']);
} else {
Cart::add([
'id' => $id,
'name' => $request->product_name,
'qty' => $request->quantity,
'price' => $product->discount_price,
'weight' => 1,
'options' => [
'size' => $request->size,
'color' => $request->color,
'image' => $product->product_thumbnail
],
]);
return response()->json(['success' => 'Item Added To Your Cart']);
}
}
}
Token Section :
$.ajaxSetup({
headers:{
'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content')
}
add #csrf in beginning of your form.
<form id="my_form" >
#csrf
<input type="text" name="name"id="name" >
<button type="submit">submit</button>
</form>
I was wondering whether I can call the action automatically through ajax one by one for each row of the GridView after the page is load.
All I can do now is trigger the call manually through button click, already returned the value correctly.
Here is my GridView:
<?php Pjax::begin(['id' => 'payment-list-view-container', 'timeout' => 5000]); ?>
<?= GridView::widget([
'id' => 'payment-table',
'dataProvider' => $dataProvider,
'resizableColumns' => false,
'tableOptions' => ['class' => 'table table-striped'],
'pjax'=>true,
'pjaxSettings' => [
'options' => [
'id' => 'payment-table',
'enablePushState' => false,
],
],
'columns' => [
[
'class' => 'kartik\grid\SerialColumn',
'header' => 'No.',
],
[
'header' => 'Title',
'attribute' => 'name',
],
[
'attribute' => 'date_start',
'header' => 'Payment Date',
'value' => function($model){
return Yii::$app->formatter->asDatetime($model->payment_date, "php:d F Y");
}
],
[
'header' => 'Action',
'format' => 'raw',
'value' => function($model) use ($export_type){
return Html::a('Open', '',
[
'data-url'=>'/model/payment/check-status/id/'. $model->id . '?exportType=' . $export_type ,
'class'=>'check-payment-status'
]);
}
],
],
]); ?>
<?php Pjax::end(); ?>
Here is my js:
<?php
$js = <<<JS
$(document).ready(function(){
function checkStatus() {
$(".check-payment-status").off().on("click", function(e){
e.preventDefault();
var url = $(this).attr("data-url");
$.pjax.defaults.timeout = false;
$.ajax({
url : url,
type : "post",
dataType: 'json',
success: function (response) {
// do something
}, error : function () {
// do nothing
}
});
});
}
checkStatus();
});
JS;
$this->registerJs($js);
I guess I need to use something like this, but still don't know how to implement it
$.each($('.check-payment-status'), function (i, el) {
//do something
});
So can I really do that? Calling the action automatically after the page load for each row?
All you need to do is to trigger the click event on the buttons.
$(document).ready(function() {
//bind the click handler
$('.btn').on('click', function(e) {
e.preventDefault();
console.log("Clicked " + $(this).text());
});
//click each button
$('.btn').each(function() {
$(this).trigger('click');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Link 1<br>
Link 2<br>
Link 3<br>
I'm trying to upload an image with another field to like the patreon image post.
I use Laravel as a backend and have been tested WORK using postman.
But for the frontend part using the q-uploader Quasar Framework - vue js, it seems I need some advice.
this is my laravel controller:
public function createImagePost(Request $request) {
$validator = Validator::make($request->all(),[
'title' => 'required',
'permission' => 'required',
'images' => 'required',
]);
if ($validator->fails()) {
return response()->json([
'status' => 'failed',
'errors' => $validator->errors()
], 500);
} else {
if ($request->hasfile('images'))
{
$images = $request->file('images');
$names = array();
foreach($images as $image) {
$imageName = Auth::user()->id.'_image_'.time().'.'.$image->getClientOriginalExtension();
$image->storeAs('user_post_images', $imageName);
$names[] = $imageName;
}
UserPost::create([
'images' => json_encode($names),
'title' => $request->title,
'tags' => $request->tags,
'description' => $request->description,
'permission' => $request->permission,
'post_user_id' => Auth::user()->id
]);
return response()->json([
'status' => 'success',
'message' => 'Post has been created successfully!'
], 200);
} else {
return response()->json([
'status' => 'ERROR VRO',
'message' => 'ERROR'
], 500);
}
}
}
and this is the quasar frontend:
<q-form #submit="createImagePost">
<q-card-section class="q-pt-none">
<!-- Fields -->
<q-uploader
label="Pick Some Images Here!"
multiple
color="teal"
accept="image/*"
style="max-width: 1200px; width: 100%"
flat
bordered
:factory="createImagePost"
url=""
ref="imageUploader"
/>
<br>
<q-input
type="text"
hint="Required"
label="Post Title"
v-model.trim="post_title"
#input="$v.post_title.$touch()"
:rules="[
val => $v.post_title.required || 'Post Title is required',
]"
:dense="dense"
/>
<br>
<q-input
type="textarea"
v-model="post_description"
hint="Tell a story"
label="Post Description"
:dense="dense"
/>
<br>
<div class="row">
<div class="col q-mr-md">
<q-select
outlined
:options="post_permission_options"
label="Permission"
hint="Required"
v-model.trim="post_permission"
#input="$v.post_permission.$touch()"
:rules="[
val => $v.post_permission.required || 'Post permission is required',
]"
/>
</div>
<div class="col">
<q-select
label="Tags"
outlined
v-model="post_tags"
use-input
use-chips
multiple
hide-dropdown-icon
input-debounce="0"
new-value-mode="add"
/>
</div>
</div>
</q-card-section>
<q-card-actions align="right" class="text-primary">
<q-btn flat label="Cancel" v-close-popup />
<q-btn flat label="Create" type="submit"/>
</q-card-actions>
</q-form>
createImagePost(files) {
let currentObj = this
currentObj.createImagePostLoading = true
const config = {
headers: { 'Content-Type': undefined }
}
const fd = new FormData()
fd.append('images', files)
fd.append('title', currentObj.title)
fd.append('tags', currentObj.tags)
fd.append('description', currentObj.description)
fd.append('permission', currentObj.permission)
axios.get('/sanctum/csrf-cookie').then(response => {
axios.post('/api/create-image-post', fd, config)
.then(function (response) {
currentObj.serverSuccess = response.data.message
currentObj.showCreatePostSuccess()
currentObj.createImagePostLoading = false
currentObj.create_image_post = false
currentObj.selected_file = []
})
.catch(function (error) {
if(error.response.data) {
currentObj.serverError = error.response.data.errors
}
currentObj.showCreatePostError()
currentObj.createImagePostLoading = false
currentObj.create_image_post = false
currentObj.errorModal = true
currentObj.selected_file = []
})
})
},
and the error message is the same as the error message that is made if the file is not found. but for this controller it works if I use postman, am I missing something with q-uploader?
Error Message :
{status: "ERROR VRO", message: "ERROR"}
status: "ERROR VRO"
message: "ERROR"
{!! Form::select('jobsList[]', $list_of_jobs, null, ['id' => 'job', 'class' => 'form-control' 'multiple', 'style' => 'width: 60%; margin-top: 10px;', 'disabled'=>'disabled']) !!}
I have this form and I am trying to load $list_of_jobs asynchronously compared to what I am doing. I am kind of confused with the way LaravelCollective Form works. Can anyone point out how I would pass that? I already have ajax call that goes and grabs the $list_of_jobs from the controller
//...
{!! Form::select('jobsList[]', [], null, ['id' => 'job', 'class' => 'form-control' 'multiple', 'style' => 'width: 60%; margin-top: 10px;', 'disabled'=>'disabled']) !!}
..//
Populating your select box using JQUERY, AJAX
<script>
$(document).ready(function() {
//Make an Ajax request to a Laravel route
//This will return the data that we can add to our Select element.
$.ajax({
url: 'YOUR URL GOES HERE',
type: 'get',
success: function(data){
//Log the data to the console so that
//you can get a better view of what the script is returning.
console.log(data);
$.each(data, function(key, value){
//Use the Option() constructor to create a new HTMLOptionElement.
var option = new Option(key, value);
//Convert the HTMLOptionElement into a JQuery object that can be used with the append method.
$(option).html(value);
//Append the option to our Select element.
$("#job").append(option);
});
}
});
});
</script>
data must be an array of objects [{}, {}, {}]
[
{'key' : 'foo', 'value' => 'bar'},
{'key' : 'kosksi', 'value' => 'makrouna'},
{'key' : 'lablebi', 'value' => 'kafteji'}
]
Update
If you want to set selected option(s) when Populating your select box :
You need to return an extra attribute selected : true|false in each object of data collection
[
{'key' : 'foo', 'value' : 'bar', 'selected' : false},
{'key' : 'kosksi', 'value' : 'makrouna', 'selected' : false},
{'key' : 'lablebi', 'value' : 'kafteji', 'selected' : true}
]
Then in success() ajax function callback
//...
$.each(data, function(key, elem){
//Use the Option() constructor to create a new HTMLOptionElement.
var option = new Option(elem.value, elem.key, false, elem.selected);
//Convert the HTMLOptionElement into a JQuery object that can be used with the append method.
$(option).html(elem.value);
//Append the option to our Select element.
$("#job").append(option);
});
//...
I have a view like this:
// snippet of view
<td><input class="form-field" type="text" id="entity" name="name" data="{{$entity->id}}" value="{{$entity->name}}" onkeyup="validation(this.value);" onblur="updateEntity(this.value,this.name,this.id,{{$entity->id}})"></td>
<td><input class="form-field" type="text" id="entity" name="type" value="{{$entity->type}}" onkeyup="validation(this.value);" onblur="updateEntity(this.value,this.name,this.id,{{$entity->id}})"></td>
Which has an ajax:
function updateEntity(value, name, data, id) {
$.ajax({
url: '/entityadmin/' + value + '/' + name + '/' + data + '/' + id,
method: 'POST',
dataType: 'json',
success: function(save) {
$('.messages').append('<div class="alert alert-success">Type Updated!<div>');
setTimeout(function() {
$(".alert").fadeTo(2000, 500).slideUp(500, function(){
$(".alert").slideUp(500);
});
}, 4000);
},
error: function(data) {
console.log(data);
$('.messages').append('<div class="alert alert-danger">Error, please try again!<div>');
setTimeout(function() {
$(".alert").fadeTo(2000, 500).slideUp(500, function(){
$(".alert").slideUp(500);
});
}, 4000);
},
headers: {
'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
}
});
}
Controller:
public function entityUpdate($value, $name, $data, $id, EntityRequestUpdate $request) {
$request->$name = $value; //like this?
if($data == "entity") {
$save = Entity::find($id);
}else{
$save = User::find($id);
}
$save->$name = $value;
$save->save();
return response()->json(['results' => $save]);
}
and request:
public function rules()
{
return [
'startdate' => 'required|date',
'endate' => 'nullable|date',
'startime' => 'required|time',
'endtime' => 'required|time',
'title' => 'required',
'type' => 'required',
'description' => 'required',
'frequency' => 'required',
'interval' => 'nullable|numeric',
'monthday' => 'nullable|numeric|min:1|max:3',
'weekday' => 'nullable|alpha|max:3',
'month' => 'nullable|numeric',
'until' => 'nullable|date',
'tags' => 'nullable',
'img' => 'nullable|file|image',
];
}
The thing is it only has to validate one field because one field is being changed each time, how can I use this validation to validate the incoming variable and return errors to ajax with the message on the error if there is any?
You can manually create a validator to validate this one field like so:
$validator = Validator::make(
[ 'name' => $value ],
collect($this->rules())->only([$name])->all()
);
This validator will take the name validator from the defined rules and check that against the first array of values.