From 514cdacc87e68526488aaf376ec58c3edfb60492 Mon Sep 17 00:00:00 2001
From: Jean-Philippe Lang
Date: Mon, 1 Oct 2007 11:39:34 +0000
Subject: [PATCH] Custom query columns: checkboxes replaced by two selects that
let the user specify columns order.
git-svn-id: http://redmine.rubyforge.org/svn/trunk@784 e93f8b46-1217-0410-a6f0-8f06a7374b81
---
app/controllers/issues_controller.rb | 2 +-
app/controllers/projects_controller.rb | 2 +-
app/models/query.rb | 3 +-
app/views/queries/_columns.rhtml | 26 ++++++++++--
app/views/queries/_form.rhtml | 4 +-
app/views/queries/edit.rhtml | 2 +-
app/views/queries/new.rhtml | 2 +-
public/javascripts/select_list_move.js | 55 ++++++++++++++++++++++++++
8 files changed, 86 insertions(+), 10 deletions(-)
create mode 100644 public/javascripts/select_list_move.js
diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb
index eadd2ad71..716816e34 100644
--- a/app/controllers/issues_controller.rb
+++ b/app/controllers/issues_controller.rb
@@ -46,7 +46,7 @@ class IssuesController < ApplicationController
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, 25, params['page']
@issues = Issue.find :all, :order => sort_clause,
- :include => [ :assigned_to, :status, :tracker, :project, :priority ],
+ :include => [ :assigned_to, :status, :tracker, :project, :priority, :category ],
:conditions => @query.statement,
:limit => @issue_pages.items_per_page,
:offset => @issue_pages.current.offset
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 284ac5655..3053bea7c 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -250,7 +250,7 @@ class ProjectsController < ApplicationController
@issue_count = Issue.count(:include => [:status, :project], :conditions => @query.statement)
@issue_pages = Paginator.new self, @issue_count, @results_per_page, params['page']
@issues = Issue.find :all, :order => sort_clause,
- :include => [ :assigned_to, :status, :tracker, :project, :priority ],
+ :include => [ :assigned_to, :status, :tracker, :project, :priority, :category ],
:conditions => @query.statement,
:limit => @issue_pages.items_per_page,
:offset => @issue_pages.current.offset
diff --git a/app/models/query.rb b/app/models/query.rb
index 400572eb2..30441d260 100644
--- a/app/models/query.rb
+++ b/app/models/query.rb
@@ -211,7 +211,8 @@ class Query < ActiveRecord::Base
if has_default_columns?
available_columns.select {|c| c.default? }
else
- available_columns.select {|c| column_names.include?(c.name) }
+ # preserve the column_names order
+ column_names.collect {|name| available_columns.find {|col| col.name == name}}.compact
end
end
diff --git a/app/views/queries/_columns.rhtml b/app/views/queries/_columns.rhtml
index f233f8ef6..b03a3277d 100644
--- a/app/views/queries/_columns.rhtml
+++ b/app/views/queries/_columns.rhtml
@@ -1,7 +1,27 @@
<% content_tag 'fieldset', :id => 'columns', :style => (query.has_default_columns? ? 'display:none;' : nil) do %>
-<% query.available_columns.each do |column| %>
-
-<% end %>
+
<%= hidden_field_tag 'query[column_names][]', '' %>
+
+
+ <%= select_tag 'available_columns',
+ options_for_select((query.available_columns - query.columns).collect {|column| [l("field_#{column.name}"), column.name]}),
+ :multiple => true, :size => 10, :style => "width:150px" %>
+ |
+
+
+
+ |
+ <%= select_tag 'query[column_names][]',
+ options_for_select(@query.columns.collect {|column| [l("field_#{column.name}"), column.name]}),
+ :id => 'selected_columns', :multiple => true, :size => 10, :style => "width:150px" %>
+ |
+
+
+<% end %>
+
+<% content_for :header_tags do %>
+<%= javascript_include_tag 'select_list_move' %>
<% end %>
diff --git a/app/views/queries/_form.rhtml b/app/views/queries/_form.rhtml
index a6b5a496c..627058df0 100644
--- a/app/views/queries/_form.rhtml
+++ b/app/views/queries/_form.rhtml
@@ -12,9 +12,9 @@
<%= check_box_tag 'default_columns', 1, @query.has_default_columns?, :id => 'query_default_columns',
- :onchange => 'if (this.checked) {Element.hide("columns")} else {Element.show("columns")}' %>
+ :onclick => 'if (this.checked) {Element.hide("columns")} else {Element.show("columns")}' %>
-<%= render :partial => 'queries/columns', :locals => {:query => query}%>
<%= render :partial => 'queries/filters', :locals => {:query => query}%>
+<%= render :partial => 'queries/columns', :locals => {:query => query}%>
diff --git a/app/views/queries/edit.rhtml b/app/views/queries/edit.rhtml
index 17b19cee9..1c99ac077 100644
--- a/app/views/queries/edit.rhtml
+++ b/app/views/queries/edit.rhtml
@@ -1,6 +1,6 @@
<%= l(:label_query) %>
-<% form_tag({:action => 'edit', :id => @query}) do %>
+<% form_tag({:action => 'edit', :id => @query}, :onsubmit => 'selectAllOptions("selected_columns");') do %>
<%= render :partial => 'form', :locals => {:query => @query} %>
<%= submit_tag l(:button_save) %>
<% end %>
diff --git a/app/views/queries/new.rhtml b/app/views/queries/new.rhtml
index 01490a3bd..631fd6c02 100644
--- a/app/views/queries/new.rhtml
+++ b/app/views/queries/new.rhtml
@@ -1,6 +1,6 @@
<%= l(:label_query_new) %>
-<% form_tag({:action => 'new', :project_id => @query.project}) do %>
+<% form_tag({:action => 'new', :project_id => @query.project}, :onsubmit => 'selectAllOptions("selected_columns");') do %>
<%= render :partial => 'form', :locals => {:query => @query} %>
<%= submit_tag l(:button_save) %>
<% end %>
diff --git a/public/javascripts/select_list_move.js b/public/javascripts/select_list_move.js
new file mode 100644
index 000000000..1ced88232
--- /dev/null
+++ b/public/javascripts/select_list_move.js
@@ -0,0 +1,55 @@
+var NS4 = (navigator.appName == "Netscape" && parseInt(navigator.appVersion) < 5);
+
+function addOption(theSel, theText, theValue)
+{
+ var newOpt = new Option(theText, theValue);
+ var selLength = theSel.length;
+ theSel.options[selLength] = newOpt;
+}
+
+function deleteOption(theSel, theIndex)
+{
+ var selLength = theSel.length;
+ if(selLength>0)
+ {
+ theSel.options[theIndex] = null;
+ }
+}
+
+function moveOptions(theSelFrom, theSelTo)
+{
+
+ var selLength = theSelFrom.length;
+ var selectedText = new Array();
+ var selectedValues = new Array();
+ var selectedCount = 0;
+
+ var i;
+
+ for(i=selLength-1; i>=0; i--)
+ {
+ if(theSelFrom.options[i].selected)
+ {
+ selectedText[selectedCount] = theSelFrom.options[i].text;
+ selectedValues[selectedCount] = theSelFrom.options[i].value;
+ deleteOption(theSelFrom, i);
+ selectedCount++;
+ }
+ }
+
+ for(i=selectedCount-1; i>=0; i--)
+ {
+ addOption(theSelTo, selectedText[i], selectedValues[i]);
+ }
+
+ if(NS4) history.go(0);
+}
+
+function selectAllOptions(id)
+{
+ var select = $(id);
+ for (var i=0; i