diff options
Diffstat (limited to 'src/view/form.ts')
-rw-r--r-- | src/view/form.ts | 149 |
1 files changed, 102 insertions, 47 deletions
diff --git a/src/view/form.ts b/src/view/form.ts index 77a8cb7..5547e0c 100644 --- a/src/view/form.ts +++ b/src/view/form.ts @@ -1,66 +1,121 @@ -import h, { classNames } from 'lib/h' -import * as dom from 'lib/dom' -import * as play from 'view/play' -import * as layout from 'view/layout' -import * as chord from 'chord' -import * as options from 'view/options' +import { h, withVar, Html, Rx } from 'lib/rx' +import * as Options from 'view/options' -// View - -export function view(): Element[] { - let opts = options.load() +interface Params { + options: Options.Model + onSubmit: (options: Options.Model) => void +} - return layout.view( +export function view({ options, onSubmit }: Params): Html { + return withVar(options, (opts, updateOptions) => h('form', - { - className: 'g-Form', - onsubmit + { className: 'g-Form', + onsubmit: opts.map(o => + (event: Event) => { + event.preventDefault() + onSubmit(o) + } + ) }, - chordCheckbox({ name: 'major', label: '', checked: opts.major }), - chordCheckbox({ name: 'minor', label: '-', checked: opts.minor }), - chordCheckbox({ name: 'seventh', label: '7', checked: opts.seventh }), - chordCheckbox({ name: 'minorSeventh', label: '-7', checked: opts.minorSeventh }), - chordCheckbox({ name: 'majorSeventh', label: '7', checked: opts.majorSeventh }), - labelInput({ type: 'number', name: 'bpm', label: 'BPM', value: opts.bpm.toString() }), - labelInput({ type: 'number', name: 'beatsPerChord', label: 'Beats per Chord', value: opts.beatsPerChord.toString() }), + chordCheckbox({ + label: '', + checked: opts.map(o => o.major), + onCheck: (checked => updateOptions(o => { + o.major = checked + return o + })) + }), + chordCheckbox({ + label: '-', + checked: opts.map(o => o.minor), + onCheck: (checked => updateOptions(o => { + o.minor = checked + return o + })) + }), + chordCheckbox({ + label: '7', + checked: opts.map(o => o.seventh), + onCheck: (checked => updateOptions(o => { + o.seventh = checked + return o + })) + }), + chordCheckbox({ + label: '-7', + checked: opts.map(o => o.minorSeventh), + onCheck: (checked => updateOptions(o => { + o.minorSeventh = checked + return o + })) + }), + chordCheckbox({ + label: '7', + checked: opts.map(o => o.majorSeventh), + onCheck: (checked => updateOptions(o => { + o.majorSeventh = checked + return o + })) + }), + numberInput({ + label: 'BPM', + value: opts.map(o => o.bpm.toString()), + onChange: (n => updateOptions(o => { + o.bpm = n + return o + })) + }), + numberInput({ + label: 'Beats per Chord', + value: opts.map(o => o.beatsPerChord.toString()), + onChange: (n => updateOptions(o => { + o.beatsPerChord = n + return o + })) + }), h('input', { type: 'submit', value: 'Play' }) ) ) } -function chordCheckbox({ name, label, checked }: any): Element { - return labelInput({ className: 'g-ChordLabel', type: 'checkbox', name, label, checked }) +interface ChordCheckboxParams { + label: string + checked: Rx<boolean> + onCheck: (checked: boolean) => void } -function onsubmit(event: Event): void { - event.preventDefault() - let input = (name: String) => document.querySelector(`input[name="${name}"]`) as HTMLInputElement - let opts = { - major: input('major').checked, - minor: input('minor').checked, - seventh: input('seventh').checked, - minorSeventh: input('minorSeventh').checked, - majorSeventh: input('majorSeventh').checked, - bpm: parseInt(input('bpm').value), - beatsPerChord: parseInt(input('beatsPerChord').value) - } - options.save(opts) - dom.show(play.view(opts)) +function chordCheckbox({ label, checked, onCheck }: ChordCheckboxParams): Html { + return h('label', + { className: 'g-ChordLabel' }, + h('input', + { type: 'checkbox', + checked, + onchange: (event: Event) => onCheck((event.target as HTMLInputElement).checked) + } + ), + label + ) } -type LabelInputParams = { - className?: string, - type: string, - name: string, - label: string, - checked?: boolean, - value?: string +interface NumberInputParams { + label: string + value: Rx<string> + onChange: (n: number) => void } -function labelInput({ className, type, name, label, checked, value }: LabelInputParams) { +function numberInput({ label, value, onChange }: NumberInputParams): Html { return h('label', - className !== undefined ? { className } : {}, - h('input', { type, name, checked, value }), + h('input', + { type: 'number', + value, + onchange: (event: Event) => { + const n = parseInt((event.target as HTMLInputElement).value) + if (typeof n === 'number') { + onChange(n) + } + } + } + ), label ) } |