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

TextBox OnValueChanged not firing when using TabStrip

10 Answers 153 Views
TabStrip
This is a migrated thread and some comments may be shown as answers.
Pete
Top achievements
Rank 1
Pete asked on 09 Jun 2015, 12:47 PM

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?

10 Answers, 1 is accepted

Sort by
0
Ivan Danchev
Telerik team
answered on 11 Jun 2015, 04:40 PM
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
0
Pete
Top achievements
Rank 1
answered on 15 Jun 2015, 09:39 AM

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();
    }
}

0
Ivan Danchev
Telerik team
answered on 16 Jun 2015, 03:39 PM
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
0
Pete
Top achievements
Rank 1
answered on 17 Jun 2015, 08:15 AM

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

0
Ivan Danchev
Telerik team
answered on 19 Jun 2015, 04:57 PM
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
0
Pete
Top achievements
Rank 1
answered on 22 Jun 2015, 08:44 AM

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>

0
Ivan Danchev
Telerik team
answered on 22 Jun 2015, 02:50 PM
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
0
Pete
Top achievements
Rank 1
answered on 22 Jun 2015, 03:17 PM

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

0
Accepted
Ivan Danchev
Telerik team
answered on 23 Jun 2015, 04:04 PM
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
0
Pete
Top achievements
Rank 1
answered on 24 Jun 2015, 09:26 AM

Hi Ivan

Thanks, that works.

Many thanks for your help with this.

Kind regards

Pete

Tags
TabStrip
Asked by
Pete
Top achievements
Rank 1
Answers by
Ivan Danchev
Telerik team
Pete
Top achievements
Rank 1
Share this question
or