Commit a14e6f0a by Usman Khalid Committed by muzaffaryousaf

Accessibility tweaks for account settings and profile pages.

TNL-1660
parent 7babb3ef
......@@ -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 %>">
......
<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>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment