Message not appear on page after function is performed in laravel - laravel

Maybe is something simple but can't understand why I don't see my message.
I have this in the controller after the function is submitted
return redirect()->route('item.show', $id)->with('alert-success', ' Review submitted successfully.');
And this in item page
#foreach (['danger', 'warning', 'success', 'info','message'] as $msg)
#if(Session::has('alert-' . $msg))
<p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }} ×</p>
#endif
#endforeach
The form is submitted successfully, data is saved in the database, the page is reloaded but the message does not appear for success.
update
array(4) {
["_token"]=>
string(40) "snB4uoaR087wrvXOuh8epR56cjtC2OCSmZJd9smn"
["_previous"]=>
array(1) {
["url"]=>
string(29) "http://example.com/item/17"
}
["flash"]=>
array(2) {
["old"]=>
array(0) {
}
["new"]=>
array(0) {
}
}
["login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d"]=>
int(9)
}
Route
Route::group(['namespace' => 'Frontend', 'middleware' => 'web'], function () {
Route::post('items/review/{item}', 'ItemController#reviewSubmit')->name('item.review');
....
}

Use flash for message stuffs:
Controller
$request->flash('alert-success', ' Review submitted successfully.');
return redirect()->route('item.show', $id);
item page:
<div class="flash-message">
#foreach (['danger', 'warning', 'success', 'info'] as $msg)
#if(Session::has('alert-' . $msg))
<p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }} ×</p>
#endif
#endforeach
</div>
Check about flash message with laravel documentation
NOTE: Make sure the middleware not applied twice, this is also be the cause of this issue. Check this

Related

Laravel 5.8: Validation multiple inputs

What I have
I have a form with 3 inputs and I want to check the following conditions:
All inputs are integers and they are required.
We do a math operation with all the numbers and we get if the operation was successfull or not.
Success: we redirect the user to a success page.
No success: we show a error message to the user with a message explaining him that the numbers aren't valid.
I resolved this with the following lines.
Controller:
function formAction(Request $request) {
$this->validate($request, [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
]);
$numbers = $request->all();
$isValid = MyOwnClass::checkMathOperation($numbers);
if($isValid) {
return redirect()->route('success');
} else {
$request->session()->flash('error', 'The numbers are not valid.');
return back();
}
}
View (using Bootstrap):
<form method="POST" action="{{ route('form-action') }}">
#csrf
<div class="form-group">
<label for="number1">number1</label>
<input id="number1" name="number1" class="form-control {{ $errors->has('number1') ? ' is-invalid' : '' }}" />
</div>
<div class="form-group">
<label for="number2">number2</label>
<input id="number2" name="number2" class="form-control {{ $errors->has('number2') ? ' is-invalid' : '' }}" />
</div>
<div class="form-group">
<label for="number3">number3</label>
<input id="number3" name="number3" class="form-control {{ $errors->has('number3') ? ' is-invalid' : '' }}" />
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
What I looking for
When MyOwnClass::checkMathOperation($numbers) is false:
To highlight number1, number2 and number3 inputs.
To show an unique custom error message
To hide the number1, number2 and number3 input error messages.
How can I do that with validators?
Solution
Create a Form Request Validation called, for example, NumbersForm using:
php artisan make:request NumbersForm
The previous command creates a App/Http/Requests/NumbersForm.php file. Make authorize() returns true, put the validation rules into rules() and create a withValidatior() function.
class NumbersForm extends FormRequest
{
public function authorize() {
return true;
}
public function rules() {
return [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
];
}
public function withValidator($validator) {
$validator->after(function ($validator) {
$numbers = $this->except('_token'); // Get all inputs except '_token'
$isValid = MyOwnClass::checkMathOperation($numbers);
if(!$isValid) {
$validator->errors()->add('number1', ' ');
$validator->errors()->add('number2', ' ');
$validator->errors()->add('number3', ' ');
$validator->errors()->add('globalError', 'The numbers are not valid.');
}
});
}
}
Note: It's not important the text in the second param of $validator->errors()->add('number1', ' ');, but it can't be empty. If it is an empty string, $errors->has('number1') returns false, and the field won't be hightlighted.
Set the controller like this:
use App\Http\Requests\NumbersForm;
function formAction(NumbersForm $request) {
$this->validated();
return redirect()->route('success');
}
And, finally, if we want to print an unique error message, we must remove the following lines from view:
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
and replace them with:
#if ($errors->has('globalError'))
<div class="alert alert-danger">
{{ $errors->first('globalError') }}
</div>
#else
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
#endif
I haven't tested this but I think it can get you going in the right direction.
1 // Highlight the inputs
You can do this by accessing the error object within your view. This object is an instance of the MessageBag object.
Here is the docs: https://laravel.com/docs/5.7/validation#working-with-error-messages
Example:
// if the error exists for the input the class will be added
<input class=" {{ $error->has('number1') ? 'highlight' : '' }}" name="number1">
<input class=" {{ $error->has('number2') ? 'highlight' : '' }}" name="number2">
<input class=" {{ $error->has('number3') ? 'highlight' : '' }}" name="number3">
2 & 3 // Show a unique custom error message and hide the default messages
See the validator docs: https://laravel.com/docs/5.8/validation#custom-error-messages && https://laravel.com/docs/5.7/validation#working-with-error-messages -- this should solve both of these.
There is a validator callback and I think you can pass your second validation into that. If these numbers aren't valid then you can add your custom error messages and access them the same way as I did above.
function formAction(Request $request) {
$validator = $this->validate($request, [
'number1' => 'integer|required',
'number2' => 'integer|required',
'number3' => 'integer|required',
]);
$validator->after(function ($validator) {
$numbers = $request->all();
$isValid = MyOwnClass::checkMathOperation($numbers);
if(!$isValid) {
$validator->errors()->add('number1', 'Unique message');
$validator->errors()->add('number2', 'Unique message');
$validator->errors()->add('number3', 'Unique message');
}
});
}
Custom Validation Rules:
To add custom messages and validation you can also write a custom validation rule
Example:
class Uppercase implements Rule
{
/**
* Determine if the validation rule passes.
*
* #param string $attribute
* #param mixed $value
* #return bool
*/
public function passes($attribute, $value)
{
return strtoupper($value) === $value;
}
/**
* Get the validation error message.
*
* #return string
*/
public function message()
{
return 'The :attribute must be uppercase.';
}
}
Custom Error Messages:
You could also add custom error messages for rules within a Request:
public function messages()
{
return [
'number1.required' => 'My custom message telling the user he needs to fill in the number1 field.',
'number1.integer' => 'My custom message telling the user he needs to use an integer.',
];
}

How to Set & Get Session Data in Laravel Package Development

I am developing a package with a contact form in Laravel. I'm trying to set & get session data, but it's not working with the following.
View
#if(session('success'))
<div class="alert alert-success alert-dismissible">
×
{{session('success')}}
</div>
#endif
Controller
public function store(Request $request)
{
//Validation
$request->validate([
'email'=>'required|max:50|unique:contact_forms,email'
]);
//Data
$contact_form = new ContactForm();
$contact_form->full_name = $request->full_name;
$contact_form->mobile = $request->mobile;
$contact_form->email = $request->email;
//Save
$contact_form->save();
//Return back
return back()->with('success','Record inserted successfully');
}
Route
Route::group(['namespace' => 'W3public\ContactForm\Http\Controllers'], function () {
Route::get('contact-us', 'ContactFormController#index');
Route::post('contact-us', 'ContactFormController#store')->name('contact-us');
});
How can I set/get session data in package development in Laravel?Thanks in advance.
Best way of doing this is flash session messages
Redirect as
$request->session()->flash('alert-success', 'Record inserted successfully!');
and in your view file
<div class="flash-message">
#foreach (['danger', 'warning', 'success', 'info'] as $msg)
#if(Session::has('alert-' . $msg))
<p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }} ×</p>
#endif
#endforeach

Laravel return flash message

I am trying to return a flash message depending on the outcome of an function however I don't really know how to do this properly, can someone help me with fixing this?
Controller:
public function postDB(Requests\NameRequest $request) {
$newName = trim($request->input('newName'));
$newLat = $request->input('newCode');
$websites = new Website();
$websites->name = $newName;
$websites->html = $newLat;
$websites->save();
if ($websites->save())
{
$message = 'success';
}else{
$message = 'error';
}
return redirect()->back()->withInput()->with('message', 'Profile updated!');
}
Request:
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'img' => 'file|image',
];
}
public function messages()
{
return [
'img.image' => 'File type is not supported! Use files with extension .jpg/.jpeg/.gif',
];
}
Template:
#if (session('status'))
#if (session('status')=="success")
<div class="alert alert-success">
{{ session('message') }}
</div>
#else
<div class="alert alert-error">
{{ session('message') }}
</div>
#endif
#endif
Route:
Route::group(['middleware' => ['web']], function () {
Route::get('home', 'BuilderController#homepage');
Route::get('pages', 'BuilderController#websites');
Route::get('template', 'BuilderController#templates');
Route::post('template2', 'BuilderController#postDB');
Route::post('template', 'BuilderController#testing');
Route::get('logout', 'BuilderController#getLogout');
Route::get('/website/{name}', 'BuilderController#website');
});
Solution :
There could be only one reason for this issue.
The laravel will pass the flash messages only if it's registered inside the middleware web
i.e.,
Route::group(['middleware' => ['web']], function () {
//The back()'s url should be registered here
});
Update :
It seems you need to redirect back with message and inputs
So, You can do like this
if ($request->hasFile('img')) {
$message = 'success';
} else {
$message = 'error';
}
return redirect()->back()->withInput()->->with('message', $message);
Update 2 :
#if (session('status'))
#if (session('status')=="success")
<div class="alert alert-success">
Congrats! Everything was fine
</div>
#else
<div class="alert alert-error">
Oops! Something went wrong
</div>
#endif
#endif
Note : You can pass the status param to your wish
If you pass message as a flash parameter name, use it, not status.
#if (session('message'))
#if (session('message')=="success")
<div class="alert alert-success">
Congrats! Everything was fine
</div>
#else
<div class="alert alert-error">
Oops! Something went wrong
</div>
#endif
#endif

How to pass array to flash message?

I want to send array of additional_feature that they are exist to flash message. Now i only send one additional_feature. Any suggestion how can i do that?
if(!empty($additional_features)){
foreach($additional_features as $additional_feature){
$data = [
'name' => $additional_feature,
];
if (!Feature::where('name', '=', $additional_feature)->exists()) {
$additional = Feature::firstOrCreate($data);
$additional_ids[] = $additional->id;
}
else{
return redirect()->back()->withFlashMessage($additional_feature . ' exists!');
}
}
}
You can use session() instead of with():
session->flash('someVar', $someArray);
Another thing you could try is to seriallize array and pass it as string. Then unserilize it and use.
Also, you could save an array using simple session:
session(['someVar' => $someArray]);
Then get it and delete manually:
session('somevar');
session()->forget('someVar');
We had the same problem and forked the package. you can find it here:
Forked at first from Laracasts/Flash to use multiple message
#if (Session::has('flash_notification.message'))
#if (Session::has('flash_notification.overlay'))
#include('flash::modal', ['modalClass' => 'flash-modal', 'title' => Session::get('flash_notification.title'), 'body' => Session::get('flash_notification.message')])
#else
<div class="alert alert-{{ Session::get('flash_notification.level') }}">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
{!! Session::get('flash_notification.message') !!}
</div>
#endif
#endif
And the content of the include flash::modal
#if (Session::has('flash_notification.messages'))
#foreach (Session::get('flash_notification.messages') as $flashMessage)
#foreach($flashMessage as $type => $message)
<script>
$(function() {
var message = ('{{ $message }}<br>').replace(/'/g, "’");
customFlashMessage({
type: "{{ $type }}",
message: message
});
});
</script>
#endforeach
#endforeach
#endif
return redirect()->back()->with(['session1' => $value, 'session2' => $value]);
In the blade template:
{{ Session::get('session1') }}
{{ Session::get('session2') }}

laravel pass validation error to custom view

I created a validation but cant show it on view, its important to return search view and don't redirect back user. help me please, thanks all?
Controller :
public function search(Request $request)
{
$msg = Validator::make($request->all(), [
'search' => 'required'
]);
if ($msg->fails()) {
return view('layouts.search')->withErrors($msg->messages());
} else {
return "Thank you!";
}
}
View :
#if($errors->any())
<ul class="alert alert-danger">
#foreach($errors as $error)
<li> {{$error}} </li>
#endforeach
</ul>
#else
You can use $error->first('name_of_error_field') to show error messages.
You can do it like this:
public function search(Request $request)
{
$validator = Validator::make($request->all(), [
'search' => 'required'
]);
if ($validator->fails()) {
return view('layouts.search')->withErrors($validator); // <----- Send the validator here
} else {
return "Thank you!";
}
}
And in view:
#if($errors->any())
<ul class="alert alert-danger">
#foreach($errors as $error)
<li> {{$error->first('name_of_error_field')}} </li>
#endforeach
</ul>
#endif
See more about Laravel Custom Validators
Hope this helps

Resources