{-# language OverloadedStrings #-} {-# language QuasiQuotes #-} module FlexTask.Processing.JavaScript ( setDefaultsJS, triggerDefaults, lockForm, ) where import Data.Text (Text) import Text.Julius (JavascriptUrl, julius, rawJS) import qualified Data.Text as T import FlexTask.Processing.Text (formatForJS) setDefaultsJS :: [Text] -> JavascriptUrl url setDefaultsJS :: forall url. [Text] -> JavascriptUrl url setDefaultsJS [Text] names = [julius| function setDefaults(values) { fieldNames.forEach((fieldName, i) => { const input = values[i]; const fields = Array.from(document.getElementsByName(fieldName)); // How to handle each field type const handlers = { radio: field => { field.checked = field.value == input; }, select: field => { Array.from(field.options).forEach(option => { option.selected = input.includes(option.value); }); }, checkbox: field => { field.checked = input.includes(field.value); }, default: (field, j) => { const inputElem = fields.length > 1 ? JSON.parse(input)[j] : input; if (inputElem !== "Missing" && inputElem !== "None") { field.value = inputElem; } } }; // Pick a fitting handler based on field attributes const getHandler = field => { const type = field.getAttribute("type")?.toLowerCase(); const tag = field.tagName.toLowerCase(); if (type === "radio") return "radio"; if (tag === "select") return "select"; if (type === "checkbox") return "checkbox"; if (type === "hidden") return null; // Skip hidden fields return "default"; }; fields.forEach((field, j) => { const key = getHandler(field); if (key && handlers[key]) { handlers[key](field, j); } }); }); } var fieldNames = #{rawJS (show names)};|] triggerDefaults :: Text -> JavascriptUrl url triggerDefaults :: forall url. Text -> JavascriptUrl url triggerDefaults Text t | Text t Text -> Text -> Bool forall a. Eq a => a -> a -> Bool == Text "[ ]" Bool -> Bool -> Bool || Text -> Int T.length Text t Int -> Int -> Bool forall a. Ord a => a -> a -> Bool < Int 2 = JavascriptUrl url forall a. Monoid a => a mempty | Bool otherwise = [julius|window.onload = setDefaults(#{rawJS (formatForJS t)});|] lockForm :: Bool -> JavascriptUrl url lockForm :: forall url. Bool -> JavascriptUrl url lockForm Bool lock | Bool lock = [julius|window.onload = function () { fieldNames.forEach(name => { Array.from(document.getElementsByName(name)) .forEach(elem => { if (elem.getAttribute("type")?.toLowerCase()=== "radio" || elem.tagName.toLowerCase === "select"){ elem.disabled = true; } else { elem.readOnly = true; } }); }); };|] | Bool otherwise = JavascriptUrl url forall a. Monoid a => a mempty