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:
parent
0dcee3ec46
commit
8e2c6989b4
2 changed files with 10 additions and 96 deletions
|
@ -6,9 +6,6 @@ approach as the [`Graphics.Input`](Graphics-Input) module for describing an
|
||||||
# Create Fields
|
# Create Fields
|
||||||
@docs field, password, email
|
@docs field, password, email
|
||||||
|
|
||||||
# Field Content
|
|
||||||
@docs Content, Selection, Direction, noContent
|
|
||||||
|
|
||||||
# Field Style
|
# Field Style
|
||||||
@docs Style, Outline, noOutline, Highlight, noHighlight, Dimensions, uniformly
|
@docs Style, Outline, noOutline, Highlight, noHighlight, Dimensions, uniformly
|
||||||
-}
|
-}
|
||||||
|
@ -75,56 +72,29 @@ defaultStyle =
|
||||||
, style = Text.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
|
{-| 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
|
called `nameField`. As the user types their name, the field will be updated
|
||||||
to match what they have entered.
|
to match what they have entered.
|
||||||
|
|
||||||
name : Input Content
|
name : Input String
|
||||||
name = input noContent
|
name = input ""
|
||||||
|
|
||||||
nameField : Signal Element
|
nameField : Signal Element
|
||||||
nameField = field name.handle id defaultStyle "Name" <~ name.signal
|
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
|
field = Native.Graphics.Input.field
|
||||||
|
|
||||||
{-| Same as `field` but the UI element blocks out each characters. -}
|
{-| 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
|
password = Native.Graphics.Input.password
|
||||||
|
|
||||||
{-| Same as `field` but it adds an annotation that this field is for email
|
{-| 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
|
addresses. This is helpful for auto-complete and for mobile users who may
|
||||||
get a custom keyboard with an `@` and `.com` button.
|
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
|
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
|
-- area = Native.Graphics.Input.area
|
||||||
|
|
|
@ -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) {
|
function updateIfNeeded(css, attribute, latestAttribute) {
|
||||||
if (css[attribute] !== latestAttribute) {
|
if (css[attribute] !== latestAttribute) {
|
||||||
css[attribute] = latestAttribute;
|
css[attribute] = latestAttribute;
|
||||||
|
@ -267,10 +259,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
|
||||||
|
|
||||||
field.type = model.type;
|
field.type = model.type;
|
||||||
field.placeholder = JS.fromString(model.placeHolder);
|
field.placeholder = JS.fromString(model.placeHolder);
|
||||||
field.value = JS.fromString(model.content.string);
|
field.value = JS.fromString(model.content);
|
||||||
var selection = model.content.selection;
|
|
||||||
var direction = selection.direction.ctor === 'Forward' ? 'forward' : 'backward';
|
|
||||||
setRange(field, selection.start, selection.end, direction);
|
|
||||||
|
|
||||||
field.elm_signal = model.signal;
|
field.elm_signal = model.signal;
|
||||||
field.elm_handler = model.handler;
|
field.elm_handler = model.handler;
|
||||||
|
@ -282,15 +271,7 @@ Elm.Native.Graphics.Input.make = function(elm) {
|
||||||
String.fromCharCode(event.keyCode) +
|
String.fromCharCode(event.keyCode) +
|
||||||
curr.slice(field.selectionEnd));
|
curr.slice(field.selectionEnd));
|
||||||
var pos = field.selectionEnd + 1;
|
var pos = field.selectionEnd + 1;
|
||||||
elm.notify(field.elm_signal.id, field.elm_handler({
|
elm.notify(field.elm_signal.id, field.elm_handler(JS.toString(next)));
|
||||||
_:{},
|
|
||||||
string: JS.toString(next),
|
|
||||||
selection: {
|
|
||||||
start: pos,
|
|
||||||
end: pos,
|
|
||||||
direction: { ctor:'Forward' }
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,46 +281,12 @@ Elm.Native.Graphics.Input.make = function(elm) {
|
||||||
if (curr === next) {
|
if (curr === next) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var direction = field.selectionDirection === 'forward' ? 'Forward' : 'Backward';
|
|
||||||
var start = field.selectionStart;
|
|
||||||
var end = field.selectionEnd;
|
|
||||||
field.value = field.elm_old_value;
|
field.value = field.elm_old_value;
|
||||||
|
elm.notify(field.elm_signal.id, field.elm_handler(JS.toString(next)));
|
||||||
elm.notify(field.elm_signal.id, field.elm_handler({
|
|
||||||
_:{},
|
|
||||||
string: JS.toString(next),
|
|
||||||
selection: {
|
|
||||||
start: start,
|
|
||||||
end: end,
|
|
||||||
direction: { ctor: direction }
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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('keypress', keyUpdate);
|
||||||
field.addEventListener('input', inputUpdate);
|
field.addEventListener('input', inputUpdate);
|
||||||
field.addEventListener('mousedown', mousedown);
|
|
||||||
|
|
||||||
return field;
|
return field;
|
||||||
}
|
}
|
||||||
|
@ -353,12 +300,9 @@ Elm.Native.Graphics.Input.make = function(elm) {
|
||||||
|
|
||||||
field.type = newModel.type;
|
field.type = newModel.type;
|
||||||
field.placeholder = JS.fromString(newModel.placeHolder);
|
field.placeholder = JS.fromString(newModel.placeHolder);
|
||||||
var value = JS.fromString(newModel.content.string);
|
var value = JS.fromString(newModel.content);
|
||||||
field.value = value;
|
field.value = value;
|
||||||
field.elm_old_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) {
|
function mkField(type) {
|
||||||
|
|
Loading…
Reference in a new issue