diff --git a/build/css/ox.ui.classic.css b/build/css/ox.ui.classic.css
index d3209358..fb8b443a 100644
--- a/build/css/ox.ui.classic.css
+++ b/build/css/ox.ui.classic.css
@@ -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)
}
diff --git a/build/css/ox.ui.css b/build/css/ox.ui.css
index d25a7944..eecdc261 100644
--- a/build/css/ox.ui.css
+++ b/build/css/ox.ui.css
@@ -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;
}
/*
diff --git a/build/js/ox.ui.js b/build/js/ox.ui.js
index a06256ea..74520f24 100644
--- a/build/js/ox.ui.js
+++ b/build/js/ox.ui.js
@@ -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"),
+ "$1"
+ );
+ }
+ 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) {
};
diff --git a/build/png/ox.ui.classic/buttonClear.png b/build/png/ox.ui.classic/buttonClear.png
new file mode 100644
index 00000000..620e25bd
Binary files /dev/null and b/build/png/ox.ui.classic/buttonClear.png differ
diff --git a/build/png/ox.ui.classic/buttonSelect.png b/build/png/ox.ui.classic/buttonSelect.png
new file mode 100644
index 00000000..28ef8b22
Binary files /dev/null and b/build/png/ox.ui.classic/buttonSelect.png differ
diff --git a/demos/test/index.html b/demos/test/index.html
index 96b29e51..85b54962 100644
--- a/demos/test/index.html
+++ b/demos/test/index.html
@@ -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"),
- "$1")
- );
- }
- });
- }
- 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") {
diff --git a/source/psd/buttons.psd b/source/psd/buttons.psd
index c307394f..06c894ff 100644
Binary files a/source/psd/buttons.psd and b/source/psd/buttons.psd differ