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
|
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
|
|
|
|
2011-06-19 17:48:32 +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');
|
|
|
|
|
2011-09-17 18:36:09 +00:00
|
|
|
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({
|
2011-09-17 17:39:38 +00:00
|
|
|
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) {
|
2011-10-22 14:50:31 +00:00
|
|
|
// 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
|
|
|
},
|
2011-09-17 17:39:38 +00:00
|
|
|
submit: function(data) {
|
2011-04-22 22:03:10 +00:00
|
|
|
self.formIsValid && that.submit();
|
|
|
|
},
|
2011-09-17 17:39:38 +00:00
|
|
|
validate: function(data) {
|
2011-11-02 17:27:20 +00:00
|
|
|
validateForm(i, data.valid);
|
2011-10-29 10:34:41 +00:00
|
|
|
// 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);
|
2011-06-19 17:48:32 +00:00
|
|
|
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);
|
2011-11-04 22:14:30 +00:00
|
|
|
self.$items[pos].remove();
|
2011-04-22 22:03:10 +00:00
|
|
|
self.options.items.splice(pos, 1);
|
|
|
|
self.$items.splice(pos, 1);
|
|
|
|
}
|
|
|
|
|
2012-06-05 09:09:44 +00:00
|
|
|
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() {
|
2012-06-05 09:09:44 +00:00
|
|
|
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
|
|
|
|
@*/
|
2012-02-04 08:58:46 +00:00
|
|
|
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;
|
|
|
|
|
|
|
|
};
|