class Para.MultiSelectInput extends Vertebra.View events: 'keyup [data-search-field]': 'onSearchKeyUp' 'click [data-add-all]': 'onAllItemsAdded' 'click [data-remove-all]': 'onAllItemsRemoved' initialize: -> @$searchField = @$('[data-search-field]') @$selectedItems = @$('[data-selected-items] tbody') @$availableItems = @$('[data-available-items]') @$input = @$('[data-multi-select-input-field]') @searchURL = @$el.data('search-url') @orderable = @$el.is('[data-orderable]') @searchParam = @$searchField.attr('name') @noSelectedItemsTemplate = @$('[data-no-selected-items]').data('no-selected-items') @noAvailableItemsTemplate = @$('[data-no-available-items]').data('no-available-items') @throttledTriggerSearch = throttle(@triggerSearch, 300, trailing: true) @availableItems = [] @selectedItems = (@buildSelectedItem(el) for el in @$selectedItems.find('[data-selected-item-id]')) @refreshSelectedItems() @refreshAvailableItems() onSearchKeyUp: -> @throttledTriggerSearch() triggerSearch: => @searchFor(@$searchField.val()) searchFor: (terms) -> terms = trim(terms) return if terms is @terms or (!terms and !@terms) @terms = terms @setLoading(true) @_currentSearchXHR?.abort() data = @$('[data-search-field-input]').serialize() @_currentSearchXHR = $.get(@searchURL, data).done(@onSearchReturn) onSearchReturn: (results) => @_currentSearchXHR = null @setLoading(false) @$('[data-available-items] tbody').html(results) @refreshAvailableItems() refreshAvailableItems: -> item.destroy() for item in @availableItems @availableItems = (@buildAvailableItem(el) for el in @$('[data-available-items] tr')) @showEmptyListHint(@noAvailableItemsTemplate, @$availableItems) unless @availableItems.length buildAvailableItem: (el) -> availableItem = new Para.MultiSelectAvailableItem(el: el) availableItem.setSelected(true) for selectedItem in @selectedItems when selectedItem.id is availableItem.id @listenTo(availableItem, 'add', @onItemAdded) availableItem onItemAdded: (item) => @selectItem(item) buildSelectedItem: (el) -> selectedItem = new Para.MultiSelectSelectedItem(el: el) @listenTo(selectedItem, 'remove', @onItemRemoved) selectedItem selectItem: (item) -> return if @alreadySelected(item) item.setSelected(true) selectedItem = @buildSelectedItem(item.$el.attr('data-selected-item-template')) @selectedItems.push(selectedItem) @refreshSelectedItems() alreadySelected: (item) -> return true for selectedItem in @selectedItems when selectedItem.id is item.id false refreshSelectedItems: -> @$selectedItems.empty() selectedItem.renderTo(@$selectedItems) for selectedItem in @selectedItems selectedItemIds = (selectedItem.id for selectedItem in @selectedItems).join(', ') @$input.val(selectedItemIds) if @selectedItems.length @initializeOrderable() else @showEmptyListHint(@noSelectedItemsTemplate, @$selectedItems) showEmptyListHint: (template, $container) -> $(template).appendTo($container) onItemRemoved: (selectedItem) => itemIndex = index for item, index in @selectedItems when item.id is selectedItem.id @selectedItems.splice(itemIndex, 1) selectedItem.destroy() @refreshSelectedItems() availableItem = item for item in @availableItems when item.id is selectedItem.id availableItem.setSelected(false) if availableItem onAllItemsAdded: -> return unless @availableItems.length @selectItem(availableItem) for availableItem in @availableItems onAllItemsRemoved: -> return unless @selectedItems.length @selectedItems = [] @refreshSelectedItems() item.setSelected(false) for item in @availableItems initializeOrderable: -> return unless @orderable columnsCount = @$selectedItems.find('> tr > td').length @$selectedItems.sortable('destroy') @$selectedItems.sortable handle: '.order-anchor' forcePlaceholderSize: true placeholder: "