forked from IntersectMBO/plutus
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SCP-2409 - Apply format info to simulator (IntersectMBO#3436)
* Add choice formatting to simulator inputs * Replace rest of number inputs in simulator with currency input * Move currency formatter to Pretty.purs * Add currency formatter for choices in simulator * Address reviews * Remove spurious import
- Loading branch information
Showing
5 changed files
with
222 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
|
||
exports.setOldValues_ = function(input) { | ||
input.old_value = input.value; | ||
input.old_selectionStart = input.selectionStart; | ||
input.old_selectionEnd = input.selectionEnd; | ||
} | ||
|
||
exports.checkChange_ = function(input) { | ||
if (/^-?[0-9]*(\.[0-9]*)?$/.test(input.value)) { | ||
exports.setOldValues_(input); | ||
} else { | ||
input.value = input.old_value; | ||
input.selectionStart = input.old_selectionStart; | ||
input.selectionEnd = input.old_selectionEnd; | ||
} | ||
} | ||
|
||
exports.formatValueString_ = function(text, decimalPlaces) { | ||
var positionSeparator = text.indexOf("."); | ||
if (positionSeparator < 0) { | ||
if (decimalPlaces > 0) { | ||
text += '.'; | ||
text = text.padEnd(text.length + decimalPlaces, '0'); | ||
} | ||
} else { | ||
text = text.substring(0, positionSeparator + decimalPlaces + 1); | ||
text = text.padEnd(positionSeparator + decimalPlaces + 1, '0'); | ||
} | ||
if (text == '') { | ||
text = '0'; | ||
} else if (text[0] == '.') { | ||
text = '0' + text; | ||
} else if ((text == '-') || ((text[0] == '-') && (text[1] == '.'))) { | ||
text = '-0' + text.substring(1); | ||
} | ||
return text; | ||
} | ||
|
||
exports.formatValue_ = function(input, decimalPlaces) { | ||
input.value = exports.formatValueString_(input.value, decimalPlaces); | ||
} | ||
|
||
exports.setValue_ = function(input, str) { | ||
input.value = str; | ||
} | ||
|
||
exports.onChangeHandler_ = function(input, decimalPlaces) { | ||
exports.checkChange_(input); | ||
exports.formatValue_(input, decimalPlaces); | ||
return input.value; | ||
} |
115 changes: 115 additions & 0 deletions
115
marlowe-playground-client/src/Halogen/CurrencyInput.purs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
module Halogen.CurrencyInput where | ||
|
||
import Prelude hiding (div) | ||
import Data.Array (filter) | ||
import Data.BigInteger (BigInteger, fromString) | ||
import Data.Maybe (Maybe(..), maybe) | ||
import Data.Monoid (guard) | ||
import Data.String (trim) | ||
import Data.String.CodeUnits (fromCharArray, toCharArray) | ||
import Data.Traversable (for) | ||
import Effect (Effect) | ||
import Effect.Uncurried (EffectFn1, EffectFn2, runEffectFn1, runEffectFn2) | ||
import Effect.Unsafe (unsafePerformEffect) | ||
import Halogen.Css (classNames) | ||
import Halogen.HTML (HTML, div, input, text) | ||
import Halogen.HTML.Events (onChange, onFocus, onInput, onKeyDown) | ||
import Halogen.HTML.Properties (InputType(..), type_, value) | ||
import Pretty (showBigIntegerAsCurrency) | ||
import Web.Event.Event (currentTarget) | ||
import Web.Event.Internal.Types (EventTarget) | ||
import Web.UIEvent.FocusEvent as FocusEvent | ||
import Web.UIEvent.KeyboardEvent as KeyboardEvent | ||
|
||
foreign import setOldValues_ :: EffectFn1 EventTarget Unit | ||
|
||
foreign import checkChange_ :: EffectFn1 EventTarget Unit | ||
|
||
foreign import formatValue_ :: EffectFn2 EventTarget Int Unit | ||
|
||
foreign import formatValueString_ :: EffectFn2 String Int String | ||
|
||
foreign import setValue_ :: EffectFn2 EventTarget String Unit | ||
|
||
foreign import onChangeHandler_ :: EffectFn2 EventTarget Int String | ||
|
||
setOldValues :: EventTarget -> Effect Unit | ||
setOldValues = runEffectFn1 setOldValues_ | ||
|
||
checkChange :: EventTarget -> Effect Unit | ||
checkChange = runEffectFn1 checkChange_ | ||
|
||
setValue :: EventTarget -> String -> Effect Unit | ||
setValue = runEffectFn2 setValue_ | ||
|
||
onChangeHandler :: EventTarget -> Int -> Effect String | ||
onChangeHandler = runEffectFn2 onChangeHandler_ | ||
|
||
currencyInput :: forall p a. Array String -> BigInteger -> String -> Int -> (Maybe BigInteger -> Maybe a) -> HTML p a | ||
currencyInput classList number prefix rawNumDecimals onValueChangeHandler = | ||
div [ classNames ([ "bg-gray-light", "flex", "items-center", "border-solid", "border", "rounded-sm", "overflow-hidden", "box-border", "focus-within:ring-1", "focus-within:ring-black" ] <> classList) ] | ||
( ( guard hasPrefix | ||
[ div [ classNames [ "flex-none", "px-2", "py-0", "box-border", "self-center" ] ] | ||
[ text prefix ] | ||
] | ||
) | ||
<> [ input | ||
[ classNames [ "flex-1", "px-1", "box-border", "self-stretch", "border-0", "outline-none" ] | ||
, onFocus | ||
( \ev -> | ||
maybe Nothing | ||
( \target -> | ||
unsafePerformEffect | ||
$ do | ||
setOldValues target | ||
pure Nothing | ||
) | ||
(currentTarget (FocusEvent.toEvent ev)) | ||
) | ||
, onKeyDown | ||
( \ev -> | ||
maybe Nothing | ||
( \target -> | ||
unsafePerformEffect | ||
$ do | ||
setOldValues target | ||
pure Nothing | ||
) | ||
(currentTarget (KeyboardEvent.toEvent ev)) | ||
) | ||
, onChange | ||
( \ev -> | ||
maybe Nothing | ||
( \target -> | ||
unsafePerformEffect | ||
$ do | ||
res <- onChangeHandler target numDecimals | ||
let | ||
mObtainedBigNumStr = fromString $ filterPoint res | ||
void $ for mObtainedBigNumStr (\x -> setValue target $ showBigIntegerAsCurrency x numDecimals) | ||
pure $ onValueChangeHandler $ mObtainedBigNumStr | ||
) | ||
(currentTarget ev) | ||
) | ||
, onInput | ||
( \ev -> | ||
maybe Nothing | ||
( \target -> | ||
unsafePerformEffect | ||
$ do | ||
checkChange target | ||
pure Nothing | ||
) | ||
(currentTarget ev) | ||
) | ||
, type_ InputText | ||
, value (showBigIntegerAsCurrency number numDecimals) | ||
] | ||
] | ||
) | ||
where | ||
numDecimals = max 0 rawNumDecimals | ||
|
||
hasPrefix = trim prefix /= "" | ||
|
||
filterPoint = fromCharArray <<< filter (\x -> x /= '.') <<< toCharArray |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters