web-dev-qa-db-fra.com

Postback ASP.NET avec JavaScript

J'ai plusieurs petits divs qui utilisent jQuery draggable. Ces divs sont placés dans un UpdatePanel et j'utilise la fonction JavaScript _doPostBack() de dragstop. où j'extrais l'information nécessaire du formulaire de pages.

Mon problème est que lorsque j'appelle cette fonction, toute la page est rechargée, mais je souhaite uniquement que le panneau de mise à jour soit rechargé.

80
ErnieStings

Voici une solution complète

balise de formulaire complète de la page asp.net

<form id="form1" runat="server">
    <asp:LinkButton ID="LinkButton1" runat="server" /> <%-- included to force __doPostBack javascript function to be rendered --%>

    <input type="button" id="Button45" name="Button45" onclick="javascript:__doPostBack('ButtonA','')" value="clicking this will run ButtonA.Click Event Handler" /><br /><br />
    <input type="button" id="Button46" name="Button46" onclick="javascript:__doPostBack('ButtonB','')" value="clicking this will run ButtonB.Click Event Handler" /><br /><br />

    <asp:Button runat="server" ID="ButtonA" ClientIDMode="Static" Text="ButtonA" /><br /><br />
    <asp:Button runat="server" ID="ButtonB" ClientIDMode="Static" Text="ButtonB" />
</form>

Contenu entier de la classe code-behind de la page

Private Sub ButtonA_Click(sender As Object, e As System.EventArgs) Handles ButtonA.Click
    Response.Write("You ran the ButtonA click event")
End Sub

Private Sub ButtonB_Click(sender As Object, e As System.EventArgs) Handles ButtonB.Click
    Response.Write("You ran the ButtonB click event")
End Sub
  • Le LinkButton est inclus pour garantir que la fonction JavaScript __doPostBack est rendue au client. Le simple fait d'avoir des contrôles Button ne provoque pas le rendu de cette fonction __doPostBack. Cette fonction sera rendue grâce à la présence d'une variété de contrôles sur la plupart des pages ASP.NET. Un bouton de lien vide n'est donc généralement pas nécessaire.

Que se passe-t-il?

Deux contrôles d'entrée sont rendus au client:

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
  • __EVENTTARGET Reçoit l'argument 1 de __doPostBack
  • __EVENTARGUMENT Reçoit l'argument 2 de __doPostBack

La fonction __doPostBack est rendue comme suit:

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
  • Comme vous pouvez le constater, il attribue les valeurs aux entrées masquées.

Lorsque le formulaire soumet/postback se produit:

  • Si vous avez fourni l'identifiant unique du bouton de contrôle du serveur dont vous souhaitez exécuter le gestionnaire de clic sur le bouton (javascript:__doPostBack('ButtonB',''), le gestionnaire de clic du bouton correspondant sera exécuté.

Que se passe-t-il si je ne veux pas exécuter de gestionnaire de clic, mais que je veux faire autre chose?

Vous pouvez passer ce que vous voulez comme arguments à __doPostBack

Vous pouvez ensuite analyser les valeurs d'entrée masquées et exécuter un code spécifique en conséquence:

If Request.Form("__EVENTTARGET") = "DoSomethingElse" Then
    Response.Write("Do Something else") 
End If

Autres notes

  • Que se passe-t-il si je ne connais pas l'ID du contrôle dont je veux exécuter le gestionnaire de clics?
    • S'il n'est pas acceptable de définir ClientIDMode="Static", Vous pouvez faire quelque chose comme ceci: __doPostBack('<%= myclientid.UniqueID %>', '').
    • Ou: __doPostBack('<%= MYBUTTON.UniqueID %>','')
    • Ceci injectera l'identifiant unique du contrôle dans le javascript, si vous le souhaitez
220
Brian Webster

Par phairoh: Utilisez ceci dans la page/composant juste au cas où le nom du panneau changerait

<script type="text/javascript">
     <!--
     //must be global to be called by ExternalInterface
         function JSFunction() {
             __doPostBack('<%= myUpdatePanel.ClientID  %>', '');
         }
     -->
     </script>
14
Laramie

Bien que la solution de Phairoh semble théoriquement valable, j'ai également trouvé une autre solution à ce problème. En transmettant l'id UpdatePanels en tant que paramètre (cible d'événement) pour la fonction doPostBack, le panneau de mise à jour publiera en retour, mais pas la page entière.

__doPostBack('myUpdatePanelId','')

* note: le deuxième paramètre est pour les arguments d'événement d'addition

espérons que cela aide quelqu'un!

EDIT: il semble donc que ce même conseil a été donné ci-dessus car je tapais :)

8
ErnieStings

En utilisant __doPostBack est directement sooooo les années 2000. Quiconque code WebForms en 2018 utilise GetPostBackEventReference

(Plus sérieusement cependant, en ajoutant ceci comme une réponse à la complétude. En utilisant le __doPostBack directement est une mauvaise pratique (le préfixe simple de tiret bas indique généralement un membre privé et le double indique un membre privé plus universel), même si cela ne changera probablement pas et ne deviendra pas obsolète à ce stade. Nous avons un mécanisme entièrement pris en charge dans ClientScriptManager.GetPostBackEventReference .)

En supposant que votre btnRefresh figure dans notre UpdatePanel et provoque une publication, vous pouvez utiliser GetPostBackEventReference comme ceci ( inspiration ):

function RefreshGrid() {
    <%= ClientScript.GetPostBackEventReference(btnRefresh, String.Empty) %>;
}
7
mlhDev

Si quelqu'un a des problèmes avec cela (comme j'étais), vous pouvez obtenir le code de publication d'un bouton en y ajoutant l'attribut UseSubmitBehavior = "false". Si vous examinez la source rendue du bouton, vous verrez le code JavaScript exact que vous devez exécuter. Dans mon cas, il utilisait le nom du bouton plutôt que son identifiant.

6
user489998

Avez-vous essayé de transmettre l'ID client du panneau de mise à jour à la fonction __doPostBack? Mon équipe a fait cela pour actualiser un panneau de mise à jour et, autant que je sache, cela a fonctionné.

__doPostBack(UpdatePanelClientID, '**Some String**');
2
Jeremy Bade

Vous ne pouvez pas appeler _doPostBack() parce que cela force la soumission du formulaire. Pourquoi ne désactivez-vous pas le PostBack sur le UpdatePanel?

1
Alex Rodrigues

Tout d'abord, n'utilisez pas les panneaux de mise à jour. Ils constituent la deuxième chose la plus diabolique que Microsoft ait jamais créée pour le développeur Web.

Deuxièmement, si vous devez utiliser les panneaux de mise à jour, essayez de définir la propriété UpdateMode sur Conditional. Ajoutez ensuite un déclencheur à un contrôle Asp: Caché que vous ajoutez à la page. Attribuez l'événement change en tant que déclencheur. Dans votre événement dragstop, modifiez la valeur du contrôle masqué.

Ceci n’a pas été testé, mais la théorie semble bonne ... Si cela ne fonctionne pas, vous pouvez essayer la même chose avec un bouton asp:, il suffit de définir le style display: none et d’utiliser l’événement click au lieu de l’événement change.

1
phairoh