Support validation on edit detail view

Original patch by: olga.smola
reviewed-by: brian
This commit is contained in:
bfederle 2012-06-26 13:30:36 -07:00
parent 9d88781e8c
commit a764c9a09d
5 changed files with 119 additions and 46 deletions

View File

@ -1641,6 +1641,12 @@ div.details div.detail-group td.value input[type=text] {
width: 93%;
}
div.details .main-groups label.error {
position: absolute;
right: 10%;
top: 6px;
}
/*** Actions*/
div.detail-group.actions {
padding: 0;

View File

@ -510,7 +510,8 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
@ -812,16 +813,16 @@
label: 'label.new.password',
isPassword: true,
validation: { required: true },
id: 'newPassword'
id: 'newPassword'
},
'password-confirm': {
label: 'label.confirm.password',
validation: {
required: true,
equalTo: '#newPassword'
},
isPassword: true
}
'password-confirm': {
label: 'label.confirm.password',
validation: {
required: true,
equalTo: '#newPassword'
},
isPassword: true
}
}
},
action: function(args) {
@ -975,7 +976,8 @@
{
username: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
@ -993,15 +995,18 @@
domain: { label: 'label.domain' },
email: {
label: 'label.email',
isEditable: true
isEditable: true,
validation: { required: true, email: true }
},
firstname: {
label: 'label.first.name',
isEditable: true
isEditable: true,
validation: { required: true }
},
lastname: {
label: 'label.last.name',
isEditable: true
isEditable: true,
validation: { required: true }
},
timezone: {
label: 'label.timezone',

View File

@ -281,14 +281,16 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
id: { label: 'label.id' },
displaytext: {
label: 'label.description',
isEditable: true
isEditable: true,
validation: { required: true }
},
storagetype: { label: 'label.storage.type' },
cpunumber: { label: 'label.num.cpu.cores' },
@ -611,14 +613,16 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
id: { label: 'label.id' },
displaytext: {
label: 'label.description',
isEditable: true
isEditable: true,
validation: { required: true }
},
systemvmtype: {
label: 'label.system.vm.type',
@ -907,14 +911,16 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
id: { label: 'label.id' },
displaytext: {
label: 'label.description',
isEditable: true
isEditable: true,
validation: { required: true }
},
iscustomized: {
label: 'label.custom.disk.size',
@ -1697,14 +1703,16 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
id: { label: 'label.id' },
displaytext: {
label: 'label.description',
isEditable: true
isEditable: true,
validation: { required: true }
},
state: { label: 'label.state' },
guestiptype: {

View File

@ -575,7 +575,8 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
@ -584,7 +585,8 @@
zoneid: { label: 'label.zone.id' },
displaytext: {
label: 'label.description',
isEditable: true
isEditable: true,
validation: { required: true }
},
hypervisor: { label: 'label.hypervisor' },
templatetype: { label: 'label.type' },
@ -1110,7 +1112,8 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
@ -1119,7 +1122,8 @@
zoneid: { label: 'label.zone.id' },
displaytext: {
label: 'label.description',
isEditable: true
isEditable: true,
validation: { required: true }
},
isready: { label: 'state.Ready', converter:cloudStack.converters.toBooleanText },
status: { label: 'label.status' },

View File

@ -320,6 +320,18 @@
}
});
};
var removeEditForm = function() {
// Remove Edit form
var $form = $detailView.find('form');
if ($form.size()) {
var $mainGroups = $form.find('div.main-groups').detach();
$form.parent('div').append($mainGroups);
$form.remove();
}
//Remove required labels
$detailView.find('span.field-required').remove();
}
// Put in original values
var cancelEdits = function($inputs, $editButton) {
@ -334,6 +346,8 @@
$editButton.fadeOut('fast', function() {
$editButton.remove();
});
removeEditForm();
};
var applyEdits = function($inputs, $editButton) {
@ -375,6 +389,7 @@
notificationArgs, function() {}, []
);
replaceListViewItem($detailView, data);
removeEditForm();
} else {
$loading.appendTo($detailView);
cloudStack.ui.notifications.add(
@ -383,6 +398,7 @@
replaceListViewItem($detailView, data);
convertInputs($inputs);
removeEditForm();
$loading.remove();
}, [],
function() {
@ -401,17 +417,24 @@
}
};
$editButton.click(function() {
var $inputs = $detailView.find('input, select');
$editButton.click(function() {
var $inputs = $detailView.find('input, select'),
$form = $detailView.find('form');
if ($(this).hasClass('done')) {
applyEdits($inputs, $editButton);
if (!$form.valid()) {
// Ignore hidden field validation
if ($form.find('input.error:visible, select.error:visible').size()) {
return false;
}
}
applyEdits($inputs, $editButton);
} else { // Cancel
cancelEdits($inputs, $editButton);
}
});
$detailView.find('td.value span').each(function() {
$detailView.find('td.value span').each(function() {
var name = $(this).closest('tr').data('detail-view-field');
var $value = $(this);
if (!$value.data('detail-view-is-editable')) return true;
@ -420,6 +443,7 @@
var selectData = $value.data('detail-view-editable-select');
var isBoolean = $value.data('detail-view-editable-boolean');
var data = !isBoolean ? cloudStack.sanitizeReverse($value.html()) : $value.data('detail-view-boolean-value');
var rules = $value.data('validation-rules') ? $value.data('validation-rules') : {};
$value.html('');
@ -461,13 +485,36 @@
name: name,
type: 'text',
value: data
}).data('original-value', data)
}).data('original-value', data)
);
}
if (rules && rules.required) {
var $required = $('<span>').addClass('field-required').text(' *');
$value.parent('td.value').prev('td.name').append($required);
}
return true;
});
if ($detailView.find('td.value span:data(detail-view-is-editable)').size()) {
var $detailsEdit = $detailView.find('div.main-groups').detach(),
$detailsEditForm = $('<form>').append($detailsEdit);
$detailView.find('div.details').append($detailsEditForm);
}
// Setup form validation
$detailView.find('form').validate();
$detailView.find('form').find('input, select').each(function() {
var data = $(this).parent('span').data('validation-rules');
if (data) {
$(this).rules('add', data);
} else {
$(this).rules('add', {});
}
});
return $detailView;
}
};
@ -683,23 +730,26 @@
//???
/*
if("pollAgainIfValueIsIn" in value) {
if ((content in value.pollAgainIfValueIsIn) && (value.pollAgainFn != null)) {
//poll again
var intervalKey = setInterval(function() {
var toClearInterval = value.pollAgainFn(context);
if(toClearInterval == true) {
clearInterval(intervalKey);
$('.detail-view .toolbar .button.refresh').click(); //click Refresh button to refresh detailView
}
}, 2000);
}
}
*/
if("pollAgainIfValueIsIn" in value) {
if ((content in value.pollAgainIfValueIsIn) && (value.pollAgainFn != null)) {
//poll again
var intervalKey = setInterval(function() {
var toClearInterval = value.pollAgainFn(context);
if(toClearInterval == true) {
clearInterval(intervalKey);
$('.detail-view .toolbar .button.refresh').click(); //click Refresh button to refresh detailView
}
}, 2000);
}
}
*/
$name.html(_l(value.label));
$value.html(_s(content));
// Set up validation metadata
$value.data('validation-rules', value.validation);
// Set up editable metadata
if(typeof(value.isEditable) == 'function')
$value.data('detail-view-is-editable', value.isEditable());