Skip to content

Commit cbe1f3e

Browse files
committed
CS-15287
Support validation on edit detail view Original patch by: olga.smola reviewed-by: brian
1 parent 80b8515 commit cbe1f3e

5 files changed

Lines changed: 119 additions & 46 deletions

File tree

ui/css/cloudstack3.css

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1641,6 +1641,12 @@ div.details div.detail-group td.value input[type=text] {
16411641
width: 93%;
16421642
}
16431643

1644+
div.details .main-groups label.error {
1645+
position: absolute;
1646+
right: 10%;
1647+
top: 6px;
1648+
}
1649+
16441650
/*** Actions*/
16451651
div.detail-group.actions {
16461652
padding: 0;

ui/scripts/accounts.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,8 @@
514514
{
515515
name: {
516516
label: 'label.name',
517-
isEditable: true
517+
isEditable: true,
518+
validation: { required: true }
518519
}
519520
},
520521
{
@@ -816,16 +817,16 @@
816817
label: 'label.new.password',
817818
isPassword: true,
818819
validation: { required: true },
819-
id: 'newPassword'
820+
id: 'newPassword'
820821
},
821-
'password-confirm': {
822-
label: 'label.confirm.password',
823-
validation: {
824-
required: true,
825-
equalTo: '#newPassword'
826-
},
827-
isPassword: true
828-
}
822+
'password-confirm': {
823+
label: 'label.confirm.password',
824+
validation: {
825+
required: true,
826+
equalTo: '#newPassword'
827+
},
828+
isPassword: true
829+
}
829830
}
830831
},
831832
action: function(args) {
@@ -979,7 +980,8 @@
979980
{
980981
username: {
981982
label: 'label.name',
982-
isEditable: true
983+
isEditable: true,
984+
validation: { required: true }
983985
}
984986
},
985987
{
@@ -997,15 +999,18 @@
997999
domain: { label: 'label.domain' },
9981000
email: {
9991001
label: 'label.email',
1000-
isEditable: true
1002+
isEditable: true,
1003+
validation: { required: true, email: true }
10011004
},
10021005
firstname: {
10031006
label: 'label.first.name',
1004-
isEditable: true
1007+
isEditable: true,
1008+
validation: { required: true }
10051009
},
10061010
lastname: {
10071011
label: 'label.last.name',
1008-
isEditable: true
1012+
isEditable: true,
1013+
validation: { required: true }
10091014
},
10101015
timezone: {
10111016
label: 'label.timezone',

ui/scripts/configuration.js

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -285,14 +285,16 @@
285285
{
286286
name: {
287287
label: 'label.name',
288-
isEditable: true
288+
isEditable: true,
289+
validation: { required: true }
289290
}
290291
},
291292
{
292293
id: { label: 'label.id' },
293294
displaytext: {
294295
label: 'label.description',
295-
isEditable: true
296+
isEditable: true,
297+
validation: { required: true }
296298
},
297299
storagetype: { label: 'label.storage.type' },
298300
cpunumber: { label: 'label.num.cpu.cores' },
@@ -615,14 +617,16 @@
615617
{
616618
name: {
617619
label: 'label.name',
618-
isEditable: true
620+
isEditable: true,
621+
validation: { required: true }
619622
}
620623
},
621624
{
622625
id: { label: 'label.id' },
623626
displaytext: {
624627
label: 'label.description',
625-
isEditable: true
628+
isEditable: true,
629+
validation: { required: true }
626630
},
627631
systemvmtype: {
628632
label: 'label.system.vm.type',
@@ -911,14 +915,16 @@
911915
{
912916
name: {
913917
label: 'label.name',
914-
isEditable: true
918+
isEditable: true,
919+
validation: { required: true }
915920
}
916921
},
917922
{
918923
id: { label: 'label.id' },
919924
displaytext: {
920925
label: 'label.description',
921-
isEditable: true
926+
isEditable: true,
927+
validation: { required: true }
922928
},
923929
iscustomized: {
924930
label: 'label.custom.disk.size',
@@ -1701,14 +1707,16 @@
17011707
{
17021708
name: {
17031709
label: 'label.name',
1704-
isEditable: true
1710+
isEditable: true,
1711+
validation: { required: true }
17051712
}
17061713
},
17071714
{
17081715
id: { label: 'label.id' },
17091716
displaytext: {
17101717
label: 'label.description',
1711-
isEditable: true
1718+
isEditable: true,
1719+
validation: { required: true }
17121720
},
17131721
state: { label: 'label.state' },
17141722
guestiptype: {

ui/scripts/templates.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,8 @@
579579
{
580580
name: {
581581
label: 'label.name',
582-
isEditable: true
582+
isEditable: true,
583+
validation: { required: true }
583584
}
584585
},
585586
{
@@ -588,7 +589,8 @@
588589
zoneid: { label: 'label.zone.id' },
589590
displaytext: {
590591
label: 'label.description',
591-
isEditable: true
592+
isEditable: true,
593+
validation: { required: true }
592594
},
593595
hypervisor: { label: 'label.hypervisor' },
594596
templatetype: { label: 'label.type' },
@@ -1114,7 +1116,8 @@
11141116
{
11151117
name: {
11161118
label: 'label.name',
1117-
isEditable: true
1119+
isEditable: true,
1120+
validation: { required: true }
11181121
}
11191122
},
11201123
{
@@ -1123,7 +1126,8 @@
11231126
zoneid: { label: 'label.zone.id' },
11241127
displaytext: {
11251128
label: 'label.description',
1126-
isEditable: true
1129+
isEditable: true,
1130+
validation: { required: true }
11271131
},
11281132
isready: { label: 'state.Ready', converter:cloudStack.converters.toBooleanText },
11291133
status: { label: 'label.status' },

ui/scripts/ui/widgets/detailView.js

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,18 @@
326326
}
327327
});
328328
};
329+
330+
var removeEditForm = function() {
331+
// Remove Edit form
332+
var $form = $detailView.find('form');
333+
if ($form.size()) {
334+
var $mainGroups = $form.find('div.main-groups').detach();
335+
$form.parent('div').append($mainGroups);
336+
$form.remove();
337+
}
338+
//Remove required labels
339+
$detailView.find('span.field-required').remove();
340+
}
329341

330342
// Put in original values
331343
var cancelEdits = function($inputs, $editButton) {
@@ -340,6 +352,8 @@
340352
$editButton.fadeOut('fast', function() {
341353
$editButton.remove();
342354
});
355+
356+
removeEditForm();
343357
};
344358

345359
var applyEdits = function($inputs, $editButton) {
@@ -381,6 +395,7 @@
381395
notificationArgs, function() {}, []
382396
);
383397
replaceListViewItem($detailView, data);
398+
removeEditForm();
384399
} else {
385400
$loading.appendTo($detailView);
386401
cloudStack.ui.notifications.add(
@@ -389,6 +404,7 @@
389404
replaceListViewItem($detailView, data);
390405

391406
convertInputs($inputs);
407+
removeEditForm();
392408
$loading.remove();
393409
}, [],
394410
function() {
@@ -407,17 +423,24 @@
407423
}
408424
};
409425

410-
$editButton.click(function() {
411-
var $inputs = $detailView.find('input, select');
426+
$editButton.click(function() {
427+
var $inputs = $detailView.find('input, select'),
428+
$form = $detailView.find('form');
412429

413430
if ($(this).hasClass('done')) {
414-
applyEdits($inputs, $editButton);
431+
if (!$form.valid()) {
432+
// Ignore hidden field validation
433+
if ($form.find('input.error:visible, select.error:visible').size()) {
434+
return false;
435+
}
436+
}
437+
applyEdits($inputs, $editButton);
415438
} else { // Cancel
416439
cancelEdits($inputs, $editButton);
417440
}
418441
});
419-
420-
$detailView.find('td.value span').each(function() {
442+
443+
$detailView.find('td.value span').each(function() {
421444
var name = $(this).closest('tr').data('detail-view-field');
422445
var $value = $(this);
423446
if (!$value.data('detail-view-is-editable')) return true;
@@ -426,6 +449,7 @@
426449
var selectData = $value.data('detail-view-editable-select');
427450
var isBoolean = $value.data('detail-view-editable-boolean');
428451
var data = !isBoolean ? cloudStack.sanitizeReverse($value.html()) : $value.data('detail-view-boolean-value');
452+
var rules = $value.data('validation-rules') ? $value.data('validation-rules') : {};
429453

430454
$value.html('');
431455

@@ -467,13 +491,36 @@
467491
name: name,
468492
type: 'text',
469493
value: data
470-
}).data('original-value', data)
494+
}).data('original-value', data)
471495
);
472496
}
497+
498+
if (rules && rules.required) {
499+
var $required = $('<span>').addClass('field-required').text(' *');
500+
$value.parent('td.value').prev('td.name').append($required);
501+
}
473502

474503
return true;
475504
});
476505

506+
if ($detailView.find('td.value span:data(detail-view-is-editable)').size()) {
507+
var $detailsEdit = $detailView.find('div.main-groups').detach(),
508+
$detailsEditForm = $('<form>').append($detailsEdit);
509+
510+
$detailView.find('div.details').append($detailsEditForm);
511+
}
512+
513+
// Setup form validation
514+
$detailView.find('form').validate();
515+
$detailView.find('form').find('input, select').each(function() {
516+
var data = $(this).parent('span').data('validation-rules');
517+
if (data) {
518+
$(this).rules('add', data);
519+
} else {
520+
$(this).rules('add', {});
521+
}
522+
});
523+
477524
return $detailView;
478525
}
479526
};
@@ -689,23 +736,26 @@
689736

690737
//???
691738
/*
692-
if("pollAgainIfValueIsIn" in value) {
693-
if ((content in value.pollAgainIfValueIsIn) && (value.pollAgainFn != null)) {
694-
//poll again
695-
var intervalKey = setInterval(function() {
696-
var toClearInterval = value.pollAgainFn(context);
697-
if(toClearInterval == true) {
698-
clearInterval(intervalKey);
699-
$('.detail-view .toolbar .button.refresh').click(); //click Refresh button to refresh detailView
700-
}
701-
}, 2000);
702-
}
703-
}
704-
*/
705-
739+
if("pollAgainIfValueIsIn" in value) {
740+
if ((content in value.pollAgainIfValueIsIn) && (value.pollAgainFn != null)) {
741+
//poll again
742+
var intervalKey = setInterval(function() {
743+
var toClearInterval = value.pollAgainFn(context);
744+
if(toClearInterval == true) {
745+
clearInterval(intervalKey);
746+
$('.detail-view .toolbar .button.refresh').click(); //click Refresh button to refresh detailView
747+
}
748+
}, 2000);
749+
}
750+
}
751+
*/
752+
706753
$name.html(_l(value.label));
707754
$value.html(_s(content));
708755

756+
// Set up validation metadata
757+
$value.data('validation-rules', value.validation);
758+
709759
// Set up editable metadata
710760
if(typeof(value.isEditable) == 'function')
711761
$value.data('detail-view-is-editable', value.isEditable());

0 commit comments

Comments
 (0)