2
votes

Ok, this ought to be doable - and pretty simple, if one knows how to get a handle on the djFilteringSelect object.

Use case: I have taken over a request to extend an existing XPage with the functionality to drop down the list of values not only if the user clicks the small arrow to the right of the djFilteringSelect input field - but also if the user just clicks on the field. Most of the initial entries for this XPage are done in the manufacturing site (using touch screens - no mouse/keyboard). Subsequent processing is done by users using "normal" computers.

So I have tried to "catch" either "click", "mousedown" or "mouseup" events. I can do that - but I cannot get hold of the filteringselect that I know has a method "openDropDown()" that probably do what I need to do.... I have also tried to simulate a keypress event "arrowdown" as that also gives the same experience if I do it... And I even tried to delay the keypress event and add some context - but nothing is working.

So this is my current very simple example that is not working:

                <xe:djFilteringSelect id="Antal" defaultValue="1">
                    <xp:selectItems id="selectItems13">
                        <xp:this.value><![CDATA[${javascript:var values=[];var i=0;while(i<=20){values.push(''+i++)};return values;}]]></xp:this.value>
                    </xp:selectItems>
                    <xp:selectItem itemLabel="20+"></xp:selectItem>

                    <xp:eventHandler event="onKeyUp" submit="false">
                        <xe:this.script><![CDATA[console.log("keyUp=" + thisEvent.keyCode)]]></xe:this.script>
                    </xp:eventHandler>
                    <xp:eventHandler event="onMouseDown" submit="false">
                        <xe:this.script><![CDATA[var ct = thisEvent.currentTarget;
var se = thisEvent.srcElement;
var te = thisEvent.toElement;
setTimeout(function(ct,se,te){
var keyboardEvent = document.createEvent("KeyboardEvent");
var initMethod = typeof keyboardEvent.initKeyboardEvent !== 'undefined' ? "initKeyboardEvent" : "initKeyEvent";

keyboardEvent[initMethod](
                   "keyup", // event type : keydown, keyup, keypress
                    true, // bubbles
                    true, // cancelable
                    Window, // viewArg: should be window
                    false, // ctrlKeyArg
                    false, // altKeyArg
                    false, // shiftKeyArg
                    false, // metaKeyArg
                    40, // keyCodeArg : unsigned long the virtual key code, else 0
                    0 // charCodeArgs : unsigned long the Unicode character associated with the depressed key, else 0
);
/// Hmmmm... not working
keyboardEvent.currentTarget = ct;
keyboardEvent.srcElement = se;
keyboardEvent.toElement = te;
console.log('Fire arrow down key...');
document.dispatchEvent(keyboardEvent);
},200);
]]></xe:this.script>
                    </xp:eventHandler></xe:djFilteringSelect>

So any ideas would be appreciated - especially by the users in the manufactoring site :-)

1
would it be an option to use a different type of control for your touchscreen users? I'm sure you'll find one that does exactly what you and your users expect - Lothar Mueller
Hmmm.... Yes could be. Not ideal though as they "look like" a normal computer. Not sure how I can determine if they are using a touch screen - but it is worth trying to follow that route as well. Thanks! - John Dalsgaard
Have you played around with 9.0.1's deviceBean feature yet? Maybe that could be of help making a distinction between your devices. Also with some of the mobile control events like 'xe:singlePageApp' or 'xe:appPage' you have additional helpful event handlers at hand. Good luck - Lothar Mueller
Well, these computers are ordinary computers - just with a touch screen and "soft keyboard". So not really a candidate for an SPA (single page app). And really, we only need a few fields to be easier to "hit" with the finger - not a total redesign of the page for a subset of users ;-) - John Dalsgaard

1 Answers

1
votes

...to drop down the list of values not only if the user clicks the small arrow to the right of the djFilteringSelect input field - but also if the user just clicks on the field.

If I read your question right, you just want to bring up the drop down when a user clicks into the field. This doesn't exactly match up with your other code, and I've no idea how dojo interprets the click event from the input tag and works it through the entire dijit, but I tried adding an event handler much like the one I use when I wish for a user to forcibly fire a xe:namePicker when they click into a corresponding field.

I added the following to your xe:djFilteringSelect and it appears to be working fine; as I'm expecting it to, anyway.

    ....
    <xp:eventHandler
        event="onClick"
        submit="false">
        <xe:this.script><![CDATA[var el = dijit.byId("#{id:Antal}");
el.toggleDropDown();]]></xe:this.script>
    </xp:eventHandler>
</xe:djFilteringSelect>

[Updated] As we noticed (in the comments to this answer), this was working after the pop up had already been triggered, but not the first time. The solution is quite simple, to use the toggleDropDown() function instead of openDropDown(). Seems pretty solid and I confirmed it worked after a fresh page load, as expected. It seems that the toggle function will trigger the creation of the DOM elements that comprise the value list, as opposed to the open function. [/Updated]

showing before and after suggested change with djFilteringSelect