J'ai une série de lignes qui sont générées à l'aide d'un système de gestion des données. asp:répéteur :
<asp:repeater ID="itemsRepeater"
OnItemDataBound="itemsRepeater_ItemDataBound"
runat="Server">
<itemtemplate>
<tr>
<td>
<asp:HyperLink ID="linkView" runat="server"
Text="<%# GetItemText((Item)Container.DataItem) %>"
NavigateUrl="<%# GetViewItemUrl((Item)Container.DataItem) %>" />
</td>
<td>
<asp:HyperLink ID="linkDelete" runat="server"
Text="Delete"
NavigateUrl="<%# GetDeleteUrl((ActionItem)Container.DataItem) %>" />
</td>
</tr>
</itemtemplate>
</asp:repeater>
Le répéteur crée un tableau HTML, dont chaque ligne contient un lien vers un élément et (ce qui est essentiellement) un lien "Supprimer". L'exemple de code simplifié ci-dessus génère un code HTML similaire à celui-ci :
<TR>
<TD>
<A href="ViewItem.aspx?ItemGuid={19a149db-5675-4eee-835d-3d78372ca6f9}">
AllisonAngle_SoccerGirl001.jpg
</A>
</TD>
<TD>
<A href="DeleteItem.aspx?ItemGuid={19a149db-5675-4eee-835d-3d78372ca6f9}">Delete</A>
</TD>
</TR>
Maintenant, tout cela fonctionne, mais je veux convertir la "suppression" en côté client. Je veux être en mesure de cliquer sur le lien et il sera, sur le client javascript :
- déclencher une alerte "Êtes-vous sûr..."
- faire en sorte que le javascript soit utilisé par le serveur pour supprimer l'élément qu'ils souhaitent.
- supprimer l'élément de l'arbre DOM du client
Il y a donc quatre problèmes à résoudre :
- Comment relier le javascript au clic côté client de l'interface utilisateur ? Supprimer lien.
- Comment savoir sur quel élément l'utilisateur a cliqué Supprimer
- Empêcher un retour en arrière
- Supprimer la ligne sur laquelle l'utilisateur a cliqué
C'est ma question.
À partir d'ici, vous trouverez mes tentatives décousues pour le résoudre. Ne considérez pas que ce qui suit est lié de quelque manière que ce soit à une solution acceptée. Ce n'est pas parce que j'ai posté du code ci-dessous qu'il est utile. Et ça ne veut pas dire que je suis à deux doigts de trouver la meilleure solution. Et parce que je ne peux pas faire fonctionner quoi que ce soit ci-dessous - ça doit être une erreur.
Mes tentatives
Câblage de Javascript
La première tâche consiste à convertir le lien de suppression HTML de quelque chose comme :
<A href="DeleteItem.aspx?ItemGuid={19a149db-5675-4eee-835d-3d78372ca6f9}">
Delete
</A>
en quelque chose de plus "javascripty" :
<A href="#"
onclick="DeleteItem('DeleteItem.aspx?ItemGuid={19a149db-5675-4eee-835d-3d78372ca6f9}')">
Delete
</A>
et ajouter le script :
<script type="text/javascript">
//<![CDATA[
function DeleteItem(deleteUrl)
{
//Ask the user if they really want to
if (!confirm("Are you sure you want to delete INSERT NAME HERE?"))
{
return false;
}
//Call returns false if the server returned anything other than OK
if (!DoAjaxHit(deleteUrl)
{
return false;
}
//Remove the table row from the browser
var tableRow = document.getElementById("TODO-WHAT ID");
if (row != null)
{
//TODO: how to delete the tableRow from the DOM tree?
//document.Delete(tableRow) ?
}
//return false to prevent a postback
return false;
}
//]]>
</script>
Quelle combinaison de code ASP peut être utilisée pour créer ce qui précède ? J'ai entendu dire que asp:LinkButton a un OnClientClick dans lequel vous pouvez insérer une fonction javascript :
<asp:LinkButton ID="linkDelete" runat="server"
Text="Delete"
OnClientClick="DeleteItem(<%# GetDeleteUrl((ActionItem)Container.DataItem) %>);"/>
Le problème, c'est que le HTML rendu est littéralement contenant :
<a onclick="DeleteItem(<%# GetDeleteUrl((ActionItem)Container.DataItem)) %>);" ...>
Delete
</a>
Si je change le gestionnaire d'événement de clic du client en :
OnClientClick="DeleteItem('todo - figure this out');"/>
ça marche - aussi bien que "todo - figure this out" peut marcher.
Prévention des retours en arrière
L'appel javascript simplifié ci-dessus fonctionne réellement (je peux voir mon alerte), mais il y a un autre problème : Retourner false de la fonction javascript n'empêche pas un postback. En fait, je peux voir que la fonction href sur le code html généré n'est pas "#", mais plutôt
javascript:__doPostBack('ctl0....
J'ai essayé de modifier le code ASPX pour inclure moi-même le gestionnaire OnClick :
OnClick="#"
OnClientClick="DeleteItem('todo - figure this out');"
Mais le compilateur pense que le côté pound est un pragma, et se plaint :
Les directives du préprocesseur doivent apparaître sous la forme le premier caractère non espace sur une ligne
Identité de la rangée de la table
Les lignes de la table n'ont pas d'identifiant, elles sont générées par la fonction asp:répéteur .
Comment la fonction javascript peut-elle savoir ce qui a déclenché l'événement de clic ? Le javascript doit être capable de trouver l'élément et de le supprimer de l'arbre.
Nota: Je préférerais bien sûr une animation de type fondu + effondrement.
Normalement, vous obtenez un élément en utilisant
var tr = document.getElementById("the table row's id");
Mais les lignes de la table n'ont pas d'ID facile à connaître. Comme il y a plusieurs lignes, le serveur génère l'ID lorsqu'il construit la table. Je me rends compte qu'une solution devra être modifiée :
<TR>
en
<TR runat="server">
afin qu'il y ait une identité générée par le serveur pour chaque ligne de la table, mais comment puis-je référencer le nom généré à partir du javsscript ?
Normalement, j'aurais pensé que le problème des scripts serait résolu par l'utilisation de paramètres multiples :
function DeleteItem(tableRowElement, deleteUrl)
{
//Do a web-hit of deleteUrl to delete the item
//remove tableRowElement DOM object from the document tree
}
Mais le problème est simplement repoussé ailleurs : Comment remplir tableRowElement et deleteUrl pour l'appel à la fonction javascript ?
Un problème si simple : convertir un clic d'un postback en client-side.
Le volume des problèmes en jeu devient tout à fait stupide. Ce qui semble indiquer que soit
- l'idée solution est quelque chose de complètement différent
- il n'y a pas de solution
Références
Stackoverflow : Comment faire disparaître une ligne avant le postback ?
Stackoverflow : Javascript avant le clic sur asp:ButtonField
asp.net : Accès aux éléments répétiteurs à partir de javascript.
Stackoverflow : Comment accéder aux éléments générés par le répéteur ?