TextBox OnValueChanged not firing when using TabStrip

11 posts, 1 answers
  1. Pete
    Pete avatar
    6 posts
    Member since:
    Jun 2015

    Posted 09 Jun 2015 Link to this post

    I am trying to track what a user is doing on a page to prevent them moving off a Page View before saving it, the problem I have is that when they go straight from the changed control to the tab strip the OnValueChanged event of the text box does not fire.

    I have created a stripped out page to illustrate the problem which is below, there is no code behind in the demo.

    <%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Default.aspx.vb" Inherits="WebApplication1._Default" %>
     
    <!DOCTYPE html>
     
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <telerik:RadScriptManager runat="server" ID="RadScriptManager1"></telerik:RadScriptManager>
            <telerik:RadTabStrip runat="server" ID="RadTabStrip1" Align="Justify" AutoPostBack="true" MultiPageID="RadMultiPage1" SelectedIndex="0">
                <Tabs>
                    <telerik:RadTab Text="Basic Details" PageViewID="pageBasicDetails"/>
                    <telerik:RadTab Text="Permissions" PageViewID="pagePermissions"/>
                </Tabs>
            </telerik:RadTabStrip>
            <telerik:RadMultiPage runat="server" ID="RadMultiPage1" SelectedIndex="0" RenderSelectedPageOnly="True">
                <telerik:RadPageView runat="server" ID="pageBasicDetails">
                    <div class="contentWrapper">
                        <table>
                            <tr>
                                <td>
                                    <asp:Label runat="server" ID="lblFirstName" AssociatedControlID="FirstName" Text="First Name"></asp:Label></td>
                                <td>
                                    <telerik:RadTextBox runat="server" ID="FirstName" MaxLength="50" Width="300px" Text="John"><ClientEvents OnValueChanged="SetDirty" /></telerik:RadTextBox></td>
                                <td>
                                    <asp:RequiredFieldValidator ID="valFirstName" ControlToValidate="FirstName"
                                        CssClass="validation"
                                        ErrorMessage="First Name is required"
                                        runat="server" /></td>
                            </tr>
                            <tr>
                                <td>
                                    <asp:Label runat="server" ID="lblLastName" AssociatedControlID="LastName" Text="Last Name"></asp:Label></td>
                                <td>
                                    <telerik:RadTextBox runat="server" ID="LastName" MaxLength="50" Width="300px" Text="Smith"><ClientEvents OnValueChanged="SetDirty" /></telerik:RadTextBox></td>
                                <td>
                                    <asp:RequiredFieldValidator ID="valLastName" ControlToValidate="LastName"
                                        CssClass="validation"
                                        Display="Static"
                                        ErrorMessage="Last Name is required"
                                        runat="server" /></td>
                            </tr>
                        </table>
                    </div>
                </telerik:RadPageView>
                <telerik:RadPageView runat="server" ID="pagePermissions">
                    <div class="contentWrapper">
                    </div>
                </telerik:RadPageView>
            </telerik:RadMultiPage>
        </div>
        </form>
         
         
        <script type="text/ecmascript">
        function SetDirty(sender, eventArgs) {
            alert('SetDirty');
        }
    </script>
    </body>
    </html>

    If you go into the page and edit the first name then move to the last name control, the client side function SetDirty fires as I would expect. If you then change it again but this time click directly to the Permissions tab the SetDirty function does not fire which does not seem correct as the control value is changed and there should still be a blur event.

    Can you tell me what I am doing wrong?

  2. Ivan Danchev
    Admin
    Ivan Danchev avatar
    829 posts

    Posted 11 Jun 2015 Link to this post

    Hello,

    There are certain inconsistencies between the different browsers in the way they handler focus/blur events and while your scenario works as expected in Chrome, in IE11 and Firefox a different behavior can be observed.

    I can suggest subscribing to the RadTabStrip's OnClientTabSelecting client-side event and calling blur() on the textboxes explicitly in its handler:
    function OnClientTabSelecting(sender, eventArgs) {
        $telerik.$("#FirstName").blur();
        $telerik.$("#LastName").blur();
    }

    This would ensure consistent blurring of both textboxes when the user clicks on a Tab.

    Regards,
    Ivan Danchev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Pete
    Pete avatar
    6 posts
    Member since:
    Jun 2015

    Posted 15 Jun 2015 in reply to Ivan Danchev Link to this post

    Hi Ivan

    Thanks for that. It works fine in the ultra simplified page I gave you as an example but is not practical in the real development as it will end up being a maintenance nightmare.

    We currently have eight tabs, the page associated with each tab is built in a user control which contains at least 12 user controls. Having well over 100 lines each containing a reference to a ClientID for a control on a user control to call the blur method is not going to be maintainable.

    I've tried building a loop to iterate through all the controls and can find the text boxes no problem but calling the blur method has no effect which I guess because the RadTextBox is made up of a number of controls and the blur needs to be called on one of the others, the code I used is below, any help you can give me getting it working would be appreciated.

     Thanks 

     Pete

    for (i = 0; i < document.forms[0].elements.length; i++) {
        elm = document.forms[0].elements[i]
        alert(elm.id + '\r\n' + elm.type);
        if (elm.type == 'ComboBox' || elm.type == 'text') {
            elm.blur();
        }
    }

  5. Ivan Danchev
    Admin
    Ivan Danchev avatar
    829 posts

    Posted 16 Jun 2015 Link to this post

    Hello Pete,

    Instead of getting the textboxes by their IDs you can call blur() on all textboxes on your page by using the "input" element as a selector:
    function OnClientTabSelecting(sender, eventArgs) {
        $telerik.$("input").blur();
    }

    Regards,
    Ivan Danchev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Pete
    Pete avatar
    6 posts
    Member since:
    Jun 2015

    Posted 17 Jun 2015 in reply to Ivan Danchev Link to this post

    Hi Ivan

    Thanks for the reply. Although that works fine in the simple pager above, unfortunately it does not work work in the site I am building probably down to the complexity of the stucture.

    The actual page I am building is Master page > page > RadWindow > user control > RadTabStrip/RadMultiPage > multiple user controls.

    I will try and build a simple project to demonstrate but I don't know how I would get it to you as it is not possible to attach zip files

  7. Ivan Danchev
    Admin
    Ivan Danchev avatar
    829 posts

    Posted 19 Jun 2015 Link to this post

    Hello Pete,

    I am attaching a sample runnable project, which recreates the project structure you described.

    At my side calling blur() in the RadTabStrip's OnClientTabSelecting event handler works correctly even with TexBox controls on the Master page or in a UserControl. Please review the code, try reproducing your scenario in it and post your modifications.

    Regards,
    Ivan Danchev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  8. Pete
    Pete avatar
    6 posts
    Member since:
    Jun 2015

    Posted 22 Jun 2015 in reply to Ivan Danchev Link to this post

    Hi Ivan

    Thanks for your reply. I've reproduced my problem in your project and I am reasonably sure that the issue is one of timing although I do not know how to fix it. To reproduce remove the script from TextBoxUserControl and modify TabStripUserControl to as below. We are back in the situation where if we modify first name and you go to last name then to the tab strip the code works as expected but if you go straight to the tab strip it does not

    Thanks for your help

    Pete

     

    <%@ Control Language="C#" AutoEventWireup="true" CodeFile="TabStripUserControl.ascx.cs" Inherits="TabStripUserControl" %>
     
    <%@ Register Src="~/TextBoxUserControl.ascx" TagPrefix="tb" TagName="TextBoxUserControl" %>
    <asp:HiddenField ID="DirtyMarker" runat="server" />
    <telerik:RadTabStrip runat="server" ID="RadTabStrip1" Align="Justify" AutoPostBack="true" MultiPageID="RadMultiPage1" SelectedIndex="0" OnClientTabSelecting="OnClientTabSelecting">
        <Tabs>
            <telerik:RadTab Text="Basic Details" PageViewID="pageBasicDetails" />
            <telerik:RadTab Text="Permissions" PageViewID="pagePermissions" />
        </Tabs>
    </telerik:RadTabStrip>
    <telerik:RadMultiPage runat="server" ID="RadMultiPage1" SelectedIndex="0" RenderSelectedPageOnly="True">
        <telerik:RadPageView runat="server" ID="pageBasicDetails">
             <tb:TextBoxUserControl runat="server" ID="UserControl2" />
        </telerik:RadPageView>
        <telerik:RadPageView runat="server" ID="pagePermissions">
            <div class="contentWrapper">
            </div>
        </telerik:RadPageView>
    </telerik:RadMultiPage>
     
    <script type="text/ecmascript">
        function OnClientTabSelecting(sender, eventArgs) {
            $telerik.$("input").blur();
            if (IsDirty()) {
                eventArgs.set_cancel(true);
                alert("Unsaved changes, please save or cancel");
            }
            else {
                eventArgs.set_cancel(false);
            }
        }
        function SetDirty(sender, eventArgs) {
            document.getElementById('<% =DirtyMarker.ClientID %>').value = 'dirty';
        }
        function IsDirty() {
            var marker = document.getElementById('<% =DirtyMarker.ClientID %>');
            return marker.value == 'dirty';
        }
    </script>

  9. Ivan Danchev
    Admin
    Ivan Danchev avatar
    829 posts

    Posted 22 Jun 2015 Link to this post

    Hello Pete,

    Could there be another missing modification to the code that makes reproducing the issue possible, because at my side the changes to the TextBoxes are detected after the changes from your last post?

    Please, see a short video demonstrating what I see when clicking on the second Tab.

    Regards,
    Ivan Danchev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  10. Pete
    Pete avatar
    6 posts
    Member since:
    Jun 2015

    Posted 22 Jun 2015 in reply to Ivan Danchev Link to this post

    Hi Ivan

    Sorry that this is turning into a bit of a marathon.

    The behaviour is correct in Chrome and Firefox but not in IE 11, unfortunately 95% of our users are using IE and will not change.

    I've also tested in IETester on version 9 which also does not work correctly, versions 8 and prior don't seem to work at all but I am not worried about them

    Thanks

    Pete

  11. Answer
    Ivan Danchev
    Admin
    Ivan Danchev avatar
    829 posts

    Posted 23 Jun 2015 Link to this post

    Hello Pete,

    It seems in IE the blur is not fast enough, which leads to the "dirty" value not being set in time and the alert not being displayed. I moved the call to the blur() function to the RadTabStrip's OnClientMouseOver event handler and this gives it enough time to set the value in IE:
    <script type="text/ecmascript">
        function OnClientMouseOver(sender, args) {
           $telerik.$("input").blur();
        }
     
        function OnClientTabSelecting(sender, eventArgs) {
     
            if (IsDirty()) {
                eventArgs.set_cancel(true);
                alert("Unsaved changes, please save or cancel");
            }
            else {
                eventArgs.set_cancel(false);
            }
        }
        function SetDirty(sender, eventArgs) {
            document.getElementById('DirtyMarker').value = 'dirty';
        }
        function IsDirty() {
            var marker = document.getElementById('DirtyMarker');
             
            return marker.value == 'dirty';
        }
    </script>

    Regards,
    Ivan Danchev
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  12. Pete
    Pete avatar
    6 posts
    Member since:
    Jun 2015

    Posted 24 Jun 2015 in reply to Ivan Danchev Link to this post

    Hi Ivan

    Thanks, that works.

    Many thanks for your help with this.

    Kind regards

    Pete

Back to Top
UI for ASP.NET Ajax is Ready for VS 2017