[CLOSED] Disable or Override Touch Settings

  1. #1

    [CLOSED] Disable or Override Touch Settings

    Hello,

    We are having an issue with users who use laptops with touchscreens, certain UI elements are displaying differently than non-touchscreen systems. When MsgTarget for a field is set to Qtip, the error message is displayed on the Side when using a touchscreen enabled system. Extjs is overriding the MsgTarget if a touchscreen is detected. This behavior is reasonable for tablets and phones where hovering and displaying a tooltip is not possible, but it is not desirable for a laptop that happens to have a touchscreen but also has a mouse connected.

    We would like to have control over when extjs uses touchscreen settings. I have traced the code to the variable Ext.supports.Touch -- this gets set to true or false when the framework is first initialized. The issue is I have not found anyway to override this setting (or the function that sets it) early enough to effect the fields that are created at load time.

    Please see the following example. You must test it on a system with a touchscreen or just set Chrome F12 to emulate an iPad or something similar. Leave the field empty and click the button to check validity, the icon shows up to the side of the field. We don't want this icon to show up.

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html>
    
    <html>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
    
            <ext:FormPanel runat="server">
                <Items>
                    <ext:TextField runat="server" FieldLabel="Field"  AllowBlank="false" MsgTarget="Qtip"/>
                </Items>    
                <Buttons>
                    <ext:Button Text="Check Valid" runat="server">
                        <Listeners>
                            <Click Handler="this.up('form').isValid();">
                            </Click>
                        </Listeners>
                    </ext:Button>
                </Buttons>
            </ext:FormPanel>            
        </form>
    </body>
    </html>
    Adding "Ext.supports.Touch = false;" to a script section on the page has no effect because by the time this line runs it is too late.
    Last edited by fabricio.murta; May 09, 2017 at 2:32 AM.
  2. #2
    Hello @tylert!

    Well, there are two parts here. For one, a bug on Ext.NET. First, as the Qtip is the default value for MsgTarget, it does not get emitted at all to the resulting JavaScript code. This is a bug with Ext.NET, it should output the Qtip setting should the user forcibly specified it. For the bug part, we've created issue #1472.

    But there's an easy way to avoid the bug, just by using MsgTargetElement="qtip" instead of just MsgTarget="Qtip". Notice the former has all lowercase characters -- that's important -- while the latter uses the auto-completed from Ext.Net.MessageTarget enum.

    Although this improves the way it works (will not display the click/touchable red exclamation mark icon), but still it won't be following the mouse cursor. I believe it works much better as the error is then displayed as the user hovers the mouse over the text element though.

    Bottom end, the solution suggested here is to define, in the provided test case, the text field like that:

    <ext:TextField runat="server" FieldLabel="Field" AllowBlank="false" MsgTargetElement="qtip" />
    I hope this helps! We'll update here as soon as we fix this "default value" issue directly on Ext.NET code.
    Fabrício Murta
    Developer & Support Expert
  3. #3
    Thanks -- that is a useful workaround.

    What I really want is to disable touch settings for devices that are not tablets or phones, because I know the touch specific settings go beyond this one thing. One challenge is that I need to overwrite the touch settings when the extjs code is first initialized. If you do it after all the extjs classes are defined it is too late. Here is what I came up with -- maybe there is an easier way.

    First, in my template page I added this method (I used the Ext.NET code to figure out how to inject a script at the top of the <head> section):

    protected override void Render(HtmlTextWriter writer)
    {
        base.Render(writer);
        var s = Transformer.NET.Net.CreateToken(typeof(Transformer.NET.ItemTag), new Dictionary<string, string>{
                    {"selector", "headstart"},
                    {"index", "1"} },
                    "<script type=\"text/javascript\" src=\"script/pre_extjs.js\"></script>");
        writer.Write(s);
    }

    Then my pre_extjs.js file looks like this:
    if (!navigator.userAgent.match(/Android|BlackBerry|iPhone|iPad|iPod|Opera Mini|IEMobile/i)) {
        delete Window.prototype.ontouchend;
        delete window.ontouchend;
        var navigator;
        if ('maxTouchPoints' in Navigator.prototype) {
            navigator = Navigator.prototype;
        } else {
            navigator = Object.create(navigator);
            Object.defineProperty(window, 'navigator', {
                value: navigator,
                configurable: false,
                enumerable: false,
                writable: false
            });
        }
        Object.defineProperties(navigator, { maxTouchPoints: { value: 0, configurable: false, enumerable: true, writable: false } });
    }

    It is necessary to set navigator.maxTouchPoints to 0 and delete Window.prototype.ontouchend in order to get extjs to not use touch settings (it will then set Ext.supports.Touch = false during initialization). If we detect the user agent as a known tablet or phone user agent, then skip these touch disabling steps. The goal is just to disable touch for non-mobile devices like laptops with a touchscreen.

    I haven't tested this much at all -- I will update if we run into an issue with this workaround.
    Last edited by tylert; May 05, 2017 at 4:00 PM.
  4. #4
    Hello @tylert!

    You can simplify that a little with:

    <%@ Page Language="C#" %>
    
    <!DOCTYPE html>
    
    <html>
    <head runat="server">
        <title>My page</title>
        <script>
            console.log("Pre-Ext include code. Here, Ext.* will not exist. Ext undefined: " + (typeof Ext === 'undefined') + ".");
        </script>
        <ext:ResourcePlaceHolder runat="server" />
        <script>
            console.log("Post-Ext include code. Here, Ext.* will exist. Ext undefined: " + (typeof Ext === 'undefined') + ".");
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
    
            <ext:Component runat="server" Html="This is a page content" />
        </form>
    </body>
    </html>
    But your method is also acceptable, as it would allow making the change indirectly to the aspx pages. So whatever fits you better would be okay. The above is just an alternative supported by Ext.NET.

    By the way, the script is very useful, for example, to avoid an issue with Ext.NET and firefox with hybrid touch-click devices reported in Strange issue with Firefox 52 (UI freezes on some PCs also on Ext.Net examples...).
    Last edited by fabricio.murta; May 05, 2017 at 11:24 PM.
  5. #5
    I wasn't familiar with ResourcePlaceHolder, that will be much better.
  6. #6
    Well, glad it helped in the end! Thanks for the feedback.
    Fabrício Murta
    Developer & Support Expert

Similar Threads

  1. [CLOSED] Sencha Touch
    By x1000 in forum 1.x Legacy Premium Help
    Replies: 6
    Last Post: Aug 03, 2016, 7:56 AM
  2. Sencha Touch
    By Yannis in forum 1.x Help
    Replies: 2
    Last Post: Aug 03, 2016, 7:56 AM
  3. Sencha Touch?
    By francesco77 in forum Open Discussions
    Replies: 5
    Last Post: Aug 03, 2016, 7:54 AM
  4. Sencha Touch and Ext.NET
    By Z in forum Licensing
    Replies: 5
    Last Post: Aug 03, 2016, 7:48 AM

Tags for this Thread

Posting Permissions