ASP.net Wizard et validation
Question
J'essaye de vérifier que l'utilisateur a coché une checkbox dans un contrôle wizard. J'ai suivi votre article Verifier une checkbox par un validator - CustomValidator mais ASP.net n'arrive pas à trouver ma checkbox.
Comment faire ?
Réponse
La validation des contrôles dans un wizard n'est malheureusement pas une chose évidente, mais voici quelques éléments d'explication. Ceci est valable pour le CustomValidator mais aussi pour les autres contrôles de validation (RequiredFieldValidator, etc...)
En utilisant un CustomNavigationTemplate :
<asp:TemplatedWizardStep ID="TemplatedWizardStep1" runat="server" Title="Step1">
<ContentTemplate>
</ContentTemplate>
<CustomNavigationTemplate>
<script type="text/javascript" >
var validateAcceptCondition = function(source, args){
args.IsValid = $get('<%=TemplatedWizardStep1.CustomNavigationTemplateContainer
.FindControl("cbAcceptCondition").ClientID%>').checked;
}
</script>
<asp:CustomValidator ID="cvAcceptCondition" runat="server"
ClientValidationFunction="validateAcceptCondition"
Text="Vous devez accepter les conditions" ValidationGroup="Condition" />
<asp:CheckBox ID="cbAcceptCondition" runat="server"
Text="En cochant cette case, j'accepte les conditions ci-dessus"
ValidationGroup="Condition" />
<asp:Button ID="StartNextButton" runat="server" CommandName="MoveNext"
Text="Suivant" ValidationGroup="Condition" />
</CustomNavigationTemplate>
</asp:TemplatedWizardStep>
En validant le contenu du ContentTemplate :
<asp:TemplatedWizardStep ID="TemplatedWizardStep1" runat="server" Title="Step1">
<ContentTemplate>
<script type="text/javascript" >
var validateAcceptCondition = function(source, args){
args.IsValid = $get('<%=TemplatedWizardStep1.ContentTemplateContainer
.FindControl("cbAcceptCondition").ClientID%>').checked;
}
</script>
<asp:CustomValidator ID="cvAcceptCondition" runat="server"
ClientValidationFunction="validateAcceptCondition"
Text="Vous devez accepter les conditions" ValidationGroup="Condition" />
<asp:CheckBox ID="cbAcceptCondition" runat="server"
Text="En cochant cette case, j'accepte les conditions ci-dessus"
ValidationGroup="Condition" />
</ContentTemplate>
</asp:TemplatedWizardStep>
Un problème se pose puisqu'il faut définir la propriété ValidationGroup sur le bouton "suivant" automatiquement construit par ASP.net. Pour obtenir l'instance du contrôle, rien de tel que de faire un tour dans Reflector, on voit ainsi que l'ID du bouton créé est StartNextButton dans le container d'ID "StartNavigationTemplateContainerID". Si vous avez choisi un imagebutton alors l'id sera StartNextImageButton et enfin pour un linkbutton StartNextLinkButton. On peut donc récuperer l'instance du contrôle en faisant :
protected void Page_Load(object sender, EventArgs e)
{
((Button)wizard1.FindControl("StartNavigationTemplateContainerID$StartNextButton"))
.ValidationGroup = "Condition";
}
Si vous essayer de valider dans une étape classique les ID des boutons seront :
StepNavigationTemplateContainerID$StepPreviousButton
StepNavigationTemplateContainerID$StepNextButton
StepNavigationTemplateContainerID$CancelButton
et enfin dans l'étape finale :
FinishNavigationTemplateContainerID$FinishPreviousButton
FinishNavigationTemplateContainerID$FinishButton
FinishNavigationTemplateContainerID$CancelButton
Bien sur il ne faudra pas oublier d'effectuer la validation côté serveur en utilisant Page.Validate(validationGroup) et Page.IsValid.
Explication
Pourquoi ASP.net n'arrive t'il pas à trouver le checkbox est ainsi permettre ce code :
<script type="text/javascript" >
var validateAcceptCondition = function(source, args){
args.IsValid = $get('<%=cbAcceptCondition.ClientID%>').checked;
}
</script>
Cela vient du fait que le contrôle WizardStepBase possède l'attribut ParseChildren avec la valeur true. Cet attribut permet de définir certaines propriétés du contrôle directement dans la partie ASPX comme c'est le cas pour les propriétés ContentTemplate et CustomNavigationTemplate.