Laravel use same form for create and edit

PhpFormsLaravel

Php Problem Overview


Am quite new to Laravel and I have to create a form for create and a form for edit. In my form I have quite some jquery ajax posts. Am wondering whether Laravel does provide for an easy way for me to use the same form for my edit and create without having to add tons of logic in my code. I don't want to check if am in edit or create mode every time when assigning values to fields when the form loads. Any ideas on how I can accomplish this with minimum coding?

Php Solutions


Solution 1 - Php

I like to use form model binding so I can easily populate a form's fields with corresponding value, so I follow this approach (using a user model for example):

@if(isset($user))
    {{ Form::model($user, ['route' => ['updateroute', $user->id], 'method' => 'patch']) }}
@else
    {{ Form::open(['route' => 'createroute']) }}
@endif

    {{ Form::text('fieldname1', Input::old('fieldname1')) }}
    {{ Form::text('fieldname2', Input::old('fieldname2')) }}
    {{-- More fields... --}}
    {{ Form::submit('Save', ['name' => 'submit']) }}
{{ Form::close() }}

So, for example, from a controller, I basically use the same form for creating and updating, like:

// To create a new user
public function create()
{
    // Load user/createOrUpdate.blade.php view
    return View::make('user.createOrUpdate');
}

// To update an existing user (load to edit)
public function edit($id)
{
    $user = User::find($id);
    // Load user/createOrUpdate.blade.php view
    return View::make('user.createOrUpdate')->with('user', $user);
}

Solution 2 - Php

Pretty easy in your controller you do:

public function create()
{
    $user = new User;

    $action = URL::route('user.store');

    return View::('viewname')->with(compact('user', 'action'));
}

public function edit($id)
{
    $user = User::find($id);

    $action = URL::route('user.update', ['id' => $id]);

    return View::('viewname')->with(compact('user', 'action'));
}

And you just have to use this way:

{{ Form::model($user, ['action' => $action]) }}

   {{ Form::input('email') }}
   {{ Form::input('first_name') }}

{{ Form::close() }}

Solution 3 - Php

For the creation add an empty object to the view.

return view('admin.profiles.create', ['profile' => new Profile()]);

Old function has a second parameter, default value, if you pass there the object's field, the input can be reused.

<input class="input" type="text" name="name" value="{{old('name', $profile->name)}}">

For the form action, you can use the correct endpoint.

<form action="{{ $profile->id == null ? '/admin/profiles' :  '/admin/profiles/' . $profile->id }} " method="POST">

And for the update you have to use PATCH method.

@isset($profile->id)
 {{ method_field('PATCH')}}
@endisset

Solution 4 - Php

Another clean method with a small controller, two views and a partial view :

UsersController.php

public function create()
{
    return View::('create');
}    

public function edit($id)
{
    $user = User::find($id);
    return View::('edit')->with(compact('user'));
}

create.blade.php

{{ Form::open( array( 'route' => ['users.index'], 'role' => 'form' ) ) }}
    @include('_fields')
{{ Form::close() }}

edit.blade.php

{{ Form::model( $user, ['route' => ['users.update', $user->id], 'method' => 'put', 'role' => 'form'] ) }}
    @include('_fields')
{{ Form::close() }}

_fields.blade.php

{{ Form::text('fieldname1') }}
{{ Form::text('fieldname2') }}
{{ Form::button('Save', ['type' => 'submit']) }}

Solution 5 - Php

Simple and clean :)

UserController.php

public function create() {
	$user = new User();

	return View::make('user.edit', compact('user'));
}

public function edit($id) {
	$user = User::find($id);

	return View::make('user.edit', compact('user'));
}

edit.blade.php

{{ Form::model($user, ['url' => ['/user', $user->id]]) }}
   {{ Form::text('name') }}
   <button>save</button>
{{ Form::close() }}

Solution 6 - Php

For example, your controller, retrive data and put the view

class ClassExampleController extends Controller
{

    public function index()
    {   

        $test = Test::first(1);

        return view('view-form',[
            'field' => $test,
        ]);
    }
}

Add default value in the same form, create and edit, is very simple

<!-- view-form file -->
<form action="{{ 
	isset($field) ? 
	@route('field.updated', $field->id) : 
	@route('field.store')
}}">
    <!-- Input case -->
    <input name="name_input" class="form-control" 
    value="{{ isset($field->name) ? $field->name : '' }}">
</form>

And, you remember add csrf_field, in case a POST method requesting. Therefore, repeat input, and select element, compare each option

<select name="x_select">
@foreach($field as $subfield)
    
    @if ($subfield == $field->name)
        <option val="i" checked>
    @else
        <option val="i" >
    @endif

@endforeach
</select>

Solution 7 - Php

Instead of creating two methods - one for creating new row and one for updating, you should use findOrNew() method. So:

public function edit(Request $request, $id = 0)
{
    $user = User::findOrNew($id);
    $user->fill($request->all());
    $user->save();
}

Solution 8 - Php

    Article is a model containing two fields - title and content 
    Create a view as pages/add-update-article.blade.php   
           
        @if(!isset($article->id))
            <form method = "post" action="add-new-article-record">
            @else
             <form method = "post" action="update-article-record">
            @endif
                {{ csrf_field() }} 
                
                <div class="form-group">
                    <label for="title">Title</label>            
                    <input type="text" class="form-control" id="title" placeholder="Enter title" name="title" value={{$article->title}}>
                    <span class="text-danger">{{ $errors->first('title') }}</span>
                </div>
                <div class="form-group">
                    <label for="content">Content</label>
                    <textarea class="form-control" rows="5" id="content" name="content">
                    {{$article->content}}
        
                    </textarea>
                    <span class="text-danger">{{ $errors->first('content') }}</span>
                </div>
                <input type="hidden" name="id" value="{{{ $article->id }}}"> 
                <button type="submit" class="btn btn-default">Submit</button>
            </form>
        
Route(web.php): Create routes to controller 
        
        Route::get('/add-new-article', 'ArticlesController@new_article_form');
        Route::post('/add-new-article-record', 'ArticlesController@add_new_article');
        Route::get('/edit-article/{id}', 'ArticlesController@edit_article_form');
        Route::post('/update-article-record', 'ArticlesController@update_article_record');
        
Create ArticleController.php
       public function new_article_form(Request $request)
    {
        $article = new Articles();
        return view('pages/add-update-article', $article)->with('article', $article);
    }

    public function add_new_article(Request $request)
    {
        $this->validate($request, ['title' => 'required', 'content' => 'required']);
        Articles::create($request->all());
        return redirect('articles');
    }

    public function edit_article_form($id)
    {
        $article = Articles::find($id);
        return view('pages/add-update-article', $article)->with('article', $article);
    }

    public function update_article_record(Request $request)
    {
        $this->validate($request, ['title' => 'required', 'content' => 'required']);
        $article = Articles::find($request->id);
        $article->title = $request->title;
        $article->content = $request->content;
        $article->save();
        return redirect('articles');
    } 
        

Solution 9 - Php

You can use form binding and 3 methods in your Controller. Here's what I do

class ActivitiesController extends BaseController {
    public function getAdd() {
        return $this->form();
    }
    public function getEdit($id) {
        return $this->form($id);
    }
    protected function form($id = null) {
        $activity = ! is_null($id) ? Activity::findOrFail($id) : new Activity;

        //
        // Your logic here
        //

        $form = View::make('path.to.form')
            ->with('activity', $activity);

        return $form->render(); 
    }
}

And in my views I have

{{ Form::model($activity, array('url' => "/admin/activities/form/{$activity->id}", 'method' => 'post')) }}
{{ Form::close() }}

Solution 10 - Php

In Rails, it has form_for helper, so we could make a function like form_for.

We can make a Form macro, for example in resource/macro/html.php:

(if you don't know how to setup a macro, you can google "laravel 5 Macro")

Form::macro('start', function($record, $resource, $options = array()){
    if ((null === $record || !$record->exists()) ? 1 : 0) {
        $options['route'] = $resource .'.store';
        $options['method'] = 'POST';
        $str = Form::open($options);
    } else {
        $options['route'] = [$resource .'.update', $record->id];
        $options['method'] = 'PUT';
        $str = Form::model($record, $options);
    }
    return $str;
});

The Controller:

public function create()
{
    $category = null;
    return view('admin.category.create', compact('category'));
}

public function edit($id)
{
    $category = Category.find($id);
    return view('admin.category.edit', compact('category'));
}

Then in the view _form.blade.php:

{!! Form::start($category, 'admin.categories', ['class' => 'definewidth m20']) !!}
// here the Form fields
{{!! Form::close() !!}}

Then view create.blade.php:

@include '_form'

Then view edit.blade.php:

@include '_form'

Solution 11 - Php

UserController.php

use View;

public function create()
{
    return View::make('user.manage', compact('user'));
}

public function edit($id)
{
    $user = User::find($id);
    return View::make('user.manage', compact('user'));
}

user.blade.php

@if(isset($user))
    {{ Form::model($user, ['route' => ['user.update', $user->id], 'method' => 'PUT']) }}
@else
    {{ Form::open(['route' => 'user.store', 'method' => 'POST']) }}
@endif

// fields

{{ Form::close() }}

Solution 12 - Php

I hope this will help you!!

form.blade.php

@php
$name         = $user->name ?? null;
$email        = $user->email ?? null;
$info         = $user->info ?? null;
$role         = $user->role ?? null;
@endphp

<div class="form-group">
		{!! Form::label('name', 'Name') !!}
		{!! Form::text('name', $name, ['class' => 'form-control']) !!}
</div>

<div class="form-group">
		{!! Form::label('email', 'Email') !!}
		{!! Form::email('email', $email, ['class' => 'form-control']) !!}
</div>

<div class="form-group">
		{!! Form::label('role', 'Função') !!}
		{!! Form::text('role', $role, ['class' => 'form-control']) !!}
</div>

<div class="form-group">
		{!! Form::label('info', 'Informações') !!}
		{!! Form::textarea('info', $info, ['class' => 'form-control']) !!}
</div>

<a class="btn btn-danger float-right" href="{{ route('users.index') }}">CANCELAR</a>

create.blade.php

@extends('layouts.app')

@section('title', 'Criar usuário')

@section('content')
        {!! Form::open(['action' => 'UsersController@store', 'method' => 'POST'])  !!}
			@include('users.form')
			<div class="form-group">
                {!! Form::label('password', 'Senha') !!}
                {!! Form::password('password', ['class' => 'form-control']) !!}
            </div>
            <div class="form-group">
                {!! Form::label('password', 'Confirmação de senha') !!}
                {!! Form::password('password_confirmation', ['class' => 'form-control']) !!}
            </div>
			{!! Form::submit('ADICIONAR', array('class' => 'btn btn-primary')) !!}
		{!! Form::close() !!}
@endsection

edit.blade.php

@extends('layouts.app')

@section('title', 'Editar usuário')

@section('content')
        {!! Form::model($user, ['route' => ['users.update', $user->id], 'method' => 'PUT']) !!}
			@include('users.form', compact('user'))
			{!! Form::submit('EDITAR', ['class' => 'btn btn-primary']) !!}
        {!! Form::close() !!}
        <a href="{{route('users.editPassword', $user->id)}}">Editar senha</a>
@endsection

UsersController.php

use App\User;

Class UsersController extends Controller {
  #... 
	public function create()
	{
		return view('users.create';
	}

	public function edit($id)
	{
		$user  = User::findOrFail($id);
		return view('users.edit', compact('user');
	}
}

Solution 13 - Php

use any in the route

Route::any('cr', [CreateContent::class, 'create_content'])
->name('create_resource');

in controller use

User::UpdateOrCreate([id=>$user->id], ['field_name'=>value, ...]);

Solution 14 - Php

you can use @$variable in your single blade file for create and edit. it will not through error when variable not defined.

<input name="name" value="@{{$your_variable->name}}">

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKevin JoymungolView Question on Stackoverflow
Solution 1 - PhpThe AlphaView Answer on Stackoverflow
Solution 2 - PhpAntonio Carlos RibeiroView Answer on Stackoverflow
Solution 3 - PhppasqualeView Answer on Stackoverflow
Solution 4 - PhpSamuel De BackerView Answer on Stackoverflow
Solution 5 - PhpMantas DView Answer on Stackoverflow
Solution 6 - PhpIvan FretesView Answer on Stackoverflow
Solution 7 - PhpBaldView Answer on Stackoverflow
Solution 8 - PhpArun UpadhyayView Answer on Stackoverflow
Solution 9 - PhpafarazitView Answer on Stackoverflow
Solution 10 - PhpFredyangView Answer on Stackoverflow
Solution 11 - PhpBrynner FerreiraView Answer on Stackoverflow
Solution 12 - PhpStudent of ScienceView Answer on Stackoverflow
Solution 13 - PhpShahzada IqbalView Answer on Stackoverflow
Solution 14 - PhpWaleedView Answer on Stackoverflow