lundi 26 janvier 2009

Appeler une fonction JavaScript depuis code behind

Dans cet exemple, je montre de façon simple comment vérifier une valeur saisie par l'utilisateur en utilisant une fonction JavaScript exécutée du côté client.

Les contrôles de validation asp.net remplissent la même fonction, mais l'avantage d'utiliser JavaScript est la réduction de la taille de la page. Personnellement je préfère de loin les contrôles de validation puisqu'ils sont faciles à utiliser, à moins que de vouloir personnaliser votre validation, là il faut creuser un peu. Toutefois, je présente cette méthode car je pense qu'elle peut être utile dans certains cas...

Exemple :

image

L'utilisateur entre une valeur puis clique sur "Valider", une fonction JavaScript commée "ValiderSaisie" est alors appelée. La valeur "0" (zero) est considérée comme incorrecte.

La fonction "ValiderSaisie" est placée dans un fichier .js, celui-ci est appelé dans la page Validation.aspx. Voici la structure du projet (ne faites pas attention à la page Default.aspx):

image

La page Validation.aspx:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Validation.aspx.cs" Inherits="Validation" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<
script src="Control.js" type="text/javascript"></script>

<
html xmlns="http://www.w3.org/1999/xhtml">
<
head runat="server">
<
title>Test Validation</title>
</
head>
<
body>
<
form id="form1" runat="server">
<
table>
<
tr>
<
td>
<
asp:Label ID="Label1" runat="server" Text="Entrer une valeur :"></asp:Label>
</
td>
<
td>
<
asp:TextBox ID="txt1" runat="server" Width="120px" ></asp:TextBox>
</
td>
</
tr>
<
tr>
<
td>
&nbsp;
</td>
<
td>
<
asp:Button ID="cmdValider" runat="server" Height="26px" Text="Valider" Width="120px" />
</
td>
</
tr>
</
table>
</
form>
</
body>
</
html>

Notez l'appel du fichier "Control.js" en haut de la page. Dans ce fichier js, je place la fonction "ValiderSaisie" qui affiche toute valeur saisie, sauf pour zero où elle retourne le message "Valeur incorrecte" :

 function ValiderSaisie(MonTexte)
{
if (MonTexte.value == 0)
{
alert("Valeur incorrecte");
}
else
{
alert(MonTexte.value);
}
}

Appel de la fonction JavaScript:

Cet appel se fait en ajoutant un attribut au bouton "Valider" comme suit:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
this.cmdValider.Attributes.Add("onclick", "javascript:return ValiderSaisie(document.getElementById('" + txt1.ClientID + "'));");
}

Résultat:

Si j'entre 0 j'obtiens ceci :

image

Autrement, la valeur entrée par l'utilisateur est affichée :

  image

vendredi 23 janvier 2009

Vérifier l'existance d'un QueryString

Si on essaie d'appeler un QueryString dans une page comme ceci:

Response.Write("id = " + Request.QueryString["id"].ToString());

... alors que celui-ci n'existe pas, on obtient l'erreur suivante:

La référence d'objet n'est pas définie à une instance d'un objet.



image



Il est nécessaire de contrôler l'existance d'un QueryString avant de l'utiliser:

Méthode 1: utiliser string.IsNullOrEmpty

if (string.IsNullOrEmpty(Request.QueryString["id"]))
{
Response.Write("id n'existe pas");
}
else
{
Response.Write("id = " + Request.QueryString["id"].ToString());
}



Méthode 2: contrôler manuellement si le QueryString existe

if (Request.QueryString["id"]!="" && Request.QueryString["id"]!=null)
{
Response.Write("id n'existe pas");
}
else
{
Response.Write("id = " + Request.QueryString["id"].ToString());
}

mercredi 21 janvier 2009

Executer le code d'un Bouton en pressant la touche Entrer

Petit exemple simple:

<div id="divTest" runat="server">
<
asp:TextBox ID="txtTest" runat="server"></asp:TextBox>
<
asp:Button ID="cmdGo" runat="server" Text="Go" OnClick="cmdGo_Click" />
</
div>

code du boutton: renvoie le texte tapé par l'utilisateur:

protected void cmdGo_Click(object sender, EventArgs e)
{
Response.Write(txtTest.Text);
}

Pour exécuter le code du bouton en pressant entrer, j'ai utilisé un Div à qui j'ai ajouté un id dans la page aspx. Dans Page_Load, ajouter un attribut à ce div: sur l'evenement onkeydown verifier le code de la touche pressée et lancer l'evenement click du boutton s'il s'agit de la touche entrer dont le code est 13 :

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
this.divTest.Attributes.Add("onkeydown", "if(event.which || event.keyCode){if ((event.which==13) || (event.keyCode==13)) {document.getElementById('" + cmdGo.UniqueID + "').click();return false;}} else {return true};");

}


Resultat :

image



Le div peut etre replacé par un table aussi. Il est preferable que le div ou table soit dans le niveau le plus haut possible de la page afin que son contenu "reconnaisse" que le boutton est lancé lorsque la touche Entrer est préssée.

Div avec ScrollBar (ascenseur)

Le bon vieux Div est toujours utile, mais peut l'être particulièrement lorsqu'on a par exemple un contrôle relié aux données qui peut s'étaler sur une bonne partie de la page.

Voici un exemple avec un contrôle CheckBoxList relié aux données, que je place dans un Div avec ascenseur afin de limiter l'espace occupé dans la page.

La propriété overflow permet de doter Div d'un ascenceur. Ici je lui affecte la valeur auto qui ajoute un ascenceur seulement si c'est necessaire:

<div style="width:150px; height: 200px; overflow: auto;">
<
asp:CheckBoxList ID="CheckBoxListFruits" runat="server" DataSourceID="SqlDataSourceFruits"
DataTextField="NomFrancais" DataValueField="IDFruit" Font-Names="Tahoma"
Font-Size="9pt" ForeColor="#000099">
</
asp:CheckBoxList>
</
div>

Le resultat est le suivant : image

jeudi 8 janvier 2009

Ajax UpdatePanel et l'Upload de fichiers

Le saviez-vous ? Certains contrôles ne sont pas compatibles avec UpdatePanel:

- TreeView et les contrôles Menu;
- Les contrôles Web Parts;
- FileUpload s'ils sont utilisés pour faire un upload de fichiers avec un PostBack asynchrone;
- GridView et DetailsView lorsque la propriété EnableSortingAndPagingCallbacks est true;
- Login, PasswordRecovery, ChangePassword et CreateUserWizard dont le Content n'a pas été converti en modèles éditables;
- Le contrôle Substitution;
- Les contrôles de validation.

En tout cas, je ne le savais pas avant de passer des heures à me tirer les cheveux pour comprendre ce qui n'allait pas dans ma page :) J'ai un WebForm avec des zones de saisie et un espace pour Upload de photos, tout marchait bien, mais dès que j'ai utilisé UpdatePanel j'ai obtenu l'erreur suivante:

Sys.WebForms.PageRequestManagerServerErrorException: Object reference not set to an instance of an object

erreur upload et updatepanel

La solution est la suivante: ajouter un PostBackTrigger sur le boutton qui déclenche l'Upload afin que ce boutton provoque un PostBack

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<
ContentTemplate>
<
asp:FileUpload ID="fileUpload" runat="server" />
<
br />
<
asp:Button ID="cmdUpload" runat="server" Height="25px" OnClick="cmdUpload_Click" Text="Upload"
Width="128px" />
</
ContentTemplate>

<
Triggers>
<
asp:PostBackTrigger ControlID
="cmdUpload" />
</
Triggers
>
</
asp:UpdatePanel>



L'Upload ensuite fonctionne correctement:

fileUpload.PostedFile.SaveAs(@"c:\test\" + System.IO.Path.GetFileName(fileUpload.PostedFile.FileName));


Response.Write n'est pas non plus compatible avec UpdatePanel, j'en parlerai dans un prochain post.