Skip to content

Commit 61a58d6

Browse files
committed
fix(pfModalOverlay): allow for async validations while keeping modal open
1 parent b589e07 commit 61a58d6

File tree

4 files changed

+79
-23
lines changed

4 files changed

+79
-23
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
language: node_js
22
node_js:
3-
- '4'
3+
- '8'
44

55
cache:
66
directories:
@@ -17,7 +17,7 @@ env:
1717
- TRIGGER_REPO_BRANCH: "master"
1818

1919
before_install:
20-
- if [[ `npm -v` != 3* ]]; then npm i -g npm@3; fi
20+
- npm install -g npm@5.4.0
2121
- npm install -g bower grunt-cli
2222
- npm install patternfly-eng-release
2323

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@
5959
"karma-phantomjs-launcher": "^1.0.4",
6060
"matchdep": "0.3.0",
6161
"nsp": "^2.6.1",
62-
"patternfly-eng-release": "^3.26.54",
62+
"patternfly-eng-release": "^3.26.74",
6363
"qs": "^1.0.0",
6464
"semantic-release": "^15.0.0",
6565
"send": "^0.11.1",
@@ -98,9 +98,9 @@
9898
"help": "grunt help",
9999
"serve": "grunt serve",
100100
"start": "grunt serve",
101-
"semantic-release": "semantic-release pre && npm publish && semantic-release post",
102-
"semantic-release-post": "semantic-release post",
103-
"semantic-release-pre": "semantic-release pre"
101+
"semantic-release": "semantic-release --pre && npm publish && semantic-release --post",
102+
"semantic-release-post": "semantic-release --post",
103+
"semantic-release-pre": "semantic-release --pre"
104104
},
105105
"repository": {
106106
"type": "git",

src/modals/examples/modal-overlay.js

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@
2525
* <ul style='list-style-type: none'>
2626
* <li>.label - the text to display on the button
2727
* <li>.class - (optional) classes to add to the button
28-
* <li>.actionFn - (optional) user defined function to call when the button is clicked
28+
* <li>.actionFn - (optional) user defined function to call when the button is clicked. May optionally return false
29+
* to prevent closing the modal. For example to perfrom asynchronous validations.
2930
* <li>.isDisabled - (optional) boolean true if the button should be disabled by default
30-
* <li>.isCancel - (optional) boolean true is the button should cancel and dismiss the modal
31+
* <li>.isCancel - (optional) boolean true if the button should cancel and dismiss the modal
3132
* </ul>
3233
* @param {string=} titleId Id of the title. "modalTitle" by default
3334
* @param {boolean=} hideCloseIcon Flag indicating that the modal should hide the 'x' close icon.
@@ -39,7 +40,11 @@
3940
* @param {object=} modalBodyScope Object containing the scope for the modalBodyTemplate
4041
*
4142
* @example
42-
<example module="patternfly.modals">
43+
<example module="patternfly.modals.demo">
44+
45+
<file name="modules.js">
46+
angular.module('patternfly.modals.demo', ['patternfly.modals', 'patternfly.notification']);
47+
</file>
4348
4449
<file name="index.html">
4550
<div ng-controller="DemoModalOverlayCtrl" class="example-container">
@@ -76,7 +81,7 @@
7681
</file>
7782
7883
<file name="script.js">
79-
angular.module('patternfly.modals').controller('DemoModalOverlayCtrl', function( $scope ) {
84+
angular.module('patternfly.modals.demo').controller('DemoModalOverlayCtrl', function( $scope, $timeout ) {
8085
8186
$scope.actionsText = "";
8287
@@ -110,7 +115,15 @@
110115
third: ""
111116
},
112117
allowBackgroundDismissal: false,
113-
showNotAllowedMsg: false
118+
showNotAllowedMsg: false,
119+
maxLength: 6,
120+
firstInputInvalid: false,
121+
validating: false,
122+
formErrorNotification: {
123+
type: "danger",
124+
header: "Input is not valid.",
125+
message: "Fix the errors below to continue saving."
126+
}
114127
};
115128
$scope.actionButtons = [
116129
{
@@ -121,11 +134,22 @@
121134
label: "Save",
122135
class: "btn-primary custom-class",
123136
actionFn: function() {
124-
$scope.actionsText = "inputs {" +
137+
$scope.actionsText = "inputs {" +
125138
"\n first: " + $scope.formScope.inputs.first +
126139
"\n second: " + $scope.formScope.inputs.second +
127140
"\n third: " + $scope.formScope.inputs.third +
128141
"\n}" + $scope.actionsText;
142+
$scope.formScope.firstInputInvalid = false;
143+
$scope.formScope.validating = true;
144+
$timeout(function () {
145+
$scope.formScope.validating = false;
146+
if ($scope.formScope.inputs.first === 'apples') {
147+
$scope.showModal = false;
148+
} else {
149+
$scope.formScope.firstInputInvalid = true;
150+
}
151+
}, 3000);
152+
return false;
129153
}
130154
}];
131155
@@ -157,16 +181,36 @@
157181
158182
<file name="demo-form.html">
159183
<ng-form name="demoForm" class="form-horizontal">
184+
<pf-inline-notification ng-if="$ctrl.modalBodyScope.firstInputInvalid"
185+
pf-notification-type="$ctrl.modalBodyScope.formErrorNotification.type"
186+
pf-notification-header="$ctrl.modalBodyScope.formErrorNotification.header"
187+
pf-notification-message="$ctrl.modalBodyScope.formErrorNotification.message">
188+
</pf-inline-notification>
160189
<div class="form-group">
161190
<label class="col-sm-3 control-label required-pf" for="textInput">Field One</label>
162-
<div class="col-sm-9">
163-
<input type="text" id="textInput" class="form-control" ng-model="$ctrl.modalBodyScope.inputs.first" ng-required="true"/>
191+
<div class="col-sm-9"
192+
ng-class="{ 'has-error': demoForm.fieldOne.$dirty && demoForm.fieldOne.$touched && $ctrl.modalBodyScope.firstInputInvalid}">
193+
<input type="text" id="textInput" name="fieldOne" class="form-control"
194+
ng-model="$ctrl.modalBodyScope.inputs.first" ng-required="true"/>
195+
<div class="has-error" ng-show="$ctrl.modalBodyScope.firstInputInvalid">
196+
<span class="help-block">
197+
Invalid value for Field One. Only acceptable value is 'apples'
198+
</span>
199+
</div>
164200
</div>
165201
</div>
166202
<div class="form-group">
167203
<label class="col-sm-3 control-label" for="textInput2">Field Two</label>
168-
<div class="col-sm-9">
169-
<input type="text" id="textInput2" class="form-control" ng-model="$ctrl.modalBodyScope.inputs.second"/>
204+
<div class="col-sm-9"
205+
ng-class="{ 'has-error': demoForm.fieldTwo.$dirty && demoForm.fieldTwo.$touched && demoForm.fieldTwo.$error.maxlength}" >
206+
<input type="text" name="fieldTwo" id="textInput2" class="form-control"
207+
ng-model="$ctrl.modalBodyScope.inputs.second"
208+
ng-maxlength="$ctrl.modalBodyScope.maxLength" />
209+
<div class="has-error" ng-show="demoForm.fieldTwo.$error.maxlength">
210+
<span class="help-block">
211+
Field Two exceeds max length of {{$ctrl.modalBodyScope.maxLength}}!
212+
</span>
213+
</div>
170214
</div>
171215
</div>
172216
<div class="form-group">
@@ -187,6 +231,9 @@
187231
</div>
188232
</div>
189233
</div>
234+
<div ng-if="$ctrl.modalBodyScope.validating">
235+
<div class="spinner spinner-lg blank-slate-pf-icon"></div>
236+
</div>
190237
</ng-form>
191238
</file>
192239

src/modals/modal-overlay/modal-overlay.component.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ angular.module('patternfly.modals')
1919
'use strict';
2020

2121
var ctrl = this;
22+
var modalInstance;
2223

2324
ctrl.open = function () {
24-
$uibModal.open({
25+
modalInstance = $uibModal.open({
2526
component: 'pfModalOverlayContent',
2627
backdrop: ctrl.backgroundClose ? true : 'static',
2728
resolve: {
@@ -53,8 +54,9 @@ angular.module('patternfly.modals')
5354
return ctrl.actionButtons;
5455
}
5556
}
56-
})
57-
.result.then(
57+
});
58+
59+
modalInstance.result.then(
5860
function (dismissCause) {
5961
ctrl.close({'dismissCause': dismissCause}); // closed
6062
},
@@ -71,8 +73,12 @@ angular.module('patternfly.modals')
7173
};
7274

7375
ctrl.$onChanges = function (changesObj) {
74-
if (changesObj.showModal && changesObj.showModal.currentValue === true) {
75-
ctrl.open();
76+
if (changesObj.showModal) {
77+
if (changesObj.showModal.currentValue === true) {
78+
ctrl.open();
79+
} else if (changesObj.showModal.currentValue === false && modalInstance) {
80+
modalInstance.dismiss('showModal set to false');
81+
}
7682
}
7783
};
7884
}
@@ -103,9 +109,12 @@ angular.module('patternfly.modals').component('pfModalOverlayContent', {
103109

104110
ctrl.ok = function (label, actionFn) {
105111
if (typeof actionFn === "function") {
106-
actionFn();
112+
if (actionFn() !== false) {
113+
ctrl.close({$value: label});
114+
}
115+
} else {
116+
ctrl.close({$value: label});
107117
}
108-
ctrl.close({$value: label});
109118
};
110119

111120
ctrl.cancel = function (actionFn) {

0 commit comments

Comments
 (0)