2011-04-14 64 views
8

我想從Codebehind中顯示一個jQuery UI對話框,並且需要在回發後刷新它。jQuery對話框 - 回發但UpdatePanel沒有得到更新

該對話框是用於過濾和查找數據的控件。因此,用戶從DropDownLists中選擇並在文本框中輸入文本,單擊「應用按鈕」,發生異步回發,根據用戶的選擇過濾數據,結果將顯示在GridView中。因此我需要更新GridView周圍的UpdatePanel。

的異步回有幫助的工作從這些鏈接:

(基本上dlg.parent().appendTo(jQuery("form:first"));溶液)

問題:我無法更新UpdatePanel既沒有UpdateMode =「Always」也沒有手動從代碼隱藏通過UpdatePanel.Update()。我認爲這與Dialog不在UpdatePanel內部或類似的地方有關。希望有人能幫助我。

一些來源:

function createChargeFilterDialog() { 
    //setup dialog 
    $('#Dialog_ChargeFilter').dialog({ 
     modal: true, 
     resizable: false, 
     autoOpen: false, 
     draggable: true, 
     hide: "Drop", 
     width: 850, 
     height: 600, 
     position: "center", 
     title: "Charge-Filter", 
     buttons: { 
      "Close": function() { 
       $(this).dialog("close"); 
      } 
     }, 
     open: function (type, data) { 
      $(this).parent().appendTo(jQuery("form:first")) 
     }, 
     close: function (type, data) { 
     } 
    }); 
} 

它從代碼隱藏調用時BtnShowDialog(外面的jQuery的對話框)通過

AjaxControlToolkit.ToolkitScriptManager.RegisterStartupScript _ 
      (Me.Page, GetType(Page), "showChargeFilterDialog", "createChargeFilterDialog();$('#Dialog_ChargeFilter').dialog('open');", True) 

更新被點擊:我也注意到一個問題,回傳值。所有文本框如果爲空或沒有附加逗號。這表示控件根據以下方式呈現多次:http://www.componentart.com/community/forums/t/60999.aspx

我確定這兩個問題都是相關的。整個對話框及其所有控件將在每個異步回發中重新創建,因此所有控件名稱在DOM中存在多次(導致ViewState逗號附加問題)。這些控件僅在FireBug/IE Deveoper Toolbar中可見,而不是在HTML源中,因此我認爲jQuery會導致這些問題。我如何處置對話框或我如何阻止娛樂(檢查是否已存在)的對話框?這是因爲對話框是在UpdatePanel中還是因爲它在UpdatePanel之外移動(通過Javascript)?

銷燬異步回發之前該對話框並不能解決問題,因爲對話框將完全消失:

<asp:Button ID="BtnApplyFilter" OnClientClick="$('#Dialog_ChargeFilter').dialog('destroy');" ... /> 

你的幫助是極大的讚賞。


解決方案:我用從AjaxControlToolkit的ModalPopupExtender結束。在一些小問題之後,它像異步回發的魅力一樣工作(如果您希望彈出窗口保持可見狀態,請不要忘記在每個代碼隱藏函數中調用MPE.Show())。如果有人感興趣,我可以添加更多的代碼。

+0

Hello Tim。我也有同樣的問題。我想知道你是否最終找到了這個潛在的解決方案。我已經在整個應用程序中實現了jquery對話框,但是我需要在這個對話框中的兩個下拉列表之間進行綁定。因此,我將更改爲ModalPopUpExtender作爲最終選項。請看看我的問題:http://stackoverflow.com/questions/8082921/dropdownlist-selected-index-changed-event-inside-jquery-dialog。此致, – aleafonso 2011-11-11 09:07:59

回答

1

我不知道,但是這可能是BZ其工作權ANS形成我,當我用

AjaxControlToolkit.ToolkitScriptManager.RegisterStartupScript 

試試這個?

ScriptManager.RegisterClientScriptBlock(Me.Page, GetType(Page), "showChargeFilterDialog", "createChargeFilterDialog();$('#Dialog_ChargeFilter').dialog('open');", True) 
+0

謝謝,但那也行不通。雖然我已經在代碼隱藏中改變它並且調用了'UpdatePanel.Update()',內容將是相同的。 – 2011-04-14 11:27:55

5

我認爲它有事情做 與對話不是的 裏面的UpdatePanel或類似的東西。

我也注意到 回傳值有問題。所有文本框,如果 爲空或者沒有附加逗號。

你確實在這兩方面都是正確的。問題的關鍵在於腳本管理器「認爲」它應該更新jQuery實際移動到頁面上不同位置的元素,從而導致元素的多個副本以及您提到的問題。

我已經看到使用嵌套的UpdatePanels這個問題,但它也可能發生在其他情況。

這是一個問題,其解決方法很麻煩。

選項1 - 更改jQuery UI的源代碼。我沒有任何運氣可以快速修復;很少重寫整個插件,我無法找到一個容易使對話框正確工作而無需重新排序DOM。另外,通過這條路線,現在你「擁有」了源代碼,因爲你修改了它。

選項2 - 每當部分渲染頁面時調整DOM以刪除重複元素。您可以輸出一些額外的腳本來清理虛假的重複元素。我不喜歡這種方法,因爲它允許DOM在腳本運行之前處於無效狀態。

選項3 - 手動覆蓋UpdatePanel的渲染。代碼看起來是這樣的:

private bool _hasDomPresence 
{ 
    get 
    { 
     return ViewState["__hasDomPresence"] == null ? false : (bool)ViewState["__hasDomPresence"]; 
    } 
    set 
    { 
     ViewState["__hasDomPresence"] = value; 
    } 
} 

protected override void OnLoad(EventArgs e) 
{ 
    if(!ScriptManager.GetCurrent(this.Page).IsInAsyncPostBack) 
    { 
     // a full postback means we no longer have a DOM presence 
     _hasDomPresence = false; 
    } 

    base.OnLoad(e); 
} 

protected virtual void ShowDetailDialog() 
{ 
    // code to show the offending dialog 

    // we are showing it, so note the fact that it now has a DOM presence 
    _hasDomPresence = true; 
} 

protected override void Render(HtmlTextWriter writer) 
{ 
    foreach(Control c in this.Controls) 
    { 
     // 
     // find the offending control's parent container prior to it being rendered 
     // In my scenario, the parent control is just a server-side DIV 
     if(c == this.DetailDialog) 
     { 
      // 
      // here, I am checking whether or not the panel actually needs to be 
      // rendered. If not, I set it to invisible, thus keeping a new DOM 
      // element from being created. 
      if(!this.DetailUpdatePanel.IsInPartialRendering && _hasDomPresence) 
      { 
       this.DetailUpdatePanel.Visible = false; 
      } 
     } 
    } 

    base.Render(writer); 
} 

這也將混淆事件驗證,因爲頁面的客戶端和服務器版本不匹配(或至少ASP.Net不能告訴他們這樣做)。我能找到的唯一方法就是關閉事件驗證。

使用適當的安全模型,事件驗證不是100%必要的,但我不喜歡被迫關閉它。

總之,這是我發佈的最邪惡的代碼,如果你使用它,蓬鬆的白色小貓會死亡,但這種方法似乎工作。

希望這會有所幫助。

+0

感謝您解決此問題。但同時我放棄了jQuery-Dialog方法,並使用最新的AjaxControlToolkit版本中的ModalPopupExtender。在解決一些較小的問題後,它可以很好地處理異步回發,無論客戶端或服務器端開放。再次感謝:) – 2011-04-15 15:30:22

4

這是我如何解決同樣的問題。它會刪除所有舊對話框,並將新更新的對話框添加回表單,以便回傳工作。我將下面的代碼放在一個腳本塊中,該塊通過代碼後面的ScriptManager.RegisterStartupScript添加到頁面中。

$('#divMyDialogAdded').remove(); 

$('#divMyDialog').dialog({ 
    autoOpen: false, 
    modal: true 
}).parent().appendTo('form:first'); 

$('#divMyDialog').attr('id', 'divMyDialogAdded'); 
+0

這也適用於我,雖然我最終把它放在我的jQuery準備處理程序和pageLoad isPartialLoad處理程序而不是使用ScriptManager。 – 2013-01-14 19:01:24

1

我認爲jQuery和腳本管理/更新面板時生成和分析confilct它創建的腳本,你應該在更新面板的觸發正確,才能在代碼中使用這個背後方法處理事件:

 UpdatePanel2.Update(); 

,所以我有這樣的問題,可以通過解決它下面的代碼(這是我的示例代碼):

<!--------- show for dialog ---> 
<div id="dialog" style="direction: rtl;"> 
    <asp:ScriptManager ID="ScriptManager1" runat="server"> 
    </asp:ScriptManager> 
    <asp:UpdatePanel ID="UpdatePanel2" runat="server" RenderMode="Block" UpdateMode="Conditional" EnableViewState="True" ChildrenAsTriggers="True"> 
     <ContentTemplate> 
      <div> 
       <table> 
        <tr> 
         <td> 
          <asp:ListBox ID="lstSLA" runat="server" SelectionMode="Single" Width="250px" Height="350px"> 
          </asp:ListBox> 
         </td> 
         <td valign="middle"> 
          <asp:Button ID="BtnUpMove" runat="server" Text=" top" OnClick="BtnUpMove_Click" /> 
          <div> 
           <br /> 
          </div> 
          <asp:Button ID="BtnDownMove" runat="server" Text="down" OnClick="BtnDownMove_Click" /> 
         </td> 
        </tr> 
        <tr> 
         <td colspan="2" align="center"> 
          <asp:Button ID="btnSavePeriority" runat="server" Text="Save" OnClick="btnSavePeriority_Click" /> 
         </td> 
         <td> 
         </td> 
        </tr> 
       </table> 
      </div> 
     </ContentTemplate> 
     <Triggers> 
      <asp:PostBackTrigger ControlID="btnSavePeriority" /> 
      <asp:AsyncPostBackTrigger ControlID="BtnUpMove" EventName="Click" /> 
      <asp:AsyncPostBackTrigger ControlID="BtnDownMove" EventName="Click" /> 
     </Triggers> 
    </asp:UpdatePanel> 
</div> 

,並在C#代碼: 保護沃伊d BtnUpMove_Click(object sender,EventArgs e) int SelectedIndex = lstSLA.SelectedIndex;

 if (SelectedIndex == -1) // nothing selected 
     { 
      UpdatePanel2.Update(); 
      return; 
     } 
     if (SelectedIndex == 0) // already at top of list 
     { 
      UpdatePanel2.Update(); 
      return; 
     } 

     ListItem Temp; 
     Temp = lstSLA.SelectedItem; 

     lstSLA.Items.Remove(lstSLA.SelectedItem); 
     lstSLA.Items.Insert(SelectedIndex - 1, Temp); 
     UpdatePanel2.Update(); 
     lstSLA.SelectedIndex = -1; 
    } 
    protected void BtnDownMove_Click(object sender, EventArgs e) 
    { 
     int SelectedIndex = lstSLA.SelectedIndex; 

     if (SelectedIndex == -1) // nothing selected 
     { 
      UpdatePanel2.Update(); 
      return; 
     } 
     if (SelectedIndex == lstSLA.Items.Count - 1) // already at top of list    
     { 
      UpdatePanel2.Update(); 
      return; 
     } 

     ListItem Temp; 
     Temp = lstSLA.SelectedItem; 

     lstSLA.Items.Remove(lstSLA.SelectedItem); 
     lstSLA.Items.Insert(SelectedIndex + 1, Temp); 
     UpdatePanel2.Update(); 
     lstSLA.SelectedIndex = -1; 

    } 
    protected void btnSavePeriority_Click(object sender, EventArgs e) 
    { 
     if (lstSLA.Items.Count == 0) return; 
     try 
     { 
      var db = DatabaseHelper.GetITILDataAccess(); 
      ServiceLevel srvlvl = new ServiceLevel(); 
      int priority = 1; 
      foreach (ListItem ls in lstSLA.Items) 
      { 
       srvlvl = new ServiceLevel(); 
       srvlvl = db.ServiceLevels.Single(p => p.ID == long.Parse(ls.Value)); 
       srvlvl.priority = priority; 
       priority++; 
       ServiceLevelManagement.Update(srvlvl); 

      } 
      ShowMessage(ITILMessages.InsertComplete); 
     } 
     catch (Exception ex) 
     { } 
     finally { } 

    }