Project

General

Profile

Feature #34420 » wip_custom_dropdown_with_sortable_items.patch

Marius BĂLTEANU, 2021-01-10 01:09

View differences:

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="&#8594;" class="move-right"
16
       onclick="moveOptions(this.form.<%= available_tag_id %>, this.form.<%= selected_tag_id %>);" />
17
      <input type="button" value="&#8592;" 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="&#8648;" onclick="moveOptionTop(this.form.<%= selected_tag_id %>);" />
30
      <input type="button" value="&#8593;" onclick="moveOptionUp(this.form.<%= selected_tag_id %>);" />
31
      <input type="button" value="&#8595;" onclick="moveOptionDown(this.form.<%= selected_tag_id %>);" />
32
      <input type="button" value="&#8650;" 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;}
(3-3/4)