MediCoder Aide

Blogues » MediCoder » Anatomie d'un formulaire: grand nettoyage
Par mytto20880 points 

Anatomie d'un formulaire: grand nettoyage

Voici un exemple typique de formulaire qui, correct en son temps et toujours opérationnel, n'a pas suivi les améliorations du framework, la propagation étant la face B laborieuse du refactoring? permanent de Mediboard.

<form name="editPrestFrm{{$_sejour->sejour_id}}" method="post">
  <input type="hidden" name="m"          value="dPplanningOp" />
  <input type="hidden" name="dosql"      value="do_sejour_aed" />
  <input type="hidden" name="sejour_id"  value="{{$_sejour->sejour_id}}" />
  <input type="hidden" name="patient_id" value="{{$_sejour->patient_id}}" />
  <select name="prestation_id" onchange="submitFormAjax(this.form, 'systemMsg')">
    <option value="">— Prestation</option>
    {{foreach from=$prestations item=_prestation}}
    <option value="{{$_prestation->_id}}" 
      {{if $_sejour->prestation_id == $_prestation->_id}} selected = selected {{/if}}
    >
      {{$_prestation->_view}}
    </option>
    {{/foreach}}
  </select>
</form>

Essayons de tout analyser, morceau par morceau

Entête

<form name="editPrestFrm{{$_sejour->sejour_id}}" method="post">

  • le nom n'est pas merveilleux, le suffixe Frm est un brin inutile, il s'agit bien d'un formulaire...
  • La clé de sejour_id l'objet est explicite, on aurait préfèrait un _id voir un _guid (solution retenue
  • le onsubmit n'est pas intercepté, ce qui signifie aucun contrôle côté client et une soumission Ajax gérée par les champs : c'est mal!

Résultat :

<form name="Prestations-{{$_sejour->_guid}}" method="post" onsubmit="return onSubmitFormAjax(this);">

Contrôleur

<input type="hidden" name="m"     value="dPplanningOp" />
<input type="hidden" name="dosql" value="do_sejour_aed" />

Le contrôleur est explicite est cible un script spécifique, ce qui n'est pas nécessaire dans l'immense majorité des cas, en paticulier ici. On passera donc la classe pour aiguiller sans effort.

{{mb_class object=$_sejour}}

Clé

<input type="hidden" name="sejour_id"  value="{{$_sejour->sejour_id}}" />
<input type="hidden" name="patient_id" value="{{$_sejour->patient_id}}" />

  • La clé est passée de manière inutilement explicite, et n'utilise pas le helper dédié mb_key.
  • la clé étrangère vers le patient est ici totalement inutile

{{mb_key object=$_sejour}}

Sélection

C'est ici le champ qui justifie le formulaire, choisir une clé étrangère parmi une collection, en l'occurrence associer une prestation à un séjour.

<select name="prestation_id" onchange="submitFormAjax(this.form, 'systemMsg')">
    <option value="">— Prestation</option>
    {{foreach from=$prestations item=_prestation}}
    <option value="{{$_prestation->_id}}" 
      {{if $_sejour->prestation_id == $_prestation->_id}} selected = selected {{/if}}
    >
      {{$_prestation->_view}}
    </option>
    {{/foreach}}
  </select>

On utilise ici un select que l'on créé de toutes pièces avec de nombreux défauts :

  • pas de classes, donc pas de contrôle côté client
  • traitement de la soumission (ancienne version en plus ! ) dans l'évènement onchange en lieu et place d'un simple déclenchement
  • foreach totalement standard et répétitif, géré par le mb_field des propriétés? de type référence, en passant une collection d'objets

{{mb_field object=$_sejour field=prestation_id choose=CPrestation options=$prestations onchange="this.form.onsubmit();"}}

Au total

Pour résumer ce long discours :

<form name="Prestations-{{$_sejour->_guid}}" method="post" onsubmit="return onSubmitFormAjax(this);">
  {{mb_class object=$_sejour}}
  {{mb_key   object=$_sejour}}
  {{mb_field object=$_sejour field=prestation_id choose=CPrestation options=$prestations onchange="this.form.onsubmit();"}}
</form>

A défaut de propager avec une voracité infatigable, commençons par ne plus en créer de vilains formulaires !

Sponsors privilégiés

Mediboard project