mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-06 21:27:40 +00:00
GUACAMOLE-302: Merge logic for automatically focusing relevant login fields.
This commit is contained in:
@@ -72,7 +72,14 @@ angular.module('form').directive('guacForm', [function form() {
|
|||||||
*
|
*
|
||||||
* @type Boolean
|
* @type Boolean
|
||||||
*/
|
*/
|
||||||
disabled : '='
|
disabled : '=',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the field to be focused, if any.
|
||||||
|
*
|
||||||
|
* @type String
|
||||||
|
*/
|
||||||
|
focused : '='
|
||||||
|
|
||||||
},
|
},
|
||||||
templateUrl: 'app/form/templates/form.html',
|
templateUrl: 'app/form/templates/form.html',
|
||||||
@@ -180,6 +187,19 @@ angular.module('form').directive('guacForm', [function form() {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the given field should be focused or not.
|
||||||
|
*
|
||||||
|
* @param {Field} field
|
||||||
|
* The field to check.
|
||||||
|
*
|
||||||
|
* @returns {Boolean}
|
||||||
|
* true if the given field should be focused, false otherwise.
|
||||||
|
*/
|
||||||
|
$scope.isFocused = function isFocused(field) {
|
||||||
|
return field && (field.name === $scope.focused);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the given field should be displayed to the
|
* Returns whether the given field should be displayed to the
|
||||||
* current user.
|
* current user.
|
||||||
|
@@ -61,7 +61,14 @@ angular.module('form').directive('guacFormField', [function formField() {
|
|||||||
*
|
*
|
||||||
* @type Boolean
|
* @type Boolean
|
||||||
*/
|
*/
|
||||||
disabled : '='
|
disabled : '=',
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this field should be focused.
|
||||||
|
*
|
||||||
|
* @type Boolean
|
||||||
|
*/
|
||||||
|
focused : '='
|
||||||
|
|
||||||
},
|
},
|
||||||
templateUrl: 'app/form/templates/formField.html',
|
templateUrl: 'app/form/templates/formField.html',
|
||||||
|
@@ -1 +1 @@
|
|||||||
<input type="checkbox" ng-disabled="disabled" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
<input type="checkbox" ng-disabled="disabled" ng-model="typedValue" guac-focus="focused" autocorrect="off" autocapitalize="off"/>
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
ng-model="typedValue"
|
ng-model="typedValue"
|
||||||
ng-model-options="modelOptions"
|
ng-model-options="modelOptions"
|
||||||
guac-lenient-date
|
guac-lenient-date
|
||||||
|
guac-focus="focused"
|
||||||
placeholder="{{'FORM.FIELD_PLACEHOLDER_DATE' | translate}}"
|
placeholder="{{'FORM.FIELD_PLACEHOLDER_DATE' | translate}}"
|
||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
autocapitalize="off"/>
|
autocapitalize="off"/>
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
ng-disabled="disabled"
|
ng-disabled="disabled"
|
||||||
ng-model="model"
|
ng-model="model"
|
||||||
ng-hide="readOnly"
|
ng-hide="readOnly"
|
||||||
|
guac-focus="focused"
|
||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
autocapitalize="off"/>
|
autocapitalize="off"/>
|
||||||
<a href="mailto:{{model}}" ng-show="readOnly">{{model}}</a>
|
<a href="mailto:{{model}}" ng-show="readOnly">{{model}}</a>
|
||||||
|
@@ -10,7 +10,9 @@
|
|||||||
<guac-form-field ng-repeat="field in form.fields" namespace="namespace"
|
<guac-form-field ng-repeat="field in form.fields" namespace="namespace"
|
||||||
ng-if="isVisible(field)"
|
ng-if="isVisible(field)"
|
||||||
data-disabled="disabled"
|
data-disabled="disabled"
|
||||||
field="field" model="values[field.name]"></guac-form-field>
|
focused="isFocused(field)"
|
||||||
|
field="field"
|
||||||
|
model="values[field.name]"></guac-form-field>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1 +1 @@
|
|||||||
<select ng-model="model" ng-options="language.key as language.value for language in languages | toArray | orderBy: key"></select>
|
<select guac-focus="focused" ng-model="model" ng-options="language.key as language.value for language in languages | toArray | orderBy: key"></select>
|
@@ -1 +1 @@
|
|||||||
<input type="number" ng-disabled="disabled" ng-model="typedValue" autocorrect="off" autocapitalize="off"/>
|
<input type="number" ng-disabled="disabled" ng-model="typedValue" guac-focus="focused" autocorrect="off" autocapitalize="off"/>
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<div class="password-field">
|
<div class="password-field">
|
||||||
<input type="{{passwordInputType}}" ng-disabled="disabled" ng-model="model" ng-trim="false" autocorrect="off" autocapitalize="off"/>
|
<input type="{{passwordInputType}}" ng-disabled="disabled" ng-model="model" ng-trim="false" guac-focus="focused" autocorrect="off" autocapitalize="off"/>
|
||||||
<div class="icon toggle-password" ng-click="togglePassword()" title="{{getTogglePasswordHelpText() | translate}}"></div>
|
<div class="icon toggle-password" ng-click="togglePassword()" title="{{getTogglePasswordHelpText() | translate}}"></div>
|
||||||
</div>
|
</div>
|
@@ -1,2 +1,2 @@
|
|||||||
<select ng-model="model" ng-disabled="disabled"
|
<select ng-model="model" ng-disabled="disabled" guac-focus="focused"
|
||||||
ng-options="option as getFieldOption(option) | translate for option in field.options | orderBy: value"></select>
|
ng-options="option as getFieldOption(option) | translate for option in field.options | orderBy: value"></select>
|
||||||
|
@@ -1 +1 @@
|
|||||||
<textarea ng-model="model" autocorrect="off" autocapitalize="off" ng-disabled="disabled"></textarea>
|
<textarea ng-model="model" guac-focus="focused" autocorrect="off" autocapitalize="off" ng-disabled="disabled"></textarea>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<div class="text-field">
|
<div class="text-field">
|
||||||
<input type="text" ng-model="model" autocorrect="off" autocapitalize="off"
|
<input type="text" ng-model="model" autocorrect="off" autocapitalize="off" guac-focus="focused"
|
||||||
ng-disabled="disabled" ng-attr-list="{{ dataListId }}"/>
|
ng-disabled="disabled" ng-attr-list="{{ dataListId }}"/>
|
||||||
<datalist ng-if="dataListId" id="{{ dataListId }}">
|
<datalist ng-if="dataListId" id="{{ dataListId }}">
|
||||||
<option ng-repeat="option in field.options | orderBy: option"
|
<option ng-repeat="option in field.options | orderBy: option"
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
ng-disabled="disabled"
|
ng-disabled="disabled"
|
||||||
ng-model="typedValue"
|
ng-model="typedValue"
|
||||||
ng-model-options="modelOptions"
|
ng-model-options="modelOptions"
|
||||||
|
guac-focus="focused"
|
||||||
guac-lenient-time
|
guac-lenient-time
|
||||||
placeholder="{{'FORM.FIELD_PLACEHOLDER_TIME' | translate}}"
|
placeholder="{{'FORM.FIELD_PLACEHOLDER_TIME' | translate}}"
|
||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
|
@@ -3,6 +3,7 @@
|
|||||||
<!-- Available time zone regions -->
|
<!-- Available time zone regions -->
|
||||||
<select class="time-zone-region"
|
<select class="time-zone-region"
|
||||||
ng-disabled="disabled"
|
ng-disabled="disabled"
|
||||||
|
guac-focus="focused"
|
||||||
ng-model="region"
|
ng-model="region"
|
||||||
ng-options="name for name in regions | orderBy: name"></select>
|
ng-options="name for name in regions | orderBy: name"></select>
|
||||||
|
|
||||||
|
@@ -102,6 +102,13 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
|
|||||||
*/
|
*/
|
||||||
$scope.submitted = false;
|
$scope.submitted = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The field that is most relevant to the user.
|
||||||
|
*
|
||||||
|
* @type Field
|
||||||
|
*/
|
||||||
|
$scope.relevantField = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a previous login attempt is continuing.
|
* Returns whether a previous login attempt is continuing.
|
||||||
*
|
*
|
||||||
@@ -144,6 +151,8 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
|
|||||||
$scope.enteredValues[field.name] = '';
|
$scope.enteredValues[field.name] = '';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$scope.relevantField = getRelevantField();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -200,6 +209,26 @@ angular.module('login').directive('guacLogin', [function guacLogin() {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the field most relevant to the user given the current state
|
||||||
|
* of the login process. This will normally be the first empty field.
|
||||||
|
*
|
||||||
|
* @return {Field}
|
||||||
|
* The field most relevant, null if there is no single most relevant
|
||||||
|
* field.
|
||||||
|
*/
|
||||||
|
var getRelevantField = function getRelevantField() {
|
||||||
|
|
||||||
|
for (var i = 0; i < $scope.remainingFields.length; i++) {
|
||||||
|
var field = $scope.remainingFields[i];
|
||||||
|
if (!$scope.enteredValues[field.name])
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
// Reset state after authentication and routing have succeeded
|
// Reset state after authentication and routing have succeeded
|
||||||
$rootScope.$on('$routeChangeSuccess', function routeChanged() {
|
$rootScope.$on('$routeChangeSuccess', function routeChanged() {
|
||||||
$scope.enteredValues = {};
|
$scope.enteredValues = {};
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
namespace="'LOGIN'"
|
namespace="'LOGIN'"
|
||||||
content="remainingFields"
|
content="remainingFields"
|
||||||
model="enteredValues"
|
model="enteredValues"
|
||||||
|
focused="relevantField.name"
|
||||||
data-disabled="submitted"></guac-form>
|
data-disabled="submitted"></guac-form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user