Skip to content

Commit 082ab6e

Browse files
committed
Disable the 'Submit' buttons until validation is completed. Add an indicator while validation is in progress.
1 parent cf76cdf commit 082ab6e

2 files changed

Lines changed: 126 additions & 6 deletions

File tree

ehr/resources/web/ehr/data/StoreCollection.js

Lines changed: 60 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Ext4.define('EHR.data.StoreCollection', {
1212
serverStores: null,
1313
hasLoaded: false, //will be set true after initial load
1414
clientDataChangeBuffer: 150,
15+
validationRequestsInFlight: 0,
1516
ignoredClientEvents: {},
1617

1718
constructor: function(){
@@ -20,7 +21,7 @@ Ext4.define('EHR.data.StoreCollection', {
2021
this.serverStores = Ext4.create('Ext.util.MixedCollection', false, this.getKey);
2122

2223
this.callParent(arguments);
23-
this.addEvents('commitcomplete', 'commitexception', 'validation', 'initialload', 'load', 'clientdatachanged', 'serverdatachanged');
24+
this.addEvents('commitcomplete', 'commitexception', 'beforevalidation', 'validationstart', 'validation', 'validationcomplete', 'initialload', 'load', 'clientdatachanged', 'serverdatachanged');
2425

2526
this.on('clientdatachanged', this.onClientDataChanged, this, {buffer: this.clientDataChangeBuffer});
2627
},
@@ -218,7 +219,7 @@ Ext4.define('EHR.data.StoreCollection', {
218219
}
219220
else
220221
{
221-
//this really isnt the right event to fire, but it will force a recalulation of buttons on the panel
222+
//this really isn't the right event to fire, but it will force a recalculation of buttons on the panel
222223
this.fireEvent('validation', this);
223224
}
224225
},
@@ -230,12 +231,34 @@ Ext4.define('EHR.data.StoreCollection', {
230231
},
231232

232233
validateRecords: function(recordMap){
234+
if(this.fireEvent('beforevalidation', this)===false)
235+
return;
233236
for (var serverStoreId in recordMap){
234237
var serverStore = this.serverStores.get(serverStoreId);
235238
serverStore.validateRecords(Ext4.Object.getValues(recordMap[serverStoreId]), true);
236239
}
237240
},
238241

242+
onValidationRequestStart: function(){
243+
this.validationRequestsInFlight++;
244+
245+
if (this.validationRequestsInFlight === 1){
246+
this.fireEvent('validationstart', this);
247+
}
248+
},
249+
250+
onValidationRequestComplete: function(){
251+
if (!this.validationRequestsInFlight){
252+
return;
253+
}
254+
255+
this.validationRequestsInFlight--;
256+
257+
if (this.validationRequestsInFlight === 0){
258+
this.fireEvent('validationcomplete', this);
259+
}
260+
},
261+
239262
serverToClientDataMap: null,
240263

241264
getServerToClientDataMap: function(){
@@ -472,11 +495,31 @@ Ext4.define('EHR.data.StoreCollection', {
472495
if (EHR.debug)
473496
console.log(commands);
474497

498+
var success = this.getOnCommitSuccess(recordsArr, validateOnly, retainErrors);
499+
var failure = this.getOnCommitFailure(recordsArr, validateOnly);
475500
var cfg = {
476501
url : LABKEY.ActionURL.buildURL('query', 'saveRows', this.containerPath),
477502
method : 'POST',
478-
success: this.getOnCommitSuccess(recordsArr, validateOnly, retainErrors),
479-
failure: this.getOnCommitFailure(recordsArr, validateOnly),
503+
success: function(response, options){
504+
try {
505+
success.call(this, response, options);
506+
}
507+
finally {
508+
if (validateOnly){
509+
this.onValidationRequestComplete();
510+
}
511+
}
512+
},
513+
failure: function(response, options){
514+
try {
515+
failure.call(this, response, options);
516+
}
517+
finally {
518+
if (validateOnly){
519+
this.onValidationRequestComplete();
520+
}
521+
}
522+
},
480523
scope: this,
481524
timeout: 5000000, //a little extreme?
482525
transacted: true,
@@ -498,9 +541,20 @@ Ext4.define('EHR.data.StoreCollection', {
498541
if (validateOnly){
499542
cfg.jsonData.validateOnly = true;
500543
cfg.jsonData.extraContext.isValidateOnly = true;
544+
this.onValidationRequestStart();
545+
}
546+
547+
var request;
548+
try {
549+
request = LABKEY.Ajax.request(cfg);
501550
}
551+
catch (e){
552+
if (validateOnly){
553+
this.onValidationRequestComplete();
554+
}
502555

503-
var request = LABKEY.Ajax.request(cfg);
556+
throw e;
557+
}
504558

505559
Ext4.Array.forEach(recordsArr, function(command){
506560
Ext4.Array.forEach(command, function(rec){
@@ -893,4 +947,4 @@ Ext4.define('EHR.data.StoreCollection', {
893947
s.checkForServerErrorChanges();
894948
}, this);
895949
}
896-
});
950+
});

ehr/resources/web/ehr/panel/DataEntryPanel.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Ext4.define('EHR.panel.DataEntryPanel', {
1212
storeCollection: null,
1313
hideErrorPanel: false,
1414
useSectionBorder: true,
15+
validationInProgress: false,
1516

1617
layout: 'anchor',
1718
border: false,
@@ -33,7 +34,10 @@ Ext4.define('EHR.panel.DataEntryPanel', {
3334
this.storeCollection.on('initialload', this.onStoreCollectionInitialLoad, this);
3435
this.storeCollection.on('commitcomplete', this.onStoreCollectionCommitComplete, this);
3536
this.storeCollection.on('validation', this.onStoreCollectionValidation, this);
37+
this.storeCollection.on('validationstart', this.onValidationStart, this);
38+
this.storeCollection.on('validationcomplete', this.onValidationComplete, this);
3639
this.storeCollection.on('beforecommit', this.onStoreCollectionBeforeCommit, this);
40+
this.storeCollection.on('beforevalidation', this.onBeforeValidation, this);
3741
this.storeCollection.on('commitexception', this.onStoreCollectionCommitException, this);
3842
//this.storeCollection.on('serverdatachanged', this.onStoreCollectionServerDataChanged, this);
3943

@@ -83,6 +87,45 @@ Ext4.define('EHR.panel.DataEntryPanel', {
8387
}
8488
},
8589

90+
onBeforeValidation: function(sc){
91+
function processItem(item) {
92+
if(item.disableOn) {
93+
item.setDisabled(true);
94+
if (item.setTooltip)
95+
item.setTooltip('Disabled waiting on validation. Select "More Actions" -> "Re-Validate" if this is not clearing.');
96+
}
97+
98+
if (item.menu) {
99+
item.menu.items.each(function (menuItem) {
100+
processItem(menuItem);
101+
}, this);
102+
}
103+
}
104+
105+
var btns = this.getToolbarItems();
106+
if (btns){
107+
Ext4.Array.forEach(btns, function(toolbar){
108+
toolbar.items.each(function(item){
109+
processItem(item);
110+
}, this);
111+
}, this);
112+
}
113+
},
114+
115+
onValidationStart: function(){
116+
if (!this.hasStoreCollectionLoaded){
117+
return;
118+
}
119+
120+
this.validationInProgress = true;
121+
this.setValidationIndicatorVisible(true);
122+
},
123+
124+
onValidationComplete: function(){
125+
this.validationInProgress = false;
126+
this.setValidationIndicatorVisible(false);
127+
},
128+
86129
onStoreCollectionValidation: function(sc){
87130
if (!this.hasStoreCollectionLoaded){
88131
return;
@@ -509,6 +552,21 @@ Ext4.define('EHR.panel.DataEntryPanel', {
509552
return this.dirtyStateArea;
510553
},
511554

555+
getValidationIndicator: function(){
556+
if (!this.validationIndicator || this.validationIndicator.isDestroyed){
557+
this.validationIndicator = this.down('#validationIndicator');
558+
}
559+
560+
return this.validationIndicator;
561+
},
562+
563+
setValidationIndicatorVisible: function(visible){
564+
var indicator = this.getValidationIndicator();
565+
if (indicator){
566+
indicator.setVisible(visible);
567+
}
568+
},
569+
512570
getButtons: function(){
513571
var buttons = [{
514572
xtype: 'container',
@@ -562,6 +620,14 @@ Ext4.define('EHR.panel.DataEntryPanel', {
562620
}
563621
}
564622

623+
buttons.push({
624+
xtype: 'container',
625+
itemId: 'validationIndicator',
626+
hidden: !this.validationInProgress,
627+
html: '<span><i class="fa fa-spinner fa-pulse"></i> Validating...</span>',
628+
style: 'padding-left: 8px; line-height: 24px;'
629+
});
630+
565631
return buttons;
566632
},
567633

0 commit comments

Comments
 (0)