I have set up a controller with some validation.
public function attemptLogin()
{
$rules = array(
'email'=>'required|email',
'password'=>'required'
);
$validator = Validator::make(Input::all() , $rules);
if($validator->fails()){
return Redirect::to('login')->withErrors($validator);
};
}
If I output the messages directly in the controller
$messages = $validator->messages();
print_R($messages->all());
I get the validation errors - however if I redirect:
return Redirect::to('login')->withErrors($validator);
The $errors array available in the view is always coming up empty.
From laravel four documentation
Note that when validation fails, we pass the Validator instance to the
Redirect using the withErrors method. This method will flash the error
messages to the session so that they are available on the next
request.
Variable $errors it's not an array.
The $errors variable will be an instance of
MessageBag.
For some reason I don't really like #seamlss idea.
You can use this instead.
#if(Session::has('errors'))
<? $errors = Session::get('errors'); ?>
<div class="alert alert-error">
<button type="button" class="close" data-dismiss="alert">×</button>
<ul>
<li id="form-errors" >
<h3> {{ $errors->first('email') }}</h3>
</li>
</ul>
</div>
#endif
I've used some bootstrap components, don't get confused, the only thing you need is the lines with the curly braces and the magical # sign.
From laravel docs error-messages-and-views
So, it is important to note that an $errors variable will always be
available in all of your views, on every request, allowing you to
conveniently assume the $errors variable is always defined and can be
safely used.
You can also check this
#if( $errors->has('email') )
<div class="control-group error">
<label class="control-label" for="email">Email</label>
<div class="controls">
<input type="text" id="email" placeholder="Email" name="email">
<span class="help-inline">{{ $errors->first('email') }}</span>
</div>
</div>
#endif
I've had success redirecting using ->withErrors($validation)
And then in the view checking the condition #if( $errors->count() > 0 )...
#if( $errors->count() > 0 )
<p>The following errors have occurred:</p>
<ul id="form-errors">
{{ $errors->first('username', '<li>:message</li>') }}
{{ $errors->first('password', '<li>:message</li>') }}
{{ $errors->first('password_confirmation', '<li>:message</li>') }}
</ul>
#endif
Have you tried:
return Redirect::to('login')->withErrors($validator);
or
return Redirect::to('login')->withErrors($validator->messages());
Here is another possibility when you have difficulty showing errors, and when they are passed correctly via ->withErrors(). If you redirect to a controller action that has to perform any sort of its own state checking and itself calls ->withErrors(), it will shadow the $errors first injected.
Try the following
return Redirect::to('login')->with('errors',$validator->errors->all());
then from your view loop through this errors
foreach($errors as $error) {
print $error;
}
Related
The new #error directive was introduced in Laravel 5.8.13. So, instead of doing this:
// old
#if ($errors->has('email'))
<span>{{ $errors->first('email') }}</span>
#endif
You can now do this
// new
#error('email')
<span>{{ $message }}</span>
#enderror
However, I'm having issues trying to target only the input fields where the error was made among several similar input fields. These fields are similar because they have the same name. But they are also in seperate forms and have different submit buttons.
My html blade file is setup with multiple inputs generated from a #forelse statement. I've created a simple error check to check if a negative number is entered and to redirect back to the same page with an error message. The #error directive is also used to insert a custom class to target input field for styling.
#forelse($accounts as $account)
<form method="POST" action="{{ route('account.update', $account->id) }}">
#csrf
<div>
<input type="number" name="credit" class="#error('credit') is-invalid #enderror" required>
<input type="submit" class="btn" value="ok">
#error('credit')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</form>
#empty
#endforelse
The form submits to the update() method in AccountController.php
public function update(Request $request, Account $account)
{
if($request->input('credit') < 0)
{
return back()->withErrors(['credit'=>'enter a positive amount']);
}
// ... other logic
}
The problem is that when a negative number is entered in one input field, the error message shows up for every input with the same name, even when they are not in the same form.
I think making the input names unique will solve this, but this will make my backend logic more complex than is required.
Is there anyway of making the error message show for just the target input after the redirect, without having to use unique names for each input field?
Interestingly, the #error directive is not programmatically tied to any input field by an input name. It is only spatially related to an input field by proximity and can be placed any where on the page.
Also, you can conveniently use any string within the #error directive as long as same is passed to the withErrors() call in the controller.
So, solving the problem of targeting the appropriate input among multiple ones becomes as simple as using any unique string (not necessarily the target input name) as key in the withErrors() method call and retrieving the error message by passing the same string to the #error directive. In my case, I chose to use the account id as the unique string.
In AccountController.php:
public function update(Request $request, Account $account)
{
if($request->input('credit') < 0)
{
return back()->withErrors([$account->id=>'enter a positive amount']);
}
// ... other logic
}
And in the html blade template:
#forelse($accounts as $account)
<form method="POST" action="{{ route('account.update', $account->id) }}">
#csrf
<div>
<input type="number" name="credit" class="#error($account->id) is-invalid #enderror" required>
<input type="submit" class="btn" value="ok">
#error($account->id)
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</form>
#empty
#endforelse
NOTE: Using a non existent key in any #error directive breaks the code for other #error directives and will cause no error messages to be displayed.
A solution would be doing the following:
store the value / posted form in a variable using the value of the submit button
ditch the error directive and use the old version
combine the old version with the variable to check wether you have the correct form or not
You'll get something like this:
#if ($errors->has('email') && $submitted_form_identifier === $form_identifier)
<span>{{ $errors->first('email') }}</span>
#endif
good day,
I new in laravel Framework and I face this two problems : -
first one
I want to redirect to my page after 2 seconds automatically.
the second one
I make custom function call (is exist )
if this function returns true data I want to print "name exist before " but the problem here is form was rested when this function returns true and print message.
how to prevent form resetting from inputs value?
here is my code
controller code
enter code here
public function add(Request $request)
{
// start add
if($request->isMethod('post'))
{
if(isset($_POST['add']))
{
// start validatio array
$validationarray=$this->validate($request,[
//'name' =>'required|max:25|min:1|unique:mysql2.products,name|alpha',
'name' =>'required|alpha',
'price' =>'required|numeric',
]);
// check name is exist
if(true !=dBHelper::isExist('mysql2','products','`status`=? AND `deleted` =? AND `name`=?',array(1,1,$validationarray['name'])))
{
$product=new productModel();
// start add
$product->name=$request->input('name');
$product->save();
$add=$product->id;
$poducten=new productEnModel();
$poducten->id_product=$add;
$poducten->name=$request->input('name');
$poducten->price=$request->input('price');
$poducten->save();
$dataview['message']='data addes';
}else{
$dataview['message']='name is exist before';
}
}
}
$dataview['pagetitle']="add product geka";
return view('productss.add',$dataview);
}
this is my routes
Route::get('/products/add',"produtController#add");
Route::post('/products/add',"produtController#add");
this is my view
#extends('layout.header')
#section('content')
#if(isset($message))
{{$message}}
#endif
#if(count($errors)>0)
<div class="alert alert-danger">
<ul>
#foreach($errors->all() as $error)
<li>{{$error}}</li>
#endforeach
</ul>
</div>
#endif
<form role="form" action="add" method="post" enctype="multipart/form-data">
{{csrf_field()}}
<div class="box-body">
<div class="form-group{{$errors->has('name')?'has-error':''}}">
<label for="exampleInputEmail1">Employee Name</label>
<input type="text" name="name" value="{{Request::old('name')}}" class="form-control" id="" placeholder="Enter Employee Name">
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email Address</label>
<input type="text" name="price" value="{{Request::old('price')}}" class="form-control" id="" placeholder="Enter Employee Email Address">
</div>
</div>
<!-- /.box-body -->
<div class="box-footer">
<button type="submit" name="add" class="btn btn-primary">Add</button>
</div>
</form>
#endsection
I hope that I understood your question.
Instead of using {{ Request::old('price') }} use {{ old('price') }}
This should retrieve the form data after page was reloaded.
Try the below the code for error display in view page
$validator = Validator::make($params, $req_params);
if ($validator->fails()) {
$errors = $validator->errors()->toArray();
return Redirect::to($web_view_path)->with('errors', $errors);
}
You want to automatically redirect to another page submit the form using ajax and use below the settimeout menthod.
setTimeout(function(){ // Here mentioned the redirect query }, 3000);
//use $request instead of $_POST
if($request->isMethod('post'))
{
if(isset($request['add']))
{
// start validatio array
$validationarray=$this->validate($request,[
//'name' =>'required|max:25|min:1|unique:mysql2.products,name|alpha',
'name' =>'required|alpha',
'price' =>'required|numeric',
]);
// check name is exist
I'm doing a view that has a password protection. Basically when you access that resource, you have a view that indicates that you need to put a password.
The correct behavior of this should be
You access the View
The user enters the password and sends the POST form
If the method redirects back with certain value, you must see the real content of the page.
So my blade code is the following:
#if ($passedPassword = Session::get('passedPassword'))
...here goes the real/true view content
#else
<section class="questionnaire-questions">
<div>
<form
action="{{ route('questionnaire.password', ['questionnaire' => $questionnaire->id]) }}"
method="POST">
{{ csrf_field() }}
<h3 class="text-center">#lang('questionnaire.password.advice')<h3>
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<div class="goal-input-group numeric">
<label>PASSWORD</label>
<input
style='visibility: visible;'
name="password"
type="password"
>
</div>
</div>
</div>
<div class="text-center">
<button type="submit" class="goal-btn goal-btn-lg goal-btn-artic-blue">#lang('questionnaire.password')</button>
</div>
</form>
</div>
</section>
#endif
That view is rendered with the following method:
public function show(Questionnaire $questionnaire) {
$data = [];
$data['questionnaire'] = $questionnaire;
\Session::flash('passedPassword', false);
return view('questionnaires.show', array('data' => $data));
}
In the previous method I'm passing the passedPassword, but I can't find a way to pass it as a flash variable. If there is a way to add data like
return back()->with(array(
'passedPassword' => false
));
But using the view method I'll really appreciate to know how.
Then, when the user clics the button I call the next function:
public function password(Request $request, Questionnaire $questionnaire) {
if (strcmp($questionnaire->password, $request->input('password')) == 0) {
return back()->with(array(
'passedPassword' => false
));
}
}
But even when the password is correct, I got the password view, the flash/session variable never arrived to the view.
Is there something I'm missing or doing wrong?
Thanks in advance.
As Dan told me in the comments, I was setting to false the value of the session variable.
So first I remove the \Session::flash('passedPassword', false); during the show method.
Then I modify my blade logic. In my case sometimes the password is needed and sometimes not.
#if (($passwordLength === 0) || ($passwordLength !== 0 && Session::has('passedPassword')))
With that, If the resource has no password we let the user pass. Or in the case it has a password and also we have the passedPassword variable, we also let the user see the content.
Still learning Phalcon through the tutorials but I have an issue with displaying form error messages beside form fields.
The form code is as follows
<?php
use Phalcon\Forms\Form;
use Phalcon\Forms\Element\Text;
use Phalcon\Forms\Element\TextArea;
use Phalcon\Validation;
use Phalcon\Validation\Validator\PresenceOf;
use Phalcon\Validation\Validator\Email;
class ContactForm extends Form
{
public function initialize()
{
// Name
$fullname = new Text('fullname');
$fullname->setFilters(array('striptags', 'string'));
$fullname->addValidators(array(
new PresenceOf(array(
'message' => 'Full Name is required'
))
));
$this->add($fullname);
// Email and text area fields with validators
/**
* Prints messages for a specific element
*/
public function messages($name)
{
if ($this->hasMessagesFor($name)) {
foreach ($this->getMessagesFor($name) as $message) {
$this->flash->error($message);
}
}
}
}
The form in using volt engine is below
{{ form('pages/contact') }}
<div class="controls controls-row">
{{ form.render('fullname') }}
{{ form.render('email') }}
<span class="help-inline error">{{ form.messages('fullname') }}</span>
<span class="help-inline error">{{ form.messages('email') }}</span>
</div>
<div class="controls">
<span class="help-inline error">{{ form.messages('comments') }}</span>
{{ form.render('comments') }}
</div>
<div class="controls">
{{ submit_button('Send It', 'class': 'btn btn-primary pull-right') }}
</div>
</form><!--end form-->
The code handling the form in the contactAction() is below
$form = new ContactForm();
if ($this->request->isPost() == true)
{
if ($form->isValid($_POST)==false)
{
$form->messages("fullname");
$form->messages("email");
$form->messages("comments");
}else
{
//send email
}
}
$this->view->form =$form
By calling the $form->messages("fullname") and for other fields the validation message will be printed using {{ flash.output() }} which is usually at the top of the page where I placed the code. How do I get the flash messages to display beside the form fields?
Please help. Thanks
After a lot of playing around, I simply changed the messages function in the ContactForm class to return message and not flash the message.
public function messages($name)
{
if ($this->hasMessagesFor($name)) {
foreach ($this->getMessagesFor($name) as $message) {
return '<font color="FF0000">'.$message.'</font>';
}
}
}
other parts of the code still remains the same.
Inside a Laravel4 + Bootstrap 2.3.1 I have a form properly working with validation.
There are three fields obligatory: Name - Email - Phone.
When nothing is inserted, or the email is not in a proper format, the error messages are displayed.
But besides this, I would like to make the fields red, to show better where the error is.
How can I do this in Laravel + Bootstrap?
This is the form with the three fields obligatory:
<form name="room" method="post" class="narrow_width">
<label><span><i class="icon-user"></i></span> Name <span class="color-red">*</span></label>
{{ Form::text('name',Input::old('name'), array('class' => 'span7 border-radius-none')) }}
<label><span><i class="icon-envelope-alt"></i></span> Email <span class="color-red">*</span></label>
{{ Form::text('email',Input::old('email'), array('class' => 'span7 border-radius-none')) }}
<label><span><i class="icon-phone"></i></span> Phone number <span class="color-red">*</span></label>
{{ Form::text('phone',Input::old('phone'), array('class' => 'span7 border-radius-none')) }}
<p><button type="submit" name="submit" class="btn-u">Send Message</button></p>
</form>
Thank you very much!
I don't think there's an easy way to do this with the laravel Form class. I personally use my own package https://github.com/AndreasHeiberg/theme for this. You can use it if you wan't but it's subject to change.
Anyway raw code to do this is the following:
<div class="control-group {{ $errors->has($id) ? 'error' : false }}">
<label for="{{ $id }}" class="control-label">{{ $text }} {{ $required ? '<span class="required-red">*</span>' : ''}}</label>
<div class="controls">
<input type="{{ $type }}" id="{{ $id }}" name="{{ $id }}" value="{{ $value }}">
#if ($helpText)
<span class='help-inline'>{{ $helpText }}</span>
#endif
#foreach($errors->get($id) as $message)
<span class='help-inline'>{{ $message }}</span>
#endforeach
</div>
</div>
This being the important part
<div class="control-group {{ $errors->has($id) ? 'error' : false }}">
You can wrap this up in a form macro http://laravel.com/docs/html#custom-macros use a helper function or my package to do this.
With my package you would just use:
+#formText('name')
You can easily use Form macros, there is a bunch available here for Bootstrap 3:
http://forums.laravel.io/viewtopic.php?id=11960
Hope this helps...
Thanks for your efforts, especially #AndHeiberg.
For reason of simplicity, i decide to renounce to Laravel-Bootstrap validation and use instead a jquery plugin: https://github.com/jzaefferer/jquery-validation
The main reason is that is extremely easy to use.
It's enough to call the plugin and insert 'required' into the tag.
And the plugin will do all the rest, highlighting the field in red and displaying an error message for that field.
If your intention is to make the error more obvious to where it is, you can wrap the message text that is returned from Laravel validation errors in a span and give styling to that.
{{ $errors->first('email', "<span class='error'>:message</span>")}}
where :message is a "placeholder" for your error message. And then you can give any styling to .error spans as you wish. Check this Laracast lesson for more details (after 3:10).
In bootstrap, you can create errorfield with the id "inputError":
<input type="text" class="form-control" id="inputError">