Skip to content
Snippets Groups Projects
Commit c6ba7474 authored by cahrens's avatar cahrens
Browse files

Make HTML for non-editable views more logical.

TNL-3297
parent b92d239e
No related merge requests found
...@@ -143,7 +143,11 @@ class FieldsMixin(object): ...@@ -143,7 +143,11 @@ class FieldsMixin(object):
""" """
self.wait_for_field(field_id) 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): def value_for_text_field(self, field_id, value=None, press_enter=True):
""" """
......
...@@ -24,6 +24,16 @@ class AccountSettingsTestMixin(EventsTestMixin, WebAppTest): ...@@ -24,6 +24,16 @@ class AccountSettingsTestMixin(EventsTestMixin, WebAppTest):
USER_SETTINGS_CHANGED_EVENT_NAME = 'edx.user.settings.changed' USER_SETTINGS_CHANGED_EVENT_NAME = 'edx.user.settings.changed'
ACCOUNT_SETTINGS_REFERER = u"/account/settings" 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): def log_in_as_unique_user(self, email=None):
""" """
Create a unique user and return the account's username and id. Create a unique user and return the account's username and id.
...@@ -116,14 +126,6 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, WebAppTest): ...@@ -116,14 +126,6 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, WebAppTest):
self.username, self.user_id = self.log_in_as_unique_user() self.username, self.user_id = self.log_in_as_unique_user()
self.visit_account_settings_page() 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): def test_page_view_event(self):
""" """
Scenario: An event should be recorded when the "Account Settings" Scenario: An event should be recorded when the "Account Settings"
...@@ -444,3 +446,18 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, WebAppTest): ...@@ -444,3 +446,18 @@ class AccountSettingsPageTest(AccountSettingsTestMixin, WebAppTest):
for field_id, title, link_title in providers: 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.title_for_field(field_id), title)
self.assertEqual(self.account_settings_page.link_title_for_link_field(field_id), link_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): ...@@ -147,6 +147,26 @@ class LearnerProfileTestMixin(EventsTestMixin):
with self.assert_events_match_during(event_filter=event_filter, expected_events=[expected_event]): with self.assert_events_match_during(event_filter=event_filter, expected_events=[expected_event]):
yield 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') @attr('shard_4')
class OwnLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest): class OwnLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
...@@ -677,7 +697,7 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest): ...@@ -677,7 +697,7 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
Then I shouldn't see the profile visibility selector dropdown. Then I shouldn't see the profile visibility selector dropdown.
Then I see some of the profile fields are shown. 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() username, __ = self.log_in_as_unique_user()
profile_page = self.visit_profile_page(different_username) profile_page = self.visit_profile_page(different_username)
self.verify_profile_page_is_private(profile_page, is_editable=False) self.verify_profile_page_is_private(profile_page, is_editable=False)
...@@ -693,7 +713,7 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest): ...@@ -693,7 +713,7 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
Then I see that only the private fields are shown. Then I see that only the private fields are shown.
""" """
under_age_birth_year = datetime.now().year - 10 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, privacy=self.PRIVACY_PUBLIC,
birth_year=under_age_birth_year birth_year=under_age_birth_year
) )
...@@ -713,29 +733,52 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest): ...@@ -713,29 +733,52 @@ class DifferentUserLearnerProfilePageTest(LearnerProfileTestMixin, WebAppTest):
Then I shouldn't see the profile visibility selector dropdown. Then I shouldn't see the profile visibility selector dropdown.
Also `location`, `language` and `about me` fields are not editable. 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() username, __ = self.log_in_as_unique_user()
profile_page = self.visit_profile_page(different_username) profile_page = self.visit_profile_page(different_username)
profile_page.wait_for_public_fields() profile_page.wait_for_public_fields()
self.verify_profile_page_is_public(profile_page, is_editable=False) 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) 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 # TODO: There are several existing color contrast errors on this page,
if privacy is None: # we will ignore this error in the test until we fix them.
privacy = self.PRIVACY_PUBLIC profile_page.a11y_audit.config.set_rules({
self.visit_profile_page(username, privacy=privacy) "ignore": ['color-contrast'],
})
# Set the user's year of birth profile_page.a11y_audit.check_for_accessibility_errors()
if birth_year:
self.set_birth_year(birth_year)
# Log the user out profile_page.make_field_editable('language_proficiencies')
LogoutPage(self.browser).visit() 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 ...@@ -63,6 +63,10 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
expect(view.$('.u-field-title').text().trim()).toContain(expectedTitle); 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) { var expectMessageContains = function(view, expectedText) {
expect(view.$('.u-field-message').html()).toContain(expectedText); expect(view.$('.u-field-message').html()).toContain(expectedText);
}; };
...@@ -167,7 +171,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -167,7 +171,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
expectMessageContains(view, view.indicators.canEdit); expectMessageContains(view, view.indicators.canEdit);
view.$el.click(); view.$el.click();
} else { } else {
expectTitleAndMessageToContain(view, data.title, data.helpMessage, false); expectTitleAndMessageToContain(view, data.title, data.helpMessage);
} }
expect(view.el).toHaveClass('mode-edit'); expect(view.el).toHaveClass('mode-edit');
...@@ -254,6 +258,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -254,6 +258,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
createFieldData: createFieldData, createFieldData: createFieldData,
createErrorMessage: createErrorMessage, createErrorMessage: createErrorMessage,
expectTitleToContain: expectTitleToContain, expectTitleToContain: expectTitleToContain,
expectDropdownSrTitleToContain: expectDropdownSrTitleToContain,
expectTitleAndMessageToContain: expectTitleAndMessageToContain, expectTitleAndMessageToContain: expectTitleAndMessageToContain,
expectMessageContains: expectMessageContains, expectMessageContains: expectMessageContains,
expectAjaxRequestWithData: expectAjaxRequestWithData, expectAjaxRequestWithData: expectAjaxRequestWithData,
......
...@@ -10,7 +10,10 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -10,7 +10,10 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
describe("edx.FieldViews", function () { describe("edx.FieldViews", function () {
var requests, var requests,
timerCallback; timerCallback,
dropdownSelectClass = '.u-field-value > select',
dropdownButtonClass = '.u-field-value > button',
textareaLinkClass = '.u-field-value a';
var fieldViewClasses = [ var fieldViewClasses = [
FieldViews.ReadonlyFieldView, FieldViews.ReadonlyFieldView,
...@@ -89,11 +92,11 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -89,11 +92,11 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
}); });
var view = new FieldViews.ReadonlyFieldView(fieldData).render(); var view = new FieldViews.ReadonlyFieldView(fieldData).render();
FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage, false); FieldViewsSpecHelpers.expectTitleAndMessageToContain(view, fieldData.title, fieldData.helpMessage);
expect(view.$('.u-field-value input').val().trim()).toBe(USERNAME); expect(view.fieldValue()).toBe(USERNAME);
view.model.set({'username': 'bookworm'}); 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() { 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 ...@@ -133,13 +136,30 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
}); });
var view = new FieldViews.DropdownFieldView(fieldData).render(); 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'); 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]}); view.model.set({'name': fieldData.options[1][0]});
expect(view.el).toHaveClass('mode-display'); 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(); view.$el.click();
expect(view.el).toHaveClass('mode-display'); 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() { 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 ...@@ -210,12 +230,16 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
expect(view.modelValueIsSet()).toBe(false); expect(view.modelValueIsSet()).toBe(false);
expect(view.displayValue()).toBe(''); expect(view.displayValue()).toBe('');
if(editable === 'toggle') { view.showEditMode(true); } if (editable === 'toggle') {
view.$('.u-field-value > select').val(FieldViewsSpecHelpers.SELECT_OPTIONS[0]).change(); 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]); expect(view.fieldValue()).toBe(FieldViewsSpecHelpers.SELECT_OPTIONS[0][0]);
AjaxHelpers.respondWithNoContent(requests); 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. // When server returns success, there should no longer be an empty option.
expect($(view.$('.u-field-value option')[0]).val()).toBe('si'); expect($(view.$('.u-field-value option')[0]).val()).toBe('si');
}); });
...@@ -236,16 +260,18 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -236,16 +260,18 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
// set bio to empty to see the placeholder. // set bio to empty to see the placeholder.
fieldData.model.set({bio: ''}); fieldData.model.set({bio: ''});
var view = new FieldViews.TextareaFieldView(fieldData).render(); 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.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!'; var bio = 'Too much to tell!';
view.model.set({'bio': bio}); view.model.set({'bio': bio});
expect(view.el).toHaveClass('mode-display'); 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(); view.$el.click();
expect(view.el).toHaveClass('mode-display'); 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() { 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 ...@@ -270,23 +296,26 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
FieldViewsSpecHelpers.expectTitleToContain(view, fieldData.title); FieldViewsSpecHelpers.expectTitleToContain(view, fieldData.title);
FieldViewsSpecHelpers.expectMessageContains(view, view.indicators.canEdit); FieldViewsSpecHelpers.expectMessageContains(view, view.indicators.canEdit);
expect(view.el).toHaveClass('mode-placeholder'); 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(); view.$('.wrapper-u-field').click();
expect(view.el).toHaveClass('mode-edit'); expect(view.el).toHaveClass('mode-edit');
view.$(valueInputSelector).val(BIO).focusout(); view.$(valueInputSelector).val(BIO).focusout();
expect(view.fieldValue()).toBe(BIO); expect(view.fieldValue()).toBe(BIO);
expect(view.$(textareaLinkClass).length).toBe(0);
AjaxHelpers.expectJsonRequest( AjaxHelpers.expectJsonRequest(
requests, 'PATCH', view.model.url, {'bio': BIO} requests, 'PATCH', view.model.url, {'bio': BIO}
); );
AjaxHelpers.respondWithNoContent(requests); AjaxHelpers.respondWithNoContent(requests);
expect(view.el).toHaveClass('mode-display'); expect(view.el).toHaveClass('mode-display');
expect(view.$(textareaLinkClass).length).toBe(1);
view.$('.wrapper-u-field').click(); view.$('.wrapper-u-field').click();
view.$(valueInputSelector).val('').focusout(); view.$(valueInputSelector).val('').focusout();
AjaxHelpers.respondWithNoContent(requests); AjaxHelpers.respondWithNoContent(requests);
expect(view.el).toHaveClass('mode-placeholder'); 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() { it("correctly renders LinkFieldView", function() {
...@@ -298,7 +327,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers ...@@ -298,7 +327,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
}); });
var view = new FieldViews.LinkFieldView(fieldData).render(); 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); 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 ...@@ -311,7 +340,7 @@ define(['backbone', 'jquery', 'underscore', 'common/js/spec_helpers/ajax_helpers
}); });
var view = new FieldViews.LinkFieldView(fieldData).render(); 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); expect(view.$('.u-field-value > a .u-field-link-title-' + view.options.valueAttribute).text().trim()).toBe(fieldData.linkTitle);
}); });
......
...@@ -225,7 +225,7 @@ ...@@ -225,7 +225,7 @@
}, },
finishEditing: function() { finishEditing: function() {
if (this.persistChanges === false) {return;} if (this.persistChanges === false || this.mode !== 'edit') {return;}
if (this.fieldValue() !== this.modelValue()) { if (this.fieldValue() !== this.modelValue()) {
this.saveValue(); this.saveValue();
} else { } else {
...@@ -271,11 +271,11 @@ ...@@ -271,11 +271,11 @@
}, },
fieldValue: function () { fieldValue: function () {
return this.$('.u-field-value input').val(); return this.$('.u-field-value').text();
}, },
updateValueInField: function () { updateValueInField: function () {
this.$('.u-field-value input').val(_.escape(this.modelValue())); this.$('.u-field-value ').html(_.escape(this.modelValue()));
} }
}); });
...@@ -345,9 +345,10 @@ ...@@ -345,9 +345,10 @@
this.$el.html(this.template({ this.$el.html(this.template({
id: this.options.valueAttribute, id: this.options.valueAttribute,
mode: this.mode, mode: this.mode,
editable: this.editable,
title: this.options.title, title: this.options.title,
screenReaderTitle: this.options.screenReaderTitle || 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, iconName: this.options.iconName,
showBlankOption: (!this.options.required || !this.modelValueIsSet()), showBlankOption: (!this.options.required || !this.modelValueIsSet()),
selectOptions: this.options.options, selectOptions: this.options.options,
...@@ -376,7 +377,13 @@ ...@@ -376,7 +377,13 @@
}, },
fieldValue: function () { 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; return value === '' ? null : value;
}, },
...@@ -390,7 +397,9 @@ ...@@ -390,7 +397,9 @@
}, },
updateValueInField: function () { 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() || ''); var value = this.displayValue(this.modelValue() || '');
if (this.modelValueIsSet() === false) { if (this.modelValueIsSet() === false) {
...@@ -437,7 +446,9 @@ ...@@ -437,7 +446,9 @@
}, },
disableField: function(disable) { 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 @@ ...@@ -473,6 +484,7 @@
id: this.options.valueAttribute, id: this.options.valueAttribute,
screenReaderTitle: this.options.screenReaderTitle || this.options.title, screenReaderTitle: this.options.screenReaderTitle || this.options.title,
mode: this.mode, mode: this.mode,
editable: this.editable,
value: value, value: value,
message: this.helpMessage, message: this.helpMessage,
messagePosition: this.options.messagePosition || 'footer', messagePosition: this.options.messagePosition || 'footer',
...@@ -504,11 +516,16 @@ ...@@ -504,11 +516,16 @@
modelValue: function() { modelValue: function() {
var value = this._super(); var value = this._super();
return value ? $.trim(value) : ''; return value ? $.trim(value) : '';
}, },
fieldValue: function () { 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 () { saveValue: function () {
......
<% if (title) { %> <% if (editable !== 'never') { %>
<label class="u-field-title" for="u-field-select-<%- id %>"> <% if (title && titleVisible) { %>
<%- title %> <label class="u-field-title" for="u-field-select-<%- id %>">
</label> <%- title %>
<% } %> </label>
<% } else { %>
<% if (!titleVisible) { %> <label class="sr" for="u-field-select-<%- id %>">
<label class="sr" for="u-field-select-<%- id %>"> <%- screenReaderTitle %>
<%- screenReaderTitle %> </label>
</label> <% } %>
<% } %> <% } %>
<% if (iconName) { %> <% if (iconName) { %>
...@@ -15,19 +15,24 @@ ...@@ -15,19 +15,24 @@
<% } %> <% } %>
<span class="u-field-value"> <span class="u-field-value">
<select name="select" id="u-field-select-<%- id %>" aria-describedby="u-field-message-<%- id %>"> <% if (editable === 'never') { %>
<% 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="sr"><%- screenReaderTitle %> &nbsp;</span>
<span class="u-field-value-readonly"></span> <span class="u-field-value-readonly"></span>
<span class="sr">&nbsp; <%- gettext('Click to edit') %></span> <% } else { %>
</button> <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>
<span class="u-field-message" id="u-field-message-<%- id %>"> <span class="u-field-message" id="u-field-message-<%- id %>">
......
<label class="u-field-title" aria-hidden="true"> <% if (title) { %>
<%- title %> <span class="u-field-title" aria-hidden="true"><%- title %></span>
</label> <% } %>
<span class="sr" for="u-field-input-<%- id %>"><%- screenReaderTitle %></span> <span class="sr" for="u-field-value-<%- id %>"><%- screenReaderTitle %></span>
<span class="u-field-value"> <span class="u-field-value" id="u-field-value-<%- id %>" aria-describedby="u-field-message-<%- id %>"><%- value %></span>
<input id="u-field-input-<%- id %>" aria-describedby="u-field-message-<%- id %>" type="text" name="input" readonly=true value="<%- value %>">
</span>
<span class="u-field-message" id="u-field-message-<%- id %>"> <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-notification" aria-live="polite"></span>
<span class="u-field-message-help" id="u-field-help-message-<%- id %>"> <%- message %></span> <span class="u-field-message-help" id="u-field-help-message-<%- id %>"> <%- message %></span>
......
<div class="wrapper-u-field"> <div class="wrapper-u-field">
<div class="u-field-header"> <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') { %> <% if (messagePosition === 'header') { %>
<span class="u-field-message" id="u-field-message-<%- id %>"> <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-notification" aria-live="polite"></span>
...@@ -9,14 +13,23 @@ ...@@ -9,14 +13,23 @@
<% }%> <% }%>
</div> </div>
<div class="u-field-value" id="u-field-value-<%- id %>" aria-labelledby="u-field-title-<%- id %>"><% <div class="u-field-value" id="u-field-value-<%- id %>"
var textareaDescribedBy = (message ? 'u-field-message-help-' : 'u-field-placeholder-value-') + id; <% if (mode === 'edit') { %>
if (mode === 'edit') {%> aria-labelledby="u-field-title-<%- id %>"><textarea id="u-field-textarea-<%- id %>" rows="4"
<textarea id="u-field-textarea-<%- id %>" rows="4" aria-describedby="<%- textareaDescribedBy %>"><%- value %></textarea> <% if (message) { %>
<% } else { aria-describedby="u-field-message-help-<%- id %>"
%><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><% <% } %>
} ><%- value %></textarea>
%><span class="sr" id="u-field-placeholder-value-<%- id %>"><%- placeholderValue %></span> <% } 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>
<div class="u-field-footer"> <div class="u-field-footer">
......
...@@ -12,7 +12,7 @@ from microsite_configuration import microsite ...@@ -12,7 +12,7 @@ from microsite_configuration import microsite
<%namespace name='static' file='/static_content.html'/> <%namespace name='static' file='/static_content.html'/>
<%block name="pagetitle">${_("Account Settings")}</%block> <%block name="pagetitle">${_("Account Settings")}</%block>
<%block name="nav_skip">#u-field-input-username</%block> <%block name="nav_skip">#content</%block>
% if duplicate_provider: % if duplicate_provider:
<section> <section>
......
...@@ -8,7 +8,7 @@ from openedx.core.lib.json_utils import EscapedEdxJSONEncoder ...@@ -8,7 +8,7 @@ from openedx.core.lib.json_utils import EscapedEdxJSONEncoder
%> %>
<%block name="pagetitle">${_("Learner Profile")}</%block> <%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> <%block name="bodyclass">view-profile</%block>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment