Here is my case, I got a Request Class which I create using artisan :
php artisan make:request StoreSomethingRequest
Then I put my rules there, and then I can use it in my Controller method like this:
public function store(StoreSomethingRequest $request)
{
}
But what I need is, I want to separate 2 Request logic based on the button in my view (Assumes there is more than 1 submit button in my view). So my controller will look like this :
public function store(Request $request)
{
if($request->submit_button === 'button1')
{
// I want to validate using StoreSomethingRequest here
}
else
{
// I dont want to validate anything here
}
}
I would appreciate any suggestion / help. Please. :D
You can use something like this in your request class inside rules method.
public function rules()
{
$rules = [
'common_parameter_1' => 'rule:rule',
'common_parameter_2' => 'rule:rule',
];
if($this->submit_button === 'button1')
{
$rules['custom_parameter_for_button_1'] = 'rule:rule';
}
else
{
$rules['custom_parameter_for_button_2'] = 'rule:rule';
}
return $rules;
}
Add name and value attributes on the HTML submit buttons. Then check which one has been submitted. Example:
<button type="submit" name="action" value="button1">Save 1</button>
<button type="submit" name="action" value="button2">Save 2</button>
Then in the handler:
If (Request::input('action') === 'button1') {
//do action 1
} else {
// do action 2
}
Related
I have a view in my Laravel project that lets me filter my records then I have the option to download the records to excel but when I click download, it ends up filtering the records instead of exporting to excel.
Controller:
public function exportvehicles()
{
return Excel::download(new VehicleLog, 'users.xlsx');
}
Model:
public function collection()
{
return VehicleLog::all();
}
View:
<button class="btn btn-primary">Export to Excel</button>
Routes:
Route::get('users/export/', 'ReportController#exportvehicles');
If you did not use ajax or something. Try this.
Export to Excel
Probable, you send post request for download process. Since the filter button is also between the form tags, it is also seen as the submit button. For this reason, you need to write type = "submit" in the upload button and type = "button" in the filter button. If you share html codes, I can answer more correctly.
In Vehicle Controller
Use Maatwebsite\Excel\Facades\Excel;
use App\Exports\VehicleExport;
Use App\VehicleLog;
public function exportvehicles(){
$vehicle = VehicleLog::all();
$data = [
'success' => 'success'
'vehicles' => $vehicle
];
return Excel::download(new VehicleExport($data), 'Vehicledata.xlsx');
}
and in VehhicleExport.php
public function __construct($data) {
$this->data = $data;
}
public function view(): View
{
//dd($this->data);
return view('Spreadsheets.Vehicle_data',$this->data);
}
after this you have to make balde part as how you want to export
I'm trying to validate a radio button in Laravel. This is my code, but it doesn't work.
In my case, i have a dynamic form with many questions with different of type such as : radio, checkbook, single input, number input,... So I have to use array name for each type of question. For example : name="radio['.$k.']".
In my controller i make validation and $key is the $k value in initial form.
public function rules()
{
$rules = [];
if (Input::has('radio')) {
foreach (Input::get('radio') as $key => $val) {
$rules['radio.' . $key] = 'required';
}
}
if (Input::has('singleinput')) {
foreach (Input::get('singleinput') as $key => $val) {
$rules['singleinput.'.$key] = 'required|max:10';
}
}
}
public function messages()
{
$messages = [];
if (Input::has('radio')) {
// some code here;
}
}
public function answer_store($survey_id, $patient_id)
{
$rule = $this->rules();
$message = $this->messages();
$validator = Validator::make(Input::all(), $rule, $message);
}
In the view:
<input type="radio" name="radio['.$k.']" value="'.$str1.'">'.$answer->answer_body
My code works with text input type but not with radio & checkbox.
Anyone can help me?
Okay with no reply, this is my answer if you are using Laravel 5.
Laravel 5 uses requests when you submit a form. You can perform validation on that data before it executes your controller.
Firstly use your terminal to run a artisan command
php artisan make:request MyRequest
This will create a file in App\Http\Requests.
Put this in the new request file
<?php namespace App\Http\Requests;
use App\Http\Requests\Request;
class MyRequest 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()
{
return [
'myRadios' => 'required'
];
}
}
In your view, have radios like the following, ensuring the group of radios you want all have the same name.
<input type="radio" name="myRadios" value="1"> Number 1
<input type="radio" name="myRadios" value="2"> Number 2
<input type="radio" name="myRadios" value="3"> Number 3
In your Controller you will need to reference the request file and put it into your function using dependency injection.
When you want to use the value of the radio that was selected, you use the $request array
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Http\Requests\MyRequest;
class MyController extends Controller {
/**
* Display a listing of the resource.
*
* #return Response
*/
public function myFormFunction(MyRequest $request)
{
//Get the value of the radio selected
$myVariable = $request['myRadios'];
}
}
?>
After one day, I found the solution for my problem.
Using if (Input::has('radio')) { } in the rule code. Because if i
don't select anything, don't have any information related radio to
validate.
For array of radio questions I use:
<input type="radio" name="radio['.$count_radio.']" value="'.$str1.'">
My problem is i don't know how many radio question each form. I have many different form. I will count number of radio form in View file and pass to Controll ($count_radio).
In controller, i make rule like this:
for ($key = 1; $key <= $count_radio; $key++) {
$rules['radio.' . $key] = 'required';
}
I also add error with this code in View:
if($errors->has('radio.'.$count_radio.'')) {
echo $errors->first('radio.'.$count_radio.'');
}
That's all.
You have the input tag ending in </label>.
Not sure if that will help.
I have form like this :
name (required).
slug (required).
slug is required in back end but user is allowed to leave it blank in form field ( if user leave slug blank, it will use name as the input instead ).
I have tried with Event form listener but it said You cannot change value of submitted form. I tried with Data transformers like this :
public function reverseTransform($slug)
{
if ($slug) {
return $slug;
} else {
return $this->builder->get('name')->getData();
}
}
return $this->builder->get('name')->getData(); always return null. So I tried like this:
public function reverseTransform($slug)
{
if ($slug) {
return $slug;
} else {
return $_POST['category']['name'];
}
}
it works but I think it against the framework. How I can done this with right way?
You can also do it in the controller
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
// get the data sent from your form
$data = $form->getData();
$slug = $data->getSlug();
// if no slug manually hydrate the $formObject
if(!$slug)
{
$formObject->setSlug($data->getName());
}
$em->persist($formObject);
$em->flush();
return ....
}
}
If you use a function to keep the code at one place then you should also not work with Request data.
In the form action you call that function including the name variable.
public function reverseTransform($name, $slug)
{
if (!empty($slug)) {
return $slug;
} else {
return $name;
}
}
Another possible way is to set via request class like this:
Array form <input name="tag['slug']"...>:
public function createAction(Request $request)
{
$postData = $request->request->get('tag');
$slug = ($postData['slug']) ? $postData['slug'] : $postData['name'];
$request->request->set('tag', array_merge($postData,['slug' => $slug]));
.......
Common form <input name="slug"...>:
$request->request->set('slug', 'your value');
I think this is the best way because if you are using dml-filter-bundle you don't need to filter your input in your controller like this again:
$this->get('dms.filter')->filterEntity($entity);
Everything looks right to me. It's so simple, but I dont know. I've looked everywhere.
Problem: It doesn't redirect. It doesn't give error nothing happens.
But when I enter the browser http://site.dev/fail
it shows "fail" word on screen (so it works).
routes.php:
Route::post('getir' , 'Ahir\Ticket\Controllers\TicketController#postInsert');
Route::get('fail', function() { return 'fail'; });
Route::get('success', function() { return 'success'; });
edit everything
Scenario:
on site.dev/ (homepage) I press submit that form has this.
form action="getir" method="POST" role="form"
so button redirect me to
Route::post('getir' , 'Ahir\Ticket\Controllers\TicketController#postInsert');
so this postInsert is triggered below at controller ticket.
controller ticket:
<?php namespace Ahir\Ticket\Controllers;
use BaseController, Input;
//use Ahir\Ticket\Repositories\TicketInterface;
use Ahir\Ticket\Adapters\AdapterInterface ;
class TicketController extends BaseController {
public function __construct(AdapterInterface $adapter) //TicketInterface $repository
{
//$this->repository = $repository;
$this->adapter = $adapter;
}
public function postInsert()
{
$this->adapter->postInsert();
}
}
then it comes here
codes
public function postInsert()
{
// create the validation rules ------------------------
$rules = array(
'title' => 'required',
'content' => 'required',
);
$validator = Validator::make(Input::all(), $rules);
if ($validator->fails()) {
// i added here return vardump('fail'); it displays on screen.
// so i know that program comes here
// but the redirect below neither gives error nor redirect.
//nothing happens here. idk why!
return Redirect::to('fail')->withErrors($validator);
} else {
// validation successful ---------------------------
$this->obj->insert([
'title' => Input::get('title') ,
'content' => Input::get('content')
]);
//here DOESNT work too.
return Redirect::to('success');
}
The problem is that you don't return anything from the calling function.
Your application calls the postInsert() method on your ticket controller. This function calls another function which returns a Redirect.
But you don't pass that returned Redirect back to the application, so the postInsert() function just terminates without any output. The application doesn't know what happens within the postInsert() function, it just waits for something to be returned. And since nothing is returned, the HTTP response is simply empty. In order to pass that Redirect back to the application, you also have to return it from the calling function:
public function postInsert()
{
return $this->adapter->postInsert();
}
I found CodeIgniter form validation to show error message with load->view method, and will lost field error message if use "redirect".
Currently I use one function to show form page, and another function to deal form post.
class Users extends CI_Controller {
function __construct() {
parent::__construct();
}
public function sign_up()
{
$this->load->view('users/sign_up');
}
public function do_sign_up(){
$this->form_validation->set_rules('user_login', 'User Name', 'trim|required|is_unique[users.login]');
$this->form_validation->set_rules('user_email', 'Email', 'trim|required|valid_email|is_unique[users.email]');
if ($this->form_validation->run() == FALSE) {
$this->load->view('users/sign_up');
}else {
// save post user data to users table
redirect_to("users/sign_in");
}
When form validation failed, url in browser will changed to "/users/do_sign_up", I want to keep same url in sign_up page.
Use redirect("users/sign_up") method in form validation failed will keep same url, but validation error message will lost.
in Rails, I cant use routes to config like this:
get "users/sign_up" => "users#signup"
post "users/sign_up" => "users#do_signup"
imho it's not necessary to check the request method because if the user 'GET' to the page you want to show the sign up view... if they user 'POST' to the page and fails validation you ALSO want to show the sign up view. You only won't want to show the sign up view when the user 'POST' to the page and passes validation.
imho here's the most elegant way to do it in CodeIgniter:
public function sign_up()
{
// Setup form validation
$this->form_validation->set_rules(array(
//...do stuff...
));
// Run form validation
if ($this->form_validation->run())
{
//...do stuff...
redirect('');
}
// Load view
$this->load->view('sign_up');
}
Btw this is what im doing inside my config/routes.php to make my CI become RoR-like. Remember that your routes.php is just a normal php file so u can put a switch to generate different routes depending on the request method.
switch ($_SERVER['REQUEST_METHOD'])
{
case 'GET':
$route['users/sign_up'] = "users/signup";
break;
case 'POST':
$route['users/sign_up'] = "users/do_signup";
break;
}
Here is my approach in CodeIgniter 4. I think you only need one method to complete the task.
In your app/Config/Routes.php
/*
* --------------------------------------------------------------------
* Route For Sign up page
* --------------------------------------------------------------------
*/
$routes->match(['get','post'], 'signup', 'Users::Signup');
In your app/Views/signup.php
<?php print form_open('/signup', ['method' => 'POST']);?>
<!--All other inputs go here, for example-->
<input type="text" name="firstname">
<?php print form_close();?>
In your app/Controllers/Users.php
namespace App\Controllers
use App\Controllers\BaseController;
class Users extends BaseController
{
public function Signup(){
helper(['form', 'url']);
//run validations here
if ($this->request->getMethod() === 'post' && $this->validate([
'firstname' => [
'label' => 'Firstname',
'rules' => 'required|alpha_space',
'errors' => [
'required' =>'Please enter your <strong>Firstname</strong> e.g.John',
'alpha_space' => 'Only alphabetic characters or spaces for <strong>Firstname</strong> field'
]
],
])){
//do other stuff here such as save data to database
$first_name=$this->request->getPost('firstname');
//if all go well here you can redirect to a favorite page
//e.g /success page
return redirect()->to('/success');
}
//if is get or post
print view('signup');
}
}
<button type="submit"class="md-btn btn-sm md-fab m-b-sm indigo" id="filterbtn" formaction="<?php echo base_url(); ?>front/get_filter/<?php echo$device_id;?>"><i class="fa fa-bar-chart"></i></button>
<button type="submit"class="md-btn btn-sm md-fab m-b-sm indigo" id="filterbtn" formaction="<?php echo base_url(); ?>front/get_data/<?php echo$device_id;?>"><i class="fa fa-th-list"></i></button>