Accessibility tweaks for account settings and profile pages.
TNL-1660
This commit is contained in:
committed by
muzaffaryousaf
parent
7babb3efed
commit
a14e6f0a7e
@@ -161,7 +161,8 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
validValue: 'My Name',
|
||||
invalidValue1: '',
|
||||
invalidValue2: '@',
|
||||
validationError: "Think again!"
|
||||
validationError: "Think again!",
|
||||
defaultValue: ''
|
||||
}, requests);
|
||||
}
|
||||
|
||||
@@ -180,7 +181,8 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
validValue: Helpers.FIELD_OPTIONS[1][0],
|
||||
invalidValue1: Helpers.FIELD_OPTIONS[2][0],
|
||||
invalidValue2: Helpers.FIELD_OPTIONS[3][0],
|
||||
validationError: "Nope, this will not do!"
|
||||
validationError: "Nope, this will not do!",
|
||||
defaultValue: null
|
||||
}, requests);
|
||||
});
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ define(['underscore'], function(_) {
|
||||
username: 'student',
|
||||
name: 'Student',
|
||||
email: 'student@edx.org',
|
||||
level_of_education: '',
|
||||
gender: '',
|
||||
level_of_education: null,
|
||||
gender: null,
|
||||
year_of_birth: '3', // Note: test birth year range is a string from 0-3
|
||||
requires_parental_consent: false,
|
||||
country: '',
|
||||
language: '',
|
||||
country: '1',
|
||||
language: null,
|
||||
bio: "About the student",
|
||||
language_proficiencies: [{code: '1'}],
|
||||
profile_image: PROFILE_IMAGE
|
||||
|
||||
@@ -114,7 +114,7 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
expectMessageContains(view, view.helpMessage);
|
||||
view.showSuccessMessage();
|
||||
expectMessageContains(view, view.indicators.success);
|
||||
jasmine.Clock.tick(5000);
|
||||
jasmine.Clock.tick(7000);
|
||||
// Message gets reset
|
||||
expectMessageContains(view, view.helpMessage);
|
||||
|
||||
@@ -122,7 +122,7 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
expectMessageContains(view, view.indicators.success);
|
||||
// But if we change the message, it should not get reset.
|
||||
view.showHelpMessage("Do not reset this!");
|
||||
jasmine.Clock.tick(5000);
|
||||
jasmine.Clock.tick(7000);
|
||||
expectMessageContains(view, "Do not reset this!");
|
||||
};
|
||||
|
||||
@@ -138,9 +138,11 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
} else {
|
||||
expectTitleAndMessageToContain(view, data.title, data.helpMessage, false);
|
||||
}
|
||||
|
||||
expect(view.el).toHaveClass('mode-edit');
|
||||
expect(view.fieldValue()).not.toContain(data.validValue);
|
||||
|
||||
if (view.fieldValue() !== null) {
|
||||
expect(view.fieldValue()).not.toContain(data.validValue);
|
||||
}
|
||||
|
||||
view.$(data.valueInputSelector).val(data.validValue).change();
|
||||
// When the value in the field is changed
|
||||
@@ -185,8 +187,8 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
|
||||
view.$(data.valueInputSelector).val('').change();
|
||||
// When the value in the field is changed
|
||||
expect(view.fieldValue()).toBe('');
|
||||
request_data[data.valueAttribute] = '';
|
||||
expect(view.fieldValue()).toBe(data.defaultValue);
|
||||
request_data[data.valueAttribute] = data.defaultValue;
|
||||
AjaxHelpers.expectJsonRequest(
|
||||
requests, 'PATCH', url, request_data
|
||||
);
|
||||
|
||||
@@ -121,7 +121,8 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
validValue: 'My Name',
|
||||
invalidValue1: 'Your Name',
|
||||
invalidValue2: 'Her Name',
|
||||
validationError: "Think again!"
|
||||
validationError: "Think again!",
|
||||
defaultValue: ''
|
||||
}, requests);
|
||||
});
|
||||
|
||||
@@ -164,7 +165,8 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
validValue: FieldViewsSpecHelpers.SELECT_OPTIONS[0][0],
|
||||
invalidValue1: FieldViewsSpecHelpers.SELECT_OPTIONS[1][0],
|
||||
invalidValue2: FieldViewsSpecHelpers.SELECT_OPTIONS[2][0],
|
||||
validationError: "Nope, this will not do!"
|
||||
validationError: "Nope, this will not do!",
|
||||
defaultValue: null
|
||||
}, requests);
|
||||
});
|
||||
|
||||
@@ -188,7 +190,8 @@ define(['backbone', 'jquery', 'underscore', 'js/common_helpers/ajax_helpers', 'j
|
||||
validValue: FieldViewsSpecHelpers.SELECT_OPTIONS[0][0],
|
||||
invalidValue1: FieldViewsSpecHelpers.SELECT_OPTIONS[1][0],
|
||||
invalidValue2: FieldViewsSpecHelpers.SELECT_OPTIONS[2][0],
|
||||
validationError: "Nope, this will not do!"
|
||||
validationError: "Nope, this will not do!",
|
||||
defaultValue: null
|
||||
}, requests);
|
||||
});
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
if (_.isArray(modelValue) && modelValue.length > 0) {
|
||||
return modelValue[0].code;
|
||||
} else {
|
||||
return '';
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@
|
||||
|
||||
var usernameFieldView = new FieldsView.ReadonlyFieldView({
|
||||
model: accountSettingsModel,
|
||||
screenReaderTitle: gettext('Username'),
|
||||
valueAttribute: "username",
|
||||
helpMessage: ""
|
||||
});
|
||||
@@ -70,12 +71,12 @@
|
||||
var sectionOneFieldViews = [
|
||||
new FieldsView.DropdownFieldView({
|
||||
model: accountSettingsModel,
|
||||
screenReaderTitle: gettext('Location'),
|
||||
screenReaderTitle: gettext('Country'),
|
||||
required: true,
|
||||
editable: editable,
|
||||
showMessages: false,
|
||||
iconName: 'fa-map-marker',
|
||||
placeholderValue: '',
|
||||
placeholderValue: gettext('Add Country'),
|
||||
valueAttribute: "country",
|
||||
options: options.country_options,
|
||||
helpMessage: ''
|
||||
|
||||
@@ -59,7 +59,10 @@
|
||||
// Update model to get the latest urls of profile image.
|
||||
this.model.fetch().done(function () {
|
||||
view.setCurrentStatus('');
|
||||
view.render();
|
||||
view.$('.u-field-upload-button').focus();
|
||||
}).fail(function () {
|
||||
view.setCurrentStatus('');
|
||||
view.showErrorMessage(view.errorMessage);
|
||||
});
|
||||
},
|
||||
@@ -67,7 +70,6 @@
|
||||
imageChangeFailed: function (e, data) {
|
||||
this.setCurrentStatus('');
|
||||
this.showImageChangeFailedMessage(data.jqXHR.status, data.jqXHR.responseText);
|
||||
this.render();
|
||||
},
|
||||
|
||||
showImageChangeFailedMessage: function (status, responseText) {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
var Mustache = window.Mustache || RequireMustache;
|
||||
|
||||
var messageRevertDelay = 4000;
|
||||
var messageRevertDelay = 6000;
|
||||
var FieldViews = {};
|
||||
|
||||
FieldViews.FieldView = Backbone.View.extend({
|
||||
@@ -176,10 +176,7 @@
|
||||
this.showSuccessMessage();
|
||||
},
|
||||
|
||||
showDisplayMode: function(render) {
|
||||
this.mode = 'display';
|
||||
if (render) { this.render(); }
|
||||
|
||||
updateDisplayModeClass: function() {
|
||||
this.$el.removeClass('mode-edit');
|
||||
|
||||
this.$el.toggleClass('mode-hidden', (this.editable === 'never' && !this.modelValueIsSet()));
|
||||
@@ -187,6 +184,12 @@
|
||||
this.$el.toggleClass('mode-display', (this.modelValueIsSet()));
|
||||
},
|
||||
|
||||
showDisplayMode: function(render) {
|
||||
this.mode = 'display';
|
||||
if (render) { this.render(); }
|
||||
this.updateDisplayModeClass();
|
||||
},
|
||||
|
||||
showEditMode: function(render) {
|
||||
this.mode = 'edit';
|
||||
if (render) { this.render(); }
|
||||
@@ -233,6 +236,7 @@
|
||||
this.$el.html(this.template({
|
||||
id: this.options.valueAttribute,
|
||||
title: this.options.title,
|
||||
screenReaderTitle: this.options.screenReaderTitle || this.options.title,
|
||||
value: this.modelValue(),
|
||||
message: this.helpMessage
|
||||
}));
|
||||
@@ -345,7 +349,8 @@
|
||||
},
|
||||
|
||||
fieldValue: function () {
|
||||
return this.$('.u-field-value select').val();
|
||||
var value = this.$('.u-field-value select').val();
|
||||
return value === '' ? null : value;
|
||||
},
|
||||
|
||||
displayValue: function (value) {
|
||||
@@ -358,16 +363,17 @@
|
||||
},
|
||||
|
||||
updateValueInField: function () {
|
||||
this.$('.u-field-value select').val(this.modelValue() || '');
|
||||
|
||||
var value = this.displayValue(this.modelValue() || '');
|
||||
if (this.modelValueIsSet() === false) {
|
||||
value = this.options.placeholderValue || '';
|
||||
}
|
||||
this.$('.u-field-value').attr('aria-label', this.options.title);
|
||||
this.$('.u-field-value-readonly').html(Mustache.escapeHtml(value));
|
||||
|
||||
if (this.mode === 'display') {
|
||||
var value = this.displayValue(this.modelValue() || '');
|
||||
if (this.modelValueIsSet() === false) {
|
||||
value = this.options.placeholderValue || '';
|
||||
}
|
||||
this.$('.u-field-value').attr('aria-label', this.options.title);
|
||||
this.$('.u-field-value-readonly').html(Mustache.escapeHtml(value));
|
||||
this.showDisplayMode(false);
|
||||
} else {
|
||||
this.$('.u-field-value select').val(this.modelValue() || '');
|
||||
this.updateDisplayModeClass();
|
||||
}
|
||||
},
|
||||
|
||||
@@ -377,6 +383,13 @@
|
||||
this.saveAttributes(attributes);
|
||||
},
|
||||
|
||||
showDisplayMode: function(render) {
|
||||
this._super(render);
|
||||
if (this.editable === 'toggle') {
|
||||
this.$('.u-field-value a').focus();
|
||||
}
|
||||
},
|
||||
|
||||
showEditMode: function(render) {
|
||||
this._super(render);
|
||||
if (this.editable === 'toggle') {
|
||||
@@ -386,10 +399,13 @@
|
||||
|
||||
saveSucceeded: function() {
|
||||
if (this.editable === 'toggle') {
|
||||
this.showDisplayMode(true);
|
||||
} else {
|
||||
this.showEditMode(true);
|
||||
this.showDisplayMode();
|
||||
}
|
||||
|
||||
if (this.options.required && this.modelValueIsSet()) {
|
||||
this.$('option[value=""]').remove();
|
||||
}
|
||||
|
||||
this._super();
|
||||
},
|
||||
|
||||
@@ -410,13 +426,13 @@
|
||||
'focusout textarea': 'finishEditing',
|
||||
'change textarea': 'adjustTextareaHeight',
|
||||
'keyup textarea': 'adjustTextareaHeight',
|
||||
'keydown textarea': 'adjustTextareaHeight',
|
||||
'keydown textarea': 'onKeyDown',
|
||||
'paste textarea': 'adjustTextareaHeight',
|
||||
'cut textarea': 'adjustTextareaHeight'
|
||||
},
|
||||
|
||||
initialize: function (options) {
|
||||
_.bindAll(this, 'render', 'adjustTextareaHeight', 'fieldValue', 'saveValue', 'updateView');
|
||||
_.bindAll(this, 'render', 'onKeyDown', 'adjustTextareaHeight', 'fieldValue', 'saveValue', 'updateView');
|
||||
this._super(options);
|
||||
this.listenTo(this.model, "change:" + this.options.valueAttribute, this.updateView);
|
||||
},
|
||||
@@ -443,6 +459,15 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
onKeyDown: function (event) {
|
||||
if (event.keyCode === 13) {
|
||||
event.preventDefault();
|
||||
this.finishEditing(event);
|
||||
} else {
|
||||
this.adjustTextareaHeight();
|
||||
}
|
||||
},
|
||||
|
||||
adjustTextareaHeight: function() {
|
||||
var textarea = this.$('textarea');
|
||||
textarea.css('height', 'auto').css('height', textarea.prop('scrollHeight') + 10);
|
||||
@@ -483,6 +508,7 @@
|
||||
this._super();
|
||||
if (this.editable === 'toggle') {
|
||||
this.showDisplayMode(true);
|
||||
this.$('a').focus();
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -552,7 +578,6 @@
|
||||
this._super(options);
|
||||
_.bindAll(this, 'render', 'imageChangeSucceeded', 'imageChangeFailed', 'fileSelected',
|
||||
'watchForPageUnload', 'onBeforeUnload');
|
||||
this.listenTo(this.model, "change:" + this.options.valueAttribute, this.render);
|
||||
},
|
||||
|
||||
render: function () {
|
||||
|
||||
@@ -121,3 +121,13 @@
|
||||
color: $gray-l1;
|
||||
}
|
||||
}
|
||||
|
||||
.u-field-dropdown {
|
||||
&.mode-display select, &.mode-placeholder select {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&.mode-edit a.u-field-value-display {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,26 +5,23 @@
|
||||
<% } %>
|
||||
|
||||
<% if (iconName) { %>
|
||||
<i class="u-field-icon icon fa <%- iconName %> fa-fw" aria-hidden="true" ></i>
|
||||
<i class="u-field-icon icon fa <%- iconName %> fa-fw" aria-hidden="true"></i>
|
||||
<% } %>
|
||||
|
||||
<span class="u-field-value">
|
||||
<% if (mode === 'edit') { %>
|
||||
<select name="select" id="u-field-select-<%- id %>" aria-describedby="u-field-message-<%- id %>">
|
||||
<% if (showBlankOption) { %>
|
||||
<option value=""></option>
|
||||
<% } %>
|
||||
<% _.each(selectOptions, function(selectOption) { %>
|
||||
<option value="<%- selectOption[0] %>"><%- selectOption[1] %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
<% } else { %>
|
||||
<a href="#" class="u-field-value-display">
|
||||
<span class="sr"><%- screenReaderTitle %></span>
|
||||
<span class="u-field-value-readonly"></span>
|
||||
<span class="sr"><%- gettext('Click to edit') %></span>
|
||||
</a>
|
||||
<% }%>
|
||||
<select name="select" id="u-field-select-<%- id %>" aria-describedby="u-field-message-<%- id %>">
|
||||
<% if (showBlankOption) { %>
|
||||
<option value=""></option>
|
||||
<% } %>
|
||||
<% _.each(selectOptions, function(selectOption) { %>
|
||||
<option value="<%- selectOption[0] %>"><%- selectOption[1] %></option>
|
||||
<% }); %>
|
||||
</select>
|
||||
<a href="#" class="u-field-value-display">
|
||||
<span class="sr"><%- screenReaderTitle %></span>
|
||||
<span class="u-field-value-readonly"></span>
|
||||
<span class="sr"><%- gettext('Click to edit') %></span>
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<span class="u-field-message" id="u-field-message-<%- id %>">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<label class="u-field-title" for="u-field-input-<%- id %>">
|
||||
<%- gettext(title) %>
|
||||
<label class="u-field-title" aria-hidden="true">
|
||||
<%- title %>
|
||||
</label>
|
||||
<span class="sr" for="u-field-input-<%- id %>"><%- screenReaderTitle %></span>
|
||||
<span class="u-field-value">
|
||||
<input id="u-field-input-<%- id %>" aria-describedby="u-field-message-<%- id %>" type="text" name="input" readonly=true value="<%- value %>">
|
||||
</span>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
if (mode === 'edit') {
|
||||
%><textarea id="u-field-textarea-<%- id %>" rows="4" aria-describedby="u-field-placeholder-value-<%- id %>"><%- value %></textarea><%
|
||||
} else {
|
||||
%><a href="#" class="u-field-value-display"><span class="sr"><%- screenReaderTitle %></span><span class="u-field-value-readonly" aria-hidden="false" aria-describedby="u-field-placeholder-value-<%- id %>"><%- value %></span><span class="sr"><%- gettext('Click to edit') %></span></a><%
|
||||
%><a href="#"><span class="sr"><%- screenReaderTitle %></span><span class="u-field-value-readonly" aria-hidden="false" aria-describedby="u-field-placeholder-value-<%- id %>"><%- value %></span><span class="sr"><%- gettext('Click to edit') %></span></a><%
|
||||
}
|
||||
%><span class="sr" id="u-field-placeholder-value-<%- id %>"><%- placeholderValue %></span>
|
||||
</div>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<%namespace name='static' file='/static_content.html'/>
|
||||
|
||||
<%block name="pagetitle">${_("Account Settings")}</%block>
|
||||
<%block name="nav_skip">#u-field-input-username</%block>
|
||||
|
||||
<%block name="header_extras">
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<%namespace name='static' file='/static_content.html'/>
|
||||
|
||||
<%block name="pagetitle">${_("Learner Profile")}</%block>
|
||||
<%block name="nav_skip">#u-field-select-account_privacy</%block>
|
||||
|
||||
<%block name="bodyclass">view-profile</%block>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user