diff --git a/lib/assets/javascripts/best_in_place.js b/lib/assets/javascripts/best_in_place.js index 764ddd67..79a42783 100644 --- a/lib/assets/javascripts/best_in_place.js +++ b/lib/assets/javascripts/best_in_place.js @@ -55,6 +55,12 @@ BestInPlaceEditor.prototype = { $(this.activator).bind('click', {editor: this}, this.clickHandler); }, + abortIfConfirm : function () { + if (confirm("Are you sure you want to discard your changes?")) { + this.abort(); + } + }, + update : function() { var editor = this; if (this.formType in {"input":1, "textarea":1} && this.getValue() == this.oldValue) @@ -386,34 +392,54 @@ BestInPlaceEditor.forms = { this.element.find("form").bind('submit', {editor: this}, BestInPlaceEditor.forms.textarea.submitHandler); if (this.cancelButton) { this.element.find("input[type='button']").bind('click', {editor: this}, BestInPlaceEditor.forms.textarea.cancelButtonHandler) - } else { - this.element.find("textarea").bind('blur', {editor: this}, BestInPlaceEditor.forms.textarea.blurHandler); } + this.element.find("textarea").bind('blur', {editor: this}, BestInPlaceEditor.forms.textarea.blurHandler); this.element.find("textarea").bind('keyup', {editor: this}, BestInPlaceEditor.forms.textarea.keyupHandler); + this.blurTimer = null; + this.userClicked = false; }, getValue : function() { return this.sanitizeValue(this.element.find("textarea").val()); }, + // When buttons are present, use a timer on the blur event to give precedence to clicks blurHandler : function(event) { - event.data.editor.update(); + if (event.data.editor.okButton) { + event.data.editor.blurTimer = setTimeout(function () { + if (!event.data.editor.userClicked) { + event.data.editor.abortIfConfirm(); + } + }, 500); + } else { + if (event.data.editor.cancelButton) { + event.data.editor.blurTimer = setTimeout(function () { + if (!event.data.editor.userClicked) { + event.data.editor.update(); + } + }, 500); + } else { + event.data.editor.update(); + } + } }, submitHandler : function(event) { + event.data.editor.userClicked = true; + clearTimeout(event.data.editor.blurTimer); event.data.editor.update(); }, cancelButtonHandler : function(event) { - event.data.editor.abort(); - event.stopPropagation(); + event.data.editor.userClicked = true; + clearTimeout(event.data.editor.blurTimer); + event.data.editor.abortIfConfirm(); + event.stopPropagation(); // Without this, click isn't handled }, keyupHandler : function(event) { if (event.keyCode == 27) { - if (confirm("Are you sure you want to discard your changes?")) { - event.data.editor.abort(); - } + event.data.editor.abortIfConfirm(); } } } diff --git a/spec/integration/js_spec.rb b/spec/integration/js_spec.rb index 72e192a9..6eb4e344 100644 --- a/spec/integration/js_spec.rb +++ b/spec/integration/js_spec.rb @@ -210,10 +210,6 @@ end end - it "should do the above 3 for text areas" do - pending - end - it "should correctly use an OK submit button when so configured for a text area" do @user.save! visit user_path(@user) @@ -249,13 +245,60 @@ $("##{id} textarea").val('1Q84'); $("##{id} input[type='button']").click(); JS + page.driver.browser.switch_to.alert.accept + + visit user_path(@user) + within("#favorite_books") do + page.should have_content('The City of Gold and Lead') + end + end + + it "should not submit text area on blur if there's an OK button present" do + @user.save! + visit user_path(@user) + + within("#favorite_books") do + page.should have_content('The City of Gold and Lead') + end + id = BestInPlace::Utils.build_best_in_place_id @user, :favorite_books + page.execute_script <<-JS + $("##{id}").click(); + $("##{id} textarea").val('1Q84'); + $("##{id} textarea").blur(); + JS + sleep 1 # Increase if browser is slow + page.driver.browser.switch_to.alert.accept + visit user_path(@user) within("#favorite_books") do page.should have_content('The City of Gold and Lead') end end + it "should still submit text area on blur if there's only a Cancel button present" do + @user.save! + visit user_path(@user, :suppress_ok_button => 1) + + within("#favorite_books") do + page.should have_content('The City of Gold and Lead') + end + + id = BestInPlace::Utils.build_best_in_place_id @user, :favorite_books + page.execute_script %{$("##{id}").click();} + page.should have_no_css("##{id} input[type='submit']") + page.execute_script <<-JS + $("##{id} textarea").val('1Q84'); + $("##{id} textarea").blur(); + JS + sleep 1 # Increase if browser is slow + + visit user_path(@user) + within("#favorite_books") do + page.should have_content('1Q84') + end + end + it "should show validation errors" do @user.save! visit user_path(@user)