2012-05-07 4 views
5

Ho un UpdatePanel ASP.NET con il seguente:jQuery Dialog 'Close' in conflitto con ASP.NET UpdatePanel

<asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional"> 
<ContentTemplate> 
    <%-- jQuery dialog - Suppliers --%> 
    <div id="divSuppliers" style="display: none;"> 
     <asp:ListBox ID="lstSuppliers" runat="server" SelectionMode="Single" Rows="10" Width="100%" 
      DataValueField="SupplierID" DataTextField="SupplierName"> 
     </asp:ListBox> 
     <br /><br /> 
     <asp:Button ID="btnSelectSupplier" runat="server" Text="Select 2" OnClick="btnSelectSupplier_Click" /> 
    </div> 

    <asp:GridView ID="gvSuppliers" runat="server" AutoGenerateColumns="false" SkinID="gvSkin" 
     DataKeyNames="SupplierID" EmptyDataText="No Existing User Roles"> 
     <Columns> 
      <asp:TemplateField HeaderText="Supplier Name"> 
       <ItemTemplate> 
        <asp:Label ID="lblSupplierName" runat="server" Text='<%# Eval("SupplierName") %>'></asp:Label> 
       </ItemTemplate> 
      </asp:TemplateField> 
     </Columns> 
    </asp:GridView> 

    <asp:Button ID="btnAddSupplier" runat="server" Text="Add Supplier" 
     Visible="false" OnClick="btnAddSupplier_Click" /> 

</ContentTemplate> 
<Triggers> 
    <asp:AsyncPostBackTrigger ControlID="btnSelectSupplier" /> 
</Triggers> 
</asp:UpdatePanel> 

abbastanza semplice, in realtà. Nient'altro che un div che uso per il mio jQuery Dialog popup, un controllo GridView di ASP.NET con una singola colonna e un pulsante ASP.NET per i postback asincroni.

Ecco l'evento click che gestisce il postback asincrono per btnSelectSupplier.

protected void btnSelectSupplier_Click(object sender, EventArgs e) { 

    // +=+=+=+=+=+=+=+=+=+=+=+=+=+=  
    // WORKS JUST FINE 
    List<SupplierItem> suppliers = new List<SupplierItem>();  

    foreach (int i in lstSuppliers.GetSelectedIndices()) { 
     suppliers.Add(
      new SupplierItem { SupplierID = Convert.ToInt32(lstSuppliers.Items[i].Value), SupplierName = lstSuppliers.Items[i].Text }); 
     lstSuppliers.Items[i].Selected = false; 
    } 

    gvSuppliers.DataSource = suppliers; 
    gvSuppliers.DataBind(); 

    // +=+=+=+=+=+=+=+=+=+=+=+=+=+= 
    // DOES NOT WORK!! 
    string jq = "$('#divSuppliers').dialog('close');"; 

    ScriptManager sm = ScriptManager.GetCurrent(this); 
    if (sm != null && sm.IsInAsyncPostBack) { 
     ScriptManager.RegisterClientScriptBlock(
      this, typeof(Page), Guid.NewGuid().ToString(), 
      jq, true); 
    } 
} 

PROBLEMA: Il GridView aggiornerà bene durante il postback asincrono (vedere l'evento click sopra); tuttavia, la finestra di dialogo jQuery rifiuta di chiudere (di nuovo, vedere l'evento sopra e dove dice NON FUNZIONA). Sto registrando il javascript (jquery) con ScriptManager nella pagina e quindi dovrebbe essere in esecuzione e chiudere la finestra di dialogo, ma per qualche motivo non lo è.

MODIFICA: Codice che apre la finestra di dialogo jQuery e la rende modale.

+0

può visualizzare un codice jquery? Posso risolvere questo ... – Thulasiram

+0

L'unico jQuery rilevante è incluso nel mio codice sopra (vedere il codice evento del clic). La finestra di dialogo chiusa non funziona per qualche motivo: questo è tutto. – Jagd

+0

Hai provato a eseguire '$ ('# divSuppliers'). Dialog ('close');' in una console JS come Firebug o Developer Console in Safari/Chrome –

risposta

2

Il div utilizzato per la finestra di dialogo dell'interfaccia utente jQuery deve trovarsi all'esterno di UpdatePanel.

Su btnAddSupplier_Click si crea una finestra di dialogo e si sposta all'esterno di UpdatePanel.
Dopo btnSelectSupplier_Click si dispone di 2 div con ID divSuppliers, quello spostato e quello received from server (il meccanismo UpdatePanel consente gli aggiornamenti parziali delle pagine ricostruendo l'intero DOM UpdatePanel con html restituito dal server).

Vorrei anche suggerire di utilizzare console.log per aiutare con il debug.
Aggiungi alla finestra di chiusura js: console.log($('#divSuppliers'))

+0

Probabilmente hai ragione a spostare la finestra di dialogo jQuery al di fuori del pannello di aggiornamento. In un primo momento l'ho avuto in quel modo, ma per qualche motivo non ricordo di averlo spostato all'interno dell'aggiornamento. Non l'avrei spostato lì senza una ragione. Ad ogni modo, dovrò fare qualche altro test e vedere se funziona quando avrò un po 'di tempo extra. Continuo a pensare che sto solo andando a strappare la. Junk e basta usare jQuery con AJAX invece. – Jagd

+0

Quando il pannello di aggiornamento viene aggiornato, il suo intero html viene cancellato e aggiornato con il contenuto ricevuto dal server, inclusa la finestra di dialogo div, quindi rimangono 2 div con lo stesso id, quello spostato all'esterno e quello che è stato ricreato dall'aggiornamento aggiornamento del pannello. – eitanpo

+0

Dovresti creare un nuovo 'divSuppliersDialog' vuoto al di fuori del pannello di aggiornamento e usarlo per la finestra di dialogo. Dovrai usare "RegisterClientScriptBlock' per spostare' divSuppliers' come figlio di 'divSuppliersDialog' prima di visualizzarlo (come già fai). – eitanpo

1

Avete considerato di seguire un percorso più semplice e associare un evento al lato client del pulsante per chiudere la finestra di dialogo?

$(function() { 
    $('#btnSelectSupplier').click(function() { 

     $('#divSuppliers').dialog('close'); 
    }); 
}); 

Il flusso è sempre lo stesso dal punto di vista dell'utente. Fanno clic sul pulsante e la finestra di dialogo si chiude. Il codice lato server verrà eseguito dopo la chiusura della finestra di dialogo, ma dal momento che non sembra esserci alcuna logica lato server che decida se si desidera chiudere la finestra di dialogo o meno dopo il clic, questo potrebbe soddisfare le proprie esigenze.

EDIT Vedo il tuo problema. Si esegue in un problema perché, invece di aprire la tua finestra esistente, si sta ridefinendo il dialogo sui clic:

string jq = "var dlg = $('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); dlg.parent().appendTo($('form:first'));"; 

Invece, si vuole definire la finestra di dialogo nella funzione document.ready.

$(function() { 
    //define the div as a dialog. By default, it will not open until you tell it to 
$('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); 

}); 

Al click, si dovrebbe aprire in questo modo

$('#divSuppliers').dialog('open'); 

Ancora una volta si può decidere di fare questo lato client invece di cercare di spingere lo script nella pagina sull'evento lato server, ma Questo dipende da te.

più semplice soluzione completa:

$(function() { 

$('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); 

$('#btnAddSupplier').click(function() { 

    $('#divSuppliers').dialog('close'); 
}); 
$('#btnSelectSupplier').click(function() { 

    $('#divSuppliers').dialog('open'); 
}); 
}); 
+0

Funziona, ma solo la prima volta che clicco su btnSelectSupplier. Se riapro la finestra di dialogo (ciò avviene facendo clic su un pulsante diverso) e quindi facendo clic su btnSelectSupplier non chiude la finestra di dialogo. Inserisco un avviso nell'evento click btnSelectSupplier per assicurarmi che venga sollevato ogni volta che si fa clic sul pulsante, e l'avviso è apparso. È quasi come se il div per la finestra di dialogo jquery non venga trovato dopo la prima volta che viene chiuso. – Jagd

+0

Ho aggiornato la mia risposta dopo aver visto i tuoi aggiornamenti. Stavi ridefinendo la finestra di dialogo al clic invece di chiamare la funzione .dialog ('apri'). – Rondel

0

Quindi, ecco la soluzione: non provate a miscelare con l'UpdatePanel ASP.NET con la finestra di jQuery, perché semplicemente non giocano bene insieme.

Avevo solo preso questa direzione perché pensavo che ci sarebbe voluto meno tempo per ottenere AJAX sul posto usando i controlli ScriptManager e UpdatePanel di .NET invece di fare tutto in jQuery. A questo punto sembra che mi sia sbagliato, perché sto tornando indietro e strappando la junk .NET e sostituendo tutto con jQuery. Quindi tutto quel tempo che pensavo di salvare è andato come il vento.

Morale della storia: non mescolare i due se non è necessario.