on master help sign in
Add implementation for checkboxes, passwords, and emails.
475bc10evancz
libraries/Graphics/Input.elm+9−2
@@ -37,12 +37,19 @@ type TextState = {
37textFields : a -> { field : (TextState -> a) -> String -> TextState -> Element,
37textFields : a -> { field : (TextState -> a) -> String -> TextState -> Element,
38 events : Signal a }
38 events : Signal a }
39
39
40−textField : String -> TextState -> (Signal Element, Signal TextState)
40+text : String -> TextState -> (Signal Element, Signal TextState)
41−textField placeHolder textState =
41+text placeHolder textState =
42 let tfs = N.textFields textState
42 let tfs = N.textFields textState
43 in (lift (tfs.field id placeHolder) tfs.events, tfs.events)
43 in (lift (tfs.field id placeHolder) tfs.events, tfs.events)
44
44
45password : String -> TextState -> (Signal Element, Signal TextState)
45password : String -> TextState -> (Signal Element, Signal TextState)
46+password placeHolder textState =
47+ let tfs = N.passwords textState
48+ in (lift (tfs.field id placeHolder) tfs.events, tfs.events)
49+
46email : String -> TextState -> (Signal Element, Signal TextState)
50email : String -> TextState -> (Signal Element, Signal TextState)
51+email placeHolder textState =
52+ let tfs = N.emails textState
53+ in (lift (tfs.field id placeHolder) tfs.events, tfs.events)
47
54
48-- file?
55-- file?
libraries/Native/Graphics/Input.js+60−14
@@ -107,27 +107,66 @@ Elm.Native.Graphics.Input = function(elm) {
107 return { _:{}, button:F4(button), events:events };
107 return { _:{}, button:F4(button), events:events };
108 }
108 }
109
109
110+
111+ function checkBoxes(defaultValue) {
112+ var events = Signal.constant(defaultValue);
113+
114+ function render(model) {
115+ var b = newNode('input');
116+ b.type = 'checkbox';
117+ b.checked = model.checked;
118+ b.style.display = 'block';
119+ b.elmHandler = model.handler;
120+ function change() { elm.notify(events.id, b.elmHandler(b.checked)); }
121+ b.addEventListener('change', change);
122+ return b;
123+ }
124+
125+ function update(node, oldModel, newModel) {
126+ node.elmHandler = newModel.handler;
127+ node.checked = newModel.checked;
128+ return true;
129+ }
130+
131+ function box(handler, checked) {
132+ return A3(newElement, 13, 13, {
133+ ctor: 'Custom',
134+ type: 'CheckBox',
135+ render: render,
136+ update: update,
137+ model: { checked:checked, handler:handler }
138+ });
139+ }
140+
141+ return { _:{}, box:F2(box), events:events };
142+ }
143+
110− function textFields(defaultValue) {
144+ function mkTextPool(type) { return function textFields(defaultValue) {
111 var events = Signal.constant(defaultValue);
145 var events = Signal.constant(defaultValue);
112
146
113 function render(model) {
147 function render(model) {
114 var field = newNode('input');
148 var field = newNode('input');
115 field.elmHandler = model.handler;
149 field.elmHandler = model.handler;
116
150
117− field.id = 'test'
151+ field.id = 'test';
152+ field.type = type;
118 field.placeholder = fromString(model.placeHolder);
153 field.placeholder = fromString(model.placeHolder);
119− field.elmValue = fromString(model.state.input);
154+ field.value = fromString(model.state.input);
120− field.value = field.elmValue;
121 field.setSelectionRange(model.state.start, model.state.end);
155 field.setSelectionRange(model.state.start, model.state.end);
122 field.style.border = 'none';
156 field.style.border = 'none';
123
157
124 function update() {
158 function update() {
159+ var start = field.selectionStart,
160+ end = field.selectionEnd;
161+ if (field.selectionDirection === 'backward') {
162+ start = end;
163+ end = field.selectionStart;
164+ }
125 var state = { _:{},
165 var state = { _:{},
126 input:toString(field.value),
166 input:toString(field.value),
127− start:field.selectionStart,
167+ start:start,
128− end:field.selectionEnd };
168+ end:end };
129− field.value = field.elmValue;
130− elm.notify(events.id, state);
169+ elm.notify(events.id, field.elmHandler(state));
131 }
170 }
132 function mousedown() {
171 function mousedown() {
133 update();
172 update();
@@ -144,16 +183,20 @@ Elm.Native.Graphics.Input = function(elm) {
144 }
183 }
145
184
146 function update(node, oldModel, newModel) {
185 function update(node, oldModel, newModel) {
147− node.elmEvent = newModel.handler;
186+ node.elmHandler = newModel.handler;
148− node.elmValue = fromString(newModel.state.input);
187+ node.value = fromString(newModel.state.input);
149− node.value = node.elmValue;
188+ if (newModel.state.start <= newModel.state.end) {
150− node.setSelectionRange(newModel.state.start, newModel.state.end);
189+ node.setSelectionRange(newModel.state.start, newModel.state.end);
190+ } else {
191+ node.setSelectionRange(newModel.state.end,
192+ newModel.state.start, 'backward');
193+ }
151 }
194 }
152
195
153 function field(handler, placeHolder, state) {
196 function field(handler, placeHolder, state) {
154 return A3(newElement, 200, 30,
197 return A3(newElement, 200, 30,
155 { ctor: 'Custom',
198 { ctor: 'Custom',
156− type: 'TextField',
199+ type: type + 'Input',
157 render: render,
200 render: render,
158 update: update,
201 update: update,
159 model: { handler:handler,
202 model: { handler:handler,
@@ -163,12 +206,15 @@ Elm.Native.Graphics.Input = function(elm) {
163 }
206 }
164
207
165 return { _:{}, field:F3(field), events:events };
208 return { _:{}, field:F3(field), events:events };
209+ }
166 }
210 }
167
211
168 return elm.Native.Graphics.Input = {
212 return elm.Native.Graphics.Input = {
169 buttons:buttons,
213 buttons:buttons,
170 customButtons:customButtons,
214 customButtons:customButtons,
171− textFields:textFields
215+ textFields:mkTextPool('text'),
216+ emails:mkTextPool('email'),
217+ passwords:mkTextPool('password')
172 };
218 };
173
219
174};
220};