diff --git a/cms/djangoapps/contentstore/features/common.py b/cms/djangoapps/contentstore/features/common.py index 7afa359e39..da1e5bf3eb 100644 --- a/cms/djangoapps/contentstore/features/common.py +++ b/cms/djangoapps/contentstore/features/common.py @@ -203,16 +203,21 @@ def add_subsection(name='Subsection One'): world.css_click(save_css) -def set_date_and_time(date_css, desired_date, time_css, desired_time): - world.css_fill(date_css, desired_date) - # hit TAB to get to the time field - e = world.css_find(date_css).first - # pylint: disable=W0212 - e._element.send_keys(Keys.TAB) - world.css_fill(time_css, desired_time) - e = world.css_find(time_css).first - e._element.send_keys(Keys.TAB) - time.sleep(float(1)) +def set_date_and_time(date_css, desired_date, time_css, desired_time, key=None): + set_element_value(date_css, desired_date, key) + set_element_value(time_css, desired_time, key) + + world.wait_for_ajax_complete() + + +def set_element_value(element_css, element_value, key=None): + element = world.css_find(element_css).first + element.fill(element_value) + # hit TAB or provided key to trigger save content + if key is not None: + element._element.send_keys(getattr(Keys, key)) # pylint: disable=protected-access + else: + element._element.send_keys(Keys.TAB) # pylint: disable=protected-access @step('I have enabled the (.*) advanced module$') diff --git a/cms/djangoapps/contentstore/features/subsection.feature b/cms/djangoapps/contentstore/features/subsection.feature index 2cb708ad3c..7f0d7b85e4 100644 --- a/cms/djangoapps/contentstore/features/subsection.feature +++ b/cms/djangoapps/contentstore/features/subsection.feature @@ -38,6 +38,14 @@ Feature: CMS.Create Subsection Then I see the subsection release date is 12/25/2011 03:00 And I see the subsection due date is 01/02/2012 04:00 + Scenario: Set release and due dates of subsection on enter + Given I have opened a new subsection in Studio + And I set the subsection release date on enter to 04/04/2014 03:00 + And I set the subsection due date on enter to 04/04/2014 04:00 + And I reload the page + Then I see the subsection release date is 04/04/2014 03:00 + And I see the subsection due date is 04/04/2014 04:00 + Scenario: Delete a subsection Given I have opened a new course section in Studio And I have added a new subsection diff --git a/cms/djangoapps/contentstore/features/subsection.py b/cms/djangoapps/contentstore/features/subsection.py index 463adddd53..49a7c88383 100644 --- a/cms/djangoapps/contentstore/features/subsection.py +++ b/cms/djangoapps/contentstore/features/subsection.py @@ -55,26 +55,28 @@ def i_see_complete_subsection_name_with_quote_in_editor(step): @step('I set the subsection release date to ([0-9/-]+)( [0-9:]+)?') def set_subsection_release_date(_step, datestring, timestring): - if hasattr(timestring, "strip"): - timestring = timestring.strip() - if not timestring: - timestring = "00:00" - set_date_and_time( - 'input#start_date', datestring, - 'input#start_time', timestring) + set_subsection_date('input#start_date', datestring, 'input#start_time', timestring) + + +@step('I set the subsection release date on enter to ([0-9/-]+)( [0-9:]+)?') +def set_subsection_release_date_on_enter(_step, datestring, timestring): # pylint: disable-msg=invalid-name + set_subsection_date('input#start_date', datestring, 'input#start_time', timestring, 'ENTER') @step('I set the subsection due date to ([0-9/-]+)( [0-9:]+)?') def set_subsection_due_date(_step, datestring, timestring): - if hasattr(timestring, "strip"): - timestring = timestring.strip() - if not timestring: - timestring = "00:00" if not world.css_visible('input#due_date'): world.css_click('.due-date-input .set-date') - set_date_and_time( - 'input#due_date', datestring, - 'input#due_time', timestring) + + set_subsection_date('input#due_date', datestring, 'input#due_time', timestring) + + +@step('I set the subsection due date on enter to ([0-9/-]+)( [0-9:]+)?') +def set_subsection_due_date_on_enter(_step, datestring, timestring): # pylint: disable-msg=invalid-name + if not world.css_visible('input#due_date'): + world.css_click('.due-date-input .set-date') + + set_subsection_date('input#due_date', datestring, 'input#due_time', timestring, 'ENTER') @step('I mark it as Homework$') @@ -147,3 +149,12 @@ def see_subsection_name(name): assert world.is_css_present(css) css = 'span.subsection-name-value' assert world.css_has_text(css, name) + + +def set_subsection_date(date_css, datestring, time_css, timestring, key=None): + if hasattr(timestring, "strip"): + timestring = timestring.strip() + if not timestring: + timestring = "00:00" + + set_date_and_time(date_css, datestring, time_css, timestring, key) diff --git a/cms/static/js/base.js b/cms/static/js/base.js index bc33afc44f..cfb221066d 100644 --- a/cms/static/js/base.js +++ b/cms/static/js/base.js @@ -1,6 +1,8 @@ require(["domReady", "jquery", "underscore", "gettext", "js/views/feedback_notification", "js/views/feedback_prompt", - "js/utils/get_date", "js/utils/module", "js/utils/handle_iframe_binding", "jquery.ui", "jquery.leanModal", "jquery.form", "jquery.smoothScroll"], - function(domReady, $, _, gettext, NotificationView, PromptView, DateUtils, ModuleUtils, IframeUtils) { + "js/utils/get_date", "js/utils/module", "js/utils/handle_iframe_binding", "js/utils/change_on_enter", "jquery.ui", + "jquery.leanModal", "jquery.form", "jquery.smoothScroll"], + function(domReady, $, _, gettext, NotificationView, PromptView, DateUtils, ModuleUtils, IframeUtils, TriggerChangeEventOnEnter) +{ var $body; var $newComponentItem; @@ -89,7 +91,7 @@ domReady(function() { $('.subsection-display-name-input').each(function() { this.val = $(this).val(); }); - $("#start_date, #start_time, #due_date, #due_time").bind('change', autosaveInput); + $("#start_date, #start_time, #due_date, #due_time").change(autosaveInput).keyup(TriggerChangeEventOnEnter) $('.sync-date, .remove-date').bind('click', autosaveInput); // expand/collapse methods for optional date setters diff --git a/cms/static/js/utils/change_on_enter.js b/cms/static/js/utils/change_on_enter.js new file mode 100644 index 0000000000..08c5d396b9 --- /dev/null +++ b/cms/static/js/utils/change_on_enter.js @@ -0,0 +1,11 @@ +define(["jquery"], function($) { + // Trigger "Change" event on "Enter" keyup event + var triggerChangeEventOnEnter = function (e) { + if(e.which == 13) + { + $(this).trigger("change").blur(); + } + }; + + return triggerChangeEventOnEnter; +}); diff --git a/cms/static/js/views/settings/main.js b/cms/static/js/views/settings/main.js index 583f42c0c8..4e21109be4 100644 --- a/cms/static/js/views/settings/main.js +++ b/cms/static/js/views/settings/main.js @@ -1,5 +1,6 @@ -define(["js/views/validation", "codemirror", "underscore", "jquery", "jquery.ui", "tzAbbr", "js/models/uploads", "js/views/uploads", "jquery.timepicker", "date"], - function(ValidatingView, CodeMirror, _, $, ui, tzAbbr, FileUploadModel, FileUploadDialog) { +define(["js/views/validation", "codemirror", "underscore", "jquery", "jquery.ui", "tzAbbr", "js/models/uploads", + "js/views/uploads", "js/utils/change_on_enter", "jquery.timepicker", "date"], + function(ValidatingView, CodeMirror, _, $, ui, tzAbbr, FileUploadModel, FileUploadDialog, TriggerChangeEventOnEnter) { var DetailsView = ValidatingView.extend({ // Model class is CMS.Models.Settings.CourseDetails @@ -121,7 +122,7 @@ var DetailsView = ValidatingView.extend({ // Using the change event causes setfield to be triggered twice, but it is necessary // to pick up when the date is typed directly in the field. - datefield.change(setfield); + datefield.change(setfield).keyup(TriggerChangeEventOnEnter); timefield.on('changeTime', setfield); timefield.on('input', setfield);