mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-11-23 22:11:09 +03:00
Replace validation notifications with inline validations
issue #5409 & #5336 - update settings/general - update signin - update signup - update edit user - update reset password - update setup/three - remove `formatErrors` function from validationEngine mixin (it's no longer needed as inline validations should handle this instead)
This commit is contained in:
parent
ee89b11a6a
commit
7ab232e770
@ -13,19 +13,18 @@ var TrimFocusInput = Ember.TextField.extend({
|
||||
return false;
|
||||
}),
|
||||
|
||||
didInsertElement: function () {
|
||||
focusField: Ember.on('didInsertElement', function () {
|
||||
// This fix is required until Mobile Safari has reliable
|
||||
// autofocus, select() or focus() support
|
||||
if (this.get('focus') && !device.ios()) {
|
||||
this.$().val(this.$().val()).focus();
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
focusOut: function () {
|
||||
trimValue: Ember.on('focusOut', function () {
|
||||
var text = this.$().val();
|
||||
|
||||
this.$().val(text.trim());
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
export default TrimFocusInput;
|
||||
|
@ -63,6 +63,10 @@ export default Ember.Controller.extend({
|
||||
}),
|
||||
|
||||
actions: {
|
||||
validate: function () {
|
||||
this.get('model').validate(arguments);
|
||||
},
|
||||
|
||||
save: function () {
|
||||
var notifications = this.get('notifications'),
|
||||
config = this.get('config');
|
||||
@ -71,8 +75,10 @@ export default Ember.Controller.extend({
|
||||
config.set('blogTitle', model.get('title'));
|
||||
|
||||
return model;
|
||||
}).catch(function (errors) {
|
||||
notifications.showErrors(errors);
|
||||
}).catch(function (error) {
|
||||
if (error) {
|
||||
notifications.showAPIError(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
import Ember from 'ember';
|
||||
import DS from 'ember-data';
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
notifications: Ember.inject.service(),
|
||||
errors: DS.Errors.create(),
|
||||
users: '',
|
||||
usersArray: Ember.computed('users', function () {
|
||||
var users = this.get('users').split('\n').filter(function (email) {
|
||||
@ -62,10 +64,11 @@ export default Ember.Controller.extend({
|
||||
var self = this,
|
||||
validationErrors = this.get('validateUsers'),
|
||||
users = this.get('usersArray'),
|
||||
errorMessages,
|
||||
notifications = this.get('notifications'),
|
||||
invitationsString;
|
||||
|
||||
this.get('errors').clear();
|
||||
|
||||
if (validationErrors === true && users.length > 0) {
|
||||
this.get('authorRole').then(function (authorRole) {
|
||||
Ember.RSVP.Promise.all(
|
||||
@ -117,19 +120,15 @@ export default Ember.Controller.extend({
|
||||
});
|
||||
});
|
||||
} else if (users.length === 0) {
|
||||
// TODO: switch to inline-validation
|
||||
notifications.showAlert('No users to invite.', {type: 'error'});
|
||||
this.get('errors').add('users', 'No users to invite.');
|
||||
} else {
|
||||
errorMessages = validationErrors.map(function (error) {
|
||||
validationErrors.forEach(function (error) {
|
||||
// Only one error type here so far, but one day the errors might be more detailed
|
||||
switch (error.error) {
|
||||
case 'email':
|
||||
return {message: error.user + ' is not a valid email.'};
|
||||
self.get('errors').add('users', error.user + ' is not a valid email.');
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: switch to inline-validation
|
||||
notifications.showErrors(errorMessages);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,14 @@ import ValidationEngine from 'ghost/mixins/validation-engine';
|
||||
import {request as ajax} from 'ic-ajax';
|
||||
|
||||
export default Ember.Controller.extend(ValidationEngine, {
|
||||
validationType: 'signin',
|
||||
|
||||
submitting: false,
|
||||
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
// ValidationEngine settings
|
||||
validationType: 'signin',
|
||||
|
||||
actions: {
|
||||
authenticate: function () {
|
||||
var model = this.get('model'),
|
||||
@ -30,12 +31,12 @@ export default Ember.Controller.extend(ValidationEngine, {
|
||||
// browsers and password managers that don't send proper events on autofill
|
||||
$('#login').find('input').trigger('change');
|
||||
|
||||
this.validate({format: false}).then(function () {
|
||||
this.validate().then(function () {
|
||||
self.get('notifications').closeNotifications();
|
||||
self.send('authenticate');
|
||||
}).catch(function (errors) {
|
||||
if (errors) {
|
||||
self.get('notifications').showErrors(errors);
|
||||
}).catch(function (error) {
|
||||
if (error) {
|
||||
self.get('notifications').showAPIError(error);
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -45,27 +46,24 @@ export default Ember.Controller.extend(ValidationEngine, {
|
||||
notifications = this.get('notifications'),
|
||||
self = this;
|
||||
|
||||
if (!email) {
|
||||
// TODO: Switch to in-line validation
|
||||
return notifications.showNotification('Enter email address to reset password.', {type: 'error'});
|
||||
}
|
||||
this.validate({property: 'identification'}).then(function () {
|
||||
self.set('submitting', true);
|
||||
|
||||
self.set('submitting', true);
|
||||
|
||||
ajax({
|
||||
url: self.get('ghostPaths.url').api('authentication', 'passwordreset'),
|
||||
type: 'POST',
|
||||
data: {
|
||||
passwordreset: [{
|
||||
email: email
|
||||
}]
|
||||
}
|
||||
}).then(function () {
|
||||
self.set('submitting', false);
|
||||
notifications.showAlert('Please check your email for instructions.', {type: 'info'});
|
||||
}).catch(function (resp) {
|
||||
self.set('submitting', false);
|
||||
notifications.showAPIError(resp, {defaultErrorText: 'There was a problem with the reset, please try again.'});
|
||||
ajax({
|
||||
url: self.get('ghostPaths.url').api('authentication', 'passwordreset'),
|
||||
type: 'POST',
|
||||
data: {
|
||||
passwordreset: [{
|
||||
email: email
|
||||
}]
|
||||
}
|
||||
}).then(function () {
|
||||
self.set('submitting', false);
|
||||
notifications.showAlert('Please check your email for instructions.', {type: 'info'});
|
||||
}).catch(function (resp) {
|
||||
self.set('submitting', false);
|
||||
notifications.showAPIError(resp, {defaultErrorText: 'There was a problem with the reset, please try again.'});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,8 +20,8 @@ export default Ember.Controller.extend(ValidationEngine, {
|
||||
|
||||
notifications.closeNotifications();
|
||||
|
||||
this.toggleProperty('submitting');
|
||||
this.validate({format: false}).then(function () {
|
||||
this.validate().then(function () {
|
||||
this.toggleProperty('submitting');
|
||||
ajax({
|
||||
url: self.get('ghostPaths.url').api('authentication', 'invitation'),
|
||||
type: 'POST',
|
||||
@ -43,10 +43,9 @@ export default Ember.Controller.extend(ValidationEngine, {
|
||||
self.toggleProperty('submitting');
|
||||
notifications.showAPIError(resp);
|
||||
});
|
||||
}).catch(function (errors) {
|
||||
self.toggleProperty('submitting');
|
||||
if (errors) {
|
||||
notifications.showErrors(errors);
|
||||
}).catch(function (error) {
|
||||
if (error) {
|
||||
notifications.showAPIError(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -2,8 +2,12 @@ import Ember from 'ember';
|
||||
import SlugGenerator from 'ghost/models/slug-generator';
|
||||
import isNumber from 'ghost/utils/isNumber';
|
||||
import boundOneWay from 'ghost/utils/bound-one-way';
|
||||
import ValidationEngine from 'ghost/mixins/validation-engine';
|
||||
|
||||
export default Ember.Controller.extend(ValidationEngine, {
|
||||
// ValidationEngine settings
|
||||
validationType: 'user',
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
ghostPaths: Ember.inject.service('ghost-paths'),
|
||||
notifications: Ember.inject.service(),
|
||||
|
||||
|
@ -15,49 +15,6 @@ import TagSettingsValidator from 'ghost/validators/tag-settings';
|
||||
// our extensions to the validator library
|
||||
ValidatorExtensions.init();
|
||||
|
||||
// This is here because it is used by some things that format errors from api responses
|
||||
// This function should be removed in the notifications refactor
|
||||
// format errors to be used in `notifications.showErrors`.
|
||||
// result is [{message: 'concatenated error messages'}]
|
||||
function formatErrors(errors, opts) {
|
||||
var message = 'There was an error';
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
if (opts.wasSave && opts.validationType) {
|
||||
message += ' saving this ' + opts.validationType;
|
||||
}
|
||||
|
||||
if (Ember.isArray(errors)) {
|
||||
// get the validator's error messages from the array.
|
||||
// normalize array members to map to strings.
|
||||
message = errors.map(function (error) {
|
||||
var errorMessage;
|
||||
if (typeof error === 'string') {
|
||||
errorMessage = error;
|
||||
} else {
|
||||
errorMessage = error.message;
|
||||
}
|
||||
|
||||
return Ember.Handlebars.Utils.escapeExpression(errorMessage);
|
||||
}).join('<br />').htmlSafe();
|
||||
} else if (errors instanceof Error) {
|
||||
message += errors.message || '.';
|
||||
} else if (typeof errors === 'object') {
|
||||
// Get messages from server response
|
||||
message += ': ' + getRequestErrorMessage(errors, true);
|
||||
} else if (typeof errors === 'string') {
|
||||
message += ': ' + errors;
|
||||
} else {
|
||||
message += '.';
|
||||
}
|
||||
|
||||
// set format for notifications.showErrors
|
||||
message = [{message: message}];
|
||||
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* The class that gets this mixin will receive these properties and functions.
|
||||
* It will be able to validate any properties on itself (or the model it passes to validate())
|
||||
@ -163,15 +120,10 @@ export default Ember.Mixin.create({
|
||||
return this.validate(options).then(function () {
|
||||
return _super.call(self, options);
|
||||
}).catch(function (result) {
|
||||
// server save failed - validate() would have given back an array
|
||||
if (!Ember.isArray(result)) {
|
||||
if (options.format !== false) {
|
||||
// concatenate all errors into an array with a single object: [{message: 'concatted message'}]
|
||||
result = formatErrors(result, options);
|
||||
} else {
|
||||
// return the array of errors from the server
|
||||
result = getRequestErrorMessage(result);
|
||||
}
|
||||
// server save failed or validator type doesn't exist
|
||||
if (result && !Ember.isArray(result)) {
|
||||
// return the array of errors from the server
|
||||
result = getRequestErrorMessage(result);
|
||||
}
|
||||
|
||||
return Ember.RSVP.reject(result);
|
||||
|
@ -377,6 +377,7 @@
|
||||
}
|
||||
|
||||
.gh-flow-content .gh-flow-invite {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
max-width: 400px;
|
||||
width: 100%;
|
||||
|
@ -2,12 +2,21 @@
|
||||
<div class="gh-flow-content-wrap">
|
||||
<section class="gh-flow-content fade-in">
|
||||
<form id="reset" class="gh-signin" method="post" novalidate="novalidate" {{action "submit" on="submit"}}>
|
||||
<div class="form-group">
|
||||
{{input value=newPassword class="gh-input password" type="password" placeholder="Password" name="newpassword" autofocus="autofocus" }}
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{input value=ne2Password class="gh-input password" type="password" placeholder="Confirm Password" name="ne2password" }}
|
||||
</div>
|
||||
{{#gh-form-group errors=errors property="newPassword"}}
|
||||
{{input value=newPassword class="gh-input password" type="password" placeholder="Password" name="newpassword" autofocus="autofocus" focusOut=(action "validate" "newPassword")}}
|
||||
<div class="pw-strength">
|
||||
<div class="pw-strength-dot"></div>
|
||||
<div class="pw-strength-dot"></div>
|
||||
<div class="pw-strength-dot"></div>
|
||||
<div class="pw-strength-dot"></div>
|
||||
<div class="pw-strength-dot <!--pw-strength-activedot-->"></div>
|
||||
</div>
|
||||
{{gh-error-message errors=errors property="newPassword"}}
|
||||
{{/gh-form-group}}
|
||||
{{#gh-form-group errors=errors property="ne2Password"}}
|
||||
{{input value=ne2Password class="gh-input password" type="password" placeholder="Confirm Password" name="ne2password" focusOut=(action "validate" "ne2Password")}}
|
||||
{{gh-error-message errors=errors property="ne2Password"}}
|
||||
{{/gh-form-group}}
|
||||
<button class="btn btn-blue btn-block" type="submit" disabled={{submitting}}>Reset Password</button>
|
||||
</form>
|
||||
</section>
|
||||
|
@ -10,21 +10,22 @@
|
||||
<form id="settings-general" novalidate="novalidate">
|
||||
<fieldset>
|
||||
|
||||
<div class="form-group">
|
||||
{{#gh-form-group errors=model.errors property="title"}}
|
||||
<label for="blog-title">Blog Title</label>
|
||||
{{input id="blog-title" class="gh-input" name="general[title]" type="text" value=model.title}}
|
||||
{{gh-input id="blog-title" class="gh-input" name="general[title]" type="text" value=model.title focusOut=(action "validate" "title")}}
|
||||
{{gh-error-message errors=model.errors property="title"}}
|
||||
<p>The name of your blog</p>
|
||||
</div>
|
||||
{{/gh-form-group}}
|
||||
|
||||
<div class="form-group description-container">
|
||||
{{#gh-form-group class="description-container" errors=model.errors property="description"}}
|
||||
<label for="blog-description">Blog Description</label>
|
||||
{{textarea id="blog-description" class="gh-input" name="general[description]" value=model.description}}
|
||||
{{gh-textarea id="blog-description" class="gh-input" name="general[description]" value=model.description focusOut=(action "validate" "description")}}
|
||||
{{gh-error-message errors=model.errors property="description"}}
|
||||
<p>
|
||||
Describe what your blog is about
|
||||
{{gh-count-characters model.description}}
|
||||
</p>
|
||||
|
||||
</div>
|
||||
{{/gh-form-group}}
|
||||
</fieldset>
|
||||
|
||||
<div class="form-group">
|
||||
@ -52,7 +53,7 @@
|
||||
<div class="form-group">
|
||||
<label for="postsPerPage">Posts per page</label>
|
||||
{{! `pattern` brings up numeric keypad allowing any number of digits}}
|
||||
{{input id="postsPerPage" class="gh-input" name="general[postsPerPage]" focus-out="checkPostsPerPage" value=model.postsPerPage min="1" max="1000" type="number" pattern="[0-9]*"}}
|
||||
{{gh-input id="postsPerPage" class="gh-input" name="general[postsPerPage]" focus-out="checkPostsPerPage" value=model.postsPerPage min="1" max="1000" type="number" pattern="[0-9]*"}}
|
||||
<p>How many posts should be displayed on each page</p>
|
||||
</div>
|
||||
|
||||
@ -92,10 +93,11 @@
|
||||
</div>
|
||||
|
||||
{{#if model.isPrivate}}
|
||||
<div class="form-group">
|
||||
{{input name="general[password]" type="text" value=model.password}}
|
||||
{{#gh-form-group errors=model.errors property="password"}}
|
||||
{{gh-input name="general[password]" type="text" value=model.password focusOut=(action "validate" "password")}}
|
||||
{{gh-error-message errors=model.errors property="password"}}
|
||||
<p>This password will be needed to access your blog. All search engine optimization and social features are now disabled. This password is stored in plaintext.</p>
|
||||
</div>
|
||||
{{/gh-form-group}}
|
||||
{{/if}}
|
||||
</fieldset>
|
||||
</form>
|
||||
|
@ -8,6 +8,7 @@
|
||||
<form class="gh-flow-invite">
|
||||
<label>Enter one email address per line, we’ll handle the rest! <i class="icon-mail"></i></label>
|
||||
{{textarea class="gh-input" name="users" value=users required="required"}}
|
||||
{{gh-error-message errors=errors property="users"}}
|
||||
</form>
|
||||
|
||||
<button {{action 'invite'}} class="btn btn-default btn-lg btn-block {{buttonClass}}">
|
||||
|
@ -2,17 +2,19 @@
|
||||
<div class="gh-flow-content-wrap">
|
||||
<section class="gh-flow-content">
|
||||
<form id="login" class="gh-signin" method="post" novalidate="novalidate" {{action "validateAndAuthenticate" on="submit"}}>
|
||||
<div class="form-group">
|
||||
{{#gh-form-group errors=model.errors property="identification"}}
|
||||
<span class="input-icon icon-mail">
|
||||
{{gh-trim-focus-input class="gh-input email" type="email" placeholder="Email Address" name="identification" autocapitalize="off" autocorrect="off" tabindex="1" value=model.identification}}
|
||||
{{gh-trim-focus-input class="gh-input email" type="email" placeholder="Email Address" name="identification" autocapitalize="off" autocorrect="off" tabindex="1" value=model.identification focusOut=(action "validate" "identification")}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{gh-error-message errors=model.errors property="identification"}}
|
||||
{{/gh-form-group}}
|
||||
{{#gh-form-group errors=model.errors property="password"}}
|
||||
<span class="input-icon icon-lock forgotten-wrap">
|
||||
{{input class="gh-input password" type="password" placeholder="Password" name="password" tabindex="2" value=model.password}}
|
||||
{{input class="gh-input password" type="password" placeholder="Password" name="password" tabindex="2" value=model.password focusOut=(action "validate" "password")}}
|
||||
<button type="button" {{action "forgotten"}} class="forgotten-link btn btn-link" tabindex="4" disabled={{submitting}}>Forgot?</button>
|
||||
</span>
|
||||
</div>
|
||||
{{gh-error-message errors=model.errors property="password"}}
|
||||
{{/gh-form-group}}
|
||||
<button id="login-button" class="login btn btn-blue btn-block" type="submit" tabindex="3" disabled={{submitting}}>Sign in</button>
|
||||
</form>
|
||||
|
||||
|
@ -14,26 +14,28 @@
|
||||
<figure class="account-image">
|
||||
<div id="account-image" class="img" style="background-image: url(http://www.gravatar.com/avatar/75e958a6674a7d68fe0d575fb235116c?d=404&s=250)">
|
||||
<!-- fallback to: Ghost/core/shared/img/ghosticon.jpg -->
|
||||
<span class="sr-only">User imge</span>
|
||||
<span class="sr-only">User image</span>
|
||||
</div>
|
||||
<a class="edit-account-image" href="#"><i class="icon-photos "><span class="sr-only">Upload an image</span></i></a>
|
||||
</figure>
|
||||
<div class="form-group">
|
||||
{{#gh-form-group errors=model.errors property="email"}}
|
||||
<label for="email-address">Email address</label>
|
||||
<span class="input-icon icon-mail">
|
||||
{{input class="gh-input" type="email" name="email" autocorrect="off" value=model.email }}
|
||||
{{gh-input type="email" name="email" placeholder="Eg. john@example.com" class="gh-input" autofocus="autofocus" autocorrect="off" value=model.email focusOut=(action "validate" "email")}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{gh-error-message errors=model.errors property="email"}}
|
||||
{{/gh-form-group}}
|
||||
{{#gh-form-group errors=model.errors property="name"}}
|
||||
<label for="full-name">Full name</label>
|
||||
<span class="input-icon icon-user">
|
||||
{{gh-trim-focus-input class="gh-input" type="text" name="name" autofocus="autofocus" autocorrect="off" value=model.name }}
|
||||
{{gh-input type="text" name="name" placeholder="Eg. John H. Watson" class="gh-input" autofocus="autofocus" autocorrect="off" value=model.name focusOut=(action "validate" "name")}}
|
||||
</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
{{gh-error-message errors=model.errors property="name"}}
|
||||
{{/gh-form-group}}
|
||||
{{#gh-form-group errors=model.errors property="password"}}
|
||||
<label for="password">Password</label>
|
||||
<span class="input-icon icon-lock">
|
||||
{{input class="gh-input" type="password" name="password" autofocus="autofocus" autocorrect="off" value=model.password }}
|
||||
{{input class="gh-input" type="password" name="password" autofocus="autofocus" autocorrect="off" value=model.password focusOut=(action "validate" "password")}}
|
||||
<div class="pw-strength">
|
||||
<div class="pw-strength-dot"></div>
|
||||
<div class="pw-strength-dot"></div>
|
||||
@ -42,7 +44,8 @@
|
||||
<div class="pw-strength-dot <!--pw-strength-activedot-->"></div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
{{gh-error-message errors=model.errors property="password"}}
|
||||
{{/gh-form-group}}
|
||||
</form>
|
||||
|
||||
<button type="submit" class="btn btn-green btn-lg btn-block" {{action "signup"}} disabled={{submitting}}>Create Account</button>
|
||||
|
@ -53,32 +53,39 @@
|
||||
<button type="button" {{action "openModal" "upload" user "image"}} class="edit-user-image js-modal-image">Edit Picture</button>
|
||||
</figure>
|
||||
|
||||
<div class="form-group first-form-group">
|
||||
{{#gh-form-group class="first-form-group" errors=user.errors property="name"}}
|
||||
<label for="user-name">Full Name</label>
|
||||
{{input value=user.name id="user-name" class="gh-input user-name" placeholder="Full Name" autocorrect="off"}}
|
||||
<p>Use your real name so people can recognise you</p>
|
||||
</div>
|
||||
{{input value=user.name id="user-name" class="gh-input user-name" placeholder="Full Name" autocorrect="off" focusOut=(action "validate" "name")}}
|
||||
{{#if user.errors.name}}
|
||||
{{gh-error-message errors=user.errors property="name"}}
|
||||
{{else}}
|
||||
<p>Use your real name so people can recognise you</p>
|
||||
{{/if}}
|
||||
{{/gh-form-group}}
|
||||
|
||||
</fieldset>
|
||||
|
||||
<fieldset class="user-details-bottom">
|
||||
|
||||
<div class="form-group">
|
||||
{{#gh-form-group errors=user.errors property="slug"}}
|
||||
<label for="user-slug">Slug</label>
|
||||
{{gh-input class="gh-input user-name" id="user-slug" value=slugValue name="user" focus-out="updateSlug" placeholder="Slug" selectOnClick="true" autocorrect="off"}}
|
||||
<p>{{gh-blog-url}}/author/{{slugValue}}</p>
|
||||
</div>
|
||||
{{gh-error-message errors=user.errors property="slug"}}
|
||||
{{/gh-form-group}}
|
||||
|
||||
<div class="form-group">
|
||||
{{#gh-form-group errors=user.errors property="email"}}
|
||||
<label for="user-email">Email</label>
|
||||
{{!-- Administrators only see text of Owner's email address but not input --}}
|
||||
{{#unless isAdminUserOnOwnerProfile}}
|
||||
{{input type="email" value=user.email id="user-email" class="gh-input" placeholder="Email Address" autocapitalize="off" autocorrect="off" autocomplete="off"}}
|
||||
{{input type="email" value=user.email id="user-email" name="email" class="gh-input" placeholder="Email Address" autocapitalize="off" autocorrect="off" autocomplete="off" focusOut=(action "validate" "email")}}
|
||||
{{gh-error-message errors=user.errors property="email"}}
|
||||
{{else}}
|
||||
<span>{{user.email}}</span>
|
||||
{{/unless}}
|
||||
<p>Used for notifications</p>
|
||||
</div>
|
||||
{{/gh-form-group}}
|
||||
|
||||
{{#if rolesDropdownIsVisible}}
|
||||
<div class="form-group">
|
||||
<label for="user-role">Role</label>
|
||||
@ -94,26 +101,30 @@
|
||||
<p>What permissions should this user have?</p>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="form-group">
|
||||
|
||||
{{#gh-form-group errors=user.errors property="location"}}
|
||||
<label for="user-location">Location</label>
|
||||
{{input type="text" value=user.location id="user-location" class="gh-input"}}
|
||||
{{input type="text" value=user.location id="user-location" class="gh-input" focusOut=(action "validate" "location")}}
|
||||
{{gh-error-message errors=user.errors property="location"}}
|
||||
<p>Where in the world do you live?</p>
|
||||
</div>
|
||||
{{/gh-form-group}}
|
||||
|
||||
<div class="form-group">
|
||||
{{#gh-form-group errors=user.errors property="website"}}
|
||||
<label for="user-website">Website</label>
|
||||
{{input type="url" value=user.website id="user-website" class="gh-input" autocapitalize="off" autocorrect="off" autocomplete="off"}}
|
||||
{{input type="url" value=user.website id="user-website" class="gh-input" autocapitalize="off" autocorrect="off" autocomplete="off" focusOut=(action "validate" "website")}}
|
||||
{{gh-error-message errors=user.errors property="website"}}
|
||||
<p>Have a website or blog other than this one? Link it!</p>
|
||||
</div>
|
||||
{{/gh-form-group}}
|
||||
|
||||
<div class="form-group bio-container">
|
||||
{{#gh-form-group class="bio-container" errors=user.errors property="bio"}}
|
||||
<label for="user-bio">Bio</label>
|
||||
{{textarea id="user-bio" class="gh-input" value=user.bio}}
|
||||
{{textarea id="user-bio" class="gh-input" value=user.bio focusOut=(action "validate" "bio")}}
|
||||
{{gh-error-message errors=user.errors property="bio"}}
|
||||
<p>
|
||||
Write about you, in 200 characters or less.
|
||||
{{gh-count-characters user.bio}}
|
||||
</p>
|
||||
</div>
|
||||
{{/gh-form-group}}
|
||||
|
||||
<hr />
|
||||
|
||||
|
@ -5,7 +5,10 @@ var ResetValidator = BaseValidator.create({
|
||||
var p1 = model.get('newPassword'),
|
||||
p2 = model.get('ne2Password');
|
||||
|
||||
if (!validator.isLength(p1, 8)) {
|
||||
if (validator.empty(p1)) {
|
||||
model.get('errors').add('newPassword', 'Please enter a password.');
|
||||
this.invalidate();
|
||||
} else if (!validator.isLength(p1, 8)) {
|
||||
model.get('errors').add('newPassword', 'The password is not long enough.');
|
||||
this.invalidate();
|
||||
} else if (!validator.equals(p1, p2)) {
|
||||
|
@ -20,7 +20,7 @@ var SettingValidator = BaseValidator.create({
|
||||
},
|
||||
password: function (model) {
|
||||
var isPrivate = model.get('isPrivate'),
|
||||
password = this.get('password');
|
||||
password = model.get('password');
|
||||
|
||||
if (isPrivate && password === '') {
|
||||
model.get('errors').add('password', 'Password must be supplied');
|
||||
|
@ -7,6 +7,7 @@ var SigninValidator = BaseValidator.create({
|
||||
|
||||
if (validator.empty(id)) {
|
||||
model.get('errors').add('identification', 'Please enter an email');
|
||||
this.invalidate();
|
||||
} else if (!validator.isEmail(id)) {
|
||||
model.get('errors').add('identification', 'Invalid email');
|
||||
this.invalidate();
|
||||
|
@ -10,7 +10,10 @@ var UserValidator = BaseValidator.create({
|
||||
var name = model.get('name');
|
||||
|
||||
if (this.isActive(model)) {
|
||||
if (!validator.isLength(name, 0, 150)) {
|
||||
if (validator.empty(name)) {
|
||||
model.get('errors').add('name', 'Please enter a name.');
|
||||
this.invalidate();
|
||||
} else if (!validator.isLength(name, 0, 150)) {
|
||||
model.get('errors').add('name', 'Name is too long');
|
||||
this.invalidate();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user