Keeping modal dialog open after validation error laravel - laravel

So basically I have a blade.php, controller page and a form request page(validation). I'm trying to keep my modal dialog open if there is an error but I just cant figure it out, what part of code am I missing out on or needs to be changed?
blade.php
<div id="register" class="modal fade" role="dialog">
...
<script type="text/javascript">
if ({{ Input::old('autoOpenModal', 'false') }}) {
//JavaScript code that open up your modal.
$('#register').modal('show');
}
</script>
Controller.php
class ManageAccountsController extends Controller
{
public $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function index()
{
$users = User::orderBy('name')->get();
$roles = Role::all();
return view('manage_accounts', compact('users', 'roles'));
}
public function register(StoreNewUserRequest $request)
{
// process the form here
$this->userRepository->upsert($request);
Session::flash('flash_message', 'User successfully added!');
//$input = Input::except('password', 'password_confirm');
//$input['autoOpenModal'] = 'true'; //Add the auto open indicator flag as an input.
return redirect()->back();
}
}
class UserRepository {
public function upsert($data)
{
// Now we can separate this upsert function here
$user = new User;
$user->name = $data['name'];
$user->email = $data['email'];
$user->password = Hash::make($data['password']);
$user->mobile = $data['mobile'];
$user->role_id = $data['role_id'];
// save our user
$user->save();
return $user;
}
}
request.php
class StoreNewUserRequest extends Request
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
// create the validation rules ------------------------
return [
'name' => 'required', // just a normal required validation
'email' => 'required|email|unique:users', // required and must be unique in the user table
'password' => 'required|min:8|alpha_num',
'password_confirm' => 'required|same:password', // required and has to match the password field
'mobile' => 'required',
'role_id' => 'required'
];
}
}

Laravel automatically checks for errors in the session data and so, an $errors variable is actually always available on all your views. If you want to display a modal when there are any errors present, you can try something like this:
<script type="text/javascript">
#if (count($errors) > 0)
$('#register').modal('show');
#endif
</script>

Put If condition outside from script. This above is not working in my case
#if (count($errors) > 0)
<script type="text/javascript">
$( document ).ready(function() {
$('#exampleModal2').modal('show');
});
</script>
#endif

for possibly multiple modal windows you can expand Thomas Kim's code like following:
<script type="text/javascript">
#if ($errors->has('email_dispatcher')||$errors->has('name_dispatcher')|| ... )
$('#register_dispatcher').modal('show');
#endif
#if ($errors->has('email_driver')||$errors->has('name_driver')|| ... )
$('#register_driver').modal('show');
#endif
...
</script>
where email_dispatcher, name_dispatcher, email_driver, name_driver
are your request names being validated

just replace the name of your modal with "login-modal". To avoid error put it after the jquery file you linked or jquery initialized.
<?php if(count($login_errors)>0) : ?>
<script>
$( document ).ready(function() {
$('#login-modal').modal('show');
});
</script>
<?php endif ?>

Related

How to Validate File Upload in Laravel [duplicate]

This question already has answers here:
How to Validate on Max File Size in Laravel?
(2 answers)
Closed 4 years ago.
I've completed a tutorial to upload image files. How can I validate file uploads in the view when a user uploads a file larger than 2MB?
create.blade.php
#if (count($errors) > 0)
<div class="alert alert-danger">
<strong>Whoops!</strong> Errors.<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
#if(session('success'))
<div class="alert alert-success">
{{ session('success') }}
</div>
#endif
<div class="form-group">
<input type="file" name="photos[]" multiple aria-describedby="fileHelp"/>
<small id="fileHelp" class="form-text text-muted">jpeg, png, bmp - 2MB.</small>
</div>
Rules
public function rules()
{
$rules = [
'header' => 'required|max:255',
'description' => 'required',
'date' => 'required',
];
$photos = $this->input('photos');
foreach (range(0, $photos) as $index) {
$rules['photos.' . $index] = 'image|mimes:jpeg,bmp,png|max:2000';
}
return $rules;
}
Everything is ok, however when I try to upload a file which is larger than 2MB it gives me an error:
Illuminate \ Http \ Exceptions \ PostTooLargeException No message
How can I solve this and secure this exception?
in laravel you can not handle this case in controller as it will not get to controller/customrequest and will be handled in middleware so you can handle this in ValidatePostSize.php file:
public function handle($request, Closure $next)
{
// if ($request->server('CONTENT_LENGTH') > $this->getPostMaxSize())
{
// throw new PostTooLargeException;
// }
return $next($request);
}
/**
* Determine the server 'post_max_size' as bytes.
*
* #return int
*/
protected function getPostMaxSize()
{
if (is_numeric($postMaxSize = ini_get('post_max_size'))) {
return (int) $postMaxSize;
}
$metric = strtoupper(substr($postMaxSize, -1));
switch ($metric) {
case 'K':
return (int) $postMaxSize * 1024;
case 'M':
return (int) $postMaxSize * 1048576;
default:
return (int) $postMaxSize;
}
}
with your custom message
Or in App\Exceptions\Handler:
public function render($request, Exception $exception)
{
if ($exception instanceof \Illuminate\Http\Exceptions\PostTooLargeException) {
// handle response accordingly
}
return parent::render($request, $exception);
}
Else need to update php.ini
upload_max_filesize = 10MB
If you dont to work with any of above solutions you can use client side validation like if you are using jQuery e.g.:
$(document).on("change", "#elementId", function(e) {
if(this.files[0].size > 7244183) //set required file size 2048 ( 2MB )
{
alert("The file size is too larage");
$('#elemendId').value = "";
}
});
or
<script type="text/javascript">
function ValidateSize(file) {
var FileSize = file.files[0].size / 1024 / 1024; // in MB
if (FileSize > 2) {
alert('File size exceeds 2 MB');
$(file).val(''); //for clearing with Jquery
} else {
}
}
</script>
you have validate image in $rules. try this code:
$this->validate($request,[
'header' => 'required|max:255',
'description' => 'required',
'date' => 'required',
'photos.*' => 'image|mimes:jpeg,bmp,png|max:2000',
]);
Laravel uses its ValidatePostSize middleware to check the post_max_size of the request and then throws the PostTooLargeException if the CONTENT_LENGTH of the request is too big. This means that the exception if thrown way before it even gets to your controller.
What you can do is use the render() method in your App\Exceptions\Handler e.g.
public function render($request, Exception $exception){
if ($exception instanceof PostTooLargeException) {
return response('File too large!', 422);
}
return parent::render($request, $exception);
}
Please note that you have to return a response from this method, you can't just return a string like you can from a controller method.
The above response is to replicate the return 'File too large!'; you have in the example in your question, you can obviously change this to be something else.
Hope this helps!
You can try with putting a custom message inside message() message or add PostTooLargeException handler in Handler class. Something like that:
public function render($request, Exception $exception)
{
...
if($exception instanceof PostTooLargeException){
return redirect()->back()->withErrors("Size of attached file should be less ".ini_get("upload_max_filesize")."B", 'addNote');
}
...
}

Error in Custom Blade Directives with array as parameter

In my Laravel 5.7 app I want to use Custom Blade Directives and to pass an array in this directive
as there could be different access, like :
#loggedUserHasAccess([USER_ACCESS_ADMIN])
<div class="col">
<a class="social-inner" href="{{ route('admin.dashboard') }}" >
<span class="icon"></span><span>Backend</span>
</a>
</div>
#endLoggedUserHasAccess
And in app/Providers/AppServiceProvider.php :
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
...
\Blade::directive('loggedUserHasAccess', function (array $accessArray) {
$condition = false;
if (Auth::check()) {
$loggedUser = Auth::user();
$usersGroups = User::getUsersGroupsByUserId($loggedUser->id, false);
foreach ($usersGroups as $next_key => $nextUsersGroup) {
if (in_array($nextUsersGroup->group_id, $accessArray)) {
$condition = true;
}
}
}
return "<?php if ($condition) { ?>";
});
Blade::directive('endLoggedUserHasAccess', function () {
return "<?php } ?>";
});
But I got syntax error : https://imgur.com/a/I5s1TmQ
USER_ACCESS_ADMIN is defined in bootstrap/app.php.
looks like my syntax is invalid, but which is valid ?
Thanks!

How to pass variable from blade to LARAVEL commands

I need to pass user_id from blade to routes, and then use the variable into a laravel command. How can I do?
lista_lavori.blade.php
<div class="box-tools">
<i class="fa fa-print"></i>
</div>
web.php - route
Route::get('/stampasingoloreport/{id}', function ($id) {
Artisan::call('StampaSingoloReport:stampasingoloreport');
return back();
});
StampaSingoloReport.php - Commands
public function handle()
{
// static id i need to change this dinamically
$id = 5;
$utente = \App\User::where('id',$id)->get();
//invio email per avvertire l'utente
$data = array('utenti'=>$utente);
Mail::send('mail.invioMailReportLavoriSingoli', $data, function($message) {
$message->to('rubertocarmine94#gmail.com', 'Admin Risorse Umane') ->subject('Email da piattaforma BancaStatoHR') ;
$message->from('rubertocarmine94#gmail.com') ;
});
}
You can pass an array to call() method like
Route::get('/stampasingoloreport/{id}', function ($id) {
Artisan::call('StampaSingoloReport:stampasingoloreport',[
'id' => $id
]);
return back();
});
Now in your handle method, you can access these arguments like
protected $signature = 'StampaSingoloReport:stampasingoloreport { id } ' ;
function handle(){
$this->argument('id');
// your code
}
Hope this helps

Implement Viewstate in codeigniter

I´ve been working with aspnet for quite a while, and i´d like to implement aspnet viewstate with in php (exactly in codeigniter). Is there a way to implement ASP ViewState with Codeigniter ?
This answer will accomplish some of the goals of Viewstate in that is will preserve control values between form submits. If you navigate away from the page the data will be lost. But it's the same for Viewstate. The example code make heavy use of the CodeIgniter (CI) Framework.
Here is some documentation related to the parts of CI used here.
Form Validation
Form Helper
Session
The CI_Form_validation library suffers from not being able to keep validation results across a redirect. This class extends CI_Form_validation to overcome that limitation.
File: application/libraries/My_Form_validation.php
/**
* Extends CI_Form_validation to facilitate using the Post/Redirect/Get pattern for form handling.
* https://en.wikipedia.org/wiki/Post/Redirect/Get
* http://solidlystated.com/design/best-way-to-process-forms-with-php/
*
* The base class (CI_Form_validation) has the protected property $_field_data
* which holds all the information provided by form_validation->set_rules()
* and all the results gathered by form_validation->run().
* Form Helper and Form_Validation use the $_field_data to re-populate fields and present error messages.
*
* To use this class you must have CodeIgniter Session setup and working.
*
* This class stores $_field_data in session flash data for use in the controller method that is the
* redirect target.
*
* Class is handy for defining custom validation methods which will NOT require the "callback_" prefix.
*
*/
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Form_validation extends CI_Form_validation
{
public function __construct($rules = array())
{
parent :: __construct($rules);
$this->CI->load->library('session');
}
/**
* Enhanced version of form_validation->run(). Sets a $_SESSION item with the contents of $this->_field_data
*
* #param string $group The name of the validation group to run
* #param bool $persistent If TRUE save the state of $_field_data even if validation passes
* #return boolean TRUE on success and FALSE on failure
*/
public function run($group = '', $persistent = FALSE)
{
if(parent:: run($group))
{
if($persistent)
{
$this->CI->session->set_flashdata('validation_field_data', $this->_field_data);
}
return TRUE;
}
$this->CI->session->set_flashdata('validation_field_data', $this->_field_data);
return FALSE;
}
/**
* This is used in the redirect target defined in the form processing controller/method
*
* #return bool TRUE if $_SESSION['validation_field_data'] is set. It indicates that validation failed.
* Returns FALSE if there is no indication that validation has failed or even been run.
*/
public function is_failed_validation()
{
if(isset($_SESSION['validation_field_data']))
{
// Validation failed or is being persisted.
$this->_field_data = $_SESSION['validation_field_data'];
return TRUE;
}
return FALSE;
}
/**
* A validation function to cleanup strings
*
* #param string $str Value of the field
* #return string|bool The sanitized string or FALSE if filter_var() fails
*/
public function sanitize_str($str)
{
return filter_var($str, FILTER_SANITIZE_STRING);
}
/**
* A do-nothing routine assigned to any field we want included in validation results
* #return boolean
*/
public function alwaysTrue($val)
{
return TRUE;
}
}
Hopefully the comments explain what's going on. One major thing to understand is that form_validation only captures the $_POST data for controls that have validation rules. That's the reason for the "do-nothing" validation routine alwaysTrue(). Use this rule on any control where you want the values to persist.
The following controller shows a usage example.
File: application/controllers/Viewstate.php
class Viewstate extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load
->library('form_validation', NULL, 'fv') //renames 'form_validation' to 'fv'
->helper(['form', 'url']);
$this->fv->set_error_delimiters('<span class="error">', '</span>');
}
public function index()
{
$this->fv->is_failed_validation(); //captures validation data if it's there
//Define some data for consumption by CI's Form Helper functions
$data['username_field'] = [
'name' => 'username',
'id' => 'username',
'value' => $this->fv->set_value('username'),
'class' => 'your_css',
];
$data['confirm_username_field'] = [
'name' => 'usernameconf',
'id' => 'usernameconf',
'value' => $this->fv->set_value('usernameconf'),
'class' => 'your_css',
];
$data['comment_field'] = [
'name' => 'comment',
'id' => 'comment',
'value' => $this->fv->set_value('comment'),
'class' => 'comment',
];
$data['project_lead_field'] = [
'name' => 'project_lead',
'value' => 1,
'checked' => $this->fv->set_radio('project_lead', 1, FALSE)
];
$selected_status = ['None' => "None"]; //default dropdown item
$status_items = ["None" => "None", "Good" => "Good", 'Bad' => 'Bad', "Ugly" => "Ugly"];
//recover previously posted select item - if any
if($item = $this->session->validation_field_data['status']['postdata'])
{
$selected_status = [$item => $item];
}
$data['status_field'] = [
'name' => 'status',
'options' => $status_items,
'selected' => $selected_status
];
$this->load->view('testcase_view', $data);
}
/**
* This is the "action" that processes the form's posted data
*/
public function process()
{
//set rules and error messages at same time
$this->fv
->set_rules('username', 'User Name', ['trim', 'required', 'matches[usernameconf]'],
['required' => '<em>{field}</em> required.', 'matches' => "User Names don't match."])
->set_rules('usernameconf', '', ['trim', 'required'], ['required' => 'Retyping the User Name is required.'])
->set_rules('comment', "", ['trim', 'sanitize_str'])
->set_rules('project_lead', "", 'alwaysTrue')
->set_rules('status', "", 'alwaysTrue')
;
//So an uncheck checkbox will be part of the $_POST array
if(!isset($_POST['project_lead']))
{
$_POST['project_lead'] = 0;
}
if(FALSE == $this->fv->run('', TRUE))
{
redirect('viewstate');
}
else
{
//do something with field values e.g.
//$this->model->instert($_POST);
redirect('viewstate'); //to prove the page state is persistent
}
}
}
I included some actual field validation so readers can see how that works and how the validation results persist across a redirect.
Here is the view
File: application/views/textcase_view.php
<!DOCTYPE html>
<html>
<head>
<title>Test Persistent Page</title>
<style type="text/css">
p{
margin: 0;
}
.error {
color: #FF0000;
font-size: small;
}
.fld-label{
color: #555;
font-size: .9em;
}
.comment{
color: Blue;
font-weight: bold;
}
div{
margin-bottom: 1em;
}
div + .fld-label
/*div + .error*/
{
margin-bottom: 0;
}
</style>
</head>
<body>
<?= form_open('viewstate/process'); ?>
<span class="fld-label">User Name</span>
<div><?= form_input($username_field) ?>
<p><?= form_error('username'); ?></p>
</div>
<div class="fld-label">Retype User Name</div>
<div><?= form_input($confirm_username_field) ?>
<p><?= form_error('usernameconf'); ?></p>
</div>
<div class="fld-label">Comment</div>
<div><?= form_input($comment_field); ?></div>
<div class="fld-label">Project Lead?</div>
<div><?= form_checkbox($project_lead_field); ?></div>
<div class="fld-label">Status</div>
<div><?= form_dropdown($status_field); ?></div>
<p><input type="submit" value="Submit"></p>
<?= form_close(); ?>
</body>
</html>
The view makes heavy use of Form Helper functions such as form_open, form_close, form_input, etc.

Laravel 5.2 Custom validation message with custom validation function

I want to create custom validation rule with custom validation error message. For this I created a rule:
$rule => [
'app_id' => 'isValidTag'
]
And for custom message:
$message => [
app_id.isValidTag => 'Not a Valid id'
];
After that I created Service Provider:
class CustomValidationServiceProvider extends ServiceProvider
{
public function boot() {
//parent::boot();
$this->app->validator->resolver(function($transator,$data,$rules,$messages){
return new CustomValidator($transator,$data,$rules,$messages);
});
}
}
And my Custom validation class is:
class CustomValidator extends Validator {
if(empty($parameters)) {
return true;
}
$conext = $parameters[0];
$tag = Tag::where('id', $value)->where('context', $conext)->get();
$flag = false;
if($tag->count() > 0) {
$flag = true;
}
return $flag;
}
All is working fine but the issue is my custom message for app_id.isValidTag is not working even all other message are working fine.
Please suggest me what I missing here or in Laravel 5.2 there is some change to display message. Any idea will be appreciated.
Here is a great tutorial for this: http://itsolutionstuff.com/post/laravel-5-create-custom-validation-rule-exampleexample.html
I think you did it Laravel 4.* way. This is how it is done in Laravel 5.2
in my example where i was making registration authorisation form so files like AuthController.php was premade:
AuthController.php
Validator::make($data, [
...
// add your field for validation
'name_of_the_field' => 'validation_tag', // validation tag from validation.php
...
CustomAuthProvider.php
// if you didn't make a custom provider use Providers/AppServiceProvider.php
public function boot() {
...
Validator::extend('validation_tag', function($attribute, $value, $parameters, $validator) {
// handle here your validation
if ( your_query ) {
return true;
}
return false;
});
validation.php
...
// add your validation tag and message to be displayed
'validation_tag' => 'The field :attribute isn't good',
...
file.blade.php
// to add at the end of the page all your errors add
#if (count($errors) > 0)
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif

Resources