Laravel validation blade syntax - php

I have a dropdown like this
How could i sent the option selected on dropdown into database? I need blade syntax to send them.
Here is my piece of code for validation:
FrontController
public function insert(Request $request)
{
$request->validate([
'jenis' => 'required|string',
'kategori' => 'required|string',
'nopol' => 'required|string',
]);
DB::table('park')->insert([
'jenis' => $request->input('jenis'),
'kategori' => $request->input('kategori'),
'nopol' => $request->input('nopol'),
'created_at' => date('Y-m-d H:i:s'),
'updated_at' => date('Y-m-d H:i:s'),
'status' => true;
]);
}
home.blade.php
<div class="control-group">
<label class="control-label" for="typeahead">Jenis Kendaraan</label>
<div class="controls">
<select id="opt" name="jenis">
<option value="1">Motor</option>
<option value="2">Mobil</option>
</select>
</div>
</div>
Should i use #foreach or directly use #if #else #endif ?

I think you want to save jenis with value either 'Motor' or 'Mobile' because you are validating as a string. Just put as
<select id="opt" name="jenis">
<option value="Motor">Motor</option>
<option value="Mobil">Mobil</option>
</select>

Whatever you write in value will go in the request object.
<option value="1">Motor</option>
this what you wrote in the value , so on the form submission in request()->input('jenis') you will get 1.. you should give numeric validation or between(range) type of validation, please check the laravel docs.

In case anyone stumbled upon this via Googling how to validate actual Blade syntax, check this out.
Create a custom validation rule:
<?php
namespace App\Rules;
use Exception;
use Illuminate\Contracts\Validation\Rule;
use Illuminate\Support\Facades\File;
class BladeSyntax implements Rule
{
private $message;
public function passes($attribute, $value)
{
File::put(resource_path('views/validation.blade.php'), $value);
try {
view('validation')->render();
return true;
}
catch (Exception $exception) {
$this->message = $exception->getMessage();
return false;
}
}
public function message()
{
return explode('(', $this->message)[0];
}
}
Then use new BladeSyntax in your validation rules.

Related

Error on multi select when using Laravel Livewire

I'm using choices.js to have multiple select options in my Laravel project. However, I'm currently having an error Attempt to read property "id" on string.
PostController
public function new()
{
$tags = TagQuery::all();
return view('threads.new', compact('tags'));
}
new.blade.php
<livewire:editor :title="null" :tags="$tags" :body="null" />
livewire/editor.blade.php
#if($errors->has('tags'))<span class="text-pink-600 text-sm">{{ $errors->first('tags') }}</span>#endif
<select id="tags" multiple #if($errors->has('tags')) class="border-pink-600" #endif wire:model="tags">
#foreach($tags as $tag)
<option x-cloak value="{{ $tag->id }}">{{ $tag->name }}</option>
#endforeach
</select>
Editor.php
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class Editor extends Component
{
public $title;
public $tags;
public $body;
protected $rules = [
'title' => ['required', 'min:5', 'max:70'],
'body' => ['required', 'min:10', 'max:50000'],
'tags' => ['required', 'array', 'min:1', 'max:3'],
'tags.*' => ['exists:tags,id']
];
public function render()
{
return view('livewire.editor');
}
public function submit()
{
$this->validate();
return dd($this->title, $this->body, $this->tags);
}
}
How do I fix this issue? The code is working if submitted as normal form (without livewire). I need to use Livewire since I'm also using tiptap headless editor and I cannot pass the value of the editor from livewire to regular laravel request.

Making sure one input field is greater than the other in Laravel

I have a form that has a start_odo and an end_odo for vehicle mileage tracking that user needs to enter. The problem is that currently, they can enter a start_odo that is higher than the end_odo and that results in a negative difference. Is any way to ensure that the end_odo will always have to be higher?
Being fairly new to Laravel, I read about the gt:field but I am not quite sure how to interpret it in my code as it looks different. Could someone nudge me in the right direction.
Controller:
public function store(Request $request)
{
// $energy = new Maintenance;
$energy = new VehicleLog();
$energy->start_odo = $request->input('start_odo');
$energy->end_odo = $request->input('end_odo');
$energy->km = $request->input('end_odo') - $request->input('start_odo');
$energy->save();
return redirect('/vmaintenance')->with('success', 'data added');
}
my view:
<div class="mb-3" style="float:left;" style="margin-left: 200px;">
<label for="recipient-name" style="width: 7em"class="col-form-label">Start ODO</label>
<input type="number"style="width: 7em" name="start_odo" class="form-control" id="recipient-name" min="0" required>
</div>
<div class="mb-3">
<label for="recipient-name" class="col-form-label">End ODO</label>
<input type="number" style="width: 7em" name="end_odo" class="form-control" id="recipient-name" min="0" required>
</div>
The validation code I saw while reading:
$request->validate([
'detail' => 'gt:20',
]);
you have to figure out yourself how to write code. there are lots of answers and tutorials out there regarding this. however i am adding this answer to get you started.
in your store method, validate the data before saving to database.
public function store(Request $request)
{
// validation logic
$request->validate([
'start_odo' => 'required',
'end_odo' => 'required|gt:start_odo',
]);
// if validation passes this will now store values in db
$energy = new VehicleLog();
$energy->start_odo = $request->input('start_odo');
$energy->end_odo = $request->input('end_odo');
$energy->km = $request->input('end_odo') - $request->input('start_odo');
$energy->save();
return redirect('/vmaintenance')->with('success', 'data added');
}
now explore the doc how to show validation errors in the form and other ways to validate data.
As #zahidhasanemon had already indicated. You can achieve it with customs rules. First step would be to define the new validation rule in your AppServiceProvider.
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
Validator::extend('greater_than_field', function($attribute, $value, $parameters, $validator) {
$min_field = $parameters[0];
$data = $validator->getData();
$min_value = $data[$min_field];
return $value > $min_value;
});
Validator::replacer('greater_than_field', function($message, $attribute, $rule, $parameters) {
return str_replace(':field', $parameters[0], $message);
});
}
}
Then you can use this new validation rule in your controller like that:
$request->validate([
// other validations rules
'end_odo' => 'required|greater_than_field:start_odo',
]);

Laravel - Test Edit Form with Value tag

I'm using Laravel 5.6 to develop a website.
Currently, I want to write a test codes for the website. I'm also new to building a website in general and this is learning curve for me to learn what I'm doing wrong.
I created a Profile based on a User model and the Profile should only be editable by the authenticated User only.
The form is actually working without errors on the browser side but once i run phpunit, it will fail.
Test Script:
/** #test */
public function an_authenticated_user_can_view_the_profile_page()
{
// Generate fake instance of authenticated user
$this->be($user = factory('App\User')->create());
// Will get the URL
$response = $this->get('/profile/'.$user->name);
// Check whether the string exists
$response->assertSee('Personal details for '.$user->name);
}
Controller:
class ProfileController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function show(User $user)
{
return view('user.profiles.show', compact('user'));
}
public function update(Request $request)
{
$this->validate(request(), [
'company' => 'required',
'street' => 'required',
'city' => 'required',
'zip_code' => 'required',
'state' => 'required',
'country' => 'required',
'phone' => 'required',
]);
$profile = \Auth::user()->profile;
$profile->update($request->all());
return back()->with('success', 'Profile updated!');
}
}
View:
<div class="heading">
<h3 class="text-uppercase">Personal details for {{ $user->name }}</h3>
</div>
<form method="POST" action="/profile">
{{method_field('PATCH')}}
{{csrf_field()}}
<input type="hidden" value="{{ $user->profile->id }}" name="id">
<div class="col-md-6">
<div class="form-group">
<label for="company">Company</label>
<input id="company" type="text" class="form-control" name="company" value="{{ $user->profile->company }}" required>
</div>
</div>
</form>
Image of the commented out Form test:
Commented Form
Image of the not commented Form test:
Not commented Form
I am rather confused why my test is failing once I insert the form with a value tag. If i commented out the form or just remove the value tag, the test will pass.
Been searching for the few days and still can't find the right answer to this. Am i using the right Assertion? What am I missing here? Any inputs will help me to further understand this. Thanks!
I found the answer. It was actually the factory that I've created.
In the User model, every registration leads to creating an empty Profile.
This is the new way of how I write the test script:
/** #test */
public function an_authenticated_user_can_view_the_profile_page()
{
//Generate a fake profile
$profile = factory('App\Profile')->create();
// Assign it to the user
$user = $profile->user;
// Authenticate the user
$this->be($user);
// Will get the URL
$response = $this->get('/profile/'.$user->name);
// Check whether the string exists
$response->assertSee('Personal details for '.$user['name']);
}

Despite using 'fillable' and checking all variables, my create method in the controller is not saving input to model

I'm trying to save some data to my model using a form and my controller.
The form looks like this:
<body>
<div class="container">
<h1>Assign days to event</h1>
{{ Form::open(array('url' => 'days')) }}
<div class="form-group">
{{ Form::label('event_name', 'Event Name') }}
{{ Form::select('event_name', $events, null) }}
</div>
<div class="form-group">
{{ Form::label('day_number', 'Number of Days') }}
{{ Form::text('day_number', Input::old('day_number'), array('class' => 'form-control')) }}
</div>
{{ Form::submit('Assign!', array('class' => 'btn btn-primary')) }}
{{ Form::close() }}
</div>
</body>
My Create/Store functions in my Controller looks like this:
namespace StrawDogBuilder\Http\Controllers;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Input;
use View;
use Session;
use Redirect;
use StrawDogBuilder\Day;
use StrawDogBuilder\Event;
use Illuminate\Http\Request;
public function create()
{
$events = Event::pluck('id');
return View::make('days.create')
->with('events', $events);
}
public function store()
{
$rules = array(
'event_id' => 'required',
'day_number' => 'required'
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
return Redirect::to('days/create')
->withErrors($validator)
->withInput(Input::except('password'));
}
else {
$day = new day;
$day->event_id = Input::get('event_name');
$day->day_number = Input::get('day_number');
$day->save();
Session::flash('message', 'You have assigned this event a number of days');
return Redirect::to('days');
}
}
And my Model looks like this
class Day extends Model
{
protected $fillable = ['id','event_name','day_number'];
public function mods()
{
return $this->hasMany('App\Mod');
}
// Get the Event this day is attributed to
public function event()
{
return $this->belongsTo('App\Event');
}
}
The form is created without errors, however when I add values to the fields and hit 'Assign!' it will stay on the same page and will not indicate if it has done anything. Checking the table shows that it hasn't saved the data.
Am I missing something that causes the form to save the data via the controller, and if so what could it be?
First of all revised your form as
{!! Form::open(['route'=>'days.store']) !!}
Then in your controller
public function store(Request $request)
{
$this->validate($request,
array(
'event_id' => 'required',
'day_number' => 'required',
)
);
$day = new Day;
$day->event_id = $request->event_name;
$day->day_number = $request->day_number;
$day->save();
Session::flash('message', 'You have assigned this event a number of days');
return redirect()->route('days');
}

In Laravel 5 error in array validation with Form Request?

The part of form (the field text array)[1]:
<div id="cp1">
<div class="form-group">
{!! Form::text('names[]',null,['class'=>'form-control', 'maxlength'=>'30', 'placeholder'=>'Name']) !!}
</div>
<div class="form-group">
{!! Form::text('contents[]',null,['class'=>'form-control', 'maxlength'=>'30', 'placeholder'=>'Content']) !!}
</div>
</div>
When i send the form, validation fails with:
htmlentities() expects parameter 1 to be string, array given (View: /Applications/MAMP/htdocs/telovendogdl/resources/views/ads/new.blade.php)
this is the rules in form request:
return ['title' => 'required|min:8|max:100',
'description' => 'required|min:10|max:1100',
'price' => 'required|integer|max:15',
'city_name'=> 'required|max:70',
'category_id' => 'required|integer',
'delivery'=> 'max:70',
];
This is the function in the controller:[2]
public function newAdStore(StoreNewAdRequest $request)
{
$newAd = new Ad;
$newAd->user_id = \Auth::user()->id;
$newAd->active = 0;
$newAd->city_name = $request->input('city_name');
$newAd->category_id = $request->input('category_id');
$newAd->fill($request->all());
$newAd->save();
}
but only fails when i send the array fields from the form [1], when a delete this fields all works? what happen with that[2]?
I don't have a clear vision of your code but I am gonna try to help you debug your code ... first you need to add a rule to your StoreNewAdRequest to handle an array instead of string for names[] and contents[] :
public function rules()
{
$rules = [
'field2' => 'required|...',
'field3' => 'required|...',
....
];
foreach($this->request->get('names') as $key => $val)
{
$rules['names.'.$key] = 'required|max:100';
}
return $rules;
}
Make sure you have the right fillable params in your model
Note: the problem maybe occurred at this stage
$newAd->fill($request->all())
you are trying to fill an array of names[] & contents[] instead of strings ..

Categories