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 80b8515347
commit cbe1f3e4c4
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

@ -514,7 +514,8 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
@ -816,16 +817,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) {
@ -979,7 +980,8 @@
{
username: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
@ -997,15 +999,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

@ -285,14 +285,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' },
@ -615,14 +617,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',
@ -911,14 +915,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',
@ -1701,14 +1707,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

@ -579,7 +579,8 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
@ -588,7 +589,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' },
@ -1114,7 +1116,8 @@
{
name: {
label: 'label.name',
isEditable: true
isEditable: true,
validation: { required: true }
}
},
{
@ -1123,7 +1126,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

@ -326,6 +326,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) {
@ -340,6 +352,8 @@
$editButton.fadeOut('fast', function() {
$editButton.remove();
});
removeEditForm();
};
var applyEdits = function($inputs, $editButton) {
@ -381,6 +395,7 @@
notificationArgs, function() {}, []
);
replaceListViewItem($detailView, data);
removeEditForm();
} else {
$loading.appendTo($detailView);
cloudStack.ui.notifications.add(
@ -389,6 +404,7 @@
replaceListViewItem($detailView, data);
convertInputs($inputs);
removeEditForm();
$loading.remove();
}, [],
function() {
@ -407,17 +423,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;
@ -426,6 +449,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('');
@ -467,13 +491,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;
}
};
@ -689,23 +736,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());