This is a migrated thread and some comments may be shown as answers.

Selective updating controls on postback

11 Answers 606 Views
Ajax
This is a migrated thread and some comments may be shown as answers.
Keith
Top achievements
Rank 2
Keith asked on 18 Jun 2013, 10:33 PM
I am quite new to the ajax world, so if this is a rookie question, please be patient with me. I'm still learning.

I have a situation where I don't want to perform a postback until the user confirms that it is OK to perform a certain action. However, on postback, if the data that is sent isn't valid, the function should alert the user to one of several potential problems with the data, but if the data is valid, go ahead and update certain selected controls on the form.

If I use an ajax request, I can get success or failure and alert the user about the problem if it exists, however, I am not sure how to update the controls or prevent their update depending upon the value returned from the server.

Essentially, I want to have the user confirm via a radwindow, then if the confirmation is affirmative, then perform an ajax POST request with the data. If the server returns success, I want to then update a series of controls, however, if the server returns an error, I want to show a radwindow with the error returned from the server and leave the page exactly as it is.

11 Answers, 1 is accepted

Sort by
0
msigman
Top achievements
Rank 2
answered on 19 Jun 2013, 07:30 PM
Hi Keith,

I'm afraid this is a pretty fundamental question you've asked, but I'll do my best to provide an answer from a high level.

First, you asked about the confirmation.  This should be done in your button or hyperlink using "onclick."
<script type="text/javascript">
function confirm_delete() {
  return confirm('are you sure?');
}
</script>
...
<a href="whatever" onclick="return confirm_delete()"><img ...></a>

Next, you can do validation in the server-side methods that are called if the user confirms the popup.  If you wish to update the controls, do so as usual from the code behind file.  If not,  you may simply not update the values and they will remain what they were originally.

Hopefully that gives you a good start.

Best luck,
Matt
0
Keith
Top achievements
Rank 2
answered on 19 Jun 2013, 08:48 PM
I figured it was a basic question, and despite the novice level of the question, I am certainly not a novice programmer. Perhaps I over think things.
0
Keith
Top achievements
Rank 2
answered on 20 Jun 2013, 06:12 AM
Well apparently I am too stupid to figure it out ...

This is my scenario:
On my page I have a radlistbox that is populated when the page is rendered. Above that radlistbox is a textbox that has an event handler for the onkeyup event. This event handler changes the visibility of the items in the radlistbox to filter the contents according to the value in the textbox by setting the css display property to none.

Adjacent to the radlistbox is another control with several textboxes that are updated when an item in the radlistbox is selected.

In the codebehind, I do not fill the radlistbox or change it in any way if the page is a postback i.e.

if (!Page.IsPostBack){
   //fill the radlistbox and do other stuff on initial display
}

When the page is updated after postback, the contents of the radlistbox that were previously hidden are now visible.

Am I expecting too much?
0
msigman
Top achievements
Rank 2
answered on 20 Jun 2013, 06:40 PM
Hi Keith,

If you remove AJAX from the page (or set EnableAjax=False on the RadAjaxManager) does it work the way you want?  If not, then the problem is not with AJAX, but probably your application logic.

Matt
0
Keith
Top achievements
Rank 2
answered on 20 Jun 2013, 08:49 PM
Well of course it won't work as expected if I disable ajax. Isn't that what ajax is all about ... updating client side controls from server side code without having to update the entire page?

What this amounts to is Javascript editing the style of a control (setting display:none on a <li> element). This element is not included in the ajax update nor is it edited server-side. There is no error in the code logic. I've stepped through the entire codebehind line by line and at no point does the control get updated.

It is quite simple actually - the onkeyup event on an input control changes the style of a <li> element in a nested div. When the user clicks on one of the <li> elements, it fires a postback to update a different div.

I could understand there being a problem if the control was updating itself or if somewhere in the codebehind the control was being edited, but that isn't the case.

Consider this document:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
  <title>Test Page</title>
</head>
<body>
<form id="form1" runat="server">
  <telerik:RadScriptManager ID="RadScriptManager1" runat="server">
  </telerik:RadScriptManager>
  <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server" 
        DefaultLoadingPanelID="RadAjaxLoadingPanel1" >
        <AjaxSettings>
            <telerik:AjaxSetting AjaxControlID="RadListBox1">
                <UpdatedControls>
                    <telerik:AjaxUpdatedControl ControlID="ContentDiv" />
                </UpdatedControls>
            </telerik:AjaxSetting>
        </AjaxSettings>
    </telerik:RadAjaxManager>
  <div>
      <asp:TextBox ID="TextBox1" AutoPostBack="false" runat="server" onkeyup="filterList();"></asp:TextBox>
      <telerik:RadListBox ID="RadListBox1" runat="server" AutoPostBack="true">
      </telerik:RadListBox>
  </div>
  <div id="ContentDiv" runat="server">
      <asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
      <asp:TextBox ID="TextBox3" runat="server"></asp:TextBox>
      <asp:TextBox ID="TextBox4" runat="server"></asp:TextBox>
      <asp:TextBox ID="TextBox5" runat="server"></asp:TextBox>
  </div>
  <script type="test/javascript">
    function filterList() {
        var listbox = $find('RadListBox1');
        var textbox = $('#TextBox1');
        createMatchingList(listbox, textbox.val());
    }
    function createMatchingList(listbox, filterText) {
        if (filterText != "") {
            filterText = escapeRegExCharacters(filterText);
            var items = listbox.get_items();
            var re = new RegExp(filterText, "i");
            items.forEach
                ( function (item) {
                    var itemText = item.get_text();
                    if (itemText.match(re)) {
                        item.set_visible(true);
                    } else {
                        item.set_visible(false);
                    }
                })
            } else {
                var items = listbox.get_items();
                items.forEach
                    ( function (item) {
                        item.set_visible(true);
                    })
            }
    }
    function escapeRegExCharacters(text) {
        return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
    }
    </script>
    <telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server" >
    </telerik:RadAjaxLoadingPanel>
</form>
</body>
</html>

with this codebehind:
Public Class TestPage
    Inherits System.Web.UI.Page
  
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If (Not Page.IsPostBack) Then
            Me.TextBox1.Text = ""
            Me.TextBox2.Text = ""
            Me.TextBox3.Text = ""
            Me.TextBox4.Text = ""
            Me.TextBox5.Text = ""
            For i As Int16 = 1 to 10
                Me.RadListBox1.Items.Add(New RadListBoxItem("ListItem" & CStr(i), "ListItem" & CStr(i) & " was selected")
            Next i
        End If
    End Sub
  
    Protected Sub RadListBox1_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles RadListBox1.SelectedIndexChanged
        Dim selectedValue As String = Me.RadListBox1.SelectedItem.Value
        Me.TextBox2.Text = SelectedValue
        Me.TextBox3.Text = SelectedValue
        Me.TextBox4.Text = SelectedValue
        Me.TextBox5.Text = SelectedValue
    End Sub
  
End Class


Now, whenever you first render the page, RadListBox1 will have 10 items "ListItem1" through "ListItem10"

When you type into TextBox1, the contents of RadListBox1 will filter according to what was entered. For example, if you enter "1" then the only items that will be visible are "ListItem1" and "ListItem10". Likewise, if you enter only "9" then "ListItem9" is the only one visible.

For this test, don't enter anything and just click on one of the items in RadListBox1. You will note that the other four textboxes are updated to show the value of the selected item, namely "ListItem n was selected" where n is the item in the list.

Now, type 1 in TextBox1. The contents of RadListBox1 is filtered to show only "ListItem1" and "ListItem10" - click one of them.

Notice that every item in RadListBox1 is now visible and that the value of the clicked item is now displayed in the other four textbox controls.

At no point is RadListBox updated in the codebehind. It is however, initialized on first render when Not Page.IsPostBack evaluates to True.

Also note that the RadAjaxManager does not update RadListBox1. It only updates ContentDiv. The div containing RadListBox1 is not a child control to ContentDiv.

Keep in mind that this isn't all of the code. I've pared it down to a simple example of the problem I am seeking to resolve.
0
Radoslav
Telerik team
answered on 21 Jun 2013, 08:48 AM
Hi Keith,

I tried to reproduce the described issue but to no avail. I am sending you a simple example based on your code. Please check it out and let me know what differs in your case.

Looking forward for your reply.

Regards,
Radoslav
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
0
Keith
Top achievements
Rank 2
answered on 21 Jun 2013, 05:13 PM
Ok, I have identified the problem .. sort of.

As best I can tell, the problem is in the Ajax implementation and not the codebehind logic.

Here is the scenario:
Multiple ajaxified control are on the page.
The listbox selectedindexchanged event updates ContentDiv - everything here works as it should.

There is a top level div that contains all the controls, including the listbox that is the updated control to another control. When I remove the top level div from the ajaxified controls list for a different control, the listbox retains its appearance after postback, however, that prevents me from updating the listbox as an ajaxified control from another form event.

To be sure this wasn't happening in the codebehind, I stepped through every line of code following every action from the form. I even disabled all code that would run on postback, including all code inside the eventhandler for the selectedindexchanged ... to no avail. The listbox is still changed unless I remove the div it is located in as a child from an ajax handler.
0
Keith
Top achievements
Rank 2
answered on 21 Jun 2013, 09:59 PM
More information on the problem.

The page is organized as such:
<div id="Content" runat="server">
    <div id="Child1" runat="server">
        <!--some controls in here-->
    </div>
    <div id="Child2" runat="server">
        <!--some controls in here-->
    </div>
</div>

I have ajaxified several controls in Child1 that update Child2 on postback. There are also several controls in Child2 that update Content on postback.

The ajax code looks similar to this:
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
    <AjaxSettings>
        <telerik:AjaxSetting AjaxControlID="RadButton1inChild2">
            <UpdatedControls>
                <telerik:AjaxUpdatedControl ControlID="Content" />
            </UpdatedControls>
        </telerik:AjaxSetting>
        <telerik:AjaxSetting AjaxControlID="RadListBox1inChild1">
            <UpdatedControls>
                <telerik:AjaxUpdatedControl ControlID="Child2" />
            </UpdatedControls>
        </telerik:AjaxSetting>
    </AjaxSettings>
</telerik:RadAjaxManager>


If I use the code above as it is written, ajax works and updates all of the controls, even the ones that I don't want updated. For example, selecting an item in the listbox updates Content as well as Child2.

The interesting thing is that if I switch the ajax settings around like this:
<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server">
    <AjaxSettings>
        <telerik:AjaxSetting AjaxControlID="RadListBox1inChild1">
            <UpdatedControls>
                <telerik:AjaxUpdatedControl ControlID="Child2" />
            </UpdatedControls>
        </telerik:AjaxSetting>
        <telerik:AjaxSetting AjaxControlID="RadButton1inChild2">
            <UpdatedControls>
                <telerik:AjaxUpdatedControl ControlID="Content" />
            </UpdatedControls>
        </telerik:AjaxSetting>
    </AjaxSettings>
</telerik:RadAjaxManager>

Ajax will now throw a javascript error (something is undefined and I don't know what) and Child2 is not rendered to the browser.

To be sure that I wasn't calling anything errant in code that I could have possibly missed, I moved all code in the page initialization to only run if the page is not a postback. I also removed all code from the event handler for the listbox.

Theoretically now, when the RadListBox performs a postback, the page should initialize and nothing should happen. The list item is selected (again if I use the second ajax configuration, an error occurs and child2 isn't rendered) and amazingly, it is updated, depsite not changing anything on the page.

If I move Child1 out of Content, there is no error regardless of the order of the ajax configuration and Child1 is not updated when the RadListBox performs a postback. However, if I then include Child1 to be updated when a Child2 control make a postback, the RadListBox is updated and switching the organization of the ajax configuration causes Child2 to not be rendered.
0
Radoslav
Telerik team
answered on 26 Jun 2013, 07:14 AM
Hello Keith,

Could you please try setting the UpdateInitiatorPanelsOnly property to "true" and let me know if the issue still persists?
<telerik:RadAjaxManager ID="RadAjaxManager1" UpdateInitiatorPanelsOnly="true" runat="server"> ...

Looking forward for your reply.

Regards,
Radoslav
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
0
Keith
Top achievements
Rank 2
answered on 26 Jun 2013, 03:05 PM
It still persists.

It seems as though ajax is updating the control that initiated the request because the control that initiated the request is in the parent div at the same level as another updated control. The reason I suspect this is true is because when I move the control out of the div with an updated control, it works as expected. The problem with solving this issue by changing the parent control of my listbox is that it breaks the ability to dynamically resize the page writing client-side code to resolve the issue.

For example, in this bit of code, a control in child1 will initiate an update of controls in child2 and other sibling controls in parent. This gives the incorrect behavior.
<div id="parent">
    <div id="child1">
        <!--radlistbox is here-->
    </div>
    <div id="child2">
        <!--updated controls here-->
    </div>
    <!--another updated control here-->
    <!--another updated control here-->
    <!--another updated control here-->
</div>

When I move the child div outside the parent div, it works as expected.
<div id="waschild1"
    <!--radlistbox is here-->
</div
<div id="parent"
    <div id="child2"
        <!--updated controls here-->
    </div
    <!--another updated control here-->
    <!--another updated control here-->
    <!--another updated control here-->
</div>


So far no settings have resolved this issue for me. To top it off, the loadingpanel has stiopped displaying after the latest update of the telerik controls.
0
Maria Ilieva
Telerik team
answered on 01 Jul 2013, 01:31 PM
Hello Keith,

Unfortunately the presented approach could not be achieved with RadAjaxManager  control as the UpdatePanels are created over the parent containers. Possible approach in your case is to replace the RadListBox as you mentioned or to use regular asp UpdatePanels and add a configuration with AsyncPostBack Triggers to cover your scenario.
As for the RadAjaxLoadingPanel issue I was not able to replicate it on my end.Test the attaches sample application and verify what the difference in your case is.

Regards,
Maria Ilieva
Telerik
If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the RadControls for ASP.NET AJAX, subscribe to the blog feed now.
Tags
Ajax
Asked by
Keith
Top achievements
Rank 2
Answers by
msigman
Top achievements
Rank 2
Keith
Top achievements
Rank 2
Radoslav
Telerik team
Maria Ilieva
Telerik team
Share this question
or