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'