Get rid of Selection, simplifying the field API

Real reason is that setSelectionRange also sets the focus. This
behavior makes sense, so the underlying issue is that setting the
selection for two fields is not meaningful because only one can have
focus.

How to set focus (for fields or inputs in general) is not really
answered yet, so I think it makes the most sense to leave it out for
now.
This commit is contained in:
Evan Czaplicki 2014-03-03 00:08:58 -10:00
parent 0dcee3ec46
commit 8e2c6989b4
2 changed files with 10 additions and 96 deletions

View file

@ -6,9 +6,6 @@ approach as the [`Graphics.Input`](Graphics-Input) module for describing an
# Create Fields
@docs field, password, email
# Field Content
@docs Content, Selection, Direction, noContent
# Field Style
@docs Style, Outline, noOutline, Highlight, noHighlight, Dimensions, uniformly
-}
@ -75,56 +72,29 @@ defaultStyle =
, style = Text.defaultStyle
}
{-| Represents the current content of a text field. For example:
Content "She sells sea shells" (Selection 0 3 Backward)
This means the user highlighted the substring `"She"` backwards.
-}
type Content = { string:String, selection:Selection }
{-| The selection within a text field. `start` is never greater than `end`:
Selection 0 0 Forward -- cursor precedes all characters
Selection 5 9 Backward -- highlighting characters starting after
-- the 5th and ending after the 9th
-}
type Selection = { start:Int, end:Int, direction:Direction }
{-| The direction of selection.-}
data Direction = Forward | Backward
{-| A field with no content:
Content "" (Selection 0 0 Forward)
-}
noContent : Content
noContent = Content "" (Selection 0 0 Forward)
{-| Create a text field. The following example creates a time-varying element
called `nameField`. As the user types their name, the field will be updated
to match what they have entered.
name : Input Content
name = input noContent
name : Input String
name = input ""
nameField : Signal Element
nameField = field name.handle id defaultStyle "Name" <~ name.signal
-}
field : Handle a -> (Content -> a) -> Style -> String -> Content -> Element
field : Handle a -> (String -> a) -> Style -> String -> String -> Element
field = Native.Graphics.Input.field
{-| Same as `field` but the UI element blocks out each characters. -}
password : Handle a -> (Content -> a) -> Style -> String -> Content -> Element
password : Handle a -> (String -> a) -> Style -> String -> String -> Element
password = Native.Graphics.Input.password
{-| Same as `field` but it adds an annotation that this field is for email
addresses. This is helpful for auto-complete and for mobile users who may
get a custom keyboard with an `@` and `.com` button.
-}
email : Handle a -> (Content -> a) -> Style -> String -> Content -> Element
email : Handle a -> (String -> a) -> Style -> String -> String -> Element
email = Native.Graphics.Input.email
-- area : Handle a -> (Content -> a) -> Handle b -> ((Int,Int) -> b) -> (Int,Int) -> String -> Content -> Element
-- area : Handle a -> (String -> a) -> Handle b -> ((Int,Int) -> b) -> (Int,Int) -> String -> String -> Element
-- area = Native.Graphics.Input.area

View file

@ -209,14 +209,6 @@ Elm.Native.Graphics.Input.make = function(elm) {
});
}
function setRange(node, start, end, dir) {
if (node.parentNode) {
node.setSelectionRange(start, end, dir);
} else {
setTimeout(function(){node.setSelectionRange(start, end, dir);}, 0);
}
}
function updateIfNeeded(css, attribute, latestAttribute) {
if (css[attribute] !== latestAttribute) {
css[attribute] = latestAttribute;
@ -267,10 +259,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
field.type = model.type;
field.placeholder = JS.fromString(model.placeHolder);
field.value = JS.fromString(model.content.string);
var selection = model.content.selection;
var direction = selection.direction.ctor === 'Forward' ? 'forward' : 'backward';
setRange(field, selection.start, selection.end, direction);
field.value = JS.fromString(model.content);
field.elm_signal = model.signal;
field.elm_handler = model.handler;
@ -282,15 +271,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
String.fromCharCode(event.keyCode) +
curr.slice(field.selectionEnd));
var pos = field.selectionEnd + 1;
elm.notify(field.elm_signal.id, field.elm_handler({
_:{},
string: JS.toString(next),
selection: {
start: pos,
end: pos,
direction: { ctor:'Forward' }
},
}));
elm.notify(field.elm_signal.id, field.elm_handler(JS.toString(next)));
event.preventDefault();
}
@ -300,46 +281,12 @@ Elm.Native.Graphics.Input.make = function(elm) {
if (curr === next) {
return;
}
var direction = field.selectionDirection === 'forward' ? 'Forward' : 'Backward';
var start = field.selectionStart;
var end = field.selectionEnd;
field.value = field.elm_old_value;
elm.notify(field.elm_signal.id, field.elm_handler({
_:{},
string: JS.toString(next),
selection: {
start: start,
end: end,
direction: { ctor: direction }
},
}));
elm.notify(field.elm_signal.id, field.elm_handler(JS.toString(next)));
}
function mouseUpdate(event) {
var direction = field.selectionDirection === 'forward' ? 'Forward' : 'Backward';
elm.notify(field.elm_signal.id, field.elm_handler({
_:{},
string: field.value,
selection: {
start: field.selectionStart,
end: field.selectionEnd,
direction: { ctor: direction }
},
}));
}
function mousedown(event) {
mouseUpdate(event);
elm.node.addEventListener('mouseup', mouseup);
}
function mouseup(event) {
mouseUpdate(event);
elm.node.removeEventListener('mouseup', mouseup)
}
field.addEventListener('keypress', keyUpdate);
field.addEventListener('input', inputUpdate);
field.addEventListener('mousedown', mousedown);
return field;
}
@ -353,12 +300,9 @@ Elm.Native.Graphics.Input.make = function(elm) {
field.type = newModel.type;
field.placeholder = JS.fromString(newModel.placeHolder);
var value = JS.fromString(newModel.content.string);
var value = JS.fromString(newModel.content);
field.value = value;
field.elm_old_value = value;
var selection = newModel.content.selection;
var direction = selection.direction.ctor === 'Forward' ? 'forward' : 'backward';
setRange(field, selection.start, selection.end, direction);
}
function mkField(type) {