oxjs/source/Ox.UI/js/Form/Form.js

185 lines
5.3 KiB
JavaScript
Raw Normal View History

2011-11-05 16:46:53 +00:00
'use strict';
2011-05-16 08:24:46 +00:00
/*@
2012-05-31 10:32:54 +00:00
Ox.Form <f> Form Object
([options[, self]]) -> <o:Ox.Element> Form Object
2012-06-17 22:38:26 +00:00
change <!> change
validate <!> validate
submit <!> submit
2011-05-16 08:24:46 +00:00
options <o> Options object
error <s> error
id <s> id
2011-05-16 10:49:48 +00:00
items <a|[]> []
2011-05-16 08:24:46 +00:00
self <o> shared private variable
@*/
Ox.Form = function(options, self) {
2011-04-22 22:03:10 +00:00
self = self || {};
var that = Ox.Element({}, self)
2011-04-22 22:03:10 +00:00
.defaults({
error: '',
id: '',
items: [],
2011-12-30 09:33:01 +00:00
validate: function(valid) {
return Ox.every(valid);
}
2011-04-22 22:03:10 +00:00
})
.options(options || {}) // fixme: the || {} can be done once, in the options function
.addClass('OxForm');
Ox.extend(self, {
2011-04-22 22:03:10 +00:00
$items: [],
$messages: [],
itemIds: [],
itemIsValid: []
});
self.options.items.forEach(function(item, i) {
2011-12-30 09:33:01 +00:00
validateItem(i, function(valid) {
self.itemIsValid[i] = valid;
});
2011-04-22 22:03:10 +00:00
self.itemIds[i] = item.options('id') || item.id;
2011-11-30 14:56:01 +00:00
self.$items[i] = Ox.FormItem({element: item}).appendTo(that);
2011-04-22 22:03:10 +00:00
item.bindEvent({
autovalidate: function(data) {
2011-11-02 17:27:20 +00:00
validateForm(i, data.valid);
2011-04-22 22:03:10 +00:00
data.valid && self.$items[i].setMessage('');
2011-10-03 16:14:01 +00:00
},
2011-10-09 21:13:16 +00:00
/*
2011-10-03 16:14:01 +00:00
// fixme: should't inputs also trigger a change event?
blur: function(data) {
that.triggerEvent('change', {
id: self.itemIds[i],
data: data
});
},
2011-10-09 21:13:16 +00:00
*/
2011-10-03 16:14:01 +00:00
change: function(data) {
// fixme: shouldn't this be key/value instead of id/data?
2011-10-03 16:14:01 +00:00
that.triggerEvent('change', {
id: self.itemIds[i],
data: data
});
2011-12-30 09:33:01 +00:00
validateItem(i, function(valid) {
validateForm(i, valid);
});
2011-04-22 22:03:10 +00:00
},
submit: function(data) {
2011-04-22 22:03:10 +00:00
self.formIsValid && that.submit();
},
validate: function(data) {
2011-11-02 17:27:20 +00:00
validateForm(i, data.valid);
// timeout needed for cases where the form is removed
// from the DOM, triggering blur of an empty item -
// in this case, we don't want the message to appear
setTimeout(function() {
self.$items[i].setMessage(data.valid ? '' : data.message);
}, 0);
2011-04-22 22:03:10 +00:00
}
});
});
2011-12-30 09:33:01 +00:00
self.formIsValid = self.options.validate(self.itemIsValid);
2011-05-22 12:39:57 +00:00
function getItemIndexById(id) {
2011-04-22 22:03:10 +00:00
return self.itemIds.indexOf(id);
}
2011-11-02 17:27:20 +00:00
function validateForm(pos, valid) {
2011-04-22 22:03:10 +00:00
self.itemIsValid[pos] = valid;
2011-12-30 09:33:01 +00:00
if (self.options.validate(self.itemIsValid) != self.formIsValid) {
2011-04-22 22:03:10 +00:00
self.formIsValid = !self.formIsValid;
that.triggerEvent('validate', {
valid: self.formIsValid
});
}
}
2011-12-30 09:33:01 +00:00
function validateItem(pos, callback) {
var item = self.options.items[pos],
validate = item.options('validate');
if (validate) {
validate(item.value(), function(data) {
callback(data.valid);
});
} else {
callback(item.value && !Ox.isEmpty(item.value));
}
}
2012-05-21 10:38:18 +00:00
/*@
addItem <f> addItem
(pos, item) -> <u> add item at position
@*/
2011-04-22 22:03:10 +00:00
that.addItem = function(pos, item) {
2011-11-04 15:54:28 +00:00
Ox.Log('Form', 'addItem', pos)
2011-04-22 22:03:10 +00:00
self.options.items.splice(pos, 0, item);
self.$items.splice(pos, 0, Ox.FormItem({element: item}));
2011-04-22 22:03:10 +00:00
pos == 0 ?
self.$items[pos].insertBefore(self.$items[0]) :
self.$items[pos].insertAfter(self.$items[pos - 1]);
}
2012-05-21 10:38:18 +00:00
/*@
removeItem <f> removeItem
(pos) -> <u> remove item from position
@*/
2011-04-22 22:03:10 +00:00
that.removeItem = function(pos) {
2011-11-04 15:54:28 +00:00
Ox.Log('Form', 'removeItem', pos);
self.$items[pos].remove();
2011-04-22 22:03:10 +00:00
self.options.items.splice(pos, 1);
self.$items.splice(pos, 1);
}
that.setMessages = function(messages) {
Ox.forEach(messages, function(v) {
self.$items[getItemIndexById(v.id)].setMessage(v.message);
});
};
2012-05-21 10:38:18 +00:00
/*@
submit <f> submit
@*/
2011-04-22 22:03:10 +00:00
that.submit = function() {
that.triggerEvent('submit', {values: that.values()});
2011-04-22 22:03:10 +00:00
};
2012-05-21 10:38:18 +00:00
/*@
valid <f> valid
@*/
2011-12-30 09:33:01 +00:00
that.valid = function() {
return self.formIsValid;
};
2012-05-21 10:38:18 +00:00
/*@
values <f> values
@*/
that.values = function() {
// FIXME: this should accept a single string argument to get a single value
2011-04-22 22:03:10 +00:00
/*
get/set form values
call without arguments to get current form values
pass values as array to set values (not implemented)
*/
var values = {};
if (arguments.length == 0) {
self.$items.forEach(function($item, i) {
values[self.itemIds[i]] = self.$items[i].value();
});
2011-11-04 15:54:28 +00:00
//Ox.Log('Form', 'VALUES', values)
2011-04-22 22:03:10 +00:00
return values;
} else {
2011-11-04 15:54:28 +00:00
Ox.Log('Form', 'SET FORM VALUES', arguments[0])
2011-05-22 12:39:57 +00:00
Ox.forEach(arguments[0], function(value, key) {
var index = getItemIndexById(key);
2011-12-21 15:33:52 +00:00
index > -1 && self.options.items[index].value(value);
2011-04-22 22:03:10 +00:00
});
return that;
}
};
return that;
};