autocomplete, continued

This commit is contained in:
Rolux 2010-02-19 15:54:02 +05:30
parent 07ec8f30f7
commit c533678f44
7 changed files with 308 additions and 82 deletions

View file

@ -58,6 +58,7 @@ Forms
color: rgb(64, 64, 64);
}
.OxThemeClassic .OxButton,
.OxThemeClassic div.OxInput,
.OxThemeClassic .OxRange {
//background: -moz-linear-gradient(left top, left bottom, from(rgb(192, 192, 192)), to(rgb(160, 160, 160)));
//background: -webkit-gradient(linear, left top, left bottom, from(rgb(192, 192, 192)), to(rgb(160, 160, 160)));
@ -89,17 +90,17 @@ Forms
border-bottom: 1px solid rgb(192, 192, 192);
}
.OxThemeClassic .OxInput,
.OxThemeClassic input.OxInput,
.OxThemeClassic .OxTrack {
background: -moz-linear-gradient(top, rgb(224, 224, 224), rgb(255, 255, 255));
background: -webkit-gradient(linear, left top, left bottom, from(rgb(224, 224, 224)), to(rgb(255, 255, 255)));
}
.OxThemeClassic .OxInput:focus {
.OxThemeClassic input.OxInput:focus {
border: 1px solid rgb(160, 160, 160);
-moz-box-shadow: 0 0 2px rgb(128, 128, 128);
-webkit-box-shadow: 0 2 4px rgb(128, 128, 128);
-webkit-box-shadow: 0 0 2px rgb(128, 128, 128);
}
.OxThemeClassic .OxInput.OxPlaceholder {
.OxThemeClassic input.OxInput.OxPlaceholder {
color: rgb(160, 160, 160)
}

View file

@ -274,6 +274,32 @@ OxButtonGroup
}
/*
--------------------------------------------------------------------------------
OxInput
--------------------------------------------------------------------------------
*/
div.OxInput {
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
}
div.OxInput.OxMedium {
height: 14px;
}
div.OxInput > .OxButton:first-child {
float: left;
margin-top: -1px;
}
div.OxInput > .OxButton:last-child {
float: left;
margin-left: -1px;
margin-top: -1px;
}
input.OxInput {
float: left;
margin-left: -1px;
margin-top: -1px;
}
/*
--------------------------------------------------------------------------------
OxRange
--------------------------------------------------------------------------------
*/
@ -319,7 +345,7 @@ OxSelect
--------------------------------------------------------------------------------
*/
.OxSelect.OxMedium {
padding: 0 8px 0 8px;
}
.OxSelect > .OxButton {
text-align: left;
@ -331,7 +357,7 @@ OxSelect
-webkit-user-select: none;
}
.OxSelect.OxMedium > .OxSymbol {
margin: -16px 8px 0 8px;
margin: -16px 0 0 8px;
}
/*

View file

@ -1530,54 +1530,157 @@ requires
*/
Ox.Input = function(options, self) {
/* options:
* autocomplete function, or array of values, or dict with array of values per label or placeholder
* clear boolean, clear button, or not
* highlight boolean, highlight value in autocomplete menu, or not
* id
* label string or array (select) -- label and placeholder are mutually exclusive
* labelWidth integer (px)
* placeholder string or array (select) -- label and placeholder are mutually exclusive
* selected integer, selected label or placeholder
* size "large", "medium" or "small"
* type "text", "password", "textarea", etc.
*/
var self = self || {},
that = new Ox.Element(
options.type == "textarea" ? "textarea" : "input", self
)
that = new Ox.Element("div", self)
.defaults({
autocomplete: null,
clear: false,
highlight: false,
id: "",
placeholder: "", // can be [], will result in select
label: "",
labelWidth: 0,
placeholder: "",
selected: 0,
size: "medium",
type: "text"
})
.options(options || {})
.attr({
placeholder: self.options.placeholder
.addClass("OxInput Ox" + Ox.toTitleCase(self.options.size)),
autocomplete;
if (self.options.label) {
self.options.label = Ox.makeArray(self.options.label);
self.label = self.options.label[0];
} else if (self.options.placeholder) {
self.options.placeholder = Ox.makeArray(self.options.placeholder);
self.placeholder = self.options.placeholder[0];
}
if (Ox.isArray(self.options.autocomplete)) {
autocomplete = self.options.autocomplete;
self.options.autocomplete = {};
self.options.autocomplete[self.placeholder] = autocomplete;
}
if (self.options.label) {
that.$label = "foo";
} else if (self.options.placeholder.length > 1) {
that.$select = new Ox.Button({
style: "symbol",
type: "image",
value: "select"
})
.addClass(
"OxInput Ox" + Ox.toTitleCase(self.options.size) +
" OxPlaceholder"
)
.focus(focus)
.blur(blur)
.change(change);
if (options.autocomplete) {
self.element = that.$element[0];
self.menuId = self.options.id + "_menu"; // fixme: we do this in other places ... are we doing it the same way? var name?
self.menu = new Ox.Menu({
.click(select)
.appendTo(that);
self.placeholderId = self.options.id + "_placeholder";
self.placeholderMenu = new Ox.Menu({
element: that,
id: self.menuId,
id: self.placeholderId,
items: $.map(self.options.placeholder, function(title, position) {
return {
checked: position == self.options.selected,
id: title.toLowerCase(),
group: self.placeholderId, // fixme: same id, works here, but should be different
title: title
};
})
});
that.bindEvent("change_" + self.placeholderId, changePlaceholder);
}
that.$input = new Ox.Element(
self.options.type == "textarea" ? "textarea" : "input", self
)
.attr({
placeholder: self.placeholder,
type: self.options.type == "textarea" ? null : self.options.type
})
.addClass(
"OxInput Ox" + Ox.toTitleCase(self.options.size) +
" OxPlaceholder"
)
.focus(focus)
.blur(blur)
.change(change)
.appendTo(that);
if (self.options.clear) {
that.$clear = new Ox.Button({
style: "symbol",
type: "image",
value: "clear"
})
.click(clear)
.appendTo(that);
}
if (options.autocomplete) {
self.autocompleteId = self.options.id + "_menu"; // fixme: we do this in other places ... are we doing it the same way? var name?
self.autocompleteMenu = new Ox.Menu({
element: that,
id: self.autocompleteId,
offset: {
left: 4,
top: 0
},
size: self.options.size
});
that.bindEvent("click_" + self.menuId, onClick);
//that.bindEvent("deselect_" + self.menuId, onDeselect);
//that.bindEvent("select_" + self.menuId, onSelect);
that.bindEvent("click_" + self.autocompleteId, onClick);
}
if (options.type != "textarea") {
that.attr({
type: self.options.type
});
that.bindEvent({
key_enter: submit,
key_escape: cancel
});
function autocomplete(value, callback) {
value = value.toLowerCase();
var items = [];
if (value === "") {
items = self.options.autocomplete[self.placeholder];
} else {
$.each(self.options.autocomplete[self.placeholder], function(i, item) {
if (item.toLowerCase().indexOf(value) > -1) {
if (self.options.highlight) {
item = item.replace(
new RegExp("(" + value + ")", "ig"),
"<span class=\"OxHighlight\">$1</span>"
);
}
items.push(item);
}
});
}
callback(items);
}
function autocomplete(items) {
function call() {
var value = that.$input.val();
if (self.options.autocomplete) {
Ox.isFunction(self.options.autocomplete) ?
self.options.autocomplete(value, callback) :
autocomplete(value, callback);
}
}
function callback(items) {
var selected = 0;
if (items.length) {
items = $.map(items, function(title, position) {
if (that.val().toLowerCase() == Ox.stripTags(title.toLowerCase())) {
if (that.$input.val().toLowerCase() == Ox.stripTags(title.toLowerCase())) {
selected = position;
}
return {
@ -1585,54 +1688,88 @@ requires
title: title
};
});
self.menu.options({
self.placeholderMenu.hideMenu();
self.autocompleteMenu.options({
items: items,
selected: selected
}).showMenu();
} else {
self.menu.hideMenu();
self.autocompleteMenu.hideMenu();
}
}
function cancel() {
that.$input.trigger("blur");
}
function clear() {
that.$input.val("");
}
function change() {
}
function changePlaceholder(event, data) {
Ox.print("cP", event, data);
self.placeholder = data.value; // fixme: could be "title" as well
if (that.$input.is(".OxPlaceholder")) {
that.$input.val(self.placeholder);
}
call();
}
function blur() {
if (that.val() === "") {
that.addClass("OxPlaceholder").val(that.attr("placeholder"));
that.loseFocus();
if (that.$input.val() === "") {
that.$input.addClass("OxPlaceholder").val(that.$input.attr("placeholder"));
}
if (self.options.autocomplete) {
$document.unbind("keydown", keypress);
$document.unbind("keypress", keypress);
}
}
function focus() {
if (that.is(".OxPlaceholder")) {
that.val("").removeClass("OxPlaceholder");
that.gainFocus();
if (that.$input.is(".OxPlaceholder")) {
that.$input.val("").removeClass("OxPlaceholder");
}
if (self.options.autocomplete) {
// fixme: different in webkit and firefox (?), see keyboard handler, need generic function
$document.bind("keydown", keypress);
$document.bind("keypress", keypress);
self.options.autocomplete(that.val(), autocomplete);
Ox.isFunction(self.options.autocomplete) ?
self.options.autocomplete(that.$input.val(), callback) :
autocomplete(that.$input.val(), callback);
}
}
function keypress(event) {
if (event.keyCode != 13) {
setTimeout(function() {
var value = that.val();
if (self.options.autocomplete && value != self.value) {
var value = that.$input.val();
if (value != self.value) {
self.value = value;
self.options.autocomplete(value, autocomplete);
call();
}
}, 25);
}
}
function onClick(event, data) {
Ox.print("onClick", data)
that.focus().val(Ox.stripTags(data.title));
self.menu.hideMenu();
that.$input.focus().val(Ox.stripTags(data.title));
self.autocompleteMenu.hideMenu();
submit();
}
function select() {
self.placeholderMenu.showMenu();
}
function selection() {
// fixme: not used!
var start, end;
if (arguments.length == 0) {
return [self.element.selectionStart, self.element.selectionEnd];
@ -1642,7 +1779,22 @@ requires
self.element.setSelectionRange(start, end);
}
}
function submit() {
that.$input.trigger("blur");
that.triggerEvent("submit", that.$input.val());
}
that.width = function(value) {
that.$element.width(value);
that.$input.width(value - 2 - self.options.labelWidth -
(self.options.placeholder.length > 1) * 21 -
self.options.clear * 21);
return that;
}
return that;
};
/*
@ -1874,7 +2026,7 @@ requires
Ox.Select = function(options, self) {
var self = self || {},
that = new Ox.Element("div", self)
that = new Ox.Element("div", self) // fixme: do we use "div", or {}, or "", by default?
.defaults({
id: "",
items: [],
@ -1945,7 +2097,7 @@ requires
that.width = function(val) {
// fixme: silly hack, and won't work for css()
that.$element.width(val);
that.$element.width(val + 16);
that.$button.width(val);
that.$symbol.width(val);
return that;
@ -1982,14 +2134,21 @@ requires
Ox.MainMenu = function(options, self) {
/* options:
* extras
* menus
* size
*/
var self = self || {},
that = new Ox.Bar({}, self)
.defaults({
extras: [],
menus: [],
size: "medium"
})
.options(options || {})
.addClass("OxMainMenu Ox" + Ox.toTitleCase(self.options.size)) // fixme: bar should accept small/medium/large
.addClass("OxMainMenu Ox" + Ox.toTitleCase(self.options.size)) // fixme: bar should accept small/medium/large ... like toolbar
.click(click)
.mousemove(mousemove);
@ -2067,11 +2226,11 @@ requires
};
that.addMenuAfter = function() {
that.addMenuAfter = function(id) {
};
that.addMenuBefore = function() {
that.addMenuBefore = function(id) {
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View file

@ -290,6 +290,12 @@
type: "text",
value: "Foo"
}).addClass("margin").appendTo(mainPanel);
Ox.Button({
selectable: true,
size: size,
type: "text",
value: "Bar"
}).addClass("margin").appendTo(mainPanel);
Ox.Select({
id: "select1",
items: [
@ -326,40 +332,74 @@
}
]
}).addClass("margin").width(96).appendTo(mainPanel);
Ox.Button({
selectable: true,
size: size,
type: "text",
value: "Foo"
}).addClass("margin").appendTo(mainPanel);
Ox.Button({
selectable: true,
size: size,
type: "text",
value: "Bar"
}).addClass("margin").appendTo(mainPanel);
Ox.Input({
id: "state",
autocomplete: function(value, callback) {
value = value.toLowerCase();
var items = [],
states = [
"Alabama", "Alaska", "Arizona", "Arkansas", "California",
"Colorado", "Connecticut", "Delaware", "District of Columbia", "Florida",
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana",
"Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
"Maryland", "Massachusetts", "Michigan", "Minnessota", "Mississippi",
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire",
"New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas", "Utah",
"Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin",
"Wyoming"
];
if (value === "") {
items = states;
} else {
$.each(states, function(i, state) {
if (state.toLowerCase().indexOf(value) > -1) {
items.push(state.replace(
new RegExp("(" + value + ")", "ig"),
"<span class=\"OxHighlight\">$1</span>")
);
}
});
}
callback(items);
autocomplete: {
City: [
"Albuquerque",
"Austin",
"Baltimore",
"Boston",
"Chicago",
"Cleveland",
"Dallas",
"Denver",
"Detroit",
"El Paso",
"Honululu",
"Houston",
"Kansas City",
"Las Vegas",
"Los Angeles",
"Memphis",
"Miami",
"Minneapolis",
"Nashville",
"New Orleans",
"New York",
"Oklahoma City",
"Philadelphia",
"Phoenix",
"Pittsburgh",
"Portland",
"San Antonio",
"San Diego",
"San Francisco",
"St. Louis",
"St. Paul",
"Seattle",
"Washington"
],
State: [
"Alabama", "Alaska", "Arizona", "Arkansas", "California",
"Colorado", "Connecticut", "Delaware", "District of Columbia", "Florida",
"Georgia", "Hawaii", "Idaho", "Illinois", "Indiana",
"Iowa", "Kansas", "Kentucky", "Louisiana", "Maine",
"Maryland", "Massachusetts", "Michigan", "Minnessota", "Mississippi",
"Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire",
"New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota",
"Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island",
"South Carolina", "South Dakota", "Tennessee", "Texas", "Utah",
"Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin",
"Wyoming"
]
},
placeholder: "State"
}).addClass("margin").width(96).appendTo(mainPanel);
clear: true,
highlight: true,
id: "citystate",
placeholder: ["City", "State"]
}).addClass("margin").width(128).appendTo(mainPanel);
//*/
function switchTheme() {
if (Ox.theme() == "classic") {

Binary file not shown.