A way to detect a click anywhere but a specific control? - elm

In my app the user can click on a div to highlight it. Is there a way to detect that they've clicked somewhere away from the div? I'd like to unhighlight selected things when this happens. I tried adding an onclick to the big div that contains everything else, but that doesn't really work as desired. IIRC the big div onclick always happens after the contained div onclick, so you can't ever select anything.

You can do this by adding a on "click" event to both the divs and then in the inner div, use onWithOptions to stop the propagation of the event. Here's some (untested) code:
onClickStop msg =
onWithOptions "click"
{ stopPropagation = True, preventDefault = False }
(Json.succeed msg)
view _ =
div [ onClick Clicked ]
[ div [ onClickStop NoOp ] []
]
When the user clicks inside the nested div, the event will be ignored and its propagation to its parent will be cancelled. Only when the user clicks outside the inner div will the Clicked message will be sent to update.

Related

How do I retrieve text from an html element?

How do I get the caption from a button?
decorateOn : String -> Html Msg -> Html Msg
decorateOn selectedCaption button =
if button.text == selectedCaption then
button [ class "selectedNavigationButton" ] []
else
button [ class "navigationButton" ] []
button does not have a field named text. - The type of button
is:
Html Home.Msg
Which does not contain a field named text.
Note, I realize that the "button" is really of type Html Msg.
You need to turn your thinking on its head. Rather than seeing what is in the button text, you need to set the text at the same stage as setting the class. So that gives you something like
decorateOn : String -> Html Msg -> Html Msg
decorateOn selectedCaption button =
if selectedCaption == "the selected value" then
button [ class "selectedNavigationButton" ] [text selectedCaption ]
else
button [ class "navigationButton" ] [text selectedCaption]
You can't get the text from a button without resorting to hacks involving ports and JavaScript. Moreover, you can't really inspect anything about the Elm Virtual DOM from within Elm.
Instead, try to refactor your app so that you can get the information from your model.

HTML textarea in Elm where pressing tab adds \t and doesn't change focus

I know how to listen for tab key presses in Elm. And I know how to stop the focus from being changed using onWithOptions:
textarea
[ onWithOptions "keydown" (Options False True) <| Decode.map KeyDown keyCode ] []
I can then check, in my update function, if the keyCode pressed was a 9, representing a tab. The problem is now the default behavior of a textarea doesn't work. Anything I type doesn't appear in the textarea. Easy enough, I simply add whatever I type to the model and make the value of the textarea the model. Now I have issues with the cursor and, more importantly, clipboard pasting doesn't work...
How do I get tabs to work properly with textareas in Elm? Normally, it would seem to make sense to only call preventDefault() if the tab key was pressed. How can I conditionally call preventDefault() in Elm?
Elm does support conditional event propagation through a Decoder that either succeeds or fails. Simply map the message type you want to react to in your update function:
succeededIfTabKey : Int -> Decode.Decoder Int
succeededIfTabKey key =
if key == 9 then
Decode.succeed key
else
Decode.fail "non-tab"
tabPressed : Decode.Decoder Msg
tabPressed =
Decode.andThen succeededIfTabKey keyCode
|> Decode.map (always TabPressed)
And then use this as your attribute for your input element:
onWithOptions "keydown" { defaultOptions | preventDefault = True } tabPressed
This isn't ideal for all situations. If you want some keydown events to not preventDefault(), and other keydown events to preventDefault(), then you're out of luck.

Selecting popup without title and clicking button inside it with geb

I have a popup without title and I want to detect the window using any other criteria (for example a div that wraps the whole popup) and click a button inside it.
I've tried the following:
when:
withWindow({ $("div", class:"main.msgAlert" )}) {
$('#close').click()
}
then: true
But I always get a org.openqa.selenium.ElementNotVisibleException at te #close action.
Am I failing at detecting the window or is the error related to the button?

Sweetalert confirm button breaks input fields

I have a strange bug when I use an input field on a sweet alert I can't have the cursor inside my input field here is a jsfiddle.
https://jsfiddle.net/gvzwu5st/
If I include
showConfirmButton: false
Then it works fine here is the fiddle
https://jsfiddle.net/16L4sddt/
When you have showConfirmButton: true, the openModal() function (line 653) gives focus to the confirm button (line 662):
$okButton.focus();
When you try to click in the input field, the handleOnBlur() function (line 396) is called because the confirm button loses the focus. The functions defines the $targetElement variable which refers to the confirm button (line 397). Skipping some lines... the function will loop through each button of the modal to check if it is the element that got the focus. In your case, the target element is the input field, so it is not any of the buttons. The variable btnIndex keeps the value -1. Lines 413-416:
if (btnIndex === -1) {
// Something in the dom, but not a visible button. Focus back on the button.
$targetElement.focus();
}
So the confirm button ($targetElement) is given back the focus, which prevents the input field from ever receiving it.

Cancel WinJS.UI.Animation.pointerDown if not clicked

I'm using WinJS.UI.Animation.pointerDown and WinJS.UI.Animation.pointerUp within a WinJS repeater's item template.
The problem is if a user holds their finger or the mouse button down on an item and moves off it, the pointerUp animation doesn't seem to fire or it fires but has no effect because the element that the up event is on is not the same as the one before. The best example of this is in the animation sample in example 6 (tap and click). Hold down the mouse button on a tile and move it off. It will stay in it's animated state and won't fire the pointerup event. Here's the code I'm using.
How can I cancel the pointerdown animation if the user moves off the element?
target1.addEventListener("pointerdown", function () {
WinJS.UI.Animation.pointerDown(this);
}, false);
target1.addEventListener("pointerup", function () {
WinJS.UI.Animation.pointerUp(this);
}, false);
target1.addEventListener("click", function () {
//do something spectacular
}, false);
I'm using the click event to commit the click action so that the right click remains clear for launching the navigation at the top of the app.
Have you tried adding an event listener for pointerout? That's the event that's dispatched when a pointing device (e.g. mouse cursor or finger) is moved out of the hit test boundaries of an element.
See the docs on pointer events here:
http://msdn.microsoft.com/en-us/library/ie/hh772103(v=vs.85).aspx