ColumnSelect: add support for grouping

Similar to html’s select, options can be put into groups:

[
  { label: "Germany", group: [{ value: 0, name: "Bavaria" }, { value: 1, name: "Berlin"}],
  { label: "USA", group: [{ value: 0, name: "New York" }, { value: 1, name: "California"}]
]
This commit is contained in:
Felix Niklas 2020-03-10 16:06:42 +01:00 committed by Thorsten Eckel
parent 136937b7db
commit a3e4691a72
4 changed files with 115 additions and 42 deletions

View file

@ -1474,7 +1474,25 @@ class InputsRef extends App.ControllerContent
name: 'project-name' name: 'project-name'
id: 'project-name-123' id: 'project-name-123'
placeholder: 'Enter Project Name' placeholder: 'Enter Project Name'
options: [{value:0,name:'Apple',selected:true},{value:1,name:'Microsoft',selected:true},{value:2,name:'Google'},{value:3,name:'Deutsche Bahn'},{value:4,name:'Sparkasse'},{value:5,name:'Deutsche Post'},{value:6,name:'Mitfahrzentrale'},{value:7,name:'Starbucks'},{value:8,name:'Mac Donalds'},{value:9,name:'Flixbus'},{value:10,name:'Betahaus'},{value:11,name:'Bruno Banani'},{value:12,name:'Alpina'},{value:13,name:'Samsung'},{value:14,name:'ChariTea'},{value:15,name:'fritz-kola'},{value:16,name:'Vitamin Water'},{value:17,name:'Znuny'},{value:18,name:'Max & Moritz'}] options: [{value:0,name:'Apple',selected:true},
{value:1,name:'Microsoft',selected:true},
{value:2,name:'Google'},
{value:3,name:'Deutsche Bahn'},
{value:4,name:'Sparkasse'},
{value:5,name:'Deutsche Post'},
{value:6,name:'Mitfahrzentrale'},
{value:7,name:'Starbucks'},
{value:8,name:'Mac Donalds'},
{value:9,name:'Flixbus'},
{value:10,name:'Betahaus'},
{value:11,name:'Bruno Banani'},
{value:12,name:'Alpina'},
{value:13,name:'Samsung'},
{value:14,name:'ChariTea'},
{value:15,name:'fritz-kola'},
{value:16,name:'Vitamin Water'},
{value:17,name:'Znuny'},
{value:18,name:'Max & Moritz'}]
@$('.searchableSelectPlaceholder').replaceWith( searchableSelectObject.element() ) @$('.searchableSelectPlaceholder').replaceWith( searchableSelectObject.element() )
# selectable search # selectable search
@ -1535,7 +1553,32 @@ class InputsRef extends App.ControllerContent
attribute: attribute:
name: 'company-name' name: 'company-name'
id: 'company-name-12345' id: 'company-name-12345'
options: [{value:0,name:'Apple'},{value:1,name:'Microsoft',selected:true},{value:2,name:'Google'},{value:3,name:'Deutsche Bahn'},{value:4,name:'Sparkasse'},{value:5,name:'Deutsche Post'},{value:6,name:'Mitfahrzentrale'},{value:7,name:'Starbucks'},{value:8,name:'Mac Donalds'},{value:9,name:'Flixbus'},{value:10,name:'Betahaus'},{value:11,name:'Bruno Banani'},{value:12,name:'Alpina'},{value:13,name:'Samsung'},{value:14,name:'ChariTea'},{value:15,name:'fritz-kola'},{value:16,name:'Vitamin Water'},{value:17,name:'Znuny'},{value:18,name:'Max & Moritz'},{value:19,name:'Telefónica Deutschland Holding GmbH'}] options: [
{label:'Group A', group: [
{value:0,name:'Apple'},
{value:1,name:'Microsoft',selected:true},
{value:2,name:'Google'},
{value:3,name:'Deutsche Bahn'},
{value:4,name:'Sparkasse'},
{value:5,name:'Deutsche Post'},
{value:6,name:'Mitfahrzentrale'}
]},
{label:'Group B', group: [
{value:7,name:'Starbucks'},
{value:8,name:'Mac Donalds'},
{value:9,name:'Flixbus'},
{value:10,name:'Betahaus'},
{value:11,name:'Bruno Banani'},
{value:12,name:'Alpina'},
{value:13,name:'Samsung'},
{value:14,name:'ChariTea'},
{value:15,name:'fritz-kola'},
{value:16,name:'Vitamin Water'},
{value:17,name:'Znuny'},
{value:18,name:'Max & Moritz'},
{value:19,name:'Telefónica Deutschland Holding GmbH'}
]}
]
@$('.columnSelectPlaceholder').replaceWith( columnSelectObject.element() ) @$('.columnSelectPlaceholder').replaceWith( columnSelectObject.element() )
App.Config.set( 'layout_ref/inputs', InputsRef, 'Routes' ) App.Config.set( 'layout_ref/inputs', InputsRef, 'Routes' )

View file

@ -42,22 +42,37 @@ class App.ColumnSelect extends Spine.Controller
if !_.isEmpty(@attribute.seperator) if !_.isEmpty(@attribute.seperator)
values = [] values = []
if @attribute.value if @attribute.value
values = @attribute.value.split(';') values = @attribute.value.split(@attribute.seperator)
else if @attribute.default else if @attribute.default
values = @attribute.default.split(';') values = @attribute.default.split(@attribute.seperator)
for value in values for value in values
for option in @options.attribute.options for option in @options.attribute.options
if option.value is value # is grouped
if option.group is not undefined
for o in option.group
if o.value is value
o.selected = true
else if option.value is value
option.selected = true option.selected = true
@values = [] @values = []
allOptions = []
_.each @options.attribute.options, (option) => _.each @options.attribute.options, (option) =>
# is grouped
if option.group != undefined
for o in option.group
allOptions.push(o)
if o.selected
@values.push o.value.toString()
else
allOptions.push(option)
if option.selected if option.selected
@values.push option.value.toString() @values.push option.value.toString()
@html App.view('generic/column_select')( @html App.view('generic/column_select')(
attribute: @options.attribute attribute: @options.attribute
allOptions: allOptions
values: @values values: @values
) )

View file

@ -10,19 +10,19 @@
value="<%= @attribute.value %>" value="<%= @attribute.value %>"
multiple multiple
> >
<% for option in @attribute.options: %> <% for option in @allOptions: %>
<option value="<%= option.value %>" <%= ' selected' if option.selected %>><%= option.name %></option> <option value="<%= option.value %>" <%= ' selected' if option.selected %>><%= option.name %></option>
<% end %> <% end %>
</select> </select>
<% end %> <% end %>
<div class="columnSelect-column columnSelect-column--selected js-selected" data-name="<%= @attribute.name %>"> <div class="columnSelect-column columnSelect-column--selected js-selected" data-name="<%= @attribute.name %>">
<div class="u-placeholder u-unselectable js-placeholder<%= ' is-hidden' if @values.length %>"><%- @T('Nothing selected') %></div> <div class="u-placeholder u-unselectable js-placeholder<%= ' is-hidden' if @values.length %>"><%- @T('Nothing selected') %></div>
<% for option in @attribute.options: %> <% for option in @allOptions: %>
<div class="columnSelect-option js-remove js-option<%= ' is-hidden' if !option.selected %>" data-value="<%= option.value %>"><%= option.name %></div> <div class="columnSelect-option js-remove js-option<%= ' is-hidden' if !option.selected %>" data-value="<%= option.value %>"><%= option.name %></div>
<% end %> <% end %>
</div> </div>
<div class="columnSelect-column columnSelect-column--sidebar" data-name="<%= @attribute.name %>"> <div class="columnSelect-column columnSelect-column--sidebar" data-name="<%= @attribute.name %>">
<% if @attribute.options.length > 10: %> <% if @allOptions.length > 10: %>
<div class="columnSelect-search"> <div class="columnSelect-search">
<%- @Icon('magnifier') %> <%- @Icon('magnifier') %>
<input class="js-search" autocomplete="off"> <input class="js-search" autocomplete="off">
@ -33,7 +33,14 @@
<% end %> <% end %>
<div class="columnSelect-pool js-pool"> <div class="columnSelect-pool js-pool">
<% for option in @attribute.options: %> <% for option in @attribute.options: %>
<% if option.group != undefined: %>
<div class="columnSelect-divider" title="<%= option.label %>"><%= option.label %></div>
<% for o in option.group: %>
<div class="columnSelect-option js-select js-option<%= ' is-hidden' if o.selected %>" data-value="<%= o.value %>" title="<%= o.title %>"><%= o.name %></div>
<% end %>
<% else: %>
<div class="columnSelect-option js-select js-option<%= ' is-hidden' if option.selected %>" data-value="<%= option.value %>" title="<%= option.title %>"><%= option.name %></div> <div class="columnSelect-option js-select js-option<%= ' is-hidden' if option.selected %>" data-value="<%= option.value %>" title="<%= option.title %>"><%= option.name %></div>
<% end %> <% end %>
<% end %>
</div> </div>
</div> </div>

View file

@ -10045,17 +10045,17 @@ output {
padding: 0; padding: 0;
line-height: 22px; line-height: 22px;
.columnSelect-shadow { &-shadow {
display: none; display: none;
} }
.columnSelect-column--selected { &-column--selected {
flex: 1 1 66%; flex: 1 1 66%;
overflow: auto; overflow: auto;
padding: 7px; padding: 7px;
} }
.columnSelect-column--sidebar { &-column--sidebar {
flex-basis: 33%; flex-basis: 33%;
flex-shrink: 1; flex-shrink: 1;
border-left: 1px solid hsl(198,4%,90%); border-left: 1px solid hsl(198,4%,90%);
@ -10069,13 +10069,13 @@ output {
} }
} }
.columnSelect-pool { &-pool {
flex: 1 1 auto; flex: 1 1 auto;
overflow: auto; overflow: auto;
padding: 7px; padding: 7px;
} }
.columnSelect-option { &-option {
@extend %clickable; @extend %clickable;
padding: 0 5px; padding: 0 5px;
border-radius: 1px; border-radius: 1px;
@ -10088,13 +10088,20 @@ output {
} }
} }
&-divider {
opacity: 0.5;
~ .columnSelect-option {
padding-left: 10px;
}
}
.is-hidden, .is-hidden,
.is-filtered { .is-filtered {
display: none; display: none;
} }
}
.columnSelect-search { &-search {
position: relative; position: relative;
.icon { .icon {
@ -10107,7 +10114,7 @@ output {
position: absolute; position: absolute;
} }
.columnSelect-search-clear { &-clear {
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
@ -10124,6 +10131,7 @@ output {
border-bottom: 1px solid hsl(198,4%,90%); border-bottom: 1px solid hsl(198,4%,90%);
background: none; background: none;
} }
}
} }