on develop help sign in
selectElement implementation
commit0f43aa7bea0344c80fb7938bd11c7467f4e9f31c authorTom Smalley <tfsmalley@gmail.com> dateTue 4 Dec 2018, 20:01 (8 years ago) parent815674a
1 file changed+50−21
reflex-dom-core/src/Reflex/Dom/Builder/Hydration.hs+50−21
reflex-dom-core/src/Reflex/Dom/Builder/Hydration.hs+50−21
@@ -768,31 +768,60 @@ instance (SupportsHydrationDomBuilder t m) => DomBuilder t (HydrationDomBuilderT
768768
769769 {-# INLINABLE selectElement #-}
770770 selectElement cfg child = do
771− ((e, result), _domElement') <- makeElement "select" (cfg ^. selectElementConfig_elementConfig) child
772− let domElement = undefined :: DOM.HTMLSelectElement
773− let domSelectElement = uncheckedCastTo DOM.HTMLSelectElement domElement
774− Select.setValue domSelectElement $ cfg ^. selectElementConfig_initialValue
775− v0 <- Select.getValue domSelectElement
776− let getMyValue = Select.getValue domSelectElement
777− valueChangedByUI <- requestDomAction $ liftJSM getMyValue <$ Reflex.select (_element_events e) (WrapArg Change)
778− valueChangedBySetValue <- case _selectElementConfig_setValue cfg of
779− Nothing -> return never
780− Just eSetValue -> requestDomAction $ ffor eSetValue $ \v' -> do
781− Select.setValue domSelectElement v'
782− getMyValue -- We get the value after setting it in case the browser has mucked with it somehow
771+ ((e, result), domElementRef) <- makeElement "select" (cfg ^. selectElementConfig_elementConfig) child
772+
773+ (valueChangedByUI, triggerChangeByUI) <- newTriggerEvent
774+ (valueChangedBySetValue, triggerChangeBySetValue) <- newTriggerEvent
775+
776+ (focusChange, triggerFocusChange) <- newTriggerEvent
777+
778+ doc <- askDocument
779+
780+ -- Expected initial value from config
781+ let v0 = _selectElementConfig_initialValue cfg
782+
783+ addHydrationStep $ do
784+ domElement <- liftIO $ readIORef domElementRef
785+ let domSelectElement = uncheckedCastTo DOM.HTMLSelectElement domElement
786+ getValue = Select.getValue domSelectElement
787+
788+ -- The browser might have messed with the value, or the user could have
789+ -- altered it before activation, so we set it if it isn't what we expect
790+ liftJSM getValue >>= \v0' -> do
791+ when (v0' /= v0) $ liftIO $ triggerChangeByUI v0'
792+
793+ -- Watch for user interaction and trigger event accordingly
794+ requestDomAction_ $ (liftJSM getValue >>= liftIO . triggerChangeByUI) <$ Reflex.select (_element_events e) (WrapArg Change)
795+
796+ for_ (_selectElementConfig_setValue cfg) $ \eSetValue ->
797+ requestDomAction_ $ ffor eSetValue $ \v' -> do
798+ Select.setValue domSelectElement v'
799+ v <- getValue -- We get the value after setting it in case the browser has mucked with it somehow
800+ liftIO $ triggerChangeBySetValue v
801+
802+ let focusChange' = leftmost
803+ [ False <$ Reflex.select (_element_events e) (WrapArg Blur)
804+ , True <$ Reflex.select (_element_events e) (WrapArg Focus)
805+ ]
806+ liftIO . triggerFocusChange =<< Node.isSameNode (toNode domElement) . fmap toNode =<< Document.getActiveElement doc
807+ requestDomAction_ $ liftIO . triggerFocusChange <$> focusChange'
808+
809+ let initialFocus = False -- Assume it isn't focused, but we update the actual focus state at switchover
810+ hasFocus <- holdUniqDyn =<< holdDyn initialFocus focusChange
811+
783812 v <- holdDyn v0 $ leftmost
784813 [ valueChangedBySetValue
785814 , valueChangedByUI
786815 ]
787− hasFocus <- mkHasFocus e
788− let wrapped = SelectElement
789− { _selectElement_value = v
790− , _selectElement_change = valueChangedByUI
791− , _selectElement_hasFocus = hasFocus
792− , _selectElement_element = e
793− , _selectElement_raw = domSelectElement
794− }
795− return (wrapped, result)
816+
817+ return $ flip (,) result $ SelectElement
818+ { _selectElement_value = v
819+ , _selectElement_change = valueChangedByUI
820+ , _selectElement_hasFocus = hasFocus
821+ , _selectElement_element = e
822+ , _selectElement_raw = undefined -- TODO domSelectElement
823+ }
824+
796825 placeRawElement _ = return () -- append . toNode
797826 wrapRawElement e _ = return $ Element (EventSelector $ const never) e -- TODO
798827