Outils pour utilisateurs

Outils du site


devweb:laravel:formulaire (lu 30772 fois)

Formulaire

Ma technique de formulaire qui servira à la fois pour créer un nouvel enregistrement ou pour modifier un enregistrement.

Dans cette exemple, on gère des taches à faire.

J’utilise le bootstrap twitter ce qui explique les noms de class utilisées dans le code HTML.

Model

Classique modèle eloquent

<?php
class Todo extends Eloquent{
}

Route

J’ai pris l’habitude de gérer mes routes dans le controller

Route::controller('todo','TodoController');

Controller

Une méthode get qui affichera le formulaire et une méthode post pour traiter les résultats. On passe l’id en paramètre.

Comme j’utilise la méthode controller pour les routes, la méthode getTodoEdit sera appelé via l’url todo/todo-edit

Si on ne spécifie pas d’id dans l’url, on créer une nouvelle tache, sinon on modifiera la tache #9 avec l’url /todo/todo-edit/9

<?php
class TodoController extends BaseController {
 
	public function getTodoEdit($id=null){
		if(is_null($id)){
			//id null donc création
			$todo = new Todo; // On récupère la structure de la table Todo
		}else{
			//si id spécifié, ce sera une modification
			$todo = Todo::find($id); // On récupère les données de la tache
			//si l'id n'existe pas, on redirige sur la page avec un message d'erreur
			if(is_null($todo))
				return Redirect::to('accueil')->with('flash_error',"L'id $id n'existe pas");
		}
		// On crée des listes pour simplifier la saisie
		$etiquettes   = Todo::select('etiquette')->groupBy('etiquette')->orderBy('etiquette')->get();
		$types        = Todo::select('type')->groupBy('type')->orderBy('type')->get();
		$etats        = Todo::withTrashed()->select('etat')->groupBy('etat')->orderBy('etat')->get();
 
		// On stocke dans une variable de session d'ou on vient (utile si on utilise des filtres)
		Session::put('redirect',URL::previous());
 
		// On crée la vue contenant notre formulaire
		return View::make('todoEdit')
					->with('todo',$todo)
					->with('etiquettes',$etiquettes)
					->with('types',$types)
					->with('etats',$etats)
					;
	}
 
	public function postTodoEdit($id=null){
		// On passe par l'étape validation avant toute création/modification
		$rules = array( // On définit les règles
				'description'   => 'required|min:5',
				'etiquette'	=> 'required',
				'type'		=> 'required',
				'etat'		=> 'required'
		);
		// On personnalise les messages d'erreur si on veut
		$messages = array(
		  'description.required'    => "La description est obligatoire",
		  'description.min'	    => "La description doit faire au moins 5 caractères",
		  'etiquette.required'	    =>"L'étiquette est obligatoire",
		  'type.required'	    => "Le type est obligatoire",
		  'etat.required'	    => "L'état est obligatoire"
		);
		$v = Validator::make(Input::all(), $rules, $messages);
		// Si la validation passe, on commence le traitement
		if($v->passes()){
			if(is_null($id)){
				// id null donc création
				$todo = new Todo;
			}else{
				// si id spécifié, on récupère l'enregistrement pour le mettre à jour
				$todo = Todo::findOrFail($id); // si l'id n'existe pas dans la table, on revoie un erreur
			}
			$todo->description = Input::get('description'); // On prépare la mise à jour les champs de la table
			$todo->etiquette   = Input::get('etiquette');
			$todo->type        = Input::get('type');
			$todo->etat        = Input::get('etat');
			$todo->save(); // On sauvegarde les modifications dans la table
 
			// On redirige vers la page où on était avant d'arriver sur le formulaire. par défaut sur **/todo**
			return Redirect::to(Session::get('redirect',url('todo')))->with('flash_success','Enregistrement effectué !');;
		// Si la validation échoue
		}else{
			// On redirige sur le formulaire avec les erreurs et les valeurs des champs déjà entrés
			return Redirect::back()->withErrors($v)->withInput(); 
		}
	}
}

View

Ouvrir et fermer le formulaire. Par défaut il renvoie en POST et utilisera l’url courante.

Dans notre cas, il est impératif d’utiliser l’url courante car elle contient ou pas un id qui déterminera si on ajoute ou si on modifie un enregistrement.

{{Form::open(array('class'=>'form-horizontal'))}}
{{Form::close()}}

Un ensemble label + input text

<div class="form-group{{ $errors->has('etiquette') ? ' has-error' : '' }}">
	{{Form::label('etiquette','Etiquette', array('class'=>'col-sm-4 control-label'))}}
	<div class="col-sm-8">
		{{Form::text('etiquette',$todo->etiquette,array('class'=>'form-control'))}}
	</div>
	<span class="help-block">{{ $errors->has('etiquette') ? $errors->first('etiquette') : '' }}</span>
</div>

Un ensemble label + input text + liste de pré-saisie

<div class="form-group{{ $errors->has('etiquette') ? ' has-error' : '' }}">
	{{Form::label('etiquette','Etiquette', array('class'=>'col-sm-4 control-label'))}}
	<div class="col-sm-8">
		{{Form::text('etiquette',$todo->etiquette,array('class'=>'form-control', 'style'=>'width:auto;display:inline;'))}}
		<select class="form-control" style="display:inline; width:20px;" onChange="$('input[name=etiquette]').val($(this).val())">
			<option value="">-- Vide --</option>
          		@foreach ($etiquettes as $etiquette)
          			@if(!empty($etiquette->etiquette))
          			<option value="{{$etiquette->etiquette}}"{{($etiquette->etiquette==$todo->etiquette?' selected':'')}}>{{ucfirst($etiquette->etiquette)}}</option>
          			@endif
          		@endforeach
		</select>
	</div>
	<span class="help-block">{{ $errors->has('etiquette') ? $errors->first('etiquette') : '' }}</span>
</div>

Il est important d’utiliser la class Form pour construire les input text car lorsque la validation n’est pas bonne et que l’on revient sur le formulaire, la valeur rentrée a posteriori sera automatiquement renseigné.

Les erreurs renvoyés par →withErrors() se récupère dans la vue via l’objet $errors

Pour afficher un message d’info, on peut ajouter ce code dans la vue.

@if (Session::has('flash_success'))
    <div class="alert alert-info">
      {{Session::get('flash_success')}}
    </div>
@endif

Astuces

Le code de validation pour un code postal

'code_postal' => array('required','regex:#^(F-)?((2[A|B])|[0-9]{2})[0-9]{3}$#')
devweb/laravel/formulaire.txt · Dernière modification: 29-04-2014 23:12 de edmc73