Add form, text, and custom dropdown components

This commit is contained in:
gconsidine 2017-05-03 16:39:55 -04:00
parent 5d01340f18
commit 2509c573a5
15 changed files with 197 additions and 47 deletions

View File

@ -0,0 +1,38 @@
function track (element) {
let vm = this;
let input = {
el: element,
tabindex: vm.form.inputs.length + 1,
autofocus: vm.form.inputs.length === 0
};
vm.form.inputs.push(input);
return input;
}
function controller () {
let vm = this;
vm.form = {
inputs: []
};
vm.track = track;
}
function atForm () {
return {
restrict: 'E',
transclude: true,
templateUrl: 'static/partials/components/form/form.partial.html',
controller,
controllerAs: 'vm',
scope: {
config: '='
}
};
}
export default atForm;

View File

@ -0,0 +1,5 @@
<form>
<div class="row">
<ng-transclude></ng-transclude>
</div>
</form>

View File

@ -1,4 +1,6 @@
import badge from './badge/badge.directive';
import form from './form/form.directive';
import inputDropdown from './input/dropdown.directive';
import inputSearch from './input/search.directive';
import inputSelect from './input/select.directive';
import inputText from './input/text.directive';
@ -11,6 +13,8 @@ import toggleContent from './toggle/content.directive';
angular
.module('at.components', [])
.directive('atBadge', badge)
.directive('atForm', form)
.directive('atInputDropdown', inputDropdown)
.directive('atInputSearch', inputSearch)
.directive('atInputSelect', inputSelect)
.directive('atInputText', inputText)

View File

@ -5,9 +5,13 @@
border-radius: @at-border-radius-md;
color: @at-gray-darkest;
&, &:focus, &:active {
&, &:active {
border-color: @at-gray-light;
}
&:focus {
border-color: @at-link;
}
}
.at-Input-label {
@ -28,8 +32,36 @@
color: @at-gray;
}
.at-Dropdown-option--placeholder {
&[value=""] {
display: none;
.at-Input--focus {
border-color: @at-link;
}
.at-InputGroup {
position: relative;
width: 100%;
& > i {
position: absolute;
z-index: 4;
pointer-events: none;
right: @at-padding-sm;
top: @at-padding-sm;
}
}
.at-Dropdown {
height: @at-input-height-md;
position: relative;
}
.at-Dropdown-input {
position: relative;
z-index: 2;
pointer-events: none;
}
.at-Dropdown-select {
position: absolute;
z-index: 1;
top: 0;
}

View File

@ -0,0 +1,41 @@
function link (scope, el, attrs, form) {
scope.form = form.track(el);
scope.open = false;
let input = el.find('input')[0];
let select = el.find('select')[0];
input.addEventListener('focus', () => select.focus());
select.addEventListener('focus', () => input.classList.add('at-Input--focus'));
select.addEventListener('mousedown', () => {
scope.open = true;
});
select.addEventListener('blur', () => {
input.classList.remove('at-Input--focus');
scope.open = false;
});
select.addEventListener('change', () => {
scope.open = false;
});
}
function atInputDropdown () {
return {
restrict: 'E',
transclude: true,
replace: true,
require: '^^at-form',
templateUrl: 'static/partials/components/input/dropdown.partial.html',
link,
scope: {
config: '=',
col: '@'
}
};
}
export default atInputDropdown;

View File

@ -0,0 +1,24 @@
<div class="col-sm-{{ col }}">
<div class="form-group">
<label class="at-Input-label">
<span ng-if="config.required" class="at-Input-label--required">*</span>
<span>{{ config.label }}</span>
</label>
<div class="at-InputGroup at-Dropdown">
<input type="text" class="form-control at-Input at-Dropdown-input"
ng-attr-autofocus="{{ form.autofocus || undefined }}"
placeholder="{{ config.placeholder | uppercase }}" ng-model="config.input" />
<select class="form-control at-Dropdown-select" ng-model="config.input"
tabindex="{{ form.tabindex }}">
<optgroup ng-repeat="group in config.data" label="{{ group.category | uppercase }}">
<option ng-repeat="item in group.data" value="{{ item.name }}">
{{ item.name }}
</option>
</optgroup>
</select>
<i ng-hide="open" class="fa fa-caret-down"></i>
<i ng-show="open" class="fa fa-caret-up"></i>
</div>
</div>
</div>

View File

@ -2,7 +2,6 @@
function atInputSelect () {
function link (scope, element, attrs) {
scope.active = false;
}
return {

View File

@ -3,16 +3,23 @@
<span ng-if="config.required" class="at-Input-label--required">*</span>
<span>{{ config.label }}</span>
</label>
<select class="form-control at-Input at-Dropdown" ng-model="config.input"
ng-mousedown="opened = opened || true"
ng-class="{ 'at-Input--placeholder': input === undefined && !opened }">
<option class="at-Dropdown-option--placeholder" value="" disabled selected>
SELECT A TYPE
</option>
<optgroup ng-repeat="group in config.data" label="{{ group.category | uppercase }}">
<option ng-repeat="item in group.data" value="{{ item.id }}">
{{ item.name }}
<div class="input-group">
<select class="form-control at-Input at-Select" ng-model="config.input"
ng-mousedown="opened = opened || true"
ng-class="{ 'at-Input--placeholder': input === undefined && !opened }">
<option class="at-Select-option--placeholder" value="" disabled selected>
SELECT A TYPE
</option>
</optgroup>
</select>
<optgroup ng-repeat="group in config.data" label="{{ group.category | uppercase }}">
<option ng-repeat="item in group.data" value="{{ item.id }}">
{{ item.name }}
</option>
</optgroup>
</select>
<span class="input-group-btn">
<button class="btn at-Button--default at-Select-button">
<i class="fa fa-caret-down"></i>
</button>
</span>
</div>
</div>

View File

@ -1,12 +1,19 @@
// TODO: i18n
function link (scope, el, attrs, form) {
scope.form = form.track(el);
console.log('text', scope.form);
}
function atInputText () {
return {
restrict: 'E',
transclude: true,
replace: true,
require: '^^at-form',
templateUrl: 'static/partials/components/input/text.partial.html',
link,
scope: {
config: '='
config: '=',
col: '@'
}
};
}

View File

@ -1,8 +1,11 @@
<div class="form-group">
<label class="at-Input-label">
<span ng-if="config.required" class="at-Input-label--required">*</span>
<span>{{ config.label | uppercase }}</span>
</label>
<input type="text" class="form-control at-Input" ng-model="config.input"
placeholder="{{ config.placeholder }}" />
<div class="col-sm-{{ col }}">
<div class="form-group">
<label class="at-Input-label">
<span ng-if="config.required" class="at-Input-label--required">*</span>
<span>{{ config.label | uppercase }}</span>
</label>
<input type="text" class="form-control at-Input" ng-model="config.input"
ng-attr-autofocus="{{ form.autofocus || undefined }}" tabindex="{{ form.tabindex }}"
placeholder="{{ config.placeholder }}" />
</div>
</div>

View File

@ -136,9 +136,9 @@ var tower = angular.module('Tower', [
'features',
'ngResource',
'at.component',
'at.model',
'at.feature.credentials'
'at.components',
'at.models',
'at.features.credentials'
])
.constant('AngularScheduler.partials', urlPrefix + 'lib/angular-scheduler/lib/')

View File

@ -12,6 +12,7 @@ function AddCredentialsController (credentialType) {
vm.kind = {
label: 'Type',
placeholder: 'Select a Type',
required: true,
text: 'kind',
value: 'id',

View File

@ -4,23 +4,10 @@
</at-panel-heading>
<at-panel-body>
<at-tab-navigation>
<at-tab>Details</at-tab>
<at-tab>Permissions</at-tab>
</at-tab-navigation>
<div class="row">
<div class="col-sm-4">
<at-input-text config="vm.name"></at-input-text>
</div>
<div class="col-sm-4">
<at-input-text config="vm.description"></at-input-text>
</div>
<div class="col-sm-4">
<at-input-select config="vm.kind"></at-input-select>
</div>
</div>
<at-form>
<at-input-text col="4" config="vm.name"></at-input-text>
<at-input-text col="4" config="vm.description"></at-input-text>
<at-input-dropdown col="4" config="vm.kind"></at-input-dropdown>
</at-form>
</at-panel-body>
</at-panel>

View File

@ -80,7 +80,7 @@ config.$inject = [
];
angular
.module('at.feature.credentials', [])
.module('at.features.credentials', [])
.config(config)
.factory('CredentialList', CredentialList)
.controller('ListController', ListController)

View File

@ -28,3 +28,5 @@
@at-margin-md: 20px;
@at-border-radius-md: 5px;
@at-input-height-md: 34px;