2012-05-07 12 views
5

Mam ASP.NET UpdatePanel z następujących czynności:jQuery dialogowe 'Zamknij' konflikt z 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> 

dość proste, naprawdę. Nic więcej niż element div, którego używam dla mojego okna dialogowego jQuery Dialog, kontrolka ASP.NET GridView z jedną kolumną i przycisk ASP.NET dla asynchronicznych wywołań zwrotnych.

Oto zdarzenie click, które obsługuje asynchroniczny odświeżenie dla 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); 
    } 
} 

PROBLEM: GridView zaktualizuje dobrze podczas asynchronicznego odświeżenie strony (patrz zdarzenia click wyżej); jednak okno dialogowe jQuery odmawia zamknięcia (ponownie, zobacz zdarzenie powyżej i gdzie mówi NIE DZIAŁA). Rejestruję javascript (jquery) za pomocą ScriptManagera na stronie, więc powinno to być uruchamianie i zamykanie okna dialogowego, ale z jakiegoś powodu tak się nie dzieje.

EDYCJA: Kod, który otwiera okno dialogowe jQuery i sprawia, że ​​jest modalny.

protected void btnAddSupplier_Click(object sender, EventArgs e) { 
    lstSuppliers.ClearSelection(); 
    lstSuppliers.DataSource = Suppliers.GetAllSuppliers(); 
    lstSuppliers.DataBind(); 

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

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

Czy możesz pokazać kod jQuery? Mogę to rozwiązać ... – Thulasiram

+0

Jedyny odpowiedni jQuery jest zawarty w powyższym kodzie (zobacz kod zdarzenia kliknięcia). Zamknięcie okna dialogowego nie działa z jakiegoś powodu - to wszystko. – Jagd

+0

Czy próbowałeś uruchomić okno dialogowe '$ ('# divSuppliers'.) (" Zamknij ");' w konsoli JS, takiej jak Firebug lub Developer Console w Safari/Chrome –

Odpowiedz

2

Element div używany w oknie dialogowym jQuery UI powinien znajdować się poza panelem UpdatePanel.

Na btnAddSupplier_Click tworzysz okno dialogowe i przenosisz je poza panel UpdatePanel.
Po btnSelectSupplier_Click masz 2 elementy div z identyfikatorem divSuppliers, przeniesionym i jednym received from server (mechanizm UpdatePanel pozwala na częściowe aktualizacje strony poprzez przebudowanie całego DOM UpdatePanel z html zwrócony z serwera).

Proponuję również użyć console.log, aby pomóc w debugowaniu.
Dodaj do okna dialogowego zamykania js: console.log($('#divSuppliers'))

+0

Możesz mieć rację, jeśli chodzi o przeniesienie okna dialogowego jQuery poza aktualizację. Tak naprawdę to miałem na początku, ale z jakiegoś powodu nie przypominam sobie, że przeniosłem go do wewnątrz updatepanelu. Nie przeniosłem go tam bez powodu. W każdym razie, będę musiał zrobić więcej testów i sprawdzić, czy to działa, gdy dostanę trochę więcej czasu. Nadal uważam, że po prostu wyślę śmieci .net i zamiast tego użyję jQuery z AJAX. – Jagd

+0

Po zaktualizowaniu panelu aktualizacji cały jego kod HTML jest usuwany i aktualizowany za pomocą zawartości odebranej z serwera, w tym w oknie dialogowym div, dzięki czemu pozostało 2 elementów div o tym samym identyfikatorze, ten, który został przeniesiony na zewnątrz i ten, który został ponownie utworzony z aktualizacji aktualizacja panelu. – eitanpo

+0

Powinieneś utworzyć nowy pusty 'divSuppliersDialog' poza panelem aktualizacji i użyć go do dialogu. Będziesz musiał użyć 'RegisterClientScriptBlock', aby przenieść' divSuppliers' jako element potomny 'divSuppliersDialog' zanim go wyświetlisz (tak jak już zrobiłeś). – eitanpo

1

Czy rozważałeś pójście prostszą trasą i powiązanie zdarzenia ze stroną przycisku przycisku, aby zamknąć okno dialogowe?

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

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

Przepływ jest nadal taki sam z perspektywy użytkownika. Klikają przycisk, a okno dialogowe się zamyka. Kod po stronie serwera będzie działał po zamknięciu okna dialogowego, ale ponieważ nie ma żadnej logiki po stronie serwera, która decyduje, czy chcesz zamknąć okno dialogowe, czy nie po kliknięciu, może to pasować do twoich potrzeb.

EDYTOWANIE Widzę twój problem. Uruchomiona do problemu, ponieważ zamiast otwarcie istniejącego okna, jesteś przedefiniowanie okno na kliknięcie:

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

Zamiast chcesz zdefiniować okno w funkcji 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 }); 

}); 

Na kliknięcia, należy otworzyć go jak ten

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

Znów możesz to zrobić po stronie klienta zamiast próbować wcisnąć skrypt do strony, na razie po stronie serwera, ale to zależy od Ciebie.

Najprostszy pełne rozwiązanie:

$(function() { 

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

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

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

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

To działa, ale tylko po raz pierwszy klikam na btnSelectSupplier. Jeśli ponownie otworzę okno dialogowe (odbywa się to poprzez kliknięcie innego przycisku), a następnie kliknięcie btnSelectSupplier nie zamyka okna. Wpisuję alert do zdarzenia click btnSelectSupplier, aby upewnić się, że jest on podnoszony za każdym kliknięciem przycisku, a alert pojawił się. To prawie jak div, ponieważ okno dialogowe jquery nie zostanie znalezione po pierwszym zamknięciu. – Jagd

+0

Zaktualizowałem moją odpowiedź po zobaczeniu twoich aktualizacji. Zmieniłeś definicję okna dialogowego po kliknięciu zamiast wywoływać funkcję .dialog ("otwórz"). – Rondel

0

Więc oto rozwiązanie: nie próbuj mieszać przy użyciu ASP.NET UpdatePanel z okna dialogowego jQuery, ponieważ po prostu nie grać ładnie razem.

Poszedłem tylko w tym kierunku, ponieważ myślałem, że zajmie mi to mniej czasu na uzyskanie AJAX w miejscu za pomocą .Manager ScriptManager i UpdatePanel .NET zamiast robić to wszystko w jQuery. W tym momencie wygląda na to, że się myliłem, ponieważ wracam i wyrzucam śmieci .NET i zastępuję je jQuery. Więc cały ten czas, który myślałem, że mogę uratować, zniknął jak wiatr.

Morał z historii: nie mieszaj dwóch, jeśli nie musisz.

Powiązane problemy