Commit 300bd431 by Christina Roberts

Merge pull request #9845 from edx/christina/bio-hyperlink

Make HTML for non-editable views on leaner profile page more logical
parents 83734989 113cab87
......@@ -143,7 +143,11 @@ class FieldsMixin(object):
"""
self.wait_for_field(field_id)
return self.value_for_text_field(field_id)
query = self.q(css='.u-field-{} .u-field-value'.format(field_id))
if not query.present:
return None
return query.text[0]
def value_for_text_field(self, field_id, value=None, press_enter=True):
"""
......
......@@ -24,6 +24,16 @@ class AccountSettingsTestMixin(EventsTestMixin, WebAppTest):
USER_SETTINGS_CHANGED_EVENT_NAME = 'edx.user.settings.changed'
ACCOUNT_SETTINGS_REFERER = u"/account/settings"
def visit_account_settings_page(self):
"""
Visit the account settings page for the current user, and store the page instance
as self.account_settings_page.
"""
# pylint: disable=attribute-defined-outside-init
self.account_settings_page = AccountSettingsPage(self.browser)
self.account_settings_page.visit()
self.account_settings_page.wait_for_ajax()
def log_in_as_unique_user(self, email=None):
"""
Create a unique user and return the account's username and id.
......@@ -116,14 +126,6 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, WebAppTest):
self.username, self.user_id = self.log_in_as_unique_user()
self.visit_account_settings_page()
def visit_account_settings_page(self):
"""
Visit the account settings page for the current user.
"""
self.account_settings_page = AccountSettingsPage(self.browser)
self.account_settings_page.visit()
self.account_settings_page.wait_for_ajax()
def test_page_view_event(self):
"""
Scenario: An event should be recorded when the "Account Settings"
......@@ -444,3 +446,18 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, WebAppTest):
for field_id, title, link_title in providers:
self.assertEqual(self.account_settings_page.title_for_field(field_id), title)
self.assertEqual(self.account_settings_page.link_title_for_link_field(field_id), link_title)
@attr('a11y')
class AccountSettingsA11yTest(AccountSettingsTestMixin, WebAppTest):
"""
Class to test account settings accessibility.
"""
def test_account_settings_a11y(self):
"""
Test the accessibility of the account settings page.
"""
self.log_in_as_unique_user()
self.visit_account_settings_page()
self.account_settings_page.a11y_audit.check_for_accessibility_errors()
......@@ -147,6 +147,26 @@ class LearnerProfileTestMixin(EventsTestMixin):
with self.assert_events_match_during(event_filter=event_filter, expected_events=[expected_event]):
yield
def initialize_different_user(self, privacy=None, birth_year=None):
"""
Initialize the profile page for a different test user
"""
username, user_id = self.log_in_as_unique_user()
# Set the privacy for the new user
if privacy is None:
privacy = self.PRIVACY_PUBLIC
self.visit_profile_page(username, privacy=privacy)
# Set the user's year of birth
if birth_year:
self.set_birth_year(birth_year)
# Log the user out
LogoutPage(self.browser).visit()
return username, user_id
@attr('shard_4')
class OwnLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
......@@ -677,7 +697,7 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
Then I shouldn't see the profile visibility selector dropdown.
Then I see some of the profile fields are shown.
"""
different_username, different_user_id = self._initialize_different_user(privacy=self.PRIVACY_PRIVATE)
different_username, different_user_id = self.initialize_different_user(privacy=self.PRIVACY_PRIVATE)
username, __ = self.log_in_as_unique_user()
profile_page = self.visit_profile_page(different_username)
self.verify_profile_page_is_private(profile_page, is_editable=False)
......@@ -693,7 +713,7 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
Then I see that only the private fields are shown.
"""
under_age_birth_year = datetime.now().year - 10
different_username, different_user_id = self._initialize_different_user(
different_username, different_user_id = self.initialize_different_user(
privacy=self.PRIVACY_PUBLIC,
birth_year=under_age_birth_year
)
......@@ -713,29 +733,52 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
Then I shouldn't see the profile visibility selector dropdown.
Also `location`, `language` and `about me` fields are not editable.
"""
different_username, different_user_id = self._initialize_different_user(privacy=self.PRIVACY_PUBLIC)
different_username, different_user_id = self.initialize_different_user(privacy=self.PRIVACY_PUBLIC)
username, __ = self.log_in_as_unique_user()
profile_page = self.visit_profile_page(different_username)
profile_page.wait_for_public_fields()
self.verify_profile_page_is_public(profile_page, is_editable=False)
self.verify_profile_page_view_event(username, different_user_id, visibility=self.PRIVACY_PUBLIC)
def _initialize_different_user(self, privacy=None, birth_year=None):
@attr('a11y')
class LearnerProfileA11yTest(LearnerProfileTestMixin, WebAppTest):
"""
Class to test learner profile accessibility.
"""
def test_editable_learner_profile_a11y(self):
"""
Initialize the profile page for a different test user
Test the accessibility of the editable version of the profile page
(user viewing her own public profile).
"""
username, user_id = self.log_in_as_unique_user()
username, _ = self.log_in_as_unique_user()
profile_page = self.visit_profile_page(username)
# Set the privacy for the new user
if privacy is None:
privacy = self.PRIVACY_PUBLIC
self.visit_profile_page(username, privacy=privacy)
# TODO: There are several existing color contrast errors on this page,
# we will ignore this error in the test until we fix them.
profile_page.a11y_audit.config.set_rules({
"ignore": ['color-contrast'],
})
# Set the user's year of birth
if birth_year:
self.set_birth_year(birth_year)
profile_page.a11y_audit.check_for_accessibility_errors()
# Log the user out
LogoutPage(self.browser).visit()
profile_page.make_field_editable('language_proficiencies')
profile_page.a11y_audit.check_for_accessibility_errors()
return username, user_id
profile_page.make_field_editable('bio')
profile_page.a11y_audit.check_for_accessibility_errors()
def test_read_only_learner_profile_a11y(self):
"""
Test the accessibility of the read-only version of a public profile page
(user viewing someone else's profile page).
"""
# initialize_different_user should cause country, language, and bio to be filled out (since
# privacy is public). It doesn't appear that this is happening, although the method
# works in regular bokchoy tests. Perhaps a problem with phantomjs? So this test is currently
# only looking at a read-only profile page with a username.
different_username, _ = self.initialize_different_user(privacy=self.PRIVACY_PUBLIC)
self.log_in_as_unique_user()
profile_page = self.visit_profile_page(different_username)
profile_page.a11y_audit.check_for_accessibility_errors()
......@@ -63,6 +63,10 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
expect(view.$('.u-field-title').text().trim()).toContain(expectedTitle);
};
var expectDropdownSrTitleToContain = function(view, expectedTitle) {
expect(view.$('.u-field-value .sr').text().trim()).toContain(expectedTitle);
};
var expectMessageContains = function(view, expectedText) {
expect(view.$('.u-field-message').html()).toContain(expectedText);
};
......@@ -167,7 +171,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
expectMessageContains(view, view.indicators.canEdit);
view.$el.click();
} else {
expectTitleAndMessageToContain(view, data.title, data.helpMessage, false);
expectTitleAndMessageToContain(view, data.title, data.helpMessage);
}
expect(view.el).toHaveClass('mode-edit');
......@@ -254,6 +258,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
createFieldData: createFieldData,
createErrorMessage: createErrorMessage,
expectTitleToContain: expectTitleToContain,
expectDropdownSrTitleToContain: expectDropdownSrTitleToContain,
expectTitleAndMessageToContain: expectTitleAndMessageToContain,
expectMessageContains: expectMessageContains,
expectAjaxRequestWithData: expectAjaxRequestWithData,
......
......@@ -10,7 +10,10 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
describe("edx.FieldViews", function () {
var requests,
timerCallback;
timerCallback,
dropdownSelectClass = '.u-field-value > select',
dropdownButtonClass = '.u-field-value > button',
textareaLinkClass = '.u-field-value a';
var fieldViewClasses = [
FieldViews.ReadonlyFieldView,
......@@ -89,11 +92,11 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
});
var view = new FieldViews.ReadonlyFieldView(fieldData).render();
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
expect(view.$('.u-field-value input').val().trim()).toBe(USERNAME);
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
expect(view.fieldValue()).toBe(USERNAME);
view.model.set({'username': 'bookworm'});
expect(view.$('.u-field-value input').val().trim()).toBe('bookworm');
expect(view.fieldValue()).toBe('bookworm');
});
it("correctly renders, updates and persists changes to TextFieldView when editable == always", function() {
......@@ -133,13 +136,30 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
});
var view = new FieldViews.DropdownFieldView(fieldData).render();
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
var readOnlyDisplayClass = '.u-field-value-readonly';
FieldViewsSpecHelpers.expectDropdownSrTitleToContain(view, fieldData.title);
FieldViewsSpecHelpers.expectMessageContains(view, fieldData.helpMessage);
expect(view.el).toHaveClass('mode-hidden');
// Note that "name" will be retrieved from the model, but the options specified are
// the languages options. Therefore initially the placeholder message will be shown because
// the model value does not match any of the possible options.
expect(view.fieldValue()).toBeNull();
expect(view.$(readOnlyDisplayClass).text()).toBe(fieldData.placeholderValue);
// Make sure that the select and the button are not in the HTML.
expect(view.$(dropdownSelectClass).length).toBe(0);
expect(view.$(dropdownButtonClass).length).toBe(0);
view.model.set({'name': fieldData.options[1][0]});
expect(view.el).toHaveClass('mode-display');
expect(view.fieldValue()).toBe(fieldData.options[1][0]);
expect(view.$(readOnlyDisplayClass).text()).toBe(fieldData.options[1][1]);
view.$el.click();
expect(view.el).toHaveClass('mode-display');
// Make sure that the select and the button still are not in the HTML.
expect(view.$(dropdownSelectClass).length).toBe(0);
expect(view.$(dropdownButtonClass).length).toBe(0);
});
it("correctly renders, updates and persists changes to DropdownFieldView when editable == always", function() {
......@@ -210,12 +230,16 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
expect(view.modelValueIsSet()).toBe(false);
expect(view.displayValue()).toBe('');
if(editable === 'toggle') { view.showEditMode(true); }
view.$('.u-field-value > select').val(FieldViewsSpecHelpers.SELECT_OPTIONS[0]).change();
if (editable === 'toggle') {
expect(view.$(dropdownButtonClass).length).toBe(1);
view.showEditMode(true);
}
expect(view.$(dropdownSelectClass).length).toBe(1);
view.$(dropdownSelectClass).val(FieldViewsSpecHelpers.SELECT_OPTIONS[0]).change();
expect(view.fieldValue()).toBe(FieldViewsSpecHelpers.SELECT_OPTIONS[0][0]);
AjaxHelpers.respondWithNoContent(requests);
if(editable === 'toggle') { view.showEditMode(true); }
if (editable === 'toggle') { view.showEditMode(true); }
// When server returns success, there should no longer be an empty option.
expect($(view.$('.u-field-value option')[0]).val()).toBe('si');
});
......@@ -236,16 +260,18 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
// set bio to empty to see the placeholder.
fieldData.model.set({bio: ''});
var view = new FieldViews.TextareaFieldView(fieldData).render();
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
expect(view.el).toHaveClass('mode-hidden');
expect(view.$('.u-field-value .u-field-value-readonly').text()).toBe(fieldData.placeholderValue);
expect(view.fieldValue()).toBe(fieldData.placeholderValue);
expect(view.$(textareaLinkClass).length).toBe(0);
var bio = 'Too much to tell!';
view.model.set({'bio': bio});
expect(view.el).toHaveClass('mode-display');
expect(view.$('.u-field-value .u-field-value-readonly').text()).toBe(bio);
expect(view.fieldValue()).toBe(bio);
view.$el.click();
expect(view.el).toHaveClass('mode-display');
expect(view.$(textareaLinkClass).length).toBe(0);
});
it("correctly renders, updates and persists changes to TextAreaFieldView when editable == toggle", function() {
......@@ -270,23 +296,26 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
FieldViewsSpecHelpers.expectTitleToContain(view, fieldData.title);
FieldViewsSpecHelpers.expectMessageContains(view, view.indicators.canEdit);
expect(view.el).toHaveClass('mode-placeholder');
expect(view.$('.u-field-value .u-field-value-readonly').text()).toBe(fieldData.placeholderValue);
expect(view.fieldValue()).toBe(fieldData.placeholderValue);
expect(view.$(textareaLinkClass).length).toBe(1);
view.$('.wrapper-u-field').click();
expect(view.el).toHaveClass('mode-edit');
view.$(valueInputSelector).val(BIO).focusout();
expect(view.fieldValue()).toBe(BIO);
expect(view.$(textareaLinkClass).length).toBe(0);
AjaxHelpers.expectJsonRequest(
requests, 'PATCH', view.model.url, {'bio': BIO}
);
AjaxHelpers.respondWithNoContent(requests);
expect(view.el).toHaveClass('mode-display');
expect(view.$(textareaLinkClass).length).toBe(1);
view.$('.wrapper-u-field').click();
view.$(valueInputSelector).val('').focusout();
AjaxHelpers.respondWithNoContent(requests);
expect(view.el).toHaveClass('mode-placeholder');
expect(view.$('.u-field-value .u-field-value-readonly').text()).toBe(fieldData.placeholderValue);
expect(view.fieldValue()).toBe(fieldData.placeholderValue);
});
it("correctly renders LinkFieldView", function() {
......@@ -298,7 +327,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
});
var view = new FieldViews.LinkFieldView(fieldData).render();
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
expect(view.$('.u-field-value > a .u-field-link-title-' + view.options.valueAttribute).text().trim()).toBe(fieldData.linkTitle);
});
......@@ -311,7 +340,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
});
var view = new FieldViews.LinkFieldView(fieldData).render();
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false);
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
expect(view.$('.u-field-value > a .u-field-link-title-' + view.options.valueAttribute).text().trim()).toBe(fieldData.linkTitle);
});
......
......@@ -225,7 +225,7 @@
},
finishEditing: function() {
if (this.persistChanges === false) {return;}
if (this.persistChanges === false || this.mode !== 'edit') {return;}
if (this.fieldValue() !== this.modelValue()) {
this.saveValue();
} else {
......@@ -271,11 +271,11 @@
},
fieldValue: function () {
return this.$('.u-field-value input').val();
return this.$('.u-field-value').text();
},
updateValueInField: function () {
this.$('.u-field-value input').val(_.escape(this.modelValue()));
this.$('.u-field-value ').html(_.escape(this.modelValue()));
}
});
......@@ -345,9 +345,10 @@
this.$el.html(this.template({
id: this.options.valueAttribute,
mode: this.mode,
editable: this.editable,
title: this.options.title,
screenReaderTitle: this.options.screenReaderTitle || this.options.title,
titleVisible: this.options.titleVisible || true,
titleVisible: this.options.titleVisible !== undefined ? this.options.titleVisible : true,
iconName: this.options.iconName,
showBlankOption: (!this.options.required || !this.modelValueIsSet()),
selectOptions: this.options.options,
......@@ -376,7 +377,13 @@
},
fieldValue: function () {
var value = this.$('.u-field-value select').val();
var value;
if (this.editable === 'never') {
value = this.modelValueIsSet() ? this.modelValue () : null;
}
else {
value = this.$('.u-field-value select').val();
}
return value === '' ? null : value;
},
......@@ -390,7 +397,9 @@
},
updateValueInField: function () {
this.$('.u-field-value select').val(this.modelValue() || '');
if (this.editable !== 'never') {
this.$('.u-field-value select').val(this.modelValue() || '');
}
var value = this.displayValue(this.modelValue() || '');
if (this.modelValueIsSet() === false) {
......@@ -437,7 +446,9 @@
},
disableField: function(disable) {
this.$('.u-field-value select').prop('disabled', disable);
if (this.editable !== 'never') {
this.$('.u-field-value select').prop('disabled', disable);
}
}
});
......@@ -473,6 +484,7 @@
id: this.options.valueAttribute,
screenReaderTitle: this.options.screenReaderTitle || this.options.title,
mode: this.mode,
editable: this.editable,
value: value,
message: this.helpMessage,
messagePosition: this.options.messagePosition || 'footer',
......@@ -504,11 +516,16 @@
modelValue: function() {
var value = this._super();
return value ? $.trim(value) : '';
return value ? $.trim(value) : '';
},
fieldValue: function () {
return this.$('.u-field-value textarea').val();
if (this.mode === 'edit') {
return this.$('.u-field-value textarea').val();
}
else {
return this.$('.u-field-value .u-field-value-readonly').text();
}
},
saveValue: function () {
......
......@@ -133,6 +133,8 @@
padding: 0;
box-shadow: none;
font-size: inherit;
font-weight: inherit;
text-shadow: none;
}
......
......@@ -9,6 +9,7 @@
.view-profile {
$profile-image-dimension: 120px;
.window-wrap,
.content-wrapper {
background-color: $white;
}
......@@ -34,6 +35,7 @@
.u-field-image {
padding-top: 0;
padding-bottom: ($baseline/4);
}
.image-wrapper {
......@@ -128,10 +130,11 @@
.wrapper-profile-field-account-privacy {
@include clearfix();
@include box-sizing(border-box);
width: 100%;
margin: 0 auto 0;
border: 1px solid $gray-l3;
background-color: $gray-l4;
padding: ($baseline*0.75) 0;
width: 100%;
background-color: $gray-l3;
.u-field-account_privacy {
@extend .container;
......@@ -141,10 +144,11 @@
}
.u-field-title {
@extend %t-strong;
width: auto;
color: $base-font-color;
font-weight: $font-bold;
cursor: text;
text-shadow: none; // override bad lms styles on labels
}
.u-field-value {
......@@ -157,6 +161,10 @@
width: 100%;
padding: 0;
color: $base-font-color;
.u-field-message-notification {
color: $gray-d2;
}
}
}
}
......@@ -170,22 +178,22 @@
width: 100%;
display: inline-block;
margin-top: ($baseline*1.5);
@include margin-left($baseline/2);
}
.profile-section-one-fields {
@include float(left);
width: flex-grid(4, 12);
@include margin-left($baseline*1.5);
@include margin-left($baseline);
.u-field {
margin-bottom: ($baseline/4);
padding-top: 0;
padding-bottom: 0;
padding-top: 3px;
padding-bottom: 3px;
@include padding-left(3px);
}
.u-field-username {
margin-bottom: ($baseline/2);
input[type="text"] {
font-weight: 600;
......@@ -197,12 +205,19 @@
}
}
.u-field-icon {
display: inline-block;
vertical-align: baseline;
}
.u-field-title {
width: 0;
}
.u-field-value {
width: 200px;
display: inline-block;
vertical-align: baseline;
}
select {
......@@ -212,7 +227,13 @@
.u-field-message {
@include float(right);
width: 20px;
margin-top: 2px;
display: inline-block;
vertical-align: baseline;
margin-top: 0;
.icon {
vertical-align: baseline;
}
}
}
......@@ -224,30 +245,40 @@
.u-field-textarea {
margin-bottom: ($baseline/2);
padding: ($baseline/4) ($baseline/2) ($baseline/2);
padding: ($baseline/2) ($baseline*.75) ($baseline*.75) ($baseline*.75);
&.editable-toggle {
cursor: pointer;
}
}
.u-field-title {
font-size: 1.1em;
@extend %t-title5;
@extend %t-weight4;
display: inline-block;
margin-top: 0;
margin-bottom: ($baseline/4);
color: inherit;
}
.u-field-value {
@extend %t-copy-base;
width: 100%;
white-space: pre-line;
line-height: 1.5em;
textarea {
width: 100%;
background-color: transparent;
white-space: pre-line;
}
a {
color: inherit;
}
}
.u-field-message {
@include float(right);
width: auto;
padding-top: ($baseline/4);
}
.u-field.mode-placeholder {
......
<% if (title) { %>
<label class="u-field-title" for="u-field-select-<%- id %>">
<%- title %>
</label>
<% } %>
<% if (!titleVisible) { %>
<label class="sr" for="u-field-select-<%- id %>">
<%- screenReaderTitle %>
</label>
<% if (editable !== 'never') { %>
<% if (title && titleVisible) { %>
<label class="u-field-title" for="u-field-select-<%- id %>">
<%- title %>
</label>
<% } else { %>
<label class="sr" for="u-field-select-<%- id %>">
<%- screenReaderTitle %>
</label>
<% } %>
<% } %>
<% if (iconName) { %>
......@@ -15,19 +15,24 @@
<% } %>
<span class="u-field-value">
<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>
<button class="u-field-value-display">
<% if (editable === 'never') { %>
<span class="sr"><%- screenReaderTitle %> &nbsp;</span>
<span class="u-field-value-readonly"></span>
<span class="sr">&nbsp; <%- gettext('Click to edit') %></span>
</button>
<% } else { %>
<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>
<button class="u-field-value-display">
<span class="sr"><%- screenReaderTitle %> &nbsp;</span>
<span class="u-field-value-readonly"></span>
<span class="sr">&nbsp; <%- gettext('Click to edit') %></span>
</button>
<% } %>
</span>
<span class="u-field-message" id="u-field-message-<%- id %>">
......
<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>
<% if (title) { %>
<span class="u-field-title" aria-hidden="true"><%- title %></span>
<% } %>
<span class="sr" for="u-field-value-<%- id %>"><%- screenReaderTitle %></span>
<span class="u-field-value" id="u-field-value-<%- id %>" aria-describedby="u-field-message-<%- id %>"><%- value %></span>
<span class="u-field-message" id="u-field-message-<%- id %>">
<span class="u-field-message-notification" aria-live="polite"></span>
<span class="u-field-message-help" id="u-field-help-message-<%- id %>"> <%- message %></span>
......
<div class="wrapper-u-field">
<div class="u-field-header">
<label class="u-field-title" for="u-field-textarea-<%- id %>" id="u-field-title-<%- id %>" aria-describedby="u-field-message-help-<%- id %>"></label>
<% if (mode === 'edit') { %>
<label class="u-field-title" for="u-field-textarea-<%- id %>" id="u-field-title-<%- id %>"></label>
<% } else { %>
<span class="u-field-title" id="u-field-title-<%- id %>" aria-hidden="true"></span>
<% } %>
<% if (messagePosition === 'header') { %>
<span class="u-field-message" id="u-field-message-<%- id %>">
<span class="u-field-message-notification" aria-live="polite"></span>
......@@ -9,14 +13,23 @@
<% }%>
</div>
<div class="u-field-value" id="u-field-value-<%- id %>" aria-labelledby="u-field-title-<%- id %>"><%
var textareaDescribedBy = (message ? 'u-field-message-help-' : 'u-field-placeholder-value-') + id;
if (mode === 'edit') {%>
<textarea id="u-field-textarea-<%- id %>" rows="4" aria-describedby="<%- textareaDescribedBy %>"><%- value %></textarea>
<% } else {
%><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 class="u-field-value" id="u-field-value-<%- id %>"
<% if (mode === 'edit') { %>
aria-labelledby="u-field-title-<%- id %>"><textarea id="u-field-textarea-<%- id %>" rows="4"
<% if (message) { %>
aria-describedby="u-field-message-help-<%- id %>"
<% } %>
><%- value %></textarea>
<% } else if (editable === 'never') { %>
><p class="sr"><%- screenReaderTitle %></p><span class="u-field-value-readonly" aria-hidden="false"
<% if (message) { %>
aria-describedby="u-field-message-help-<%- id %>"
<% } %>
><%- value %></span>
<% } else { %>
><a href="#"><p class="sr"><%- screenReaderTitle %></p><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>
<div class="u-field-footer">
......
......@@ -12,7 +12,7 @@ from microsite_configuration import microsite
<%namespace name='static' file='/static_content.html'/>
<%block name="pagetitle">${_("Account Settings")}</%block>
<%block name="nav_skip">#u-field-input-username</%block>
<%block name="nav_skip">#content</%block>
% if duplicate_provider:
<section>
......
......@@ -8,7 +8,7 @@ from openedx.core.lib.json_utils import EscapedEdxJSONEncoder
%>
<%block name="pagetitle">${_("Learner Profile")}</%block>
<%block name="nav_skip">#u-field-select-account_privacy</%block>
<%block name="nav_skip">#content</%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