Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Formulaire Ajax avec POST et validation

Poster un commentaire

Dans un précédent article j’ai montré comment créer un formulaire Ajax simple avec différentes techniques.

Je vais compléter cet article (et le projet de démo de l’époque) avec la création d’un formulaire de saisie qui intègre une validation côté client ET serveur de la saisie.

Présentation du projet

Le projet peut être cloné depuis Gihub:

https://github.com/DeLeneMirouze/demoajax.git

 

Si on le lance:

On clique sur le menu Formulaire, puis le bouton Ajouter la popin s’ouvre:

Vous remarquez la présence d’une liste déroulante et de 4 zones de saisie. Une saisie incorrecte est détectée lors d’un clic sur le bouton Valider:

Si la saisie est correcte, la popin se referme et les saisies sont renvoyées vers le contrôleur pour y être traitées.

Examinons le code

Le projet d’origine a été complété:

Un contrôleur Web Api et une vue.

Côté code client à la manœuvre:

  • JQuery
  • Bootstrap pour gérer la popin

J’ai peu de choses à dire concernant Bootstrap si ce n’est qu’ici:

 

Il ne faut pas oublier ‘fade’ sinon rien ne fonctionne.

 

Côté code serveur, j’ai commencé par créer une entité EtatCivil:


public class EtatCivil
{
   public int Civilite { get; set; }

   [StringLength(80)]
   [Required(AllowEmptyStrings=false,ErrorMessage ="Nom est obligatoire")]
   public string Nom { get; set; }

   [StringLength(80)]
   [Required(AllowEmptyStrings = false, ErrorMessage = "Prénom est obligatoire")]
   public string Prenom { get; set; }

   [Required(AllowEmptyStrings = false, ErrorMessage = "Age est obligatoire")]
   public int Age { get; set; }

   public bool Success { get; set; }
   public List<string> ErrorMessages { get; set; }
}

 

Remarquez surtout la présence d’attributs d’annotation qui contribuerons à la validation serveur des saisies.

La suite se trouve dans le contrôleur qui ne présente pas de difficultés particulières, c’est du code absolument normal:

public FormViewModel Get()
{
   FormViewModelBuilder builder = new FormViewModelBuilder();
   FormViewModel vm = builder.Build();

   return vm;
}

[HttpPost]
public EtatCivil Post(EtatCivil etatCivil)
{
   Validate(etatCivil);

   if (!ModelState.IsValid)
   {
      // la validation a échouée
      etatCivil.ErrorMessages = GetModelStateErrors(ModelState);
      etatCivil.Success = false;

      return etatCivil;
   }

   etatCivil.Success = true;
   return etatCivil;
}

 

Les lignes (3) et (4) alimentent un FormViewModel qui fournit au formulaire tout ce dont il a besoin:


public class FormViewModel
{
   public FormViewModel()
   {
      Civilites = new List<Civilite>();
   }

   public EtatCivil EtatCivil { get; set; }

   public List<Civilite> Civilites { get; set; }
}

Civilites alimente la liste déroulante.

La ligne (12) dans la méthode POST valide les saisies:


private void Validate(EtatCivil etatCivil)
{
   if (etatCivil.Age < 18)
   {
      ModelState.AddModelError("age", "Age doit être plus grand que 18");
   }
   if (etatCivil.Civilite == 0)
   {
      ModelState.AddModelError("civilite", "Civilité est obligatoire");
   }
}

Vous remarquez que l’on a pas besoin de gérer les propriétés telles Nom ou Prenom car elles sont annotées. ModelState sera automatiquement renseigné. ModelState est toutefois un objet un peu trop complexe pour être géré simplement côté client d’où la présence de la méthode GetModelStateErrors() qui le transforme en liste de String.

 

La propriété Success est importante car elle permet au code Ajax de savoir si la validation a réussi ou pas.

 

Justement, regardons un peu le code Ajax que j’ai mis directement sur le formulaire, ce que l’on ne fera pas dans la vraie vie.

La popin est activée par un click sur un bouton, les choses se passent ainsi:


$('#addBtn').on("click",
   function() {
      $.ajax(
      {
         type:"GET",
         url:window.location.origin + "/api/FormApi",
         success:OnSuccess
      });

     $('#idModal').modal({show: true});
     $('#idModal').modal('show');
});

function OnSuccess(data) {
   var civilities = data.Civilites;
   // alimente la liste déroulante
   for (var i = 0; i < civilities.length; i++) {
      var civility =civilities[i];

      $('#Civilites').append('<option value="' + civility.Id + '">' + civility.Label + '</option>');
}

  populate(data);
}

Un code Ajax très classique. Les lignes (10) et (12) ouvre la popin. Le clic déclenche également un appel vers le serveur pour récupérer FormViewModel qui sera exploité dans OnSuccess.

Remarquez de quelle façon on alimente la liste déroulante.

La propriété data correspond donc à l’instance d’EtatCivil renvoyée par le contrôleur. La méthode populate ne sert qu’à copier les valeurs de data vers le formulaire.

 

Intéressons nous à la soumission du formulaire.


$('#validate').on("click",
function() {

   var data="Nom=" + $("#Nom").val();
   data +="&Prenom=" + $("#Prenom").val();
   var age=$("#Age").val();
   if (!age) {
      age=0;
   }

   data +="&Age=" + age;
   data +="&Civilite=" + $("#Civilites option:selected").val();

   $.ajax(
   {
      type:"POST",
      url:window.location.origin + "/api/FormApi",
      data:data,
      success:onSuccessPost
   });
});

function onSuccessPost(data) {
   if (data.Success) {
      $('#idModal').modal({show: false});
      $('#idModal').modal('hide');

   return;
   }

   populate(data);
}

On commence par récupérer les différentes saisies. Notez que je n’ai pas besoin de me soucier si côté contrôleur on récupère un EtatCivil ou une liste de propriété. Le binder MVC fera le boulot pour nous. Le client ignore tout du contrôleur et réciproquement.

 

Note: On pourrai ajouter une validation côté client pour faire tendance.

Comme vous le voyez, globalement ce n’est pas du code bien difficile, simplement c’est utile d’avoir un exemple sous la main pour le jour où l’on en a besoin.

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s