columnSelect widget

This commit is contained in:
Felix Niklas 2016-02-09 14:30:36 +01:00
parent 352ffd7aa8
commit 4c6120910f
6 changed files with 247 additions and 1 deletions

View file

@ -0,0 +1,29 @@
# coffeelint: disable=camel_case_classes
class App.UiElement.column_select extends App.UiElement.ApplicationUiElement
@render: (attribute, params) ->
# set multiple option
attribute.multiple = 'multiple'
# build options list based on config
@getConfigOptionList( attribute, params )
# build options list based on relation
@getRelationOptionList( attribute, params )
# add null selection if needed
@addNullOption( attribute, params )
# sort attribute.options
@sortOptions( attribute, params )
# finde selected/checked item of list
@selectedOptions( attribute, params )
# disable item of list
@disabledOptions( attribute, params )
# filter attributes
@filterOption( attribute, params )
new App.ColumnSelect( attribute: attribute ).element()

View file

@ -1516,6 +1516,14 @@ class InputsRef extends App.ControllerContent
)
@$('.js-timepicker4').timepicker()
# column select
columnSelectObject = new App.ColumnSelect
attribute:
name: 'company-name'
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'}]
@$('.columnSelectPlaceholder').replaceWith( columnSelectObject.element() )
App.Config.set( 'layout_ref/inputs', InputsRef, 'Routes' )

View file

@ -0,0 +1,86 @@
class App.ColumnSelect extends Spine.Controller
elements:
'.js-pool': 'pool'
'.js-selected': 'selected'
'.js-shadow': 'shadow'
'.js-placeholder': 'placeholder'
'.js-pool .js-option': 'poolOptions'
'.js-selected .js-option': 'selectedOptions'
'.js-search': 'search'
'.js-clear': 'clearButton'
events:
'click .js-select': 'onSelect'
'click .js-remove': 'onRemove'
'input .js-search': 'filter'
'click .js-clear': 'clear'
'keydown .js-search': 'onFilterKeydown'
className: 'form-control columnSelect'
element: =>
@el
constructor: ->
super
@values = []
@render()
render: ->
@html App.view('generic/column_select')( @options.attribute )
# keep height fixed
setTimeout =>
@el.css 'height', @el.height()
, 0
onSelect: (event) ->
@select $(event.currentTarget).attr('data-value')
select: (value) ->
@selected.find("[data-value='#{value}']").removeClass 'is-hidden'
@pool.find("[data-value='#{value}']").addClass 'is-hidden'
@values.push(value)
@shadow.val(@values)
@placeholder.addClass 'is-hidden'
if @search.val() and @poolOptions.not('.is-filtered').not('.is-hidden').size() is 0
@clear()
onRemove: (event) ->
@remove $(event.currentTarget).attr('data-value')
remove: (value) ->
@pool.find("[data-value='#{value}']").removeClass 'is-hidden'
@selected.find("[data-value='#{value}']").addClass 'is-hidden'
@values.splice(@values.indexOf(value), 1)
@shadow.val(@values)
if !@values.length
@placeholder.removeClass 'is-hidden'
filter: (event) ->
filter = $(event.currentTarget).val()
@poolOptions.each (i, el) ->
return if $(el).hasClass('is-hidden')
if $(el).text().indexOf(filter) > -1
$(el).removeClass 'is-filtered'
else
$(el).addClass 'is-filtered'
@clearButton.toggleClass 'is-hidden', filter.length is 0
clear: ->
@search.val('')
@poolOptions.removeClass 'is-filtered'
@clearButton.addClass 'is-hidden'
onFilterKeydown: (event) ->
return if event.keyCode != 13
firstVisibleOption = @poolOptions.not('.is-filtered').not('.is-hidden').first()
if firstVisibleOption
@select firstVisibleOption.attr('data-value')

View file

@ -0,0 +1,35 @@
<select
class="columnSelect-shadow js-shadow"
id="<%= @id %>"
name="<%= @name %>"
<%= @required %>
<%= @autofocus %>
value="<%= @value %>"
multiple
>
<% for option in @options: %>
<option value="<%= option.value %>"><%= option.name %></option>
<% end %>
</select>
<div class="columnSelect-column columnSelect-column--selected js-selected">
<div class="u-placeholder js-placeholder"><%- @T('No value selected') %></div>
<% for option in @options: %>
<div class="columnSelect-option is-hidden js-remove js-option" data-value="<%= option.value %>"><%= option.name %></div>
<% end %>
</div>
<div class="columnSelect-column columnSelect-column--sidebar">
<% if @options.length > 10: %>
<div class="columnSelect-search">
<%- @Icon('magnifier') %>
<input class="js-search">
<div class="columnSelect-search-clear js-clear is-hidden">
<%- @Icon('diagonal-cross') %>
</div>
</div>
<% end %>
<div class="columnSelect-pool js-pool">
<% for option in @options: %>
<div class="columnSelect-option js-select js-option" data-value="<%= option.value %>"><%= option.name %></div>
<% end %>
</div>
</div>

View file

@ -119,6 +119,12 @@
</div>
</div>
<h2>Column Select</h2>
<div class="column-select form-group">
<label>Companys</label>
<div class="columnSelectPlaceholder"></div>
</div>
<h2>Switch</h2>
<div class="switch form-group">
<div class="controls">

View file

@ -295,7 +295,8 @@ pre code.hljs {
.textarea::placeholder,
.form-control::placeholder,
.token-input::placeholder {
.token-input::placeholder,
.u-placeholder {
color: hsl(0,0%,80%);
}
@ -7771,6 +7772,87 @@ output {
}
}
.columnSelect {
display: flex;
height: auto;
line-height: 25px;
max-height: 300px;
padding: 0;
line-height: 22px;
.columnSelect-shadow {
display: none;
}
.columnSelect-column--selected {
flex-basis: 66%;
flex-grow: 1;
overflow: auto;
padding: 7px 12px;
}
.columnSelect-column--sidebar {
flex-basis: 33%;
flex-shrink: 1;
border-left: 1px dotted hsl(0,0%,90%);
display: flex;
flex-direction: column;
}
.columnSelect-pool {
flex: 1;
overflow: auto;
padding: 7px 12px;
.columnSelect-option {
padding-left: 18px;
}
}
.columnSelect-option {
cursor: pointer;
user-select: none;
}
.is-hidden,
.is-filtered {
display: none;
}
}
.columnSelect-search {
position: relative;
.icon {
fill: hsl(0,0%,90%);
}
.icon-magnifier {
left: 7px;
top: 5px;
position: absolute;
}
.columnSelect-search-clear {
position: absolute;
right: 0;
top: 0;
padding: 5px 7px;
cursor: pointer;
line-height: 1;
}
input {
width: 100%;
padding: 2px 30px 1px;
border: none;
outline: none;
border-bottom: 1px dotted hsl(0,0%,90%);
background: none;
}
}
/*
----------------