From 07c79ed7ac6948767124a80dde2369ab8e374ffd Mon Sep 17 00:00:00 2001 From: rlx <0x0073@0x2620.org> Date: Thu, 10 Nov 2011 19:52:26 +0000 Subject: [PATCH] updates to url controller, filter and form elements --- source/Ox.UI/js/Core/Ox.URL.js | 65 ++++++++-- source/Ox.UI/js/Form/Ox.Filter.js | 125 +++++++++++--------- source/Ox.UI/js/Form/Ox.FormElementGroup.js | 11 +- source/Ox.UI/js/Form/Ox.InputGroup.js | 5 +- source/Ox.UI/js/Form/Ox.TimeInput.js | 6 +- source/Ox/js/Date.js | 24 ++-- source/Ox/js/Format.js | 5 +- 7 files changed, 162 insertions(+), 79 deletions(-) diff --git a/source/Ox.UI/js/Core/Ox.URL.js b/source/Ox.UI/js/Core/Ox.URL.js index 76fd0ce0..a0e902e3 100644 --- a/source/Ox.UI/js/Core/Ox.URL.js +++ b/source/Ox.UI/js/Core/Ox.URL.js @@ -172,9 +172,12 @@ Ox.URL = function(options) { function constructCondition(condition) { var key = condition.key == '*' ? '' : condition.key, operator = condition.operator, - value = ( - Ox.isArray(condition.value) ? condition.value : [condition.value] - ).map(encodeValue).join(':'); + value; + value = ( + Ox.isArray(condition.value) ? condition.value : [condition.value] + ).map(function(value) { + return encodeValue(constructValue(value, condition.key)); + }).join(','); if (!key) { operator = operator.replace('=', ''); } else if (operator.indexOf('^') > -1) { @@ -267,6 +270,17 @@ Ox.URL = function(options) { }).join('/'); } + function constructValue(str, key) { + var findKey = Ox.getObjectById(self.options.findKeys, key), + list = findKey.list, + type = Ox.isArray(findKey.type) ? findKey.type[0] : findKey.type, + value = str; + if (type == 'list') { + return list[value]; + } + return value; + } + function decodeValue(str) { return decodeURIComponent(str); } @@ -275,7 +289,7 @@ Ox.URL = function(options) { // var chars = '/&|()=*:'; var chars = '&|()=*', ret = ''; - str.split('').forEach(function(char) { + str.toString().split('').forEach(function(char) { var index = chars.indexOf(char); ret += index > -1 ? '%' + char.charCodeAt(0).toString(16).toUpperCase() @@ -338,10 +352,12 @@ Ox.URL = function(options) { condition.operator = condition.operator.replace('=', '^') } } - if (condition.value.indexOf(':') > -1) { - condition.value = condition.value.split(':').map(decodeValue); + if (condition.value.indexOf(',') > -1) { + condition.value = condition.value.split(',').map(function(value) { + return parseValue(decodeValue(value), condition.key); + }); } else { - condition.value = decodeValue(condition.value); + condition.value = parseValue(decodeValue(condition.value), condition.key); } return condition; } @@ -429,6 +445,16 @@ Ox.URL = function(options) { ); } + function parseTime(str) { + var split = str.split(':').reverse(); + while (split.length > 3) { + split.pop(); + } + return Ox.formatDuration(split.reduce(function(prev, curr, i) { + return prev + (parseFloat(curr) || 0) * Math.pow(60, i); + }, 0)); + } + function parseURL(str, callback) { // fixme: removing trailing slash makes it impossible to search for '/' str = str.replace(/(^\/|\/$)/g, ''); @@ -589,6 +615,31 @@ Ox.URL = function(options) { } } + function parseValue(str, key) { + var findKey = Ox.getObjectById(self.options.findKeys, key), + list = findKey.list, + type = Ox.isArray(findKey.type) ? findKey.type[0] : findKey.type, + value = str; + if (type == 'boolean') { + value = ['', 'false'].indexOf(str) == -1; + } else if (type == 'date') { + value = Ox.formatDate(Ox.parseDate(str, true), '%F', true); + } else if (type == 'float') { + value = parseFloat(str) || 0; + } else if (type == 'integer') { + value = Math.round(str) || 0; + } else if (type == 'list') { + value = Math.max(list.map(function(value) { + return value.toLowerCase(); + }).indexOf(str.toLowerCase()), 0); + } else if (type == 'time') { + value = parseTime(value); + } else if (type == 'year') { + value = Math.round(str) || 1970; + } + return value.toString(); + } + function saveURL() { } diff --git a/source/Ox.UI/js/Form/Ox.Filter.js b/source/Ox.UI/js/Form/Ox.Filter.js index caee42f5..f426030b 100644 --- a/source/Ox.UI/js/Form/Ox.Filter.js +++ b/source/Ox.UI/js/Form/Ox.Filter.js @@ -61,12 +61,18 @@ Ox.Filter = function(options, self) { {id: '!<', title: 'is not before'}, {id: '>', title: 'is after'}, {id: '!>', title: 'is not after'}, - {id: '=:', title: 'is between'}, - {id: '!=:', title: 'is not between'} + {id: '=,', title: 'is between'}, + {id: '!=,', title: 'is not between'} ], list: [ {id: '=', title: 'is'}, - {id: '!=', title: 'is not'} + {id: '!=', title: 'is not'}, + {id: '<', title: 'is less than'}, + {id: '!<', title: 'is not less than'}, + {id: '>', title: 'is greater than'}, + {id: '!>', title: 'is not greater than'}, + {id: '=,', title: 'is between'}, + {id: '!=,', title: 'is not between'} ], number: [ {id: '=', title: 'is'}, @@ -75,12 +81,8 @@ Ox.Filter = function(options, self) { {id: '!<', title: 'is not less than'}, {id: '>', title: 'is greater than'}, {id: '!>', title: 'is not greater than'}, - {id: '=:', title: 'is between'}, - {id: '!=:', title: 'is not between'}/*, - {id: '^', title: 'starts with'}, - {id: '!^', title: 'does not start with'}, - {id: '$', title: 'ends with'}, - {id: '!$', title: 'does not end with'}*/ + {id: '=,', title: 'is between'}, + {id: '!=,', title: 'is not between'} ], string: [ {id: '==', title: 'is'}, @@ -95,24 +97,18 @@ Ox.Filter = function(options, self) { text: [ {id: '=', title: 'contains'}, {id: '!=', title: 'does not contain'} - ], - year: [ - {id: '=', title: 'is'}, - {id: '!=', title: 'is not'}, - {id: '<', title: 'is before'}, - {id: '!<', title: 'is not before'}, - {id: '>', title: 'is after'}, - {id: '!>', title: 'is not after'}, - {id: '=:', title: 'is between'}, - {id: '!=:', title: 'is not between'} ] }; self.defaultValue = { boolean: 'true', date: Ox.formatDate(new Date(), '%F'), - number: 0, + float: 0, + hue: 0, + integer: 0, + list: 0, string: '', text: '', + time: '00:00:00', year: new Date().getFullYear() }; self.operators = [ @@ -319,24 +315,26 @@ Ox.Filter = function(options, self) { var condition = subpos == -1 ? self.options.query.conditions[pos] : self.options.query.conditions[pos].conditions[subpos], - oldOperator = condition.operator, - oldType = Ox.getObjectById(self.options.findKeys, condition.key).type, - newType = Ox.getObjectById(self.options.findKeys, key).type, - oldConditionType = getConditionType(oldType), - newConditionType = getConditionType(newType), + oldFindKey = Ox.getObjectById(self.options.findKeys, condition.key), + newFindKey = Ox.getObjectById(self.options.findKeys, key), + oldConditionType = getConditionType(oldFindKey.type), + newConditionType = getConditionType(newFindKey.type), changeConditionType = oldConditionType != newConditionType, + changeConditionFormat = !Ox.isEqual(oldFindKey.format, newFindKey.format), wasUselessCondition = isUselessCondition(pos, subpos); Ox.Log('Form', 'old new', oldConditionType, newConditionType) condition.key = key; - if (changeConditionType) { + if (changeConditionType || changeConditionFormat) { + if (Ox.getPositionById(self.conditionOperators[newConditionType], condition.operator) == -1) { + condition.operator = self.conditionOperators[newConditionType][0].id; + } if ( ['string', 'text'].indexOf(oldConditionType) == -1 || ['string', 'text'].indexOf(newConditionType) == -1 ) { - condition.value = self.defaultValue[newType]; + condition.value = self.defaultValue[newFindKey.type]; } renderConditions(); - //self.$conditions[pos].replaceElement(1, constructConditionOperator(pos, oldOperator)); } if (!(wasUselessCondition && isUselessCondition(pos, subpos))) { triggerChangeEvent(); @@ -349,13 +347,13 @@ Ox.Filter = function(options, self) { var condition = subpos == -1 ? self.options.query.conditions[pos] : self.options.query.conditions[pos].conditions[subpos], - isBetween = operator.indexOf(':') > -1, + isBetween = operator.indexOf(',') > -1, wasBetween = Ox.isArray(condition.value), wasUselessCondition = isUselessCondition(pos, subpos); Ox.Log('FILTER', 'chCoOp', 'iB/wB', isBetween, wasBetween) condition.operator = operator; if (isBetween && !wasBetween) { - condition.operator = condition.operator.replace(':', ''); + condition.operator = condition.operator.replace(',', ''); condition.value = [condition.value, condition.value] renderConditions(); } else if (!isBetween && wasBetween) { @@ -368,10 +366,10 @@ Ox.Filter = function(options, self) { } function changeConditionValue(pos, subpos, value) { + Ox.Log('FILTER', 'cCV', pos, subpos, value); var condition = subpos == -1 ? self.options.query.conditions[pos] : self.options.query.conditions[pos].conditions[subpos]; - // fixme: change to number if needed condition.value = value; triggerChangeEvent(); } @@ -391,7 +389,7 @@ Ox.Filter = function(options, self) { function getConditionType(type) { type = Ox.isArray(type) ? type[0] : type; - if (['float', 'hue', 'integer', 'year'].indexOf(type) > -1) { + if (['float', 'hue', 'integer', 'time', 'year'].indexOf(type) > -1) { type = 'number'; } return type; @@ -543,7 +541,7 @@ Ox.Filter = function(options, self) { return { // fixme: should be "selected", not "checked" checked: Ox.isArray(condition.value) - ? operator.id == condition.operator + ':' + ? operator.id == condition.operator + ',' : operator.id == condition.operator, id: operator.id, title: operator.title @@ -578,6 +576,7 @@ Ox.Filter = function(options, self) { }) ).bindEvent({ change: function(data) { + Ox.Log('FILTER', 'change event', data) var $element = data._element.parent(); changeConditionValue( $element.data('position'), @@ -657,9 +656,27 @@ Ox.Filter = function(options, self) { findKey = Ox.getObjectById(self.options.findKeys, condition.key), isArray = Ox.isArray(condition.value), isHue, + // FIXME: always use 'int' type = findKey.type == 'integer' ? 'int' : findKey.type, + value = !isArray ? condition.value : condition.value[index], formatArgs, formatType, title; - if (findKey.format) { + if (type == 'boolean') { + $input = Ox.Select({ + items: [ + {id: 'true', title: 'true', checked: value == 'true'}, + {id: 'false', title: 'false', checked: value == 'false'} + ], + width: 288 + }); + } else if (type == 'list') { + Ox.Log('FILTER', findKey, condition) + $input = Ox.Select({ + items: findKey.list.map(function(v, i) { + return {id: i, title: v, checked: i == value} + }), + width: !isArray ? 288 : 128 + }); + } else if (findKey.format) { formatArgs = findKey.format.args formatType = findKey.format.type; if (formatType == 'color') { @@ -681,20 +698,20 @@ Ox.Filter = function(options, self) { }); } else if (formatType == 'date') { $input = Ox.DateInput(!isArray ? { - value: condition.value, + value: value, width: {day: 66, month: 66, year: 140} } : { - value: condition.value[index], + value: value, width: {day: 32, month: 32, year: 48} }); } else if (formatType == 'duration') { $input = Ox.TimeInput(!isArray ? { seconds: true, - value: '00:00:00', + value: value, width: {hours: 91, minutes: 91, seconds: 90} } : { seconds: true, - value: '00:00:00', + value: value, width: {hours: 38, minutes: 37, seconds: 37} }); } else if ([ @@ -705,13 +722,13 @@ Ox.Filter = function(options, self) { elements: [ Ox.Input({ type: type, - value: !isArray ? condition.value : condition.value[index], + value: value, width: !isArray ? 240 : 80 }), formatType == 'value' ? Ox.Select({ overlap: 'left', - items: ['K', 'M', 'G', 'T'].map(function(prefix) { - return {id: prefix + title, title: prefix + title}; + items: ['K', 'M', 'G', 'T'].map(function(prefix, i) { + return {id: Math.pow(1000, i + 1), title: prefix + title}; }), width: 48 }) : Ox.Label({ @@ -722,25 +739,21 @@ Ox.Filter = function(options, self) { }) ], float: 'right', + joinValues: function(values) { + Ox.print(values, '?????') + return formatType == 'value' + ? values[0] * values[1] + : values[0]; + }, width: !isArray ? 288 : 128 }) } } else { - if (type == 'boolean') { - $input = Ox.Select({ - items: [ - {id: 'true', title: 'true'}, - {id: 'false', title: 'false'} - ], - width: 288 - }); - } else { - $input = Ox.Input({ - type: type, - value: !isArray ? condition.value : condition.value[index], - width: !isArray ? 288 : 128 - }); - } + $input = Ox.Input({ + type: type, + value: value, + width: !isArray ? 288 : 128 + }); } return $input; } diff --git a/source/Ox.UI/js/Form/Ox.FormElementGroup.js b/source/Ox.UI/js/Form/Ox.FormElementGroup.js index 0b2294ec..b7df468a 100644 --- a/source/Ox.UI/js/Form/Ox.FormElementGroup.js +++ b/source/Ox.UI/js/Form/Ox.FormElementGroup.js @@ -24,6 +24,7 @@ Ox.FormElementGroup = function(options, self) { id: '', elements: [], float: 'left', + joinValues: null, separators: [], width: 0 }) @@ -32,7 +33,7 @@ Ox.FormElementGroup = function(options, self) { ( self.options.float == 'left' ? - self.options.elements : self.options.elements.reverse() + self.options.elements : Ox.clone(self.options.elements).reverse() ).forEach(function($element, i) { $element.css({ float: self.options.float // fixme: make this a class @@ -41,6 +42,9 @@ Ox.FormElementGroup = function(options, self) { autovalidate: function(data) { that.triggerEvent({autovalidate: data}); }, + change: function(data) { + that.triggerEvent({change: {value: that.value()}}); + }, validate: function(data) { that.triggerEvent({validate: data}); } @@ -78,13 +82,16 @@ Ox.FormElementGroup = function(options, self) { }; that.value = function() { - return self.options.elements.map(function(element) { + var values = self.options.elements.map(function(element) { var ret = null; ['checked', 'selected', 'value'].forEach(function(v) { element[v] && (ret = element[v]()); }); return ret; }); + return self.options.joinValues + ? self.options.joinValues(values) + : values; }; return that; diff --git a/source/Ox.UI/js/Form/Ox.InputGroup.js b/source/Ox.UI/js/Form/Ox.InputGroup.js index 5fd8ef72..c0b8ff80 100644 --- a/source/Ox.UI/js/Form/Ox.InputGroup.js +++ b/source/Ox.UI/js/Form/Ox.InputGroup.js @@ -137,13 +137,16 @@ Ox.InputGroup = function(options, self) { }; that.value = function() { - return self.options.inputs.map(function(input) { + var values = self.options.inputs.map(function(input) { var ret = null; ['checked', 'selected', 'value'].forEach(function(v) { input[v] && (ret = input[v]()); }); return ret; }); + return self.options.joinValues + ? self.options.joinValues(values) + : values; }; return that; diff --git a/source/Ox.UI/js/Form/Ox.TimeInput.js b/source/Ox.UI/js/Form/Ox.TimeInput.js index 31563210..90fe7c58 100644 --- a/source/Ox.UI/js/Form/Ox.TimeInput.js +++ b/source/Ox.UI/js/Form/Ox.TimeInput.js @@ -113,6 +113,10 @@ Ox.TimeInput = function(options, self) { ] : [], self.options.ampm ? [ self.$input.ampm ] : []), + joinValues: function(values) { + setValue(); + return self.options.value; + }, separators: Ox.merge([ {title: ':', width: 8}, ], self.options.seconds ? [ @@ -125,7 +129,7 @@ Ox.TimeInput = function(options, self) { width: 0 //width: self.options.width || 128 }), self) - .bindEvent('change', setValue); + /*.bindEvent('change', setValue)*/; setValue(); diff --git a/source/Ox/js/Date.js b/source/Ox/js/Date.js index 171bbe30..d3b679ef 100644 --- a/source/Ox/js/Date.js +++ b/source/Ox/js/Date.js @@ -278,16 +278,20 @@ Ox.parseDate = function(str, utc) { var date = new Date(0), defaults = [, 1, 1, 0, 0, 0], values = /(-?\d+)-?(\d+)?-?(\d+)? ?(\d+)?:?(\d+)?:?(\d+)?/.exec(str); - values.shift(); - values = values.map(function(v, i) { - return v || defaults[i]; - }); - values[1]--; - [ - 'FullYear', 'Month', 'Date', 'Hours', 'Minutes', 'Seconds' - ].forEach(function(part, i) { - Ox['set' + part](date, values[i], utc); - }); + if (values) { + values.shift(); + values = values.map(function(v, i) { + return v || defaults[i]; + }); + values[1]--; + [ + 'FullYear', 'Month', 'Date', 'Hours', 'Minutes', 'Seconds' + ].forEach(function(part, i) { + Ox['set' + part](date, values[i], utc); + }); + } else { + date = null; + } return date; }; diff --git a/source/Ox/js/Format.js b/source/Ox/js/Format.js index d0ff62d5..f6e333b8 100644 --- a/source/Ox/js/Format.js +++ b/source/Ox/js/Format.js @@ -548,6 +548,7 @@ Ox.formatValue = function(num, str, bin) { /*@ Ox.formatUnit Formats a number with a unit @*/ -Ox.formatUnit = function(num, str) { - return Ox.formatNumber(num, 3) + ' ' + str; +Ox.formatUnit = function(num, str, dec) { + dec = Ox.isUndefined(dec) ? 3 : dec; + return Ox.formatNumber(num, dec) + (str == '%' ? '' : ' ') + str; };