2011-11-05 16:46:53 +00:00
|
|
|
'use strict';
|
2012-05-21 10:38:18 +00:00
|
|
|
|
2011-05-16 08:24:46 +00:00
|
|
|
/*@
|
2012-05-31 10:32:54 +00:00
|
|
|
Ox.Input <f> Input Element
|
2011-05-16 08:24:46 +00:00
|
|
|
options <o> Options object
|
2011-05-21 17:56:15 +00:00
|
|
|
arrows <b> if true, and type is 'float' or 'int', display arrows
|
2011-05-16 08:24:46 +00:00
|
|
|
arrowStep <n> step when clicking arrows
|
|
|
|
autocomplete <a> array of possible values, or
|
|
|
|
<f> function(key, value, callback), returns one or more values
|
|
|
|
autocompleteReplace <b> if true, value is replaced
|
|
|
|
autocompleteReplaceCorrect <b> if true, only valid values can be entered
|
|
|
|
autocompleteSelect <b> if true, menu is displayed
|
|
|
|
autocompleteSelectHighlight <b> if true, value in menu is highlighted
|
2011-11-02 18:21:49 +00:00
|
|
|
autocompleteSelectMaxWidth <n|0> Maximum width of autocomplete menu, or 0
|
2014-12-17 14:35:10 +00:00
|
|
|
autocompleteSelectOffset <o|{left: 4, top: 0}> Offset of autocomplete menu
|
2011-05-16 08:24:46 +00:00
|
|
|
autocompleteSelectSubmit <b> if true, submit input on menu selection
|
2014-12-17 14:35:10 +00:00
|
|
|
autocompleteSelectUpdate <b> if true, update menu position on keypress
|
2011-05-21 17:56:15 +00:00
|
|
|
autocorrect <s|r|f|null> ('email', 'float', 'int', 'phone', 'url'), or
|
2011-05-16 08:24:46 +00:00
|
|
|
<r> regexp(value), or
|
|
|
|
<f> function(key, value, blur, callback), returns value
|
|
|
|
autovalidate <f> --remote validation--
|
|
|
|
clear <b> if true, has clear button
|
2013-08-11 09:50:43 +00:00
|
|
|
clearTooltip <s|f|''> clear button tooltip
|
2011-05-17 19:08:25 +00:00
|
|
|
changeOnKeypress <b> if true, fire change event while typing
|
2011-05-16 08:24:46 +00:00
|
|
|
disabled <b> if true, is disabled
|
|
|
|
height <n> px (for type='textarea' and type='range' with orientation='horizontal')
|
|
|
|
id <s> element id
|
|
|
|
key <s> to be passed to autocomplete and autovalidate functions
|
2011-10-03 15:02:19 +00:00
|
|
|
label <s|''> Label
|
|
|
|
labelWidth <n|64> Label width
|
2011-05-21 17:56:15 +00:00
|
|
|
max <n> max value if type is 'int' or 'float'
|
|
|
|
min <n> min value if type is 'int' or 'float'
|
2011-05-16 08:24:46 +00:00
|
|
|
name <s> will be displayed by autovalidate function ('invalid ' + name)
|
|
|
|
overlap <s> '', 'left' or 'right', will cause padding and negative margin
|
|
|
|
picker <o> picker object
|
|
|
|
rangeOptions <o> range options
|
|
|
|
arrows <b>boolean, if true, display arrows
|
2011-10-03 15:02:19 +00:00
|
|
|
//arrowStep <n> number, step when clicking arrows
|
2011-05-16 08:24:46 +00:00
|
|
|
//arrowSymbols <a> array of two strings
|
|
|
|
max <n> number, maximum value
|
|
|
|
min <n> number, minimum value
|
|
|
|
orientation <s> 'horizontal' or 'vertical'
|
|
|
|
step <n> number, step
|
|
|
|
thumbValue <b> boolean, if true, value is displayed on thumb, or
|
|
|
|
<a> array of strings per value, or
|
|
|
|
<f> function(value), returns string
|
|
|
|
thumbSize <n> integer, px
|
|
|
|
trackGradient <s> string, css gradient for track
|
|
|
|
trackImage <s> string, image url, or
|
|
|
|
<a> array of image urls
|
|
|
|
//trackStep <n> number, 0 for 'scroll here', positive for step
|
|
|
|
trackValues <b> boolean
|
2015-02-27 06:56:47 +00:00
|
|
|
readonly <b> if true, is readonly
|
2011-05-16 08:24:46 +00:00
|
|
|
serialize <f> function used to serialize value in submit
|
2011-08-12 21:00:42 +00:00
|
|
|
style <s> 'rounded' or 'square'
|
2011-05-16 08:24:46 +00:00
|
|
|
textAlign <s> 'left', 'center' or 'right'
|
2011-05-21 17:56:15 +00:00
|
|
|
type <s> 'float', 'int', 'password', 'text', 'textarea'
|
2011-05-16 08:24:46 +00:00
|
|
|
value <s> string
|
|
|
|
validate <f> remote validation
|
|
|
|
width <n> px
|
2012-07-04 11:29:18 +00:00
|
|
|
([options[, self]]) -> <o:Ox.Element> Input Element
|
|
|
|
autocomplete <!> autocomplete
|
|
|
|
autovalidate <!> autovalidate
|
|
|
|
blur <!> blur
|
|
|
|
cancel <!> cancel
|
|
|
|
change <!> input changed event
|
|
|
|
clear <!> clear
|
|
|
|
focus <!> focus
|
|
|
|
insert <!> insert
|
|
|
|
submit <!> input submit event
|
|
|
|
validate <!> validate
|
2011-05-16 08:24:46 +00:00
|
|
|
@*/
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2011-05-16 08:24:46 +00:00
|
|
|
Ox.Input = function(options, self) {
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2011-06-19 17:48:32 +00:00
|
|
|
self = self || {};
|
2012-01-03 19:41:50 +00:00
|
|
|
var that = Ox.Element({
|
2014-11-20 13:47:25 +00:00
|
|
|
element: (options || {}).element || '<div>'
|
2012-01-03 19:41:50 +00:00
|
|
|
}, self)
|
2011-04-22 22:03:10 +00:00
|
|
|
.defaults({
|
|
|
|
arrows: false,
|
|
|
|
arrowStep: 1,
|
|
|
|
autocomplete: null,
|
|
|
|
autocompleteReplace: false,
|
|
|
|
autocompleteReplaceCorrect: false,
|
|
|
|
autocompleteSelect: false,
|
|
|
|
autocompleteSelectHighlight: false,
|
2011-05-20 06:19:55 +00:00
|
|
|
autocompleteSelectMax: 0,
|
2011-11-02 18:21:49 +00:00
|
|
|
autocompleteSelectMaxWidth: 0,
|
2014-12-17 14:35:10 +00:00
|
|
|
autocompleteSelectOffset: {left: 4, top: 0},
|
2011-04-22 22:03:10 +00:00
|
|
|
autocompleteSelectSubmit: false,
|
2014-12-17 14:35:10 +00:00
|
|
|
autocompleteSelectUpdate: false,
|
2011-04-22 22:03:10 +00:00
|
|
|
autovalidate: null,
|
2011-05-17 19:08:25 +00:00
|
|
|
changeOnKeypress: false,
|
2011-04-22 22:03:10 +00:00
|
|
|
clear: false,
|
2013-08-11 09:50:43 +00:00
|
|
|
clearTooltip: '',
|
2011-05-21 17:56:15 +00:00
|
|
|
decimals: 0,
|
2013-02-25 16:39:18 +00:00
|
|
|
disabled: false,
|
|
|
|
height: 16,
|
2011-04-22 22:03:10 +00:00
|
|
|
key: '',
|
2011-05-21 17:56:15 +00:00
|
|
|
min: -Infinity,
|
|
|
|
max: Infinity,
|
2011-04-22 22:03:10 +00:00
|
|
|
label: '',
|
|
|
|
labelWidth: 64,
|
|
|
|
overlap: 'none',
|
|
|
|
placeholder: '',
|
2015-02-27 06:56:47 +00:00
|
|
|
readonly: false,
|
2011-04-22 22:03:10 +00:00
|
|
|
serialize: null,
|
|
|
|
style: 'rounded',
|
|
|
|
textAlign: 'left',
|
|
|
|
type: 'text',
|
|
|
|
validate: null,
|
|
|
|
value: '',
|
|
|
|
width: 128
|
|
|
|
})
|
2011-11-02 09:03:11 +00:00
|
|
|
.options(options || {})
|
2012-05-28 19:35:41 +00:00
|
|
|
.update(function(key, value) {
|
|
|
|
var inputWidth;
|
|
|
|
if ([
|
|
|
|
'autocomplete', 'autocompleteReplace', 'autocompleteSelect', 'autovalidate'
|
|
|
|
].indexOf(key) > -1) {
|
|
|
|
if (self.options.autocomplete && self.options.autocompleteSelect) {
|
|
|
|
self.$autocompleteMenu = constructAutocompleteMenu();
|
|
|
|
}
|
|
|
|
self.bindKeyboard = self.options.autocomplete || self.options.autovalidate;
|
|
|
|
} else if (key == 'disabled') {
|
|
|
|
self.$input.attr({disabled: value});
|
|
|
|
} else if (key == 'height') {
|
|
|
|
that.css({height: value + 'px'});
|
|
|
|
self.$input.css({height: value - 6 + 'px'});
|
2014-02-16 07:06:48 +00:00
|
|
|
} else if (key == 'label') {
|
|
|
|
self.$label.options({title: value});
|
2012-05-28 19:35:41 +00:00
|
|
|
} else if (key == 'labelWidth') {
|
|
|
|
self.$label.options({width: value});
|
|
|
|
inputWidth = getInputWidth();
|
|
|
|
self.$input.css({
|
|
|
|
width: inputWidth + 'px'
|
|
|
|
});
|
|
|
|
self.hasPasswordPlaceholder && self.$placeholder.css({
|
|
|
|
width: inputWidth + 'px'
|
|
|
|
});
|
|
|
|
} else if (key == 'placeholder') {
|
|
|
|
setPlaceholder();
|
2015-02-27 06:56:47 +00:00
|
|
|
} else if (key == 'readonly') {
|
|
|
|
self.$input.attr({readonly: value});
|
2012-05-28 19:35:41 +00:00
|
|
|
} else if (key == 'value') {
|
|
|
|
if (self.options.type == 'float' && self.options.decimals) {
|
|
|
|
self.options.value = self.options.value.toFixed(self.options.decimals);
|
|
|
|
}
|
|
|
|
self.$input.val(self.options.value);
|
|
|
|
that.is('.OxError') && that.removeClass('OxError');
|
|
|
|
setPlaceholder();
|
|
|
|
} else if (key == 'width') {
|
|
|
|
that.css({width: self.options.width + 'px'});
|
|
|
|
inputWidth = getInputWidth();
|
|
|
|
self.$input.css({
|
|
|
|
width: inputWidth + 'px'
|
|
|
|
});
|
|
|
|
self.hasPasswordPlaceholder && self.$placeholder.css({
|
|
|
|
width: inputWidth + 'px'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
})
|
2011-04-22 22:03:10 +00:00
|
|
|
.addClass(
|
2014-09-26 10:24:34 +00:00
|
|
|
'OxInput OxKeyboardFocus OxMedium Ox' + Ox.toTitleCase(self.options.style)
|
2012-06-27 17:04:34 +00:00
|
|
|
+ (self.options.type == 'textarea' ? ' OxTextarea' : '') /*+ (
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.overlap != 'none' ?
|
|
|
|
' OxOverlap' + Ox.toTitleCase(self.options.overlap) : ''
|
|
|
|
)*/
|
|
|
|
)
|
2011-11-02 09:03:11 +00:00
|
|
|
.css(
|
|
|
|
Ox.extend({
|
|
|
|
width: self.options.width + 'px'
|
|
|
|
}, self.options.type == 'textarea' ? {
|
|
|
|
height: self.options.height + 'px'
|
|
|
|
} : {})
|
|
|
|
)
|
2012-01-16 14:02:30 +00:00
|
|
|
.bindEvent(Ox.extend(self.options.type != 'textarea' ? {
|
2011-04-22 22:03:10 +00:00
|
|
|
key_enter: submit
|
2012-01-16 07:09:16 +00:00
|
|
|
} : {}, {
|
2012-02-16 16:35:59 +00:00
|
|
|
key_control_i: insert,
|
2012-01-16 07:09:16 +00:00
|
|
|
key_escape: cancel,
|
|
|
|
key_shift_enter: submit
|
2011-04-22 22:03:10 +00:00
|
|
|
}));
|
|
|
|
|
|
|
|
if (
|
2011-11-02 09:03:11 +00:00
|
|
|
Ox.isArray(self.options.autocomplete)
|
|
|
|
&& self.options.autocompleteReplace
|
|
|
|
&& self.options.autocompleteReplaceCorrect
|
|
|
|
&& self.options.value === ''
|
2011-04-22 22:03:10 +00:00
|
|
|
) {
|
|
|
|
self.options.value = self.options.autocomplete[0]
|
|
|
|
}
|
|
|
|
|
|
|
|
// fixme: set to min, not 0
|
2011-05-21 17:56:15 +00:00
|
|
|
// fixme: validate self.options.value !
|
2011-04-22 22:03:10 +00:00
|
|
|
if (self.options.type == 'float') {
|
2011-05-21 17:56:15 +00:00
|
|
|
self.decimals = Ox.repeat('0', self.options.decimals || 1)
|
2011-09-17 18:36:09 +00:00
|
|
|
Ox.extend(self.options, {
|
2011-04-22 22:03:10 +00:00
|
|
|
autovalidate: 'float',
|
|
|
|
textAlign: 'right',
|
2011-05-21 17:56:15 +00:00
|
|
|
value: self.options.value || '0.' + self.decimals
|
2011-04-22 22:03:10 +00:00
|
|
|
});
|
2011-05-21 17:56:15 +00:00
|
|
|
} else if (self.options.type == 'int') {
|
2011-09-17 18:36:09 +00:00
|
|
|
Ox.extend(self.options, {
|
2011-05-21 17:56:15 +00:00
|
|
|
autovalidate: 'int',
|
2011-04-22 22:03:10 +00:00
|
|
|
textAlign: 'right',
|
|
|
|
value: self.options.value || '0'
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self.options.label) {
|
2011-06-19 17:48:32 +00:00
|
|
|
self.$label = Ox.Label({
|
2011-04-22 22:03:10 +00:00
|
|
|
overlap: 'right',
|
2016-01-12 05:41:08 +00:00
|
|
|
style: self.options.style,
|
2011-04-22 22:03:10 +00:00
|
|
|
textAlign: 'right',
|
|
|
|
title: self.options.label,
|
|
|
|
width: self.options.labelWidth
|
|
|
|
})
|
|
|
|
.css({
|
2012-05-26 15:48:19 +00:00
|
|
|
float: 'left' // fixme: use css rule
|
2011-04-22 22:03:10 +00:00
|
|
|
})
|
2013-12-06 20:43:00 +00:00
|
|
|
.on({
|
|
|
|
click: function() {
|
|
|
|
// fixme: ???
|
|
|
|
// that.focus();
|
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
})
|
|
|
|
.appendTo(that);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self.options.arrows) {
|
|
|
|
self.arrows = [];
|
|
|
|
self.arrows[0] = [
|
2011-06-19 17:48:32 +00:00
|
|
|
Ox.Button({
|
2011-04-22 22:03:10 +00:00
|
|
|
overlap: 'right',
|
|
|
|
title: 'left',
|
|
|
|
type: 'image'
|
|
|
|
})
|
2013-12-06 20:43:00 +00:00
|
|
|
.css({float: 'left'})
|
|
|
|
.on({
|
|
|
|
click: function() {
|
2015-02-21 07:17:11 +00:00
|
|
|
clickArrow(-1);
|
2013-12-06 20:43:00 +00:00
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
})
|
|
|
|
.appendTo(that),
|
2011-06-19 17:48:32 +00:00
|
|
|
Ox.Button({
|
2011-04-22 22:03:10 +00:00
|
|
|
overlap: 'left',
|
|
|
|
title: 'right',
|
|
|
|
type: 'image'
|
|
|
|
})
|
2013-12-06 20:43:00 +00:00
|
|
|
.css({float: 'right'})
|
|
|
|
.on({
|
|
|
|
click: function() {
|
2015-02-21 07:17:11 +00:00
|
|
|
clickArrow(1);
|
2013-12-06 20:43:00 +00:00
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
})
|
|
|
|
.appendTo(that)
|
|
|
|
]
|
|
|
|
}
|
|
|
|
|
2011-10-29 10:01:28 +00:00
|
|
|
self.bindKeyboard = self.options.autocomplete
|
|
|
|
|| self.options.autovalidate
|
|
|
|
|| self.options.changeOnKeypress;
|
|
|
|
self.hasPasswordPlaceholder = self.options.type == 'password'
|
|
|
|
&& self.options.placeholder;
|
|
|
|
self.inputWidth = getInputWidth();
|
2011-04-22 22:03:10 +00:00
|
|
|
|
|
|
|
if (self.options.clear) {
|
2011-06-19 17:48:32 +00:00
|
|
|
self.$button = Ox.Button({
|
2011-04-22 22:03:10 +00:00
|
|
|
overlap: 'left',
|
2014-06-06 12:38:15 +00:00
|
|
|
// FIXME: should always be self.options.style, but there
|
|
|
|
// is a CSS bug for rounded image buttons
|
|
|
|
style: self.options.style == 'squared' ? 'squared' : '',
|
2011-04-22 22:03:10 +00:00
|
|
|
title: 'close',
|
2013-08-11 09:50:43 +00:00
|
|
|
tooltip: self.options.clearTooltip,
|
2011-04-22 22:03:10 +00:00
|
|
|
type: 'image'
|
|
|
|
})
|
|
|
|
.css({
|
|
|
|
float: 'right' // fixme: use css rule
|
|
|
|
})
|
2012-06-16 13:36:03 +00:00
|
|
|
.bindEvent({
|
|
|
|
click: clear,
|
|
|
|
doubleclick: submit
|
|
|
|
})
|
2011-04-22 22:03:10 +00:00
|
|
|
.appendTo(that);
|
|
|
|
}
|
|
|
|
|
2013-12-07 14:07:39 +00:00
|
|
|
self.$input = $(self.options.type == 'textarea' ? '<textarea>' : '<input>')
|
2014-09-26 10:24:34 +00:00
|
|
|
.addClass('OxInput OxKeyboardFocus OxMedium Ox' + Ox.toTitleCase(self.options.style))
|
2011-10-06 04:42:58 +00:00
|
|
|
.attr({
|
|
|
|
disabled: self.options.disabled,
|
2015-02-27 06:56:47 +00:00
|
|
|
readonly: self.options.readonly,
|
2011-04-22 22:03:10 +00:00
|
|
|
type: self.options.type == 'password' ? 'password' : 'text'
|
2011-10-06 04:42:58 +00:00
|
|
|
})
|
2011-11-02 09:03:11 +00:00
|
|
|
.css(
|
|
|
|
Ox.extend({
|
|
|
|
width: self.inputWidth + 'px',
|
|
|
|
textAlign: self.options.textAlign
|
|
|
|
}, self.options.type == 'textarea' ? {
|
2012-05-26 15:48:19 +00:00
|
|
|
height: self.options.height - 6 + 'px'
|
2011-11-02 09:03:11 +00:00
|
|
|
} : {})
|
|
|
|
)
|
2011-04-22 22:03:10 +00:00
|
|
|
.val(self.options.value)
|
2013-12-06 20:17:39 +00:00
|
|
|
.on({
|
2015-02-06 11:44:41 +00:00
|
|
|
click: function() {
|
|
|
|
self.options.disabled && that.gainFocus();
|
|
|
|
},
|
2013-12-06 20:17:39 +00:00
|
|
|
blur: blur,
|
|
|
|
change: change,
|
|
|
|
focus: focus
|
|
|
|
})
|
2012-06-26 16:21:39 +00:00
|
|
|
.appendTo(that);
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2014-02-03 13:30:50 +00:00
|
|
|
if (self.bindKeyboard) {
|
|
|
|
self.$input.on({
|
|
|
|
paste: keydown
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-11-02 09:03:11 +00:00
|
|
|
if (self.options.type == 'textarea') {
|
2011-11-04 15:54:28 +00:00
|
|
|
Ox.Log('Form', 'TEXTAREA', self.options.width, self.options.height, '...', that.css('width'), that.css('height'), '...', self.$input.css('width'), self.$input.css('height'), '...', self.$input.css('border'))
|
2011-11-02 09:03:11 +00:00
|
|
|
}
|
|
|
|
|
2011-04-22 22:03:10 +00:00
|
|
|
// fixme: is there a better way than this one?
|
|
|
|
// should at least go into ox.ui.theme.foo.js
|
|
|
|
// probably better: divs in the background
|
2011-10-26 08:59:30 +00:00
|
|
|
/*
|
2011-04-22 22:03:10 +00:00
|
|
|
if (self.options.type == 'textarea') {
|
2011-09-17 18:36:09 +00:00
|
|
|
Ox.extend(self, {
|
2013-02-11 10:47:55 +00:00
|
|
|
colors: Ox.Theme() == 'oxlight' ?
|
2011-04-22 22:03:10 +00:00
|
|
|
[208, 232, 244] :
|
|
|
|
//[0, 16, 32],
|
|
|
|
[32, 48, 64],
|
|
|
|
colorstops: [8 / self.options.height, self.options.height - 8 / self.options.height]
|
|
|
|
});
|
|
|
|
self.$input.css({
|
|
|
|
background: '-moz-linear-gradient(top, rgb(' +
|
|
|
|
[self.colors[0], self.colors[0], self.colors[0]].join(', ') + '), rgb(' +
|
|
|
|
[self.colors[1], self.colors[1], self.colors[1]].join(', ') + ') ' +
|
|
|
|
Math.round(self.colorstops[0] * 100) + '%, rgb(' +
|
|
|
|
[self.colors[1], self.colors[1], self.colors[1]].join(', ') + ') ' +
|
|
|
|
Math.round(self.colorstops[1] * 100) + '%, rgb(' +
|
|
|
|
[self.colors[2], self.colors[2], self.colors[2]].join(', ') + '))'
|
|
|
|
});
|
|
|
|
self.$input.css({
|
2011-05-19 10:18:39 +00:00
|
|
|
background: '-webkit-linear-gradient(top, rgb(' +
|
|
|
|
[self.colors[0], self.colors[0], self.colors[0]].join(', ') + '), rgb(' +
|
|
|
|
[self.colors[1], self.colors[1], self.colors[1]].join(', ') + ') ' +
|
|
|
|
Math.round(self.colorstops[0] * 100) + '%, rgb(' +
|
|
|
|
[self.colors[1], self.colors[1], self.colors[1]].join(', ') + ') ' +
|
|
|
|
Math.round(self.colorstops[1] * 100) + '%, rgb(' +
|
|
|
|
[self.colors[2], self.colors[2], self.colors[2]].join(', ') + '))'
|
2011-04-22 22:03:10 +00:00
|
|
|
});
|
|
|
|
}
|
2011-10-26 08:59:30 +00:00
|
|
|
*/
|
2011-04-22 22:03:10 +00:00
|
|
|
|
|
|
|
if (self.hasPasswordPlaceholder) {
|
|
|
|
self.$input.hide();
|
2013-12-07 14:07:39 +00:00
|
|
|
self.$placeholder = $('<input>')
|
2014-09-26 10:24:34 +00:00
|
|
|
.addClass('OxInput OxKeyboardFocus OxMedium Ox' +
|
2011-04-22 22:03:10 +00:00
|
|
|
Ox.toTitleCase(self.options.style) +
|
|
|
|
' OxPlaceholder')
|
2013-12-07 14:47:56 +00:00
|
|
|
.attr({type: 'text'})
|
|
|
|
.css({width: self.inputWidth + 'px'})
|
2011-04-22 22:03:10 +00:00
|
|
|
.val(self.options.placeholder)
|
2013-12-06 20:17:39 +00:00
|
|
|
.on({focus: focus})
|
2012-06-26 16:21:39 +00:00
|
|
|
.appendTo(that);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (self.options.autocomplete && self.options.autocompleteSelect) {
|
|
|
|
self.$autocompleteMenu = constructAutocompleteMenu();
|
|
|
|
}
|
|
|
|
|
|
|
|
self.options.placeholder && setPlaceholder();
|
|
|
|
|
|
|
|
function autocomplete(oldValue, oldCursor) {
|
|
|
|
|
|
|
|
oldValue = Ox.isUndefined(oldValue) ? self.options.value : oldValue;
|
2011-05-20 11:46:52 +00:00
|
|
|
oldCursor = Ox.isUndefined(oldCursor) ? cursor() : oldCursor;
|
2011-04-22 22:03:10 +00:00
|
|
|
|
2011-11-11 11:48:52 +00:00
|
|
|
Ox.Log('AUTO', 'autocomplete', oldValue, oldCursor)
|
2011-04-22 22:03:10 +00:00
|
|
|
|
|
|
|
if (self.options.value || self.options.autocompleteReplaceCorrect) {
|
2013-08-27 10:38:30 +00:00
|
|
|
var id = Ox.uid();
|
|
|
|
self.autocompleteId = id;
|
2011-05-20 06:19:55 +00:00
|
|
|
if (Ox.isFunction(self.options.autocomplete)) {
|
|
|
|
if (self.options.key) {
|
|
|
|
self.options.autocomplete(
|
|
|
|
self.options.key, self.options.value, autocompleteCallback
|
|
|
|
);
|
2011-04-22 22:03:10 +00:00
|
|
|
} else {
|
2011-05-20 06:19:55 +00:00
|
|
|
self.options.autocomplete(
|
|
|
|
self.options.value, autocompleteCallback
|
|
|
|
);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
} else {
|
2013-08-27 10:38:30 +00:00
|
|
|
autocompleteCallback(autocompleteFunction());
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!self.options.value) {
|
2011-05-20 11:46:52 +00:00
|
|
|
if (self.options.autocompleteSelect) {
|
|
|
|
self.$autocompleteMenu
|
|
|
|
.unbindEvent('select')
|
|
|
|
.hideMenu();
|
2014-12-17 19:27:04 +00:00
|
|
|
that.gainFocus();
|
2011-05-20 11:46:52 +00:00
|
|
|
self.selectEventBound = false;
|
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function autocompleteFunction() {
|
2012-05-25 07:46:29 +00:00
|
|
|
return Ox.find(
|
|
|
|
self.options.autocomplete,
|
|
|
|
self.options.value,
|
|
|
|
self.options.autocompleteReplace
|
|
|
|
);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function autocompleteCallback(values) {
|
|
|
|
|
2013-08-27 10:38:30 +00:00
|
|
|
if (self.autocompleteId != id) {
|
|
|
|
return;
|
|
|
|
}
|
2011-11-04 15:54:28 +00:00
|
|
|
//Ox.Log('Form', 'autocompleteCallback', values[0], self.options.value, self.options.value.length, oldValue, oldCursor)
|
2011-04-22 22:03:10 +00:00
|
|
|
|
|
|
|
var length = self.options.value.length,
|
2011-05-20 07:14:24 +00:00
|
|
|
newValue, newLength,
|
2011-04-22 22:03:10 +00:00
|
|
|
pos = cursor(),
|
|
|
|
selected = -1,
|
|
|
|
selectEnd = length == 0 || (values[0] && values[0].length),
|
|
|
|
value;
|
|
|
|
|
2011-05-20 07:14:24 +00:00
|
|
|
if (values[0]) {
|
2016-03-02 16:09:52 +00:00
|
|
|
if (self.options.autocompleteReplace &&
|
|
|
|
Ox.startsWith(values[0].toLowerCase(),
|
|
|
|
self.options.value.toLowerCase())) {
|
2011-05-20 07:14:24 +00:00
|
|
|
newValue = values[0];
|
2016-03-02 16:09:52 +00:00
|
|
|
selected = 0;
|
2011-05-20 07:14:24 +00:00
|
|
|
} else {
|
|
|
|
newValue = self.options.value;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (self.options.autocompleteReplaceCorrect) {
|
|
|
|
newValue = oldValue;
|
|
|
|
} else {
|
|
|
|
newValue = self.options.value
|
|
|
|
}
|
|
|
|
}
|
|
|
|
newLength = newValue.length;
|
2011-11-03 15:42:41 +00:00
|
|
|
|
2011-04-22 22:03:10 +00:00
|
|
|
if (self.options.autocompleteReplace) {
|
2011-05-20 11:46:52 +00:00
|
|
|
value = self.options.value;
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.value = newValue;
|
|
|
|
self.$input.val(self.options.value);
|
|
|
|
if (selectEnd) {
|
|
|
|
cursor(length, newLength);
|
|
|
|
} else if (self.options.autocompleteReplaceCorrect) {
|
|
|
|
cursor(oldCursor);
|
|
|
|
} else {
|
|
|
|
cursor(pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (self.options.autocompleteSelect) {
|
2012-05-22 14:29:37 +00:00
|
|
|
value = (
|
|
|
|
self.options.autocompleteReplace
|
|
|
|
? value : self.options.value
|
|
|
|
).toLowerCase();
|
2011-04-22 22:03:10 +00:00
|
|
|
if (values.length) {
|
|
|
|
self.oldCursor = cursor();
|
|
|
|
self.oldValue = self.options.value;
|
|
|
|
self.$autocompleteMenu.options({
|
2012-05-22 14:29:37 +00:00
|
|
|
items: Ox.filter(values, function(v, i) {
|
|
|
|
var ret = false;
|
2011-05-20 06:19:55 +00:00
|
|
|
if (
|
|
|
|
!self.options.autocompleteSelectMax ||
|
|
|
|
i < self.options.autocompleteSelectMax
|
|
|
|
) {
|
2012-05-22 14:29:37 +00:00
|
|
|
if (v.toLowerCase() === value) {
|
2011-05-20 06:19:55 +00:00
|
|
|
selected = i;
|
|
|
|
}
|
2012-05-22 14:29:37 +00:00
|
|
|
ret = true;
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
2011-05-20 06:19:55 +00:00
|
|
|
return ret;
|
2012-05-22 14:29:37 +00:00
|
|
|
}).map(function(v) {
|
|
|
|
return {
|
|
|
|
id: v.toLowerCase().replace(/ /g, '_'), // fixme: need function to do lowercase, underscores etc?
|
2012-06-16 20:48:30 +00:00
|
|
|
title: self.options.autocompleteSelectHighlight
|
|
|
|
? Ox.highlight(v, value, 'OxHighlight') : v
|
2012-05-22 14:29:37 +00:00
|
|
|
};
|
2011-05-20 06:40:57 +00:00
|
|
|
})
|
|
|
|
});
|
2011-05-20 11:46:52 +00:00
|
|
|
if (!self.selectEventBound) {
|
|
|
|
self.$autocompleteMenu.bindEvent({
|
2012-05-26 15:48:19 +00:00
|
|
|
select: selectMenu
|
2011-05-20 11:46:52 +00:00
|
|
|
});
|
|
|
|
self.selectEventBound = true;
|
|
|
|
}
|
2011-05-20 06:40:57 +00:00
|
|
|
self.$autocompleteMenu.options({
|
2011-04-22 22:03:10 +00:00
|
|
|
selected: selected
|
|
|
|
}).showMenu();
|
2014-12-17 14:54:59 +00:00
|
|
|
if (self.options.autocompleteSelectUpdate) {
|
2014-12-17 15:43:43 +00:00
|
|
|
self.$autocompleteMenu.updatePosition();
|
2014-12-17 14:54:59 +00:00
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
} else {
|
2011-05-20 11:46:52 +00:00
|
|
|
self.$autocompleteMenu
|
|
|
|
.unbindEvent('select')
|
|
|
|
.hideMenu();
|
2014-12-17 19:27:04 +00:00
|
|
|
that.gainFocus();
|
2011-05-20 11:46:52 +00:00
|
|
|
self.selectEventBound = false;
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
that.triggerEvent('autocomplete', {
|
|
|
|
value: newValue
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function autovalidate() {
|
|
|
|
|
|
|
|
var blur, oldCursor, oldValue;
|
|
|
|
|
|
|
|
if (arguments.length == 1) {
|
|
|
|
blur = arguments[0];
|
|
|
|
} else {
|
|
|
|
blur = false;
|
|
|
|
oldValue = arguments[0];
|
|
|
|
oldCursor = arguments[1];
|
|
|
|
}
|
|
|
|
|
2011-05-17 19:08:25 +00:00
|
|
|
if (Ox.isFunction(self.options.autovalidate)) {
|
|
|
|
if (self.options.key) {
|
|
|
|
self.options.autovalidate(
|
|
|
|
self.options.key, self.options.value, blur, autovalidateCallback
|
|
|
|
);
|
2011-04-22 22:03:10 +00:00
|
|
|
} else {
|
2011-05-17 19:08:25 +00:00
|
|
|
self.options.autovalidate(
|
|
|
|
self.options.value, blur, autovalidateCallback
|
|
|
|
);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
2011-05-17 19:08:25 +00:00
|
|
|
} else if (Ox.isRegExp(self.options.autovalidate)) {
|
2011-05-20 06:19:55 +00:00
|
|
|
autovalidateCallback(autovalidateFunction(self.options.value));
|
2011-05-17 19:08:25 +00:00
|
|
|
} else {
|
|
|
|
autovalidateTypeFunction(self.options.type, self.options.value);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function autovalidateFunction(value) {
|
2011-10-22 14:50:31 +00:00
|
|
|
value = value.split('').map(function(v) {
|
|
|
|
return self.options.autovalidate.test(v) ? v : null;
|
2011-04-22 22:03:10 +00:00
|
|
|
}).join('');
|
2011-10-22 14:50:31 +00:00
|
|
|
return {
|
|
|
|
valid: !!value.length,
|
|
|
|
value: value
|
|
|
|
};
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function autovalidateTypeFunction(type, value) {
|
|
|
|
// fixme: remove trailing zeroes on blur
|
2011-05-21 17:56:15 +00:00
|
|
|
// /(^\-?\d+\.?\d{0,8}$)/('-13000.12345678')
|
2011-04-22 22:03:10 +00:00
|
|
|
var cursor,
|
2011-05-21 17:56:15 +00:00
|
|
|
length,
|
|
|
|
regexp = type == 'float' ? new RegExp(
|
2011-11-03 15:42:41 +00:00
|
|
|
'(^' + (self.options.min < 0 ? '\\-?' : '') + '\\d+\\.?\\d'
|
|
|
|
+ (self.options.decimals ? '{0,' + self.options.decimals + '}' : '*')
|
2011-05-21 17:56:15 +00:00
|
|
|
+ '$)'
|
2012-07-09 13:59:28 +00:00
|
|
|
) : new RegExp('(^' + (self.options.min < 0 ? '\\-?' : '') + '\\d+$)');
|
2011-04-22 22:03:10 +00:00
|
|
|
if (type == 'float') {
|
2011-05-21 17:56:15 +00:00
|
|
|
if (value === '') {
|
|
|
|
value = '0.' + self.decimals;
|
|
|
|
cursor = [0, value.length];
|
|
|
|
} else if (value == '-') {
|
|
|
|
value = '-0.' + self.decimals;
|
|
|
|
cursor = [1, value.length];
|
|
|
|
} else if (value == '.') {
|
|
|
|
value = '0.' + self.decimals;
|
|
|
|
cursor = [2, value.length];
|
2011-07-23 13:44:11 +00:00
|
|
|
} else if (!/\./.test(value)) {
|
|
|
|
value += '.' + self.decimals;
|
2011-05-21 17:56:15 +00:00
|
|
|
cursor = [value.indexOf('.'), value.length];
|
2011-07-23 13:44:11 +00:00
|
|
|
} else if (/^\./.test(value)) {
|
2011-05-21 17:56:15 +00:00
|
|
|
value = '0' + value;
|
|
|
|
cursor = [2, value.length];
|
2011-07-23 13:44:11 +00:00
|
|
|
} else if (/\.$/.test(value)) {
|
2011-05-21 17:56:15 +00:00
|
|
|
value += self.decimals;
|
|
|
|
cursor = [value.indexOf('.') + 1, value.length];
|
2011-07-23 13:44:11 +00:00
|
|
|
} else if (/\./.test(value) && self.options.decimals) {
|
2011-05-21 17:56:15 +00:00
|
|
|
length = value.split('.')[1].length;
|
|
|
|
if (length > self.options.decimals) {
|
2012-05-24 09:47:33 +00:00
|
|
|
value = value.slice(0, value.indexOf('.') + 1 + self.options.decimals);
|
2011-05-21 17:56:15 +00:00
|
|
|
cursor = [oldCursor[0] + 1, oldCursor[1] + 1];
|
|
|
|
} else if (length < self.options.decimals) {
|
|
|
|
value += Ox.repeat('0', self.options.decimals - length);
|
|
|
|
cursor = [value.indexOf('.') + 1 + length, value.length];
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
}
|
2011-05-21 17:56:15 +00:00
|
|
|
} else {
|
|
|
|
if (value === '') {
|
|
|
|
value = '0';
|
|
|
|
cursor = [0, 1];
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
}
|
2011-07-23 13:44:11 +00:00
|
|
|
while (/^0\d/.test(value)) {
|
2012-05-24 09:47:33 +00:00
|
|
|
value = value.slice(1);
|
2011-05-21 17:56:15 +00:00
|
|
|
}
|
|
|
|
if (!regexp.test(value) || value < self.options.min || value > self.options.max) {
|
2011-04-22 22:03:10 +00:00
|
|
|
value = oldValue;
|
2011-05-21 17:56:15 +00:00
|
|
|
cursor = oldCursor;
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
2011-10-22 14:50:31 +00:00
|
|
|
autovalidateCallback({
|
|
|
|
cursor: cursor,
|
|
|
|
valid: true,
|
|
|
|
value: value
|
|
|
|
});
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
2011-10-22 14:50:31 +00:00
|
|
|
function autovalidateCallback(data) {
|
2011-11-04 15:54:28 +00:00
|
|
|
//Ox.Log('Form', 'autovalidateCallback', newValue, oldCursor)
|
2011-10-22 14:50:31 +00:00
|
|
|
self.options.value = data.value;
|
2011-04-22 22:03:10 +00:00
|
|
|
self.$input.val(self.options.value);
|
|
|
|
!blur && cursor(
|
2011-10-22 14:50:31 +00:00
|
|
|
data.cursor || (oldCursor[1] + data.value.length - oldValue.length)
|
2011-04-22 22:03:10 +00:00
|
|
|
);
|
|
|
|
that.triggerEvent('autovalidate', {
|
2011-10-22 14:50:31 +00:00
|
|
|
valid: data.valid,
|
|
|
|
value: data.value
|
2011-04-22 22:03:10 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
function autovalidate(blur) {
|
2011-11-04 15:54:28 +00:00
|
|
|
Ox.Log('Form', 'autovalidate', self.options.value, blur || false)
|
2011-04-22 22:03:10 +00:00
|
|
|
self.autocorrectBlur = blur || false;
|
|
|
|
self.autocorrectCursor = cursor();
|
|
|
|
Ox.isFunction(self.options.autocorrect) ?
|
|
|
|
(self.options.key ? self.options.autocorrect(
|
|
|
|
self.options.key,
|
|
|
|
self.options.value,
|
|
|
|
self.autocorrectBlur,
|
|
|
|
autocorrectCallback
|
|
|
|
) : self.options.autocorrect(
|
|
|
|
self.options.value,
|
|
|
|
self.autocorrectBlur,
|
|
|
|
autocorrectCallback
|
|
|
|
)) : autocorrectCallback(autocorrect(self.options.value));
|
|
|
|
}
|
|
|
|
|
|
|
|
function autovalidateFunction(value) {
|
|
|
|
var length = value.length;
|
2011-09-17 18:36:09 +00:00
|
|
|
return value.toLowerCase().split('').map(function(v) {
|
2011-04-22 22:03:10 +00:00
|
|
|
if (new RegExp(self.options.autocorrect).test(v)) {
|
|
|
|
return v;
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}).join('');
|
|
|
|
}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
function blur() {
|
|
|
|
that.loseFocus();
|
|
|
|
//that.removeClass('OxFocus');
|
|
|
|
self.options.value = self.$input.val();
|
|
|
|
self.options.autovalidate && autovalidate(true);
|
|
|
|
self.options.placeholder && setPlaceholder();
|
|
|
|
self.options.validate && validate();
|
2014-09-25 16:35:17 +00:00
|
|
|
self.bindKeyboard && Ox.$document.off('keydown', keydown);
|
2012-01-13 10:58:01 +00:00
|
|
|
if (!self.cancelled && !self.submitted) {
|
2012-06-16 13:36:03 +00:00
|
|
|
that.triggerEvent('blur', {value: self.options.value});
|
2012-01-13 10:58:01 +00:00
|
|
|
self.options.value !== self.originalValue && that.triggerEvent('change', {
|
|
|
|
value: self.options.value
|
|
|
|
});
|
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function cancel() {
|
2011-08-12 21:00:42 +00:00
|
|
|
self.cancelled = true;
|
2012-01-13 10:58:01 +00:00
|
|
|
self.$input.val(self.originalValue).blur();
|
2011-08-12 21:00:42 +00:00
|
|
|
self.cancelled = false;
|
|
|
|
that.triggerEvent('cancel');
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
2013-08-27 10:38:30 +00:00
|
|
|
function cancelAutocomplete() {
|
|
|
|
self.autocompleteId = null;
|
|
|
|
}
|
|
|
|
|
2011-04-22 22:03:10 +00:00
|
|
|
function change() {
|
2012-01-13 10:58:01 +00:00
|
|
|
// change gets invoked before blur
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.value = self.$input.val();
|
2012-01-13 10:58:01 +00:00
|
|
|
self.originalValue = self.options.value;
|
2012-03-18 19:50:38 +00:00
|
|
|
!self.options.changeOnKeypress && that.triggerEvent('change', {
|
2011-04-22 22:03:10 +00:00
|
|
|
value: self.options.value
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function clear() {
|
|
|
|
// fixme: set to min, not zero
|
|
|
|
// fixme: make this work for password
|
2012-06-16 13:36:03 +00:00
|
|
|
if (!self.clearTimeout) {
|
|
|
|
that.triggerEvent('clear');
|
|
|
|
self.options.value = '';
|
|
|
|
self.options.value = self.options.type == 'float' ? '0.0'
|
|
|
|
: self.options.type == 'int' ? '0'
|
|
|
|
: '';
|
|
|
|
self.$input.val(self.options.value);
|
|
|
|
cursor(0, self.options.value.length);
|
|
|
|
self.options.changeOnKeypress && that.triggerEvent({
|
|
|
|
change: {value: self.options.value}
|
|
|
|
});
|
|
|
|
self.clearTimeout = setTimeout(function() {
|
|
|
|
self.clearTimeout = 0;
|
|
|
|
}, 500);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function clickArrow(i) {
|
2012-06-14 12:31:44 +00:00
|
|
|
var originalValue = self.options.value;
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.value = Ox.limit(
|
2015-02-21 07:17:11 +00:00
|
|
|
parseFloat(self.options.value) + i * self.options.arrowStep,
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.min,
|
|
|
|
self.options.max
|
|
|
|
).toString();
|
2012-06-14 12:31:44 +00:00
|
|
|
if (self.options.value != originalValue) {
|
|
|
|
self.$input.val(self.options.value);//.focus();
|
|
|
|
that.triggerEvent('change', {value: self.options.value});
|
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
2011-09-17 17:39:38 +00:00
|
|
|
function clickMenu(data) {
|
2011-11-04 15:54:28 +00:00
|
|
|
//Ox.Log('Form', 'clickMenu', data);
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.value = data.title;
|
|
|
|
self.$input.val(self.options.value).focus();
|
|
|
|
that.gainFocus();
|
|
|
|
self.options.autocompleteSelectSubmit && submit();
|
|
|
|
}
|
|
|
|
|
2013-08-27 10:38:30 +00:00
|
|
|
function constructAutocompleteMenu() {
|
|
|
|
return Ox.Menu({
|
|
|
|
element: self.$input,
|
|
|
|
id: self.options.id + 'Menu', // fixme: we do this in other places ... are we doing it the same way? var name?,
|
|
|
|
maxWidth: self.options.autocompleteSelectMaxWidth,
|
2014-12-17 14:35:10 +00:00
|
|
|
offset: self.options.autocompleteSelectOffset
|
2013-08-27 10:38:30 +00:00
|
|
|
})
|
2014-09-26 10:24:34 +00:00
|
|
|
.addClass('OxAutocompleteMenu OxKeyboardFocus')
|
2013-08-27 10:38:30 +00:00
|
|
|
.bindEvent({
|
|
|
|
click: clickMenu,
|
|
|
|
key_enter: function() {
|
|
|
|
if (self.$autocompleteMenu.is(':visible')) {
|
|
|
|
self.$autocompleteMenu.hideMenu();
|
2014-12-17 19:27:04 +00:00
|
|
|
that.gainFocus();
|
2013-08-27 10:38:30 +00:00
|
|
|
submit();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-04-22 22:03:10 +00:00
|
|
|
function cursor(start, end) {
|
|
|
|
/*
|
|
|
|
cursor() returns [start, end]
|
|
|
|
cursor(start) sets start
|
|
|
|
cursor([start, end]) sets start and end
|
|
|
|
cursor(start, end) sets start and end
|
|
|
|
*/
|
|
|
|
var isArray = Ox.isArray(start);
|
|
|
|
if (arguments.length == 0) {
|
|
|
|
return [self.$input[0].selectionStart, self.$input[0].selectionEnd];
|
|
|
|
} else {
|
|
|
|
end = isArray ? start[1] : (end ? end : start);
|
|
|
|
start = isArray ? start[0] : start;
|
2012-05-25 21:42:10 +00:00
|
|
|
//IE8 does not have setSelectionRange
|
|
|
|
self.$input[0].setSelectionRange && self.$input[0].setSelectionRange(start, end);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function deselectMenu() {
|
2011-05-20 11:46:52 +00:00
|
|
|
return;
|
2011-11-04 15:54:28 +00:00
|
|
|
//Ox.Log('Form', 'deselectMenu')
|
2017-11-06 19:22:03 +00:00
|
|
|
/*
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.value = self.oldValue;
|
|
|
|
self.$input.val(self.options.value);
|
|
|
|
cursor(self.oldCursor);
|
2017-11-06 19:22:03 +00:00
|
|
|
*/
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function focus() {
|
|
|
|
if (
|
2011-10-29 10:01:28 +00:00
|
|
|
// that.hasClass('OxFocus') || // fixme: this is just a workaround, since for some reason, focus() gets called twice on focus
|
2011-04-22 22:03:10 +00:00
|
|
|
(self.$autocompleteMenu && self.$autocompleteMenu.is(':visible')) ||
|
|
|
|
(self.hasPasswordPlaceholder && self.$input.is(':visible'))
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
2011-08-12 21:00:42 +00:00
|
|
|
self.originalValue = self.options.value;
|
2011-04-22 22:03:10 +00:00
|
|
|
that.gainFocus();
|
2011-04-27 07:13:12 +00:00
|
|
|
that.is('.OxError') && that.removeClass('OxError');
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.placeholder && setPlaceholder();
|
|
|
|
if (self.bindKeyboard) {
|
|
|
|
// fixme: different in webkit and firefox (?), see keyboard handler, need generic function
|
2014-09-25 16:35:17 +00:00
|
|
|
Ox.$document.keydown(keydown);
|
|
|
|
//Ox.$document.keypress(keypress);
|
2011-11-11 11:48:52 +00:00
|
|
|
// temporarily disabled autocomplete on focus
|
|
|
|
//self.options.autocompleteSelect && setTimeout(autocomplete, 0); // fixme: why is the timeout needed?
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
2011-05-15 16:18:58 +00:00
|
|
|
that.triggerEvent('focus');
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function getInputWidth() {
|
2011-11-02 10:23:15 +00:00
|
|
|
return self.options.width
|
|
|
|
- (self.options.arrows ? 32 : 0)
|
|
|
|
- (self.options.clear ? 16 : 0)
|
|
|
|
- (self.options.label ? self.options.labelWidth : 0)
|
2014-05-10 13:10:54 +00:00
|
|
|
- (Ox.contains(['rounded', 'squared'], self.options.style) ? 14 : 6);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
2012-02-16 16:35:59 +00:00
|
|
|
function insert() {
|
|
|
|
var input = self.$input[0];
|
|
|
|
that.triggerEvent('insert', {
|
|
|
|
end: input.selectionEnd,
|
2012-05-22 14:08:09 +00:00
|
|
|
id: that.oxid,
|
2012-05-24 09:47:33 +00:00
|
|
|
selection: input.value.slice(input.selectionStart, input.selectionEnd),
|
2012-02-16 16:35:59 +00:00
|
|
|
start: input.selectionStart,
|
|
|
|
value: input.value
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2011-05-21 17:56:15 +00:00
|
|
|
function keydown(event) {
|
2011-04-22 22:03:10 +00:00
|
|
|
var oldCursor = cursor(),
|
|
|
|
oldValue = self.options.value,
|
2012-06-14 12:31:44 +00:00
|
|
|
newValue = oldValue.toString().slice(0, oldCursor[0] - 1),
|
2012-06-16 13:36:03 +00:00
|
|
|
hasDeletedSelectedEnd = (event.keyCode == 8 || event.keyCode == 46)
|
|
|
|
&& oldCursor[0] < oldCursor[1]
|
|
|
|
&& oldCursor[1] == oldValue.length;
|
2011-05-20 06:40:57 +00:00
|
|
|
if (
|
2011-10-29 10:01:28 +00:00
|
|
|
event.keyCode != 9 // tab
|
|
|
|
&& (self.options.type == 'textarea' || event.keyCode != 13) // enter
|
|
|
|
&& event.keyCode != 27 // escape
|
2011-05-20 06:40:57 +00:00
|
|
|
) { // fixme: can't 13 and 27 return false?
|
2011-04-22 22:03:10 +00:00
|
|
|
setTimeout(function() { // wait for val to be set
|
|
|
|
var value = self.$input.val();
|
2011-05-21 17:56:15 +00:00
|
|
|
if ((self.options.autocompleteReplace || self.options.decimals) && hasDeletedSelectedEnd) {
|
2011-11-04 15:54:28 +00:00
|
|
|
//Ox.Log('Form', 'HAS DELETED SELECTED END', event.keyCode)
|
2011-05-20 07:42:17 +00:00
|
|
|
value = newValue;
|
2011-04-22 22:03:10 +00:00
|
|
|
self.$input.val(value);
|
|
|
|
}
|
|
|
|
if (value != self.options.value) {
|
|
|
|
self.options.value = value;
|
2011-11-11 11:48:52 +00:00
|
|
|
Ox.Log('AUTO', 'call autocomplete from keydown')
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.autocomplete && autocomplete(oldValue, oldCursor);
|
|
|
|
self.options.autovalidate && autovalidate(oldValue, oldCursor);
|
2011-05-17 19:08:25 +00:00
|
|
|
self.options.changeOnKeypress && that.triggerEvent({
|
2012-02-15 16:13:09 +00:00
|
|
|
change: {value: self.options.value}
|
2011-05-17 19:08:25 +00:00
|
|
|
});
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
2014-02-03 13:30:50 +00:00
|
|
|
});
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
2011-05-20 06:40:57 +00:00
|
|
|
if (
|
2011-10-29 10:01:28 +00:00
|
|
|
(event.keyCode == 38 || event.keyCode == 40) // up/down
|
|
|
|
&& self.options.autocompleteSelect
|
|
|
|
&& self.$autocompleteMenu.is(':visible')
|
2011-05-20 06:40:57 +00:00
|
|
|
) {
|
|
|
|
//return false;
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function paste() {
|
2012-02-16 16:35:59 +00:00
|
|
|
// fixme: unused
|
2011-04-22 22:03:10 +00:00
|
|
|
var data = Ox.Clipboard.paste();
|
|
|
|
data.text && self.$input.val(data.text);
|
|
|
|
}
|
|
|
|
|
2011-09-17 17:39:38 +00:00
|
|
|
function selectMenu(data) {
|
2011-04-22 22:03:10 +00:00
|
|
|
var pos = cursor();
|
2011-05-20 11:46:52 +00:00
|
|
|
//if (self.options.value) {
|
2011-11-04 15:54:28 +00:00
|
|
|
//Ox.Log('Form', 'selectMenu', pos, data.title)
|
2012-06-16 20:48:30 +00:00
|
|
|
self.options.value = Ox.decodeHTMLEntities(data.title);
|
2011-05-20 11:46:52 +00:00
|
|
|
self.$input.val(self.options.value);
|
|
|
|
cursor(pos[0], self.options.value.length);
|
2012-02-15 16:13:09 +00:00
|
|
|
self.options.changeOnKeypress && that.triggerEvent({
|
|
|
|
change: {value: self.options.value}
|
|
|
|
});
|
2014-12-17 14:57:04 +00:00
|
|
|
if (self.options.autocompleteSelectUpdate) {
|
2014-12-17 15:43:43 +00:00
|
|
|
self.$autocompleteMenu.updatePosition();
|
2014-12-17 14:57:04 +00:00
|
|
|
}
|
2011-05-20 11:46:52 +00:00
|
|
|
//}
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function setPlaceholder() {
|
|
|
|
if (self.options.placeholder) {
|
|
|
|
if (that.hasClass('OxFocus')) {
|
|
|
|
if (self.options.value === '') {
|
|
|
|
if (self.options.type == 'password') {
|
|
|
|
self.$placeholder.hide();
|
2011-12-21 13:42:47 +00:00
|
|
|
self.$input.show().focus();
|
2011-04-22 22:03:10 +00:00
|
|
|
} else {
|
|
|
|
self.$input
|
|
|
|
.removeClass('OxPlaceholder')
|
|
|
|
.val('');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (self.options.value === '') {
|
|
|
|
if (self.options.type == 'password') {
|
|
|
|
self.$input.hide();
|
|
|
|
self.$placeholder.show();
|
|
|
|
} else {
|
|
|
|
self.$input
|
|
|
|
.addClass('OxPlaceholder')
|
|
|
|
.val(self.options.placeholder)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
self.$input
|
|
|
|
.removeClass('OxPlaceholder')
|
|
|
|
.val(self.options.value)
|
|
|
|
}
|
|
|
|
}
|
2011-11-10 10:02:04 +00:00
|
|
|
} else {
|
2011-11-11 11:08:54 +00:00
|
|
|
self.$input
|
|
|
|
.removeClass('OxPlaceholder')
|
|
|
|
.val(self.options.value);
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function setWidth() {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
function submit() {
|
2013-08-27 10:38:30 +00:00
|
|
|
cancelAutocomplete();
|
2011-11-06 11:37:07 +00:00
|
|
|
self.submitted = true;
|
2011-04-22 22:03:10 +00:00
|
|
|
self.$input.blur();
|
2011-11-06 11:37:07 +00:00
|
|
|
self.submitted = false;
|
|
|
|
//self.options.type == 'textarea' && self.$input.blur();
|
2012-06-16 13:36:03 +00:00
|
|
|
that.triggerEvent('submit', {value: self.options.value});
|
2011-04-22 22:03:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function validate() {
|
|
|
|
self.options.validate(self.options.value, function(data) {
|
|
|
|
that.triggerEvent('validate', data);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2012-05-21 10:38:18 +00:00
|
|
|
/*@
|
|
|
|
blurInput <f> blurInput
|
|
|
|
@*/
|
2011-05-16 18:05:29 +00:00
|
|
|
that.blurInput = function() {
|
|
|
|
self.$input.blur();
|
|
|
|
return that;
|
|
|
|
};
|
|
|
|
|
2012-05-21 10:38:18 +00:00
|
|
|
/*@
|
|
|
|
clearInput <f> clearInput
|
|
|
|
@*/
|
2011-05-17 07:19:30 +00:00
|
|
|
that.clearInput = function() {
|
|
|
|
clear();
|
|
|
|
return that;
|
2011-12-30 15:06:55 +00:00
|
|
|
};
|
2011-05-17 07:19:30 +00:00
|
|
|
|
2011-12-18 09:29:35 +00:00
|
|
|
/*@
|
|
|
|
focusInput <f> Focus input element
|
|
|
|
(select) -> <o> Input object
|
|
|
|
(start, end) -> <o> Input object
|
|
|
|
select <b|false> If true, select all, otherwise position cursor at the end
|
|
|
|
start <n> Selection start (can be negative)
|
|
|
|
end <n> Selection end (can be negative), or equal to start if omitted
|
|
|
|
@*/
|
|
|
|
that.focusInput = function() {
|
|
|
|
var length = self.$input.val().length,
|
|
|
|
start = Ox.isNumber(arguments[0])
|
|
|
|
? (arguments[0] < 0 ? length + arguments[0] : arguments[0])
|
2012-01-04 17:27:32 +00:00
|
|
|
: arguments[0] ? 0 : length,
|
2011-12-18 09:29:35 +00:00
|
|
|
stop = Ox.isNumber(arguments[1])
|
|
|
|
? (arguments[1] < 0 ? length + arguments[1] : arguments[1])
|
|
|
|
: Ox.isNumber(arguments[0]) ? arguments[0]
|
|
|
|
: arguments[0] ? length : 0;
|
2011-04-22 22:03:10 +00:00
|
|
|
self.$input.focus();
|
2011-12-18 09:29:35 +00:00
|
|
|
cursor(start, stop);
|
2011-04-22 22:03:10 +00:00
|
|
|
return that;
|
|
|
|
};
|
|
|
|
|
2012-05-21 10:38:18 +00:00
|
|
|
/*@
|
|
|
|
value <f> get/set value
|
|
|
|
@*/
|
2011-12-22 05:52:46 +00:00
|
|
|
// FIXME: deprecate, options are enough
|
2011-04-22 22:03:10 +00:00
|
|
|
that.value = function() {
|
2011-12-22 05:52:46 +00:00
|
|
|
if (arguments.length == 0) {
|
|
|
|
var value = self.$input.hasClass('OxPlaceholder') ? '' : self.$input.val();
|
|
|
|
if (self.options.type == 'float') {
|
|
|
|
value = parseFloat(value);
|
|
|
|
} else if (self.options.type == 'int') {
|
|
|
|
value = parseInt(value); // cannot have leading zero
|
|
|
|
}
|
|
|
|
return value;
|
|
|
|
} else {
|
|
|
|
return that.options({value: arguments[0]});
|
2011-05-24 11:43:27 +00:00
|
|
|
}
|
2011-04-22 22:03:10 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
return that;
|
|
|
|
|
|
|
|
};
|