diff --git a/app/views/timelog/_form.html.erb b/app/views/timelog/_form.html.erb index 3a0543e7c3..87cf926f18 100644 --- a/app/views/timelog/_form.html.erb +++ b/app/views/timelog/_form.html.erb @@ -1,7 +1,7 @@ <%= error_messages_for 'time_entry' %> <%= back_url_hidden_field_tag %> -
+<%= labelled_fields_for :time_entry, @time_entry do |f| %> <% if @time_entry.new_record? && params[:project_id] %> <%= hidden_field_tag 'project_id', params[:project_id] %> <% elsif @time_entry.new_record? && params[:issue_id] %> @@ -36,7 +36,7 @@ <% end %> <% end %> <%= call_hook(:view_timelog_edit_form_bottom, { :time_entry => @time_entry, :form => f }) %> -
+<% end %> <%= javascript_tag do %> $(document).ready(function(){ @@ -44,11 +44,7 @@ $('#time_entry_issue_id').val(''); }); $('#time_entry_project_id, #time_entry_issue_id').change(function(){ - $.ajax({ - url: '<%= escape_javascript(@time_entry.new_record? ? new_time_entry_path(:format => 'js') : edit_time_entry_path(:format => 'js')) %>', - type: 'post', - data: $(this).closest('form').serialize() - }); + updateTimeEntryForm('<%= escape_javascript(@time_entry.new_record? ? new_time_entry_path(:format => 'js') : edit_time_entry_path(:format => 'js')) %>'); }); }); diff --git a/app/views/timelog/edit.html.erb b/app/views/timelog/edit.html.erb index 3cc96dfd02..5479426a4e 100644 --- a/app/views/timelog/edit.html.erb +++ b/app/views/timelog/edit.html.erb @@ -1,7 +1,9 @@

<%= l(:label_spent_time) %>

-<%= labelled_form_for @time_entry, :url => time_entry_path(@time_entry), :html => {:multipart => true} do |f| %> +<%= labelled_form_for @time_entry, :url => time_entry_path(@time_entry), :html => {:id =>'time-entry-form', :multipart => true} do |f| %> +
<%= render :partial => 'form', :locals => {:f => f} %> +
<%= submit_tag l(:button_save) %> <%= cancel_button_tag_for_time_entry(@project) %> <% end %> diff --git a/app/views/timelog/edit.js.erb b/app/views/timelog/edit.js.erb index 4cba8cfe6c..fd7a13ed6f 100644 --- a/app/views/timelog/edit.js.erb +++ b/app/views/timelog/edit.js.erb @@ -1,2 +1 @@ -$('#time_entry_activity_id').html('<%= escape_javascript options_for_select(activity_collection_for_select_options(@time_entry), @time_entry.activity_id) %>'); -$('#time_entry_issue').html('<%= escape_javascript link_to_issue(@time_entry.issue) if @time_entry.issue.try(:visible?) %>'); +replaceTimeEntryFormWith('<%= escape_javascript(render :partial => 'form') %>'); diff --git a/app/views/timelog/new.html.erb b/app/views/timelog/new.html.erb index 9ec89d52ae..6941b2979a 100644 --- a/app/views/timelog/new.html.erb +++ b/app/views/timelog/new.html.erb @@ -1,7 +1,9 @@

<%= l(:label_spent_time) %>

-<%= labelled_form_for @time_entry, :url => time_entries_path, :html => {:multipart => true} do |f| %> +<%= labelled_form_for @time_entry, :url => time_entries_path, :html => {:id =>'time-entry-form', :multipart => true} do |f| %> +
<%= render :partial => 'form', :locals => {:f => f} %> +
<%= submit_tag l(:button_create) %> <%= submit_tag l(:button_create_and_continue), :name => 'continue' %> <%= cancel_button_tag_for_time_entry(@project) %> diff --git a/app/views/timelog/new.js.erb b/app/views/timelog/new.js.erb index 4cba8cfe6c..fd7a13ed6f 100644 --- a/app/views/timelog/new.js.erb +++ b/app/views/timelog/new.js.erb @@ -1,2 +1 @@ -$('#time_entry_activity_id').html('<%= escape_javascript options_for_select(activity_collection_for_select_options(@time_entry), @time_entry.activity_id) %>'); -$('#time_entry_issue').html('<%= escape_javascript link_to_issue(@time_entry.issue) if @time_entry.issue.try(:visible?) %>'); +replaceTimeEntryFormWith('<%= escape_javascript(render :partial => 'form') %>'); diff --git a/public/javascripts/application.js b/public/javascripts/application.js index 5552952cd5..3e47024579 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -634,6 +634,29 @@ function updateBulkEditFrom(url) { }); } +function updateTimeEntryForm(url) { + $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){ + $(this).data('valuebeforeupdate', $(this).val()); + }); + return $.ajax({ + url: url, + type: 'post', + data: $('#time-entry-form').serialize() + }); +} + +function replaceTimeEntryFormWith(html){ + var replacement = $(html); + $('#all_attributes input, #all_attributes textarea, #all_attributes select').each(function(){ + var object_id = $(this).attr('id'); + if (object_id && $(this).data('valuebeforeupdate')!=$(this).val()) { + replacement.find('#'+object_id).val($(this).val()); + } + }); + $('#all_attributes').empty(); + $('#all_attributes').prepend(replacement); +} + function observeAutocompleteField(fieldId, url, options) { $(document).ready(function() { $('#'+fieldId).autocomplete($.extend({ diff --git a/test/application_system_test_case.rb b/test/application_system_test_case.rb index a8b6f55d59..d813f0ce3e 100644 --- a/test/application_system_test_case.rb +++ b/test/application_system_test_case.rb @@ -81,6 +81,12 @@ class ApplicationSystemTestCase < ActionDispatch::SystemTestCase assert_equal '/my/page', current_path end + def wait_for_ajax + Timeout.timeout(Capybara.default_max_wait_time) do + loop until page.evaluate_script("jQuery.active").zero? + end + end + def clear_downloaded_files FileUtils.rm downloaded_files end diff --git a/test/functional/timelog_controller_test.rb b/test/functional/timelog_controller_test.rb index 51fc9c3103..464d73921e 100644 --- a/test/functional/timelog_controller_test.rb +++ b/test/functional/timelog_controller_test.rb @@ -143,7 +143,7 @@ class TimelogControllerTest < Redmine::ControllerTest @request.session[:user_id] = 3 post :new, :params => {:time_entry => {:project_id => 1}, :format => 'js'} assert_response :success - assert_include '#time_entry_activity_id', response.body + assert_include 'id=\"time_entry_activity_id\"', response.body end def test_get_edit_existing_time diff --git a/test/system/timelog_test.rb b/test/system/timelog_test.rb index 1761d10dc2..fdbac385cd 100644 --- a/test/system/timelog_test.rb +++ b/test/system/timelog_test.rb @@ -38,15 +38,44 @@ class TimelogTest < ApplicationSystemTestCase assert has_content?('Design') end - within 'form#new_time_entry' do + within 'form#time-entry-form' do select 'eCookbook', :from => 'Project' end + wait_for_ajax within 'select#time_entry_activity_id' do assert has_content?('Development') assert !has_content?('Design') end end + def test_changing_project_should_switch_show_or_hide_custom_fields_depending_on_roles + project1 = Project.find(1) # eCookbook + project2 = Project.find(2) # OnlineStore + project2.enable_module!(:time_tracking) + user = User.find(2) # jsmith + assert_equal [1], user.roles_for_project(project1).collect(&:id).sort + assert_equal [2], user.roles_for_project(project2).collect(&:id).sort + custom_field = TimeEntryCustomField.find(10) # Overtime + custom_field.visible = 0 + custom_field.role_ids = [1] + custom_field.save! + + log_user 'jsmith', 'jsmith' + visit '/time_entries/new' + + within 'form#time-entry-form' do + assert has_no_content?('Overtime') + + select 'eCookbook', from: 'Project' + wait_for_ajax + assert has_content?('Overtime') + + select 'OnlineStore', from: 'Project' + wait_for_ajax + assert has_no_content?('Overtime') + end + end + def test_bulk_edit log_user 'jsmith', 'jsmith' visit '/time_entries/bulk_edit?ids[]=1&ids[]=2&ids[]=3'