{-# 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) { const handlers = { radio: (field, value) => { field.checked = field.value == value; }, select: (field, value) => { Array.from(field.options).forEach(opt => { if (Array.isArray(value)) { opt.selected = value.includes(opt.value); } else { opt.selected = (opt.value === value); } }); }, checkbox: (field, value) => { if (Array.isArray(value)) { field.checked = value.includes(field.value); } else { field.checked = (field.value == value); } }, default: (field, value) => { if (value !== "Missing" && value !== "None") { field.value = value; } } }; const getHandler = field => { const t = field.getAttribute("type")?.toLowerCase(); const tag = field.tagName.toLowerCase(); if (t === "radio") return "radio"; if (tag === "select") return "select"; if (t === "checkbox") return "checkbox"; if (t === "hidden") return null; // skip hidden return "default"; }; fieldNames.forEach((names, i) => { const raw = values[i]; if (names.length > 1) { names.forEach((name, j) => { let val = Array.isArray(raw) ? raw[j] : JSON.parse(raw)[j]; document.getElementsByName(name).forEach(field => { const key = getHandler(field); if (key) handlers[key](field, val); }); }); } else { const name = names[0]; const fields = Array.from(document.getElementsByName(name)); const isList = Array.isArray(raw) || /^[\[\{]/.test(raw); fields.forEach((field, j) => { let val; const key = getHandler(field); if (isList) { const arr = Array.isArray(raw) ? raw : JSON.parse(raw); if (key === "checkbox" || key === "select") { val = arr; } else { val = arr[j]; } } else { val = raw; } if (key) handlers[key](field, val); }); } }); } 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.getAttribute("type")?.toLowerCase() === "checkbox" || elem.tagName.toLowerCase() === "select"){ elem.disabled = true; } else { elem.readOnly = true; } }); }); };|] | Bool otherwise = JavascriptUrl url forall a. Monoid a => a mempty