I have setup the laravel resource controller and utilized the edit and update methods to edit user profiles. My profile form turned out to be too long, so I would like to split it into two forms.
The trouble is that the update function appears to be built into the resource controller - I tried just copy the method, add in my inputs and rename it. I updated the routes and view, but received an error. I also tried to have both forms call the same function, but the information that wasn't included in the form was delete from my db.
My question is, how do I split my form into two, so I can update my user profile from two forms instead of one? Any help would be appreciated. Thank you
For reference, here is my ContractorController
public function edit($id)
{
//
// get the contractor
$contractor = Contractor::find($id);
// show the edit form and pass the contractor
return View::make('contractors.edit')
->with('contractor', $contractor);
}
public function update($id)
{
//
// validate
// read more on validation at http://laravel.com/docs/validation
$rules = array(
);
$validator = Validator::make(Input::all(), $rules);
// process the login
if ($validator->fails()) {
return Redirect::to('contractors/' . $id . '/edit')
->withErrors($validator)
->withInput(Input::except('password'));
} else {
// store
$contractor = Contractor::find($id);
$contractor->name = Input::get('name');
$contractor->tag_line = Input::get('tag_line');
$contractor->contact_name = Input::get('contact_name');
//would like to split items below into a separate form:
$contractor->public_email = Input::get('public_email');
$contractor->phone = Input::get('phone');
$contractor->address_1 = Input::get('address_1');
$contractor->city = Input::get('city');
$contractor->state = Input::get('state');
$contractor->zip = Input::get('zip');
$contractor->website = Input::get('website');
$contractor->story = Input::get('story');
$contractor->save();
// redirect
Session::flash('message', 'Successfully updated profile!');
return Redirect::to('contractors');
}
}
Start of form in edit.blade.php
{{ Form::model($contractor, array('route' => array('contractors.update', $contractor->id), 'class' => 'form-horizontal', 'method' => 'PUT')) }}
Related
I am currently trying to add a Clone action to my EmployeeCrudController.
The action should redirect to the Action::NEW view and have some prefilled values.
However I can't figure out how to prefill this form.
Here is where how I define my action within the EmployeeCrudController:
public function configureActions(Actions $actions): Actions
{
$cloneAction = Action::new('Clone', '')
->setIcon('fas fa-clone')
->linkToCrudAction('cloneAction');
return $actions->add(Crud::PAGE_INDEX, $cloneAction);
}
And this is how my cloneAction looks like, which currently redirects to the Action::NEW as expected but without prefilled values:
public function cloneAction(AdminContext $context): RedirectResponse
{
$id = $context->getRequest()->query->get('entityId');
$entity = $this->getDoctrine()->getRepository(Employee::class)->find($id);
$clone = new Employee();
$entity->copyProperties($clone);
$clone->setFirstname('');
$clone->setLastname('');
$clone->setEmail('');
$routeBuilder = $this->get(CrudUrlGenerator::class);
$url = $routeBuilder->build([
'Employee_lastname' => 'test',
'Employee[teamMembershipts][]' => $clone->getTeamMemberships(),
])
->setController(EmployeeCrudController::class)
->setAction(Action::NEW)
->generateUrl()
;
return $this->redirect($url);
}
You can set the value of a field in easyAdmin using the option data.
$builder->add('Employee_lastname', null, ['data' => $clone->getTeamMemberships()]);
If your field has multiple options, you can use the choices and choices_value.
I'm having an issue with looping a form in Symfony using while loop. When the user enters one student period and it matches a registration reiterate the form to let them enter a 2nd student period and then a 3rd. I'm not doing it correctly or could I reiterate entity=new Student(); to let them enter two entities .
public function createAction(Request $request){
$entity = new Student();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$student = $em->getRepository('AcmeDemoBundle:Payrollperiod')
->findOneBy([
'begindate'=>$form->get('beginDate')->getData(),
'lastdate'=>$form->get('lastDate')->getData()
]);
$registration = $em->getRepository('AcmeDemoBundle:Payrollweek')
->findBystartdateAndenddate(
$form->get('beginDate')->getData(),
$form->get('lastDate')->getData()
);
$counter = count($registration);
while($counter<=2) {
if ($student){
$this->addFlash('error', 'Duplicate error: Student Period already existed.' );
return $this->redirect($this->generateUrl('student'));
}
elseif ($registration){
foreach ($registration as $reg) {
$reg->setStudentid($entity);
}
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('payrollperiod'));
}
else{
$this->addFlash('error', ' does not match .');
return $this->redirect($this->generateUrl('student'));
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
}
Read the documentation here http://symfony.com/doc/current/reference/forms/types/form.html#allow-extra-fields on adding fields. Your UI/Front-end should created more fields when the user needs to add a second or more periods. I should generate proper Symfony form elements and then when you post, you can handle it like a standard form post, iterating over the Request since the periods will be submitted as an array.
I did something like this in the past I adding a new form row was an AJAX call to a template that described the form input fields so I wasn't having to craft form HTML in Javascript/jQuery. .append() the template results to the form-- post and process the request.
just started using Laravel but want to make sure I am using it correctly.
Most of my work is CMS based so read / write / update etc to a database.
An example of what I have done so far is an insertion into the DB:
On the view I have a form with a URL of 'addNewUser'.
In my routes I then do:
Route::post('addnewuser', array('uses' => 'UserController#addNewUser'));
My user controller 'addNewUser' method is (simplified):
public function addNewUser() {
$data = Input::all();
$rules = array(
'username' => 'required|alpha_dash|max:16|unique:users,username',
);
$validator = Validator::make($data, $rules, $messages);
if ($validator->fails())
{
Input::flash();
$errors = $validator->messages();
return Redirect::to('/register')->withErrors($validator)->withInput();
}
$user = new User;
$user->save();
return Redirect::to('/login')->with('successLogin', '1');
}
Is this correct? I have read somewhere that all DB interaction should be in the model?
Likewise when reading from the DB to display a foreach for example, I do the following directly in the view:
$builds = DB::table('blogs')->orderBy('id', 'desc')->get();
if ($builds) {
foreach ($builds as $build)
{
$safeURLSlug = stringHelpers::safeURLSlug($build->blogtitle);
echo "
// stuff
";
}
} else {
// no stuff
}
Should I be doing these sort of queries and showing of data directly in the view? or in a model / controller function etc?
Want to check im doing things 100% correct / the standard way of doing things before I get too involved.
I can see a few things that I personally would have done differently.
For example I usually put $rules as a class variable so it can be used in different functions related to your Users.
Have you tested your code yet? Any errors?
In your addNewUser function does it save any data? I know you have "simplified" above the code snippet but there should be $user->username = $data['username']; etc. in between creating your $user variable and running $user->save();, so if you excluded this on purpose then I don't see anything else with your model.
In your view code, $builds = DB::table('blogs')->orderBy('id', 'desc')->get(); should be done in your controller and passed to your view like so return View::make('example', array('builds' => $builds))
I'd also change
$builds = DB::table('blogs')->orderBy('id', 'desc')->get();
to
$builds = Blog::orderby('id','desc')->get(); if you have a Blog model, otherwise your code is fine.
You could move:
$rules = array(
'username' => 'required|alpha_dash|max:16|unique:users,username',
);
to User model as static variable, and instead of:
$validator = Validator::make($data, $rules, $messages);
you could use:
$validator = Validator::make($data, User::$rules, $messages);
But definitely you shouldn't get data from database in your View, this code should be in controller, for example:
$builds = DB::table('blogs')->orderBy('id', 'desc')->get();
return View::make('someview')->with('builds', $builds);
of course if you have Blog model, you should use here:
$builds = Blog::orderBy('id', 'desc')->get();
return View::make('someview')->with('builds', $builds);
It's also unclear what the following code does:
$safeURLSlug = stringHelpers::safeURLSlug($build->blogtitle);
but probably you could move it to your Blog model and use accessor to make the change:
public function getSafeSlugAttribute($value) {
return stringHelpers::safeURLSlug($this->blogtitle);
}
and now your view could look like this:
#foreach ($builds as $build)
{{{ $build->title }}} {{{ $build->safeSlug }}}
#endforeach
I suggest you take a look on Laravel Generators.
https://github.com/JeffreyWay/Laravel-4-Generators
Install and then run:
php artisan generate:scaffold customer
Laravel line command generator create a basic CRUD for you with controller, model, views and database migrations. That's good to safe time and keep your project with some default organization.
Here is my Form
{{ Form::open(array('url' => 'register', 'class' => 'form-signin')) }}
// form username , password .. fields here
{{ Form::close() }}
And the route is
Route::post('register', 'RegisterController#registeruser');
And the Controller is
public function registeruser()
{
//validation
return Redirect::to('/')->withErrors($validator); // main
}
As, i am being redirected i won't be having any fields that is filled in the form.
I know that i should use request and response for this.
I tried with below response, even this is a horrible try.
return Response::view('home')->header('utf-8', $messages);
But while doing above even the page reloads and the values filled in the form disappears. How can i through the errors without the values disappears ?
Is there a way to have filled the fields in the form as entered ?
You need to use ->withInput()
return Redirect::to('/')->withInput()->withErrors($validator); // main
You can use Input::flash()
public function registeruser()
{
//validation
Input::flash();
return Redirect::to('/')->withErrors($validator); // main
}
Then in the controller method that handles the redirect you can access the old input with Input::old(). Using Input::all() will only return data for the current request.
You can also use the ->withInput() chained method on your return line.
Read more about it here http://laravel.com/docs/4.2/requests
Let's suppose you have a validation like this:
$validation = Validator::make($input, $rules);
Then you need to do that:
if( $validation->fails() )
{
return Redirect::back()->withInput()->withErrors($validator->messages());
}
note the Redirect::back() that allows you to get back to your form and fill it automatically with user input
Can we edit the possible options for a choice field after the field has been created?
Let's say, the possible options for the choice field(a drop down box for categories) comes from my database. My controller would look like this:
public function addAction(Request $request){
//get the form
$categories = $this->service->getDataFromDatabase();
$form = $this->formFactory->create(new CategoryType(), $categories);
$form->handleRequest($request);
if ($form->isValid()) {
// perform some action, such as saving the task to the database, redirect
}
return $this->templating->renderResponse('TestAdminBundle:Categories:add.html.twig',
array('form' => $form->createView())
);
}
This works. $categories is populated as a dropdown box so the user can select a category. What I don't like about this code is that it has to hit the "getDataFromDatabase" service again when the user hits submit and the form validates the input. This feels unnecessary to me; ideally it should only need to hit the service when validation fails and the form has to be regenerated for the user. I'm hoping to make the controller look something like this:
public function addAction(Request $request){
//get the form
$form = $this->formFactory->create(new CategoryType());
$form->handleRequest($request);
if ($form->isValid()) {
// perform some action, such as saving the task to the database, redirect
}
$categories = $this->service->getDataFromDatabase();
$form->setData($categories); //this tells the choice field to use $categories to populate the options
return $this->templating->renderResponse('TestAdminBundle:Categories:add.html.twig',
array('form' => $form->createView())
);
}
You need to use EventSubscriber, check the docs, here: http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html#cookbook-form-events-underlying-data