Skip to content

Commit 880e312

Browse files
Convert patternfly.form module directives to components.
1 parent 9f9789d commit 880e312

File tree

11 files changed

+302
-295
lines changed

11 files changed

+302
-295
lines changed
Lines changed: 6 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* @ngdoc directive
3-
* @name patternfly.form.directive:pfFormButtons
3+
* @name patternfly.form.component:pfFormButtons
4+
* @restrict E
45
*
56
* @description
67
* Encapsulates the standard structure and styling for create and cancel buttons
@@ -20,18 +21,18 @@
2021
<div ng-controller="FormButtonCtrl">
2122
<p>Saved?</p>
2223
<p>{{ status }}</p>
23-
<form>
24+
<form name="testForm">
2425
<div class="form-group>
2526
<label class="control-label col-sm-2">Input</label>
26-
<input class="form-control col-sm-5" name="item" ng-model="input" type="text">
27+
<input class="form-control col-sm-5" name="item" ng-model="input" type="text" required>
2728
</div>
28-
<div pf-form-buttons pf-on-cancel="cancel()" pf-on-save="save(item)" pf-working="working"></div>
29+
<pf-form-buttons pf-on-cancel="cancel()" pf-on-save="save(item)" pf-working="working"></pf-form-buttons>
2930
</form>
3031
</div>
3132
</file>
3233
3334
<file name="script.js">
34-
angular.module( 'patternfly.form' ).controller( 'FormButtonCtrl', function( $scope, $timeout ) {
35+
angular.module( 'patternfly.form' ).controller( 'FormButtonCtrl', function( $scope, $timeout, $element ) {
3536
$scope.status = 'Not yet Saved'
3637
$scope.working = false;
3738
@@ -52,37 +53,3 @@
5253
</file>
5354
</example>
5455
*/
55-
angular.module('patternfly.form').directive('pfFormButtons', function () {
56-
'use strict';
57-
58-
return {
59-
replace: true,
60-
require: '^form',
61-
templateUrl: 'form/form-buttons/form-buttons.html',
62-
scope: {
63-
pfHandleCancel: '&pfOnCancel',
64-
pfHandleSave: '&pfOnSave',
65-
pfWorking: '=',
66-
pfButtonContainerClass: '@'
67-
},
68-
link: function (scope, iElement, iAttrs, controller) {
69-
if (scope.pfWorking === undefined) {
70-
scope.pfWorking = false;
71-
}
72-
73-
scope.isInvalid = function () {
74-
var invalid = controller.$invalid;
75-
76-
angular.forEach(controller, function (value) {
77-
if (value && value.$error) {
78-
if (value.$error.server) {
79-
invalid = false;
80-
}
81-
}
82-
});
83-
84-
return invalid;
85-
};
86-
}
87-
};
88-
});

src/form/examples/form-group.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/**
2+
* @ngdoc directive
3+
* @name patternfly.form.directive:pfFormGroup
4+
*
5+
* @description
6+
* Encapsulates the structure and styling for a label + input used within a
7+
* Bootstrap3 based form.
8+
*
9+
* This directive creates new scope.
10+
*
11+
* @param {string} pfLabel the text for the <label> element.
12+
* @param {string} pfFieldId the id of the form field. Default value is id of the form field element.
13+
* @param {string} pfLabelClass the class of the label element. Default value is "col-sm-2".
14+
* @param {string} pfInputClass the class of the input element. Default value is "col-sm-5".
15+
*
16+
* @example
17+
<example module="patternfly.form">
18+
19+
<file name="index.html">
20+
<form class="form-horizontal" ng-controller="FormDemoCtrl">
21+
22+
<p>Name: {{ item.name }}</p>
23+
<p>Description: {{ item.description }}</p>
24+
<pf-form-group pf-label="Name" required>
25+
<input id="name" name="name"
26+
ng-model="item.name" type="text" required/>
27+
</pf-form-group>
28+
29+
<pf-form-group pf-input-class="col-sm-9" pf-label="Description">
30+
<textarea id="description" name="description" ng-model="item.description">
31+
{{ item.description }}
32+
</textarea>
33+
</pf-form-group>
34+
</form>
35+
</file>
36+
37+
<file name="script.js">
38+
angular.module( 'patternfly.form' ).controller( 'FormDemoCtrl', function( $scope ) {
39+
$scope.item = {
40+
name: 'Homer Simpson',
41+
description: 'I like donuts and Duff. Doh!'
42+
};
43+
});
44+
</file>
45+
</example>
46+
*/
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/**
2+
* @ngdoc directive
3+
* @name patternfly.form.directive:pfRemainingCharsCount
4+
*
5+
* @description
6+
* Directive for showing a characters remaining count and triggering warning and error</br>
7+
* behavior when passing specified thresholds. When the <code>chars-warn-remaining</code> threshold is passed, </br>
8+
* the <code>chars-warn-remaining-pf</code> css class is applied to the <code>count-fld</code>, which by default, turns </br>
9+
* the remaining count number <font color='red'>red</font>.</br>
10+
* By default, characters may be entered into the text field after the <code>chars-max-limit</code> limit has been reached,</br>
11+
* the remaining count number will become a negative value. Setting the <code>blockInputAtMaxLimit</code> to <em>true</em>,</br>
12+
* will block additional input into the text field after the max has been reached; additionally a right-click 'paste' will only </br>
13+
* paste characters until the maximum character limit is reached.
14+
*
15+
* @param {string} ng-model The scope model variable which contains the initial text for the text field. Required, but</br>
16+
* can be an emptly string ("").
17+
* @param {string} count-fld The id of the field to display the 'characters-remaining' count.
18+
* @param {string} chars-max-limit Number representing the maximum number of characters to allow before dispatching a<br/>
19+
* 'overCharsMaxLimit' event. When the number of characters falls below <code>chars-max-limit</code>, a 'underCharsMaxLimit'<br/>
20+
* event is dispatched.
21+
* @param {string} chars-warn-remaining Number of remaining characters to warn upon. The 'chars-warn-remaining-pf'<br/>
22+
* class will be applied to the <code>count-fld</code> when the remaining characters is less than the<br/>
23+
* <code>chars-warn-remaining</code> threshold. When/if the number of remaining characters becomes greater than the<br/>
24+
* <code>chars-warn-remaining</code> threshold, the 'chars-warn-remaining-pf' class is removed from the <code>count-fld</code> field.
25+
* @param {boolean=} block-input-at-max-limit If true, no more characters can be entered into the text field when the<br/>
26+
* <code>chars-max-limit</code> has been reached. If false (the default), characters may be entered into the text field after the<br/>
27+
* max. limit has been reached, but these additional characters will trigger the 'overCharsMaxLimit' event to be<br/>
28+
* dispatched. When <code>blockInputAtMaxLimit</code> is <em>true</em>, a right-click 'paste' will only paste<br/>
29+
* characters until the maximum character limit is reached.
30+
*
31+
* @example
32+
<example module="patternfly.example">
33+
<file name="index.html">
34+
<div ng-controller="DemoCtrl" style="display:inline-block; width: 100%;">
35+
36+
<style>
37+
textarea {
38+
resize: none;
39+
}
40+
</style>
41+
42+
<div class="container">
43+
<strong>Max limit: 20, warn when 5 or less remaining, disable button after max limit</strong>
44+
<div class="row">
45+
<div class="col-md-4">
46+
47+
<form>
48+
<div class="form-group">
49+
<label for="messageArea"></label>
50+
<textarea class="form-control" pf-remaining-chars-count id="messageArea_1" ng-model="messageArea1text" chars-max-limit="20" chars-warn-remaining="5"
51+
count-fld="charRemainingCntFld_1" name="text" placeholder="Type in your message" rows="5"></textarea>
52+
</div>
53+
<span class="pull-right chars-remaining-pf">
54+
<span id="charRemainingCntFld_1"></span>
55+
<button id="postBtn_1" ng-disabled="charsMaxLimitExceeded" type="submit" class="btn btn-default">Post New Message</button>
56+
</span>
57+
</form>
58+
59+
</div>
60+
</div>
61+
<br>
62+
<strong>Max limit: 10, warn when 2 or less remaining, block input after max limit</strong>
63+
<div class="row">
64+
<div class="col-md-4">
65+
<form>
66+
<div class="form-group">
67+
<label for="messageArea"></label>
68+
<textarea class="form-control" pf-remaining-chars-count id="messageArea_2" ng-model="messageArea2text" chars-max-limit="10" chars-warn-remaining="2"
69+
block-input-at-max-limit="true" count-fld="charRemainingCntFld_2" name="text"
70+
placeholder="Type in your message" rows="5"></textarea>
71+
</div>
72+
<span class="pull-left">
73+
<button id="postBtn_2" type="submit" class="btn btn-default">Submit</button>
74+
</span>
75+
<span class="pull-right chars-remaining-pf">
76+
<span id="charRemainingCntFld_2"></span>
77+
</span>
78+
</form>
79+
</div>
80+
</div>
81+
<br>
82+
<strong>Max limit: 10, warn when 5 or less remaining, block input after max limit</strong>
83+
<div class="row">
84+
<div class="col-md-4">
85+
<input id="input_3" pf-remaining-chars-count chars-max-limit="10" ng-model="messageInput3text" chars-warn-remaining="5" count-fld="charRemainingCntFld_3"
86+
block-input-at-max-limit="true"/>
87+
<span class="chars-remaining-pf"><span id="charRemainingCntFld_3" style="padding-left: 5px"></span>Remaining</span>
88+
</div>
89+
</div>
90+
</div>
91+
</file>
92+
93+
<file name="script.js">
94+
angular.module( 'patternfly.example', ['patternfly.form']);
95+
96+
angular.module( 'patternfly.example' ).controller( 'DemoCtrl', function( $scope ) {
97+
$scope.messageArea1text = "Initial Text";
98+
$scope.messageArea2text = "";
99+
$scope.messageInput3text = "";
100+
101+
$scope.charsMaxLimitExceeded = false;
102+
103+
// 'tfId' will equal the id of the text area/input field which
104+
// triggered the event
105+
$scope.$on('overCharsMaxLimit', function (event, tfId) {
106+
if(!$scope.charsMaxLimitExceeded){
107+
$scope.charsMaxLimitExceeded = true;
108+
}
109+
});
110+
111+
// 'tfId' will equal the id of the text area/input field which
112+
// triggered the event
113+
$scope.$on('underCharsMaxLimit', function (event, tfId) {
114+
if($scope.charsMaxLimitExceeded){
115+
$scope.charsMaxLimitExceeded = false;
116+
}
117+
});
118+
119+
});
120+
121+
</file>
122+
</example>
123+
*/
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
angular.module('patternfly.form').component('pfFormButtons', {
2+
3+
bindings: {
4+
pfHandleCancel: '&pfOnCancel',
5+
pfHandleSave: '&pfOnSave',
6+
pfWorking: '=',
7+
pfButtonContainerClass: '@'
8+
},
9+
require: {
10+
form: '^form'
11+
},
12+
templateUrl: 'form/form-buttons/form-buttons.html',
13+
controller: function () {
14+
'use strict';
15+
16+
var ctrl = this;
17+
18+
if (ctrl.pfWorking === undefined) {
19+
ctrl.pfWorking = false;
20+
}
21+
22+
ctrl.isInvalid = function () {
23+
var invalid = ctrl.form.$invalid;
24+
25+
if (ctrl.form && ctrl.form.name && ctrl.form.name.$error) {
26+
if (ctrl.form.name.$error.server) {
27+
invalid = false;
28+
}
29+
}
30+
31+
return invalid;
32+
};
33+
}
34+
});

src/form/form-buttons/form-buttons.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
<div class="form-group">
2-
<div class="{{ pfButtonContainerClass }}">
2+
<div class="{{$ctrl.pfButtonContainerClass}}">
33
<div class="control-group buttons">
44
<button class="btn btn-default"
55
type="button"
6-
ng-click="pfHandleCancel()"
7-
ng-disabled="pfWorking"
6+
ng-click="$ctrl.pfHandleCancel()"
7+
ng-disabled="$ctrl.pfWorking"
88
translate>
99
Cancel
1010
</button>
1111

1212
<button class="btn btn-primary"
13-
ng-click="pfHandleSave(); pfWorking = true"
14-
ng-disabled="isInvalid() || pfWorking">
13+
ng-click="$ctrl.pfHandleSave(); $ctrl.pfWorking = true"
14+
ng-disabled="$ctrl.isInvalid() || $ctrl.pfWorking">
1515

16-
<i class="icon-spinner icon-spin" ng-show="pfWorking"></i>
17-
<span ng-show="pfWorking" translate>Saving...</span>
18-
<span ng-hide="pfWorking" translate>Save</span>
16+
<i class="icon-spinner icon-spin" ng-show="$ctrl.pfWorking"></i>
17+
<span ng-show="$ctrl.pfWorking" translate>Saving...</span>
18+
<span ng-hide="$ctrl.pfWorking" translate>Save</span>
1919
</button>
2020
</div>
2121
</div>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
angular.module('patternfly.form').component('pfFormGroup', {
2+
3+
bindings: {
4+
pfLabel: '@',
5+
pfField: '@',
6+
pfLabelClass: '@',
7+
pfInputClass: '@'
8+
9+
},
10+
require: {
11+
form: '^form'
12+
},
13+
transclude: true,
14+
templateUrl: 'form/form-group/form-group.html',
15+
16+
controller: function ($scope, $element) {
17+
'use strict';
18+
19+
var ctrl = this;
20+
21+
ctrl.$postLink = function () {
22+
var input;
23+
var type;
24+
25+
if (!ctrl.pfLabelClass) {
26+
ctrl.pfLabelClass = 'col-sm-2';
27+
}
28+
29+
if (!ctrl.pfInputClass) {
30+
ctrl.pfInputClass = 'col-sm-5';
31+
}
32+
33+
input = getInput($element);
34+
type = input.attr('type');
35+
36+
if (['checkbox', 'radio', 'time'].indexOf(type) === -1) {
37+
input.addClass('form-control');
38+
}
39+
40+
if (!ctrl.pfField) {
41+
ctrl.pfField = input.attr('id');
42+
}
43+
44+
if (input.attr('required')) {
45+
$element.addClass('required');
46+
}
47+
48+
if (ctrl.form[ctrl.pfField]) {
49+
ctrl.error = ctrl.form[ctrl.pfField].$error;
50+
}
51+
};
52+
53+
ctrl.hasErrors = function () {
54+
return ctrl.form[ctrl.pfField] && ctrl.form[ctrl.pfField].$invalid && ctrl.form[ctrl.pfField].$dirty;
55+
};
56+
57+
function getInput (element) {
58+
// table is used for bootstrap3 date/time pickers
59+
var input = element.find('table');
60+
61+
if (input.length === 0) {
62+
input = element.find('input');
63+
64+
if (input.length === 0) {
65+
input = element.find('select');
66+
67+
if (input.length === 0) {
68+
input = element.find('textarea');
69+
}
70+
}
71+
}
72+
return input;
73+
}
74+
}
75+
});

0 commit comments

Comments
 (0)