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">
Related
I have an multi-delete functionality (kind of like PHPMyAdmin, checkboxes you can check to delete multiple items). The functionality itself works, but I'm implementing it in my functional test. However, somehow it doesn't work.
This is the code of my service (where multi-delete is handled, this is in a function that's called within controllers)
$form = $this->formFactory->createBuilder()->setMethod('DELETE')->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$this->deleteKeys($request);
return new RedirectResponse($this->session->get('referer'));
}
The function renders a template with the form, a button and a list of all items being deleted. This is the template:
{{ form_start(form) }}
<div class="row">
<div class="col-md-12">
<div class="box">
<div class="box-body">
{{ form_widget(form) }}
<p>{{ 'standard.Are you sure you want to delete the following items'|trans }}?</p>
<p>
{% for item in items %}
<strong class="d-block">{{ item.displayProp }}</strong>
<input type="hidden" name="items[]" value="{{ item.id }}">
{% endfor %}
</p>
</div>
<div class="box-footer">
<input class="btn btn-danger" type="submit" name="delete_items" value="{{ 'standard.Delete'|trans }}">
<a class="btn btn-default" href="{{ app.session.get('referer') }}">{{ 'standard.Cancel'|trans }}</a>
</div>
</div>
</div>
</div>
{{ form_end(form) }}
So, testing it via my browser, it works completely fine. Then, lets look at the code in my test. The code to get to the confirm page works, it shows the right items selected to delete. But it contains a form:
$form = $crawler->selectButton('delete_items')->form(null, 'DELETE');
$crawler = $this->client->submit($form);
So, it selects the form based on the delete_items button name (which exists), it doesn't throw an error or something, it submits the form, but after it, getting the HTML of $crawler still displays the "deleted" items. Again, if I test the functionality in the browser in the module itself, it works, but in the functional test it somehow doesn't.
Also I tried using $this->client->followRedirect() which says the request isn't redirected. But it's just a normal delete form without validation so I don't see why it shouldn't work.
EDIT:
Apparently somehow the form isn't submitted, var_dump($form->isSubmitted()); says false. I'm not sure why it isn't submitted though since it does get submitted if I test it in the browser though.
I want to give an error message if a string is entered in a integer inputfield with an multidimensional array.
View:
<div class="col-md-8">
<input name="answer[sleep][score]" type="text" class="form-control #error('answer[sleep][score]') #enderror" placeholder="Score" value="{{ #$answer_array['sleep']['score'] }}">
#error('answer[sleep][score]')
<span class="invalid-feedback" role="alert">
<strong>Geen letters alsjeblieft.😉</strong>
</span>
#enderror
</div>
Controller:
$request->validate([
'answer.sleep.score' => 'nullable|numeric',
]);
when i click save it just refreshes the page and does nothing. Can anybody please help me, how do i show the error on a multidimensional array.
Thanks!
#error is a blade directive used to display error messages in your template. The right way to use it is:
#error('answer.sleep.score')
<div>{{ $message }}</div>
#enderror
Notice that in order to detect whether the error message exists, I'm using the same format as you did in the validation i.e. answer.sleep.score and NOT answer[sleep][score].
If you want to add a class to your input element when an error is detected you can do this:
<input name="answer[sleep][score]" type="text" class="form-control {{ $errors->has('answer.sleep.score') ? 'error-class' : '' }}" placeholder="Score" value="{{ old('answer.sleep.score') }}">
By using old, you can pre-fill input field with the posted value.
You can use regular expression for the validation will be much better then this:
$request->validate([
'answer.sleep.score' => 'nullable|regex:/^[0-9]*$/',
]);
This allow you to enter only numbers in the field.
I write the form.blade.php like this:
<div class="form-group">
<label>Start at</label>
<div id="start_date" class="input-group date form_datetime col-md-4" data-date-format="yyyy-mm-dd hh:ii:ss">
<input class="form-control" name="start_at" size="16" type="text" value="{{ $activity->start_at }}">
<span class="input-group-addon"><span class="glyphicon glyphicon-remove"></span></span>
<span class="input-group-addon"><span class="glyphicon glyphicon-th"></span></span>
</div>
</div>
Both Create and Edit method use the view to display the form. In the Edit method, the $activity is used and everything is normal. But in the Create method, the $activity is null, so I have a error in {{ $activity->start_at }}.
I know I can use if(!empty($activity)) to prevent this error. but I do not want to use this anywhere.
What is the better way?
You could use this,
{{ $activity->start_at or '' }}
I also like to reuse code and use the same view to create or edit an object. What I do is to pass a brand new instance of the object to the create view. This way I have the object on its initial state including defaults (if any) and I am able to prefill those defaults (if any) on the displayed form. It gives me an additional benefit: if anything goes wrong with the validation at the server level the user doesn't lose any data, I just need to do something like this in the view:
<div class="form-group">
<label for="test_field" class="control-label">Fecha de firma</label>
<input type="text" value="{{ ( !empty($isabi) ? $isabi->fecha_firma : old('fecha_firma')) }}"
name="fecha_firma" id="isabi-fechafirma" class="form-control" placeholder="Este campo es obligatorio">
</div>
This is the create method with extra functionality removed for clarity (check if the user is authenticated, linking the created object with the company the user works for and other stuff):
public function create()
{
return view('isabis.create', [
"isabi" => new Isabi()
])->with($this->data);
}
I use $this->data for view configuration. Hope this helps.
I'm using Former with Laravel to build a form, and I'm trying to get two fields to be next to each other (in this case, first and last name) and then an email field below it. I've tried adding using Former::col_md_6_text, and adding ->addClass('col-md-6') and neither seemed to do much of anything. Below is the code I'm using in the form:
{{ Former::text('first_name')
->label("First Name")
->placeholder('First Name')
->required();
}}
{{ Former::text('last_name')
->label("First Name")
->placeholder('Last Name')
->required();
}}
{{ Former::text('email')
->label("Your Email")
->placeholder('Your Email')
->required();
}}
Any ideas?
This is how I've done it in the past - I dont think Former could wrap the field in another div
<div class="col-md-6">
{{ Former::text('first_name')
->label("First Name")
->placeholder('First Name')
->required();
}}
</div>
<div class="col-md-6">
{{ Former::text('last_name')
->label("First Name")
->placeholder('Last Name')
->required();
}}
</div>
There is an open github issue on this exact thing. There are some workarounds in there - but at the moment doesnt seem to be a natual option.
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;
}