Content-Length: 363168 | pFad | http://github.com/purescript-halogen/purescript-halogen/issues/822

2B open and showModal are missing for dialog · Issue #822 · purescript-halogen/purescript-halogen · GitHub
Skip to content

open and showModal are missing for dialog #822

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jquesada2016 opened this issue Oct 29, 2023 · 15 comments
Open

open and showModal are missing for dialog #822

jquesada2016 opened this issue Oct 29, 2023 · 15 comments

Comments

@jquesada2016
Copy link

I saw that diallog had an open row in it's attribute row type. However, I don't see any functions to create the open attribute for the dialog element.

Also, showModal would be a great addition, although it is neither a property nor an attribute, as per the spec, but it might not be a bad idea to add it as a helper prop where the VDom can call .showModal() and .close() on the element as the prop is added/removed.

@flip111
Copy link

flip111 commented Jan 17, 2024

@jquesada2016 can you point to the relevant documentation?

@jquesada2016
Copy link
Author

Is this good enough?

@garyb
Copy link
Member

garyb commented Jan 22, 2024

I agree that being able to control this via property would be much more pleasant to deal with, I think it'll need special support in Prop in halogen-vdom most likely. I don't think we'd need a separate showDialog though, it could use the open property for that.

@jquesada2016
Copy link
Author

I believe we would definitely need a showModal property, because open and showModal have very different behaviors. open shows the modal, but does not render, by default, an overlay, and elements underneath the modal are still interactive. Whereas showModal opens the dialog in modal mode, showing an overlay by default, and prevents elements under the dialog from being interacted with.

@garyb
Copy link
Member

garyb commented Jan 22, 2024

Ah whoops, of course. What I meant then is I think open would also need special handling as I think you have to call show rather than just setting it.

@jquesada2016
Copy link
Author

Yes! Exactly right. Setting the open attribute only works when initially rendering the HTML in SSR. After the page has loaded, you need to call el.show() or el.showModal(), and el.close() to close it.

@Hi-Angel
Copy link

Hi-Angel commented Oct 6, 2024

Till it's implemented, can please someone tell how to call showModal manually? I mean, I know how to do FFI and I have a modal dialog per this:

  render :: ButtonState -> H.ComponentHTML ButtonAction () m
  render _ = HH.dialog [HP.style "padding: 0"]
                       [HH.form [HP.style "padding: 1rem", methodDialog]
                                [HH.button_ [HH.text "X"]]]
    where
      -- "dialog" value isn't implemented yet, there's a PR
      methodDialog = HH.attr (AttrName "method") "dialog"

but how do I combine this halogen-purescript element with the showModal from FFI? Is there a documentation on how to do something similar?

@Hi-Angel
Copy link

Hi-Angel commented Oct 7, 2024

Anyway, I couldn't find any way to integrate FFI into Halogen, so I presume the way you're supposed to work with that is by moving both component search and work on it to an FFI element as follows:

FFI.js:

"use strict";

// See: https://github.com/purescript-halogen/purescript-halogen/issues/822
export const showModal = function(query) {
    let n = document.querySelector(query);
    if (n) {
        n.showModal();
        return true;
    }
    return false;
};

FFI.purs:

module FFI where

import Effect (Effect)

foreign import showModal :: String -> Effect Boolean

And then adding a mymodal id in the component code and using #mymodal in either handleAction or handleQuery.

import FFI (showModal)

  render _ = HH.dialog [HP.style "padding: 0", HP.id "mymodal"]
  
  handleQuery (SetEnabled next) = do
    _ <- H.liftEffect $ showModal "#mymodal"
  

@flip111
Copy link

flip111 commented Oct 7, 2024

@Hi-Angel "officially" you are supposed to use refs. Here is a demo https://github.com/flip111/halogen-focus/blob/main/src/Main.purs#L58

@Hi-Angel
Copy link

Hi-Angel commented Oct 7, 2024

So, I tried adding it and looking at the generated index.js, but I can't see any way to combine a val <- H.getHTMLElementRef focusRef with some FFI's val.showModal().

Also, isn't it the same as what I'm doing by creating a HP.id "mymodal" and then finding it via document.querySelector()? I mean, since focusRef contains a name and not just a reference, it apparently does search by id, so there's not much difference compared to document.querySelector(), unless I'm missing something.

@Hi-Angel
Copy link

Hi-Angel commented Oct 7, 2024

Okay, so, answering both questions:

So, I tried adding it and looking at the generated index.js, but I can't see any way to combine a val <- H.getHTMLElementRef focusRef with some FFI's val.showModal().

The val is the element in this case, so I can create a function accepting val and calling showModal on it.

So my answer above becomes:

FFI.js:

"use strict";

// See: https://github.com/purescript-halogen/purescript-halogen/issues/822
export const showModal = function(elem) {
    elem.showModal();
};

FFI.purs:

module FFI where

import Prelude (Unit)
import Effect (Effect)
import Web.HTML.HTMLElement

foreign import showModal :: HTMLElement -> Effect Unit

and in the component code:

import FFI (showModal)

focusRef :: H.RefLabel
focusRef = H.RefLabel "mymodal"

  render _ = HH.dialog [HP.style "padding: 0", HP.ref focusRef]
  
  handleQuery (SetEnabled next) = do
    H.getHTMLElementRef focusRef >>= traverse_ \elem -> H.liftEffect $ showModal elem
  

Also, isn't it the same as what I'm doing by creating a HP.id "mymodal" and then finding it via document.querySelector()? I mean, since focusRef contains a name and not just a reference, it apparently does search by id, so there's not much difference compared to document.querySelector(), unless I'm missing something.

Right. Well, the only difference is that the check for whether search succeeded moves to inside PureScript, but other than that there's no difference.

@flip111
Copy link

flip111 commented Oct 7, 2024

So, I tried adding it and looking at the generated index.js, but I can't see any way to combine a val <- H.getHTMLElementRef focusRef with some FFI's val.showModal().

There are two separate issues here

  1. How to get the element. Only for this i pointed to my example. You can use ref instead of query selector with FFI.
  2. How to call show for modal. This has to be done through FFI until it is natively implemented in halogen.

You can make your FFI function something like foreign import showModal :: HTMLElement -> Effect Boolean then after val <- H.getHTMLElementRef focusRef you pass val to your FFI function.

it apparently does search by id

It's done by holding a reference to the value AFAIK not through attributes directly on the DOM level.

so there's not much difference compared to document.querySelector(), unless I'm missing something.

There isn't much difference in my opinion as well. Refs are supposed to give you more type safety and assurance that the element is there. Opposed to having a type in your css query selection or something removed the element from the dom and now things start to crash


I wrote all that before i read your second post, i see you figured it out :D

@acple
Copy link
Contributor

acple commented Oct 7, 2024

Seems to be some ffi definition mistakes?
for HTMLElement -> Effect Unit:

"use strict";

// See: https://github.com/purescript-halogen/purescript-halogen/issues/822
export const showModal = function(elem) {
    return function () {
        elem.showModal();
    };
};

@Hi-Angel
Copy link

Hi-Angel commented Oct 7, 2024

Oh, so that's why I was getting a weird Uncaught TypeError: eff is not a function error in the browser console. Barring this message the code was otherwise working fine. Thanks!

@garyb
Copy link
Member

garyb commented Oct 7, 2024

Using refs is indeed not really that much different than using DOM methods like querySelector or getElementById, aside from the fact it guarantees that you are 100% definitely getting the element that the ref property lives on. In theory you could be picking up an element outside of the component when using the DOM methods due multiple elements with the same ID, or a selector that isn't specific enough, etc.

There's also that getRef and getHTMLElementRef just operate in HalogenM without a MonadEffect constraint being imposed on the m, but that's mostly not very interesting since likely you'll need MonadEffect on m to do anything with the element anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/purescript-halogen/purescript-halogen/issues/822

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy