diff --git a/app/controllers/cost_reports_controller.rb b/app/controllers/cost_reports_controller.rb index d0973af10e..91f58aa69e 100644 --- a/app/controllers/cost_reports_controller.rb +++ b/app/controllers/cost_reports_controller.rb @@ -27,6 +27,16 @@ class CostReportsController < ApplicationController redirect_to :action => :index end + def available_values + filter = filter_class(params[:filter_name].to_s) + render_404 unless filter + @available_values = filter.available_values + + respond_to do |format| + format.html { render :layout => !request.xhr? } + end + end + ## # Determines if the request contains filters to set def set_filter? #FIXME: rename to set_query? diff --git a/app/helpers/reporting_helper.rb b/app/helpers/reporting_helper.rb index 46368d2714..1f2ffc1958 100644 --- a/app/helpers/reporting_helper.rb +++ b/app/helpers/reporting_helper.rb @@ -144,4 +144,14 @@ module ReportingHelper def show_row(row) link_to_details(row) << row.render { |k,v| show_field(k,v) } end + + ## + # Finds the Filter-Class for as specific filter name while being careful with the filter_name parameter as it is user input. + def filter_class(filter_name) + klass = CostQuery::Filter.const_get(filter_name.to_s.camelize) + return klass if klass.is_a? Class + nil + rescue NameError + return nil + end end \ No newline at end of file diff --git a/app/views/cost_reports/available_values.rhtml b/app/views/cost_reports/available_values.rhtml new file mode 100644 index 0000000000..4723e04c5d --- /dev/null +++ b/app/views/cost_reports/available_values.rhtml @@ -0,0 +1,5 @@ +<% @available_values.each do |name, id, *args| %> + <%= render :partial => 'cost_reports/filters/available_value', + :locals => { :name => name, :id => id, :level => args.first }, + :layout => !request.xhr? %> +<% end %> diff --git a/app/views/cost_reports/filters/_available_value.rhtml b/app/views/cost_reports/filters/_available_value.rhtml new file mode 100644 index 0000000000..5dafad42e5 --- /dev/null +++ b/app/views/cost_reports/filters/_available_value.rhtml @@ -0,0 +1,11 @@ +<%# + This partial requires the following locals: + name String: The displayed name of the option + id Integer: The id the option refers to + level Integer: The indendation level of this option +%> + +<% name_prefix = ((level && level > 0) ? (' ' * 2 * level + '» ') : '') %> + \ No newline at end of file diff --git a/app/views/cost_reports/filters/_multi_values.rhtml b/app/views/cost_reports/filters/_multi_values.rhtml index 15b7fb9e9c..5b43b2f184 100644 --- a/app/views/cost_reports/filters/_multi_values.rhtml +++ b/app/views/cost_reports/filters/_multi_values.rhtml @@ -14,13 +14,7 @@ id="<%= element[:filter_name] %>_arg_1_val" class="select-small" multiple="multiple"> <%# multiple will be disabled/enabled later by JavaScript anyhow. We need to specify multiple here because of a IE6-bug. %> - <% element[:values].each do |name, id, *args| %> - <% level = args.first #nesting_level is optional for values %> - <% name_prefix = ((level && level > 0) ? (' ' * 2 * level + '» ') : '') %> - - <% end %> + <%# content will be inserted on filter activation %> <%= link_to_function image_tag('bullet_toggle_plus.png'), "toggle_multi_select($('#{element[:filter_name]}_arg_1_val'));", :style => "vertical-align: bottom;" %> diff --git a/assets/javascripts/reporting.js b/assets/javascripts/reporting.js index 4c6923e89e..aab442d1e7 100644 --- a/assets/javascripts/reporting.js +++ b/assets/javascripts/reporting.js @@ -89,6 +89,7 @@ function show_filter(field) { var field_el = $('tr_' + field); register_remove_hover(field); if (field_el !== null) { + load_available_values_for_filter(field); field_el.show(); toggle_filter(field); $('rm_' + field).value = field; @@ -270,6 +271,54 @@ function disable_all_group_bys() { }); } +function serialize_filter_and_group_by() { + var ret_str = Form.serialize('query_form'); + var rows = Sortable.serialize('group_rows'); + var columns = Sortable.serialize('group_columns'); + if (rows !== null && rows != "") { + ret_str += "&" + rows; + } + if(columns !== null && columns != "") { + ret_str += "&" + columns; + } + return ret_str; +} + +function init_group_bys() { + var options = { + tag:'span', + overlap:'horizontal', + constraint:'horizontal', + containment: ['group_columns','group_rows'], + //only: "group_by", + dropOnEmpty: true, + format: /^(.*)$/, + hoverclass: 'drag_container_accept' + }; + Sortable.create('group_columns', options); + Sortable.create('group_rows', options); +} + +function load_available_values_for_filter(filter_name) { + var select; + select = $('' + filter_name + '_arg_1_val'); + if (select.childElements().length == 0) { + new Ajax.Updater({ success: select }, '/cost_reports/available_values', { + parameters: { filter_name: filter_name }, + insertion: 'bottom', + evalScripts: false, + onCreate: function (a,b) { + $('operators_' + filter_name).disable(); + $('' + filter_name + '_arg_1_val').disable(); + }, + onComplete: function (a,b) { + $('operators_' + filter_name).enable(); + $('' + filter_name + '_arg_1_val').enable(); + } + }); + } +} + function defineElementGetter() { if (document.getElementsByClassName == undefined) { document.getElementsByClassName = function(className)