Feature #34420 » wip_custom_dropdown_with_sortable_items.patch
app/views/queries/_columns.html.erb | ||
---|---|---|
2 | 2 |
<% available_tag_id = "available_#{tag_id}" %> |
3 | 3 |
<% selected_tag_id = "selected_#{tag_id}" %> |
4 | 4 | |
5 |
<span class="query-columns"> |
|
6 |
<span> |
|
7 |
<%= label_tag available_tag_id, l(:description_available_columns) %> |
|
8 |
<%= select_tag 'available_columns', |
|
9 |
options_for_select(query_available_inline_columns_options(query)), |
|
10 |
:id => available_tag_id, |
|
11 |
:multiple => true, :size => 10, |
|
12 |
:ondblclick => "moveOptions(this.form.#{available_tag_id}, this.form.#{selected_tag_id});" %> |
|
13 |
</span> |
|
14 |
<span class="buttons"> |
|
15 |
<input type="button" value="→" class="move-right" |
|
16 |
onclick="moveOptions(this.form.<%= available_tag_id %>, this.form.<%= selected_tag_id %>);" /> |
|
17 |
<input type="button" value="←" class="move-left" |
|
18 |
onclick="moveOptions(this.form.<%= selected_tag_id %>, this.form.<%= available_tag_id %>);" /> |
|
19 |
</span> |
|
20 |
<span> |
|
21 |
<%= label_tag selected_tag_id, l(:description_selected_columns) %> |
|
22 |
<%= select_tag tag_name, |
|
23 |
options_for_select(query_selected_inline_columns_options(query)), |
|
24 |
:id => selected_tag_id, |
|
25 |
:multiple => true, :size => 10, |
|
26 |
:ondblclick => "moveOptions(this.form.#{selected_tag_id}, this.form.#{available_tag_id});" %> |
|
27 |
</span> |
|
28 |
<span class="buttons"> |
|
29 |
<input type="button" value="⇈" onclick="moveOptionTop(this.form.<%= selected_tag_id %>);" /> |
|
30 |
<input type="button" value="↑" onclick="moveOptionUp(this.form.<%= selected_tag_id %>);" /> |
|
31 |
<input type="button" value="↓" onclick="moveOptionDown(this.form.<%= selected_tag_id %>);" /> |
|
32 |
<input type="button" value="⇊" onclick="moveOptionBottom(this.form.<%= selected_tag_id %>);" /> |
|
5 |
<% selected_columns = query_selected_inline_columns_options(query) %> |
|
6 |
<% available_columns = query_available_inline_columns_options(query) %> |
|
7 |
<div class="query-columns drdn"> |
|
8 |
<span class="drdn-trigger"> |
|
9 |
<%= "#{selected_columns.count} out of #{available_columns.count} columns" %> |
|
33 | 10 |
</span> |
11 |
<div class="drdn-content"> |
|
12 |
<div class="quick-search"> |
|
13 |
<%= search_field_tag('q', '', :id => nil, :class => 'autocomplete', :autocomplete => 'off') %> |
|
14 |
</div> |
|
15 |
<ul class="drdn-items"> |
|
16 |
<% query_selected_inline_columns_options(query).each do |c| %> |
|
17 |
<li> |
|
18 |
<span class="item-content"> |
|
19 |
<%= check_box_tag 'c[]', c.last, true, id: "c_#{c.last}" %> |
|
20 |
<%= label_tag "c_#{c.last}", c.first %> |
|
21 |
</span> |
|
22 |
<span class="icon-only icon-sort-handle sort-handle"></span> |
|
23 |
</li> |
|
24 |
<% end %> |
|
25 |
<% query_available_inline_columns_options(query).each do |c| %> |
|
26 |
<li> |
|
27 |
<span class="item-content"> |
|
28 |
<%= check_box_tag 'c[]', c.last, nil, id: "c_#{c.last}" %> |
|
29 |
<%= label_tag "c_#{c.last}", c.first %> |
|
30 |
</span> |
|
31 |
<span class="icon-only icon-sort-handle sort-handle"></span> |
|
32 |
</li> |
|
33 |
<% end %> |
|
34 |
</ul> |
|
35 |
</div> |
|
34 | 36 |
</span> |
35 | ||
36 | 37 |
<%= javascript_tag do %> |
37 |
$(document).ready(function(){ |
|
38 |
$('.query-columns').closest('form').submit(function(){ |
|
39 |
$('#<%= selected_tag_id %> option:not(:disabled)').prop('selected', true); |
|
38 |
$(document).ready(function(){ |
|
39 |
$('.query-columns').closest('form').submit(function(){ |
|
40 |
$('#<%= selected_tag_id %> option:not(:disabled)').prop('selected', true); |
|
41 |
}); |
|
40 | 42 |
}); |
41 |
});
|
|
43 |
enableAutocomplete(document.querySelector(".query-columns"));
|
|
42 | 44 |
<% end %> |
45 |
app/views/queries/_query_form.html.erb | ||
---|---|---|
12 | 12 |
</fieldset> |
13 | 13 | |
14 | 14 |
<% if @query.available_columns.any? %> |
15 |
<fieldset id="options" class="collapsible collapsed">
|
|
15 |
<fieldset id="options" class="collapsible"> |
|
16 | 16 |
<legend onclick="toggleFieldset(this);" class="icon icon-collapsed"><%= l(:label_options) %></legend> |
17 |
<div class="hidden">
|
|
17 |
<div class=""> |
|
18 | 18 |
<% if @query.available_display_types.size > 1 %> |
19 | 19 |
<div> |
20 | 20 |
<span class="field"><label for='display_type'><%= l(:label_display_type) %></label></span> |
public/javascripts/application.js | ||
---|---|---|
1103 | 1103 |
tribute.attach(element); |
1104 | 1104 |
} |
1105 | 1105 | |
1106 |
function enableAutocomplete(element) { |
|
1107 |
const items = $(element).find('.drdn-items') |
|
1108 |
items.sortable(); |
|
1109 |
// ToDo: Replace disableSelection with CSS user-select |
|
1110 |
items.disableSelection(); |
|
1111 | ||
1112 |
element.querySelector("input.autocomplete").addEventListener('input', function(event) { |
|
1113 |
filterValues(element, event) |
|
1114 |
}) |
|
1115 | ||
1116 |
function filterValues(context, event) { |
|
1117 |
var input, filter, ul, li, a, i, txtValue; |
|
1118 |
input = event.currentTarget; |
|
1119 |
filter = input.value.toLowerCase(); |
|
1120 | ||
1121 |
ul = element.querySelector(".drdn-items"); |
|
1122 |
li = ul.getElementsByTagName("li"); |
|
1123 | ||
1124 |
for (i = 0; i < li.length; i++) { |
|
1125 |
a = li[i].querySelector("span"); |
|
1126 |
txtValue = a.textContent || a.innerText; |
|
1127 | ||
1128 |
if (txtValue.toLowerCase().indexOf(filter) > -1) { |
|
1129 |
li[i].style.display = ''; |
|
1130 |
} else { |
|
1131 |
li[i].style.display = 'none'; |
|
1132 |
} |
|
1133 |
} |
|
1134 |
} |
|
1135 |
} |
|
1136 | ||
1106 | 1137 | |
1107 | 1138 |
$(document).ready(setupAjaxIndicator); |
1108 | 1139 |
$(document).ready(hideOnLoad); |
public/stylesheets/application.css | ||
---|---|---|
155 | 155 | |
156 | 156 |
/***** Dropdown *****/ |
157 | 157 |
.drdn {position:relative;} |
158 |
.drdn ul { |
|
159 |
margin: 0; |
|
160 |
padding: 0; |
|
161 |
} |
|
158 | 162 |
.drdn-trigger { |
159 | 163 |
box-sizing:border-box; |
160 | 164 |
overflow:hidden; |
... | ... | |
190 | 194 |
overflow:hidden; |
191 | 195 |
text-overflow: ellipsis; |
192 | 196 |
white-space:nowrap; |
193 |
padding:4px 8px; |
|
197 |
padding-left: 8px; |
|
198 |
padding-right: 8px; |
|
194 | 199 |
} |
195 | 200 |
.drdn-items>a:hover {text-decoration:none;} |
196 | 201 |
.drdn-items>*:focus {border:1px dotted #bbb;} |
... | ... | |
216 | 221 |
.contextual .drdn-items {padding:2px; min-width: 160px;} |
217 | 222 |
.contextual .drdn-items>a {padding: 5px 8px;} |
218 | 223 |
.contextual .drdn-items>a.icon {padding-left: 24px; background-position-x: 4px;} |
219 |
.contextual .drdn-items>a:hover {color:#2A5685; border:1px solid #628db6; background-color:#eef5fd; border-radius:3px;} |
|
224 |
.contextual .drdn-items>a:hover, .query-columns .drdn-items li:hover {color:#2A5685; border:1px solid #628db6; background-color:#eef5fd; border-radius:3px;}
|
|
220 | 225 | |
221 | 226 |
#project-jump.drdn {width:200px;display:inline-block;} |
222 |
#project-jump .drdn-trigger { |
|
227 |
#project-jump .drdn-trigger, .query-columns .drdn-trigger {
|
|
223 | 228 |
width:100%; |
224 | 229 |
height:24px; |
225 | 230 |
display:inline-block; |
... | ... | |
233 | 238 |
} |
234 | 239 |
#project-jump .drdn.expanded .drdn-trigger {background-image:url(../images/arrow_up.png);} |
235 | 240 |
#project-jump .drdn-content {width:280px;} |
236 |
#project-jump .drdn-items>* {color:#555 !important;} |
|
241 |
#project-jump .drdn-items>* {color:#555 !important; padding-top: 4px; padding-bottom: 8px;}
|
|
237 | 242 |
#project-jump .drdn-items>a:hover {background-color:#759FCF; color:#fff !important;} |
238 | 243 | |
239 | 244 |
/***** Tables *****/ |
... | ... | |
397 | 402 |
height:100%; |
398 | 403 |
vertical-align: middle; |
399 | 404 |
} |
400 |
.query-columns label { |
|
405 |
/*.query-columns label {
|
|
401 | 406 |
display:block; |
402 |
} |
|
407 |
}*/
|
|
403 | 408 |
.query-columns .buttons input[type=button] { |
404 | 409 |
width:35px; |
405 | 410 |
display:block; |
... | ... | |
407 | 412 |
.query-columns select { |
408 | 413 |
min-width:150px; |
409 | 414 |
} |
415 |
.query-columns .drdn-trigger { |
|
416 |
height: 24px; |
|
417 |
} |
|
418 | ||
419 |
.query-columns .drdn-items span.sort-handle { |
|
420 |
float: right; |
|
421 |
display: none; |
|
422 |
} |
|
423 |
.query-columns .drdn-items li:hover span.sort-handle { |
|
424 |
display: block; |
|
425 |
} |
|
426 | ||
410 | 427 | |
411 | 428 |
.query-totals {text-align:right; margin-top:-2.3em;} |
412 | 429 |
.query-totals>span:not(:first-child) {margin-left:0.6em;} |