IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Mise en place de composants Telerik en MVC3

Synopsis

Date de publication : 12/07/2011. Date de mise à jour : 12/07/2011.

Par Julien Brasselet
 


       Version PDF (Miroir)   Version hors-ligne (Miroir)
Viadeo Twitter Facebook Share on Google+        



0. Introduction
I. Diagramme UML
II. La couche d'accès aux données
III. Rappel sur MVC
III-A. Présentation générale
III-B. Le modèle
III-C. La vue
III-D. Le contrôleur
IV. Le moteur Razor
IV-A. Présentation
IV-B. Quelques exemples
V. Création d'une solution MVC3 Telerik
V-A. Télécharger le composant Telerik
V-B. Créer une solution Telerik
V-C. Description de la solution
V-D. Création du modèle
VI. Quelques composants Telerik
VI-A. Le calendrier
VI-A-1. Définition du calendrier
VI-A-2. Action sur une sélection
VI-A-3. La date Picker
VI-B. Le combo box
VI-B-1. Le combo box classique
VI-B-2. La liste déroulante
VII. La grille Télérik
VII-A. Data binding
VII-A-1. Serveur
VII-A-2. Ajax
VII-B. Paging and Sorting
VII-C. Filtre et Groupe
VII-D. CRUD
VII-E. Objets complexes
VII-F. Templates d'affichage
VII-F-1. Templates serveur
VII-F-2. Templates client
VII-F-3. Les fonctions de mise à jour
VII-F-4. Aller plus loin
VIII. Conclusion
IX. Liens


0. Introduction

L'architecture MVC (Modèle-Vue-Controleur) permet une nette séparation des concepts d'interface, des données et de la logique de contrôle d'une application Web.

Dans ce but, Microsoft a développé son propre framework MVC. Ce dernier a évolué au fil des années. La version MVC3 a apporté son lot de nouveauté avec principalement un nouveau moteur de rendu appelé Razor.

En parallèle, Telerik avait développé des composants utilisables aisément en ASP.Net Ajax. Telerik met également à disposition des composants utilisables avec le modèle MVC3 tels des grilles, des menus ou des onglets. Ces composants permettent un développement plus rapide et fournissent une interface agréable pour le développeur et l'utilisateur.

Cet article montrera comment implémenter certains de ses composants dans une solution MVC assez simple.


I. Diagramme UML

Nous partirons sur une modèle assez simple représentant une application de gestion de formations.

Sans-titre-6.gif
NB : Ce modèle n'est ni complet ni optimal. Il est juste là pour servir de base aux interfaces.


II. La couche d'accès aux données

La couche d'accès aux données a été codée afin de conserver les modifications en mémoire tant que l'on ne change pas de page.

Cette couche se base sur des DTO et des factory.


III. Rappel sur MVC


III-A. Présentation générale

L'architecture MVC oblige à la séparation des couches de l'application, ce qui en fait une base solide pour le développement et donc une très bonne pratique.

Cette architecture peut être représentée ainsi.

Sans-titre-2.gif

III-B. Le modèle

Le modèle est la représentation du comportement de l'application. Ses responsabilités sont la gestion des traitements des données ainsi que l'accès à la base de données. Il doit garantir l'intégrité des données.

Il ne doit en aucun cas gérer la présentation des données.


III-C. La vue

La vue est souvent l'interface utilisateur. Elle ajoute une couche dite de présentation aux données afin de les rendre plus lisible et aisément manipulable. Cette dernière action est très souvent liée au contrôleur.

Elle ne doit en aucun cas effectuer de traitement sur les données.


III-D. Le contrôleur

Le contrôleur va recevoir les actions effectuées sur la vue. Il va lancer les différentes actions liées à l'action réalisées dans la vue.

Si les données doivent être modifiées, il fera appel au modèle pour lancer le traitement adéquat. Si la vue doit être modifiée, il le lui signifiera.


IV. Le moteur Razor


IV-A. Présentation

Razor est un nouveau moteur de rendu utilisé dans le cadre d'ASP.Net MVC3. Il est toujours possible d'utiliser l'ancien moteur ASP.Net. Néanmoins ce nouveau moteur est, à mon sens, indiscutablement plus lisible et pratique à utiliser.

Ce moteur a été développé afin :

  • De limiter les caractères séparant le code serveur du code HTML,
  • D'être facile à apprendre,
  • D'améliorer l'intellisense,
  • D'être facilement testable.
Le blog de Scott Guthrie (http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx) explique plus en détail les nouveautés de ce moteur et son utilisation. Je vais juste reprendre quelques exemples rapides pour cet article.


IV-B. Quelques exemples

Pour commencer, le moteur razor s'appuie essentiellement sur le caractère @ et le HTML.

Voici un comparatif d'un simple code affichant la date du jour

Moteur ASP.N et Moteur Razor
< h2 > <% :   DateTime .Now   %> </ h2 > < h2 > @ DateTime .Now </ h2 >

Le moteur Razor sait déterminer la fin d'une variable et passer de nouveau à l'interprétation du code HTML. Cet exemple simple n'est pas des plus parlant mais imaginons une liste affichant un identifiant et un libellé. Les codes suivants montrent bien la différence de lisibilité des deux moteurs :

Moteur ASP.N et Moteur Razor
< ul   id =" maliste "> <%   foreach  ( var  p  in   ViewBag.liste ) %> < li > <% = p.identifiant   %>  -  <% = p.libelle   %> </ li > <%  }  %> </ ul > < ul   id =" maliste "> @ foreach  ( var  p  in   ViewBag.liste ) { < li > @ p.identifiant  -  @ p.libelle </ li > } </ ul >

Le blog de Scott Guthrie montre également l'utilisation de bloc de code, l'intelligence si jamais une adresse email est rencontrée (et le caractère @ non pris en compte)

Nous ne nous attarderons pas plus sur la syntaxe Razor ici-même.


V. Création d'une solution MVC3 Telerik


V-A. Télécharger le composant Telerik

La dll Telerik pour les composats MVC est téléchargeable ici (via un msi) :

http://www.telerik.com/products/aspnet-mvc.aspx

NB : Il est nécessaire de se créer un compte sur le site Telerik.

Il faut ensuite installer le msi téléchargé.


V-B. Créer une solution Telerik

Ouvrir un nouveau projet Telerik MVC3 Web Application (Razor)

image
Le wizard Telerik se lance alors

image
image
NB : Telerik propose plusieurs skins de base.


V-C. Description de la solution

La solution est composée initialement de plusieurs dossiers dont trois primordiaux représentant les vues, le modèle et les contrôleurs.

Sans-titre-2.jpg

V-D. Création du modèle

Par simplicité, aucune base de données ne sera utilisée dans les sources. Les fonctions ramèneront juste des listes enregistrées en session.

Nous allons maintenant créer des vues afin de tester les différents composants Telerik.


VI. Quelques composants Telerik


VI-A. Le calendrier


VI-A-1. Définition du calendrier

Le contrôle calendrier est réellement très simple à utiliser.

Nous y noterons 3 caractéristiques principales :

  • Une date courante
  • Une date minimale
  • Une date Maximale
Voici comment le définir dans la vue
Définition d'un composant Calendar Telerik avec le moteur Razor
@(Html.Telerik().Calendar()
   .Name("Calendar")
   .Value((DateTime)ViewData["selectedDate"])
   .MinDate((DateTime)ViewData["minDate"])
   .MaxDate((DateTime)ViewData["maxDate"])
)
Il suffit dans le contrôleur de remplir les variables du ViewData (ici entre le 8juin 2011 et le 15 aout 2012) pour obtenir un beau calendrier

Sans-titre-3.gif

VI-A-2. Action sur une sélection

Il est également possible de réaliser une action sur la sélection d'une date.
other
@(Html.Telerik().Calendar()
   .Name("Calendar")
   .Selection(settings => settings
      .Action("SelectAction", new { date="{0}"})
      .Dates(
         new List<DateTime> {
            DateTime.Today.AddDays(-1),
            DateTime.Today.AddDays(2),
            DateTime.Today.AddDays(3),
         }
      )
   )
)
Un attribut action a été ajouté en définissant le paramètre à envoyer. Il est suivit d'un attribut Dates qui limite ne nombre de date soumise à cette action.


VI-A-3. La date Picker

Il est possible de vouloir un bouton permettant d'afficher le calendrier. Pour cela il faut utiliser le Date Picker dont voici un exemple de code
other
@(Html.Telerik().DatePicker()
   .Name("DatePicker")
   .HtmlAttributes(new { id = "DatePicker_wrapper" })
   .Min((DateTime)ViewData["minDate"])
   .Max((DateTime)ViewData["maxDate"])
   .ShowButton(true)
   .Value((DateTime)ViewData["selectedDate"])    
)
Ceci nous donne le rendu suivant :

Sans-titre-2.gif

VI-B. Le combo box


VI-B-1. Le combo box classique

Nous allons ici afficher la liste des formations dans un combo box.

La première chose à faire est de passer à la vue le modèle que nous utiliserons. Cela s'effectue bien entendu dans le contrôleur
other
public ActionResult Index()
{
return View(GestFormat.Models.FormationFactory.SelectAll().ToList());
}
Coté IHM, le code razor est des plus simplistes :
other
@(Html.Telerik().ComboBox()
   .Name("ComboBox")
   .BindTo(new SelectList(Model, "Identifiant", "Libelle"))
   .Filterable(filtering => { filtering.FilterMode(AutoCompleteFilterMode.StartsWith);})
   .Effects(fx=>fx.Slide()
      .Opacity()
      .OpenDuration(500)
      .CloseDuration(200)
      )
)
L'attribut Filterable permet de proposer les éléments commençant par le texte taper dans l'input (dans cet exemple) Il peut également être configuré avec l'option Contains.

La propriété Effects permet de gérer les effets d'affichage de la liste des éléments (toggle/slide, opacité, temps d'ouverture et de fermeture)


VI-B-2. La liste déroulante

Les différences entre la liste déroulante et le combo box. Il n'est pas possible d'effectuer de saisie dans la liste déroulante et son aspect est différent.

Coté code, nous retrouvons la même structure
other
@(Html.Telerik().DropDownList()
   .Name("DropDownList")
   .BindTo(new SelectList(Model, "Identifiant", "Libelle"))
   .Effects(fx=>fx.Slide()
      .Opacity()
      .OpenDuration(500)
      .CloseDuration(200)
      )
)
Sans-titre-3.gif

VII. La grille Télérik

Un des composants les plus demandé en Web est le GridView. Ce composant est souvent la source de bien des soucis et de développement spécifique.

La grille Telerik propose d'innombrables possibilités :

  • Binding server / client / webservices
  • Tri / Filtre / Pagination
  • Agrégation
  • Templates
Cette liste est loin d'être exhaustive. Nous verrons quelques options dans ce paragraphe. Le site de Telerik et l'installation du framework MVC propose d'autres exemples plus complexes.


VII-A. Data binding


VII-A-1. Serveur

Nous allons commencer ici par binder les données coté serveur. Nous afficherons les données des sessions de formations.

Pour commencer, nous passerons la liste des sessions de formation à la vue via le contrôleur.
other
public ActionResult Index()
{
return View(GestFormat.Models. FormateurFactory.SelectAll());
}
Nous pouvons maintenant créer notre grille
other
@model List<GestFormat.Models.FormateurDto>
@{
   Layout = "~/Views/Shared/_Layout.cshtml";
}
 
@(Html.Telerik().Grid(Model)
   .Name("Grid")
   .Columns(columns =>
   {
      columns.Bound(o => o.Identifiant).Width(100);
      columns.Bound(o => o.Nom).Width(200);
      columns.Bound(o => o.Prenom).Width(200);
      columns.Bound(o => o.Inscription).Format("{0:dd/MM/yyyy}").Width(120);
   })
   .DataBinding(dataBinding =>
   {
      dataBinding.Server().Select("Index", "Grid");
   }
   )
   .Footer(true)
)
Voici le rendu de notre grille binder coté serveur (qui ne nous aura pas demandé beaucoup d'effort)

Sans-titre-2.gif

VII-A-2. Ajax

Le principe est le même pour le binding coté Ajax. Les modifications nécessaire se situe coté contrôleur avec l'ajout d'un attribut devant la fonction de chargement ainsi qu'un léger changement dans le passage du model.
other
public ActionResult Index()
{
return View();
}
 
 [GridAction]
public ActionResult _Index()
{
return View(new GridModel(GestFormat.Models.FormateurFactory.SelectAll()));
}
Coté interface, le seul changement est d'indiquer à la grille qu'elle sera binder en ajax
other
@model List<GestFormat.Models.FormateurDto>
          
@{
   Layout = "~/Views/Shared/_Layout.cshtml";
}
 
@(Html.Telerik().Grid(Model)
   .Name("Grid")
   .Columns(columns =>
   {
      columns.Bound(o => o.Identifiant).Width(100);
      columns.Bound(o => o.Nom).Width(200);
      columns.Bound(o => o.Prenom).Width(200);
      columns.Bound(o => o.Inscription).Format("{0:dd/MM/yyyy}").Width(120);
   })
   .DataBinding(dataBinding =>
   {
      dataBinding.Ajax().Select("_Index", "Grid");
   }
   )
   .Footer(true)
)
Le rendu est exactement le même.

Nous réaliserons la suite du TP avec un databinding ajax.


VII-B. Paging and Sorting

Afin de gérer les fonctions de tri et de pagination, il n'est pas nécessaire de modifier son code au niveau du model ou du contrôleur. Seule la vue se verra modifiée et très peu.

En effet il suffit d'ajouter les attributs Sortable et Pageable à la définition de la grille.
other
@(Html.Telerik().Grid(Model)
   .Name("Grid")
   .Columns(columns => {...})
   .DataBinding(dataBinding => {...})
   .Pageable()
   .Sortable()
   .Footer(true)
)
Sans-titre-2.jpg

VII-C. Filtre et Groupe

Il existe également une fonctionnalité simple afin de filtrer les données. Les modifications sont encore une fois uniquement coté interface.
other
@(Html.Telerik().Grid(Model)
   .Name("Grid")
   .Columns(columns => {...})
   .DataBinding(dataBinding => {...})
   .Filterable()
   .Footer(true)
)
Sans-titre-3.gif
Il est enfin possible de gérer des groupes de données en déplaçant les colonnes dans le header.
other
@(Html.Telerik().Grid(Model)
   .Name("Grid")
   .Columns(columns => {...})
   .DataBinding(dataBinding => {...})
   .Filterable()
   .Groupable()
   .Footer(true)
)
Sans-titre-2.gif
Sans-titre-3.gif

VII-D. CRUD

L'intérêt des grilles, outre la présentation des données, est de pouvoir réaliser des modifications sur les données sans passer par une page intermédiaire. Nous allons voir ici comment réaliser les opérations élémentaires de modification, ajout et suppression des données.

Il existe plusieurs modes pour la création et l'édition des données :

  • In-line : modification directement dans la grille
Sans-titre-2.gif
  • Pop-up : affichage d'un pop-up pour la modification
Sans-titre-2.gif
  • In-Form : affichage d'un formulaire dans la grille
Sans-titre-2.gif
Nous prendrons le cas d'une modification in-line.

NB : L'aspect des formulaires des opérations Pop-up et In-Form dépendra entre autres de vos Data Annotations. Pensez-y !

Plusieurs paramètres sont nécessaires dans la définition de la grille. Avant tout, il est indispensable de déterminer la DataKey, soit la clé de votre table. Pour cela, la grille possède une propriété DataKeys dont voici un exemple :
other
@(Html.Telerik().Grid(Model)
   .Name("Grid")
   .DataKeys(keys => { keys.Add(p => p.Identifiant); })
...
Il faut ensuite implémenter le bouton d'ajout d'une nouvelle instance :
.ToolBar(commands => commands.Insert().ButtonType(GridButtonType.Image).ImageHtmlAttributes(new { style = "margin-left:0" }))
  • Il existe plusieurs types de bouton (GridButtonType) :BareImageImageImageAndTextText

Il faut ensuite ajouter les boutons d'édition et de suppression
other
.Columns(columns =>
   {
      columns.Command(commands => { commands.Edit().ButtonType(GridButtonType.Image); commands.Delete().ButtonType(GridButtonType.Image); }).Width(100).Title("Commands");
      columns.Bound(o => o.Identifiant);
...
Il ne faut pas oublier de changer le binding afin de référencer les fonctions d'ajout, modification et suppression
other
.DataBinding(dataBinding =>
   {
      dataBinding.Ajax()
         .Select("_Index", "Grid")
         .Insert("_Insert", "Grid")
         .Update("_Update", "Grid")
         .Delete("_Delete", "Grid"); ;
   }
   )
Enfin, il faut définir le mode d'édition de la grille
.Editable(editing => editing.Mode(GridEditMode.InLine))

Voici un exemple de fonctions gérant les CRUD dans le contrôleur.
other
[GridAction]
public ActionResult _Insert()
{
      Models.FormateurDto dto = new Models.FormateurDto();
      if (TryUpdateModel(dto))
      {
            Models.FormateurFactory.Insert(dto);
      }
      return View(new GridModel(Models.FormateurFactory.SelectAll()));
}

[GridAction]
public ActionResult _Update(int id)
{
      Models.FormateurDto dto = new Models.FormateurDto { Identifiant = id };
      if (TryUpdateModel(dto))
      {
            Models.FormateurFactory.Update(dto);
      }
      return View(new GridModel(Models.FormateurFactory.SelectAll()));
}
 
[GridAction]
public ActionResult _Delete(int id)
{
      Models.FormateurDto dto = Models.FormateurFactory.Search(id);
      if (dto != null)
      {
            Models.FormateurFactory.Delete(dto);
      }
 
      return View(new GridModel(Models.FormateurFactory.SelectAll()));
}

VII-E. Objets complexes

Essayons maintenant d'afficher une grille avec par exemple nos sessions de formations. Les sessions contiennent des liens vers les formateurs, les formations et les salles.

Le code cshtml contient le code suivant
other
@model List<GestFormat.Models.SessionFormationDto>
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
@(Html.Telerik().Grid(Model)
   .Name("Grid")
   .DataKeys(keys => { keys.Add(p => p.Identifiant); })
      .ToolBar(commands => commands.Insert().ButtonType(GridButtonType.Image).ImageHtmlAttributes(new { style = "margin-left:0" }))
   .Columns(columns =>
   {
      columns.Command(commands => { commands.Edit().ButtonType(GridButtonType.Image); commands.Delete().ButtonType(GridButtonType.Image); }).Width(100).Title("Commands");
      columns.Bound(o => o.Identifiant);
      columns.Bound(o => o.Formation.Libelle).Width(200);
      columns.Bound(o => o.Formateur.Nom).Width(200);
      columns.Bound(o => o.Formateur.Prenom).Width(200);
      columns.Bound(o => o.Salle.Numero).Width(80);
      columns.Bound(o => o.DebutSession).Format("{0:dd/MM/yyyy}").Width(120);
      columns.Bound(o => o.FinSession).Format("{0:dd/MM/yyyy}").Width(120);
   })
   .DataBinding(dataBinding =>
   {
      dataBinding.Ajax()
         .Select("_Index", "GridTemplate")
         .Insert("_Insert", "GridTemplate")
         .Update("_Update", "GridTemplate")
         .Delete("_Delete", "GridTemplate"); ;
   }
   )
   .Editable(editing => editing.Mode(GridEditMode.PopUp))
   .Pageable()
   .Sortable()
   .Footer(true)
)
A remarquer que je suis passé en mode de modification pop-up.

Notre grille a donc l'aspect suivant

Sans-titre-2.gif
Nous désirons ajouter une nouvelle session

Sans-titre-2.gif
Seuls les champs « simples » de notre dto apparaissent à l'écran. L'intérêt est donc limité.

De même, dans le mode inline, notre interface de modification aura cette allure

Sans-titre-2.gif
Il serait préférable d'avoir une liste déroulante permettant de choisir le formateur et le numéro de la salle.

Pour combler ses « manques », nous allons utiliser des templates d'affichage.


VII-F. Templates d'affichage

Il est possible d'effectuer des templates coté serveur ou coté client. Ici nous afficherons la liste des formateurs à la place des colonnes Nom et Prénom.


VII-F-1. Templates serveur

Pour créer un template de modification, plusieurs étapes vont être nécessaires :

  • Ajouter un attribut au DTO de session,
  • Remplir une structure de données contenant la liste des formateurs,
  • Créer un fichier de template d'affichage et un d'édition.
Nous allons tout d'abord ajouter un attribut à notre formateurDto contenu dans notre sessionDto :
other
public class SessionFormationDto
{
   [ScaffoldColumn(false)]
   public Int32? Identifiant { get; set; }
 
   [DisplayName("Formation")]
   public FormationDto Formation { get; set; }
 
   [DisplayName("Salle")]
   public SalleDto Salle { get; set; }
 
   [DisplayName("Formateur"), UIHint("ListeFormateur")]
   public FormateurDto Formateur { get; set; }
 
   [DisplayName("Début")]
   [DataType(DataType.Date)]
   public DateTime DebutSession { get; set; }
 
   [DisplayName("Fin")]
   [DataType(DataType.Date)]
   public DateTime FinSession { get; set; }
   }
L'attribut en question est le UIHint. Cet attribut indique qu'il faut utiliser des templates ayant pour nom ListeFormateur.

Nous allons ensuite mettre la liste des formateurs dans le ViewData. Ici la fonction ramène des FormateurDto contenant l'identifiant et la concaténation du nom et du prénom dans le nom.
other
public ActionResult _Index()
{
   ViewData["Formateurs"] = Models.FormateurFactory.SelectAllForDdl();
   return View(new GridModel(Models.SessionFormationFactory.SelectAll()));
}
NB : Cette affectation devra être effectuée dans toutes les fonctions renvoyant la vue (insert, update, delete, etc.)

Ensuite, nous allons créer les templates d'affichage et d'édition. Pour cela il est nécessaire de créer dans le répertoire de la vue des répertoires appelés DisplayTemplates et EditorTemplates.

Sans-titre-3.gif
Nous allons désormais créer les templates.

Le template d'affichage sera très simple. Nous allons afficher le prénom du formateur suivi de son nom. Nous avons vu que notre fichier template devra porter le nom de ListeFormateur. Il devra aussi avoir une extension cshtml. Sa structure sera très simple :
other
@model GestFormat.Models.FormateurDto
          
@Model.Prenom @Model.Nom

Le template d'édition se basera sur une simple liste déroulante.
other
@(Html.Telerik().DropDownList()
.Name("LeFormateur")
.BindTo(new SelectList((IEnumerable)ViewData["Formateurs"], "Identifiant", "Nom"))
)
Enfin nous allons modifier notre vue. La modification sera très simple. AU lieu d'afficher le nom et le prénom, nous allons simplement indiquer à l'interpréteur razor d'afficher le formateurDto.

Notre code d'affichage devient le suivant :
other
.Columns(columns =>
   {
      columns.Command(commands => { commands.Edit().ButtonType(GridButtonType.Image); commands.Delete().ButtonType(GridButtonType.Image); }).Width(100).Title("Commands");
      columns.Bound(o => o.Identifiant);
      columns.Bound(o => o.Formation.Libelle).Width(200);
      columns.Bound(o => o.Formateur).Width(400);
      columns.Bound(o => o.Salle.Numero).Width(80);
      columns.Bound(o => o.DebutSession).Format("{0:dd/MM/yyyy}").Width(120);
      columns.Bound(o => o.FinSession).Format("{0:dd/MM/yyyy}").Width(120);
   })
Voici le rendu de la liste :

Sans-titre-2.gif
Sans-titre-3.gif

VII-F-2. Templates client

La création d'un template coté client se base globalement sur le même principe. Afin d'obtenir le même affichage pour le formateur que dans l'exemple précédent, il est nécessaire de créer un attribut permettant d'afficher le formateur en tant que chaine de caractère. Cet attribut devra posséder un UIHint. Voici un exemple :
other
[DisplayName("Formateur"), UIHint("ListeFormateur")]
public String LeFormateur { get; set; }
La recherche des données remplira ce champ.

Ensuite il faudra créer uniquement un template pour l'édition. Il diffèrera légèrement de celui vu précédemment :
other
@(Html.Telerik().DropDownList()
.Name("LeFormateur")
.BindTo(new SelectList((IEnumerable)ViewData["Formateurs"], "Identifiant", "Nom"))
)

Avant-dernière étape, il faut modifier la vue pour prendre en compte le template :
other
@model List<GestFormat.Models.SessionFormationDto>
@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
 
@(Html.Telerik().Grid(Model)
   .Name("Grid")
   .DataKeys(keys => { keys.Add(p => p.Identifiant); })
      .ToolBar(commands => commands.Insert().ButtonType(GridButtonType.Image).ImageHtmlAttributes(new { style = "margin-left:0" }))
   .Columns(columns =>
   {
      columns.Command(commands => { commands.Edit().ButtonType(GridButtonType.Image); commands.Delete().ButtonType(GridButtonType.Image); }).Width(100).Title("Commands");
      columns.Bound(o => o.Identifiant);
      columns.Bound(o => o.Formation.Libelle).Width(200);
      columns.Bound(o => o.LeFormateur).Width(400);
      columns.Bound(o => o.Salle.Numero).Width(80);
      columns.Bound(o => o.DebutSession).Format("{0:dd/MM/yyyy}").Width(120);
      columns.Bound(o => o.FinSession).Format("{0:dd/MM/yyyy}").Width(120);
   })
   .DataBinding(dataBinding =>
   {
      dataBinding.Ajax()
         .Select("_Index", "GridTemplate")
         .Insert("_Insert", "GridTemplate")
         .Update("_Update", "GridTemplate")
         .Delete("_Delete", "GridTemplate"); ;
   }
   )
   .Editable(editing => editing.Mode(GridEditMode.InLine))
   .Footer(true)
)
 
@section HeadContent 
{
    <script type="text/javascript">
       function onEdit(e) {
          $(e.form).find('#LeFormateur').data('tDropDownList').select(function (dataItem) {
             return dataItem.Text == e.dataItem['LeFormateur'];
          });
       }    
    </script>
} 
Nous avons ajouté ici une section HeadContent qui contient du javascript. Ce dernier indique que sur l'appel de la fonction onEdit, le libellé LeFormateur sera modifié par une liste déroulante, celle définit dans le template.

Néanmoins, il est nécessaire de déclarer dans le layout principal la prise en compte de cette section juste avant la balise <body>:
other
<html>
<head>
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
    <script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")" type="text/javascript"></script>
@(Html.Telerik().StyleSheetRegistrar().DefaultGroup(group => group.Add("telerik.common.css").Add("telerik.windows7.css").Combined(true).Compress(true)))</head>
@RenderSection("HeadContent", required:false)
<body>
NB : Notez qu'il est possible d'obliger chaque page à avoir une section HeadContent en modifiant le required:false en required:true.


VII-F-3. Les fonctions de mise à jour

Nous avions vu dans le paragraphe CRUD, la mise à jour des données via les fonctions Insert, Update et Delete.

Dans le cas des templates, il est nécessaire de modifier ces fonctions. Nous avons ici une liste déroulante avec les formateurs qui nous enverra l'identifiant du formateur sélectionné. La signature de la fonction update devient donc :
other
[GridAction]
public ActionResult _Update(Int32 id, Int32 maListe)
{
   Models.SessionFormationDto dto = new Models.SessionFormationDto { 
      Identifiant = id 
   };
   if (TryUpdateModel(dto))
   {
      Models.SessionFormationFactory.Update(dto, maListe);
   }
   ViewData["Formateurs"] = Models.FormateurFactory.SelectAllForDdl();
   return View(new GridModel(Models.SessionFormationFactory.SelectAllClient()));
}
De même la fonction d'insertion prendra en paramètre la liste déroulante
other
[GridAction]
public ActionResult _Insert(Int32 maListe)
{
   ...
}
NB : Le nom du paramètre est important. Il doit être identique (insensible à la casse) au nom donné à la liste déroulante dans le template.


VII-F-4. Aller plus loin

Il est ensuite possible bien entendu de faire la même chose sur les autres champs, ajouter des fonctions de vérification sur les champs ou créer des templates plus complexes.

Il est également possible de créer des templates dans le cas de modification en pop-up. La modification s'effectue de la même façon.

Attention néanmoins, il m'arrive régulièrement des problèmes d'affichage au niveau des grilles lorsque j'utilise les templates et les fonctions de pagination (colonne de template légèrement décalé.) Il faut alors jouer avec les largeurs de colonne, ce qui peut se révéler fastidieux.


VIII. Conclusion

Cet article présente les premières possibilités de l'utilisation des composants Telerik en MVC. Ces composants permettent de réaliser simplement des interfaces stylées et automatisent des taches quelques fois rébarbatives en termes d'implémentation.

Une seule chose m'a réellement ennuyé lors de mes tests avec ces composants : il est vraiment difficile de personnaliser son style. Les fichiers css sont complexes, long et pas toujours très parlant. L'affichage des images se fait via un seul fichier et des coordonnées ciblant une zone de ce fichier. Là encore difficile de personnaliser son interface sur le sujet.

Il est possible d'utiliser le constructeur de style de Telerik à cette adresse : http://stylebuilder.telerik.com/.


IX. Liens

Le blog de Scott Guthrie : http://weblogs.asp.net/scottgu/archive/2010/07/02/introducing-razor.aspx

Site telerik MVC

Forum Telerik MVC



               Version PDF (Miroir)   Version hors-ligne (Miroir)

Valid XHTML 1.0 TransitionalValid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2011 Julien Brasselet. Aucune reproduction, même partielle, ne peut être faite de ce site ni de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.