columnSelect widget
This commit is contained in:
parent
352ffd7aa8
commit
4c6120910f
6 changed files with 247 additions and 1 deletions
|
@ -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()
|
|
@ -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' )
|
||||
|
||||
|
||||
|
|
86
app/assets/javascripts/app/lib/app_post/column_select.coffee
Normal file
86
app/assets/javascripts/app/lib/app_post/column_select.coffee
Normal 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')
|
|
@ -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>
|
|
@ -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">
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
----------------
|
||||
|
|
Loading…
Reference in a new issue