Added the autocomplete Inspector editor. Minor fixes in the Inspector memory management. Added destroy() method to the existing autocomplete control.
This commit is contained in:
parent
c47f69a012
commit
889a25f1c6
|
|
@ -1258,8 +1258,9 @@ this.shown=false
|
|||
this.listen()}
|
||||
Autocomplete.prototype={constructor:Autocomplete,select:function(){var val=this.$menu.find('.active').attr('data-value')
|
||||
this.$element.val(this.updater(val)).change()
|
||||
return this.hide()},updater:function(item){return item},show:function(){var pos=$.extend({},this.$element.position(),{height:this.$element[0].offsetHeight})
|
||||
this.$menu.insertAfter(this.$element).css({top:pos.top+pos.height,left:pos.left}).show()
|
||||
return this.hide()},updater:function(item){return item},show:function(){var pos=$.extend({},this.$element.position(),{height:this.$element[0].offsetHeight}),cssOptions={top:pos.top+pos.height,left:pos.left}
|
||||
if(this.options.matchWidth){cssOptions.width=this.$element[0].offsetWidth}
|
||||
this.$menu.insertAfter(this.$element).css(cssOptions).show()
|
||||
this.shown=true
|
||||
return this},hide:function(){this.$menu.hide()
|
||||
this.shown=false
|
||||
|
|
@ -1293,9 +1294,9 @@ return this},next:function(event){var active=this.$menu.find('.active').removeCl
|
|||
if(!next.length){next=$(this.$menu.find('li')[0])}
|
||||
next.addClass('active')},prev:function(event){var active=this.$menu.find('.active').removeClass('active'),prev=active.prev()
|
||||
if(!prev.length){prev=this.$menu.find('li').last()}
|
||||
prev.addClass('active')},listen:function(){this.$element.on('focus',$.proxy(this.focus,this)).on('blur',$.proxy(this.blur,this)).on('keypress',$.proxy(this.keypress,this)).on('keyup',$.proxy(this.keyup,this))
|
||||
if(this.eventSupported('keydown')){this.$element.on('keydown',$.proxy(this.keydown,this))}
|
||||
this.$menu.on('click',$.proxy(this.click,this)).on('mouseenter','li',$.proxy(this.mouseenter,this)).on('mouseleave','li',$.proxy(this.mouseleave,this))},eventSupported:function(eventName){var isSupported=eventName in this.$element
|
||||
prev.addClass('active')},listen:function(){this.$element.on('focus.autocomplete',$.proxy(this.focus,this)).on('blur.autocomplete',$.proxy(this.blur,this)).on('keypress.autocomplete',$.proxy(this.keypress,this)).on('keyup.autocomplete',$.proxy(this.keyup,this))
|
||||
if(this.eventSupported('keydown')){this.$element.on('keydown.autocomplete',$.proxy(this.keydown,this))}
|
||||
this.$menu.on('click.autocomplete',$.proxy(this.click,this)).on('mouseenter.autocomplete','li',$.proxy(this.mouseenter,this)).on('mouseleave.autocomplete','li',$.proxy(this.mouseleave,this))},eventSupported:function(eventName){var isSupported=eventName in this.$element
|
||||
if(!isSupported){this.$element.setAttribute(eventName,'return;')
|
||||
isSupported=typeof this.$element[eventName]==='function'}
|
||||
return isSupported},move:function(e){if(!this.shown)return
|
||||
|
|
@ -1325,7 +1326,13 @@ this.select()
|
|||
this.$element.focus()},mouseenter:function(e){this.mousedover=true
|
||||
this.$menu.find('.active').removeClass('active')
|
||||
$(e.currentTarget).addClass('active')},mouseleave:function(e){this.mousedover=false
|
||||
if(!this.focused&&this.shown)this.hide()}}
|
||||
if(!this.focused&&this.shown)this.hide()},destroy:function(){this.hide()
|
||||
this.$element.removeData('autocomplete')
|
||||
this.$menu.remove()
|
||||
this.$element.off('.autocomplete')
|
||||
this.$menu.off('.autocomplete')
|
||||
this.$element=null
|
||||
this.$menu=null}}
|
||||
var old=$.fn.autocomplete
|
||||
$.fn.autocomplete=function(option){return this.each(function(){var $this=$(this),data=$this.data('autocomplete'),options=typeof option=='object'&&option
|
||||
if(!data)$this.data('autocomplete',(data=new Autocomplete(this,options)))
|
||||
|
|
|
|||
|
|
@ -53,14 +53,19 @@
|
|||
show: function () {
|
||||
var pos = $.extend({}, this.$element.position(), {
|
||||
height: this.$element[0].offsetHeight
|
||||
})
|
||||
}),
|
||||
cssOptions = {
|
||||
top: pos.top + pos.height
|
||||
, left: pos.left
|
||||
}
|
||||
|
||||
if (this.options.matchWidth) {
|
||||
cssOptions.width = this.$element[0].offsetWidth
|
||||
}
|
||||
|
||||
this.$menu
|
||||
.insertAfter(this.$element)
|
||||
.css({
|
||||
top: pos.top + pos.height
|
||||
, left: pos.left
|
||||
})
|
||||
.css(cssOptions)
|
||||
.show()
|
||||
|
||||
this.shown = true
|
||||
|
|
@ -194,19 +199,19 @@
|
|||
|
||||
listen: function () {
|
||||
this.$element
|
||||
.on('focus', $.proxy(this.focus, this))
|
||||
.on('blur', $.proxy(this.blur, this))
|
||||
.on('keypress', $.proxy(this.keypress, this))
|
||||
.on('keyup', $.proxy(this.keyup, this))
|
||||
.on('focus.autocomplete', $.proxy(this.focus, this))
|
||||
.on('blur.autocomplete', $.proxy(this.blur, this))
|
||||
.on('keypress.autocomplete', $.proxy(this.keypress, this))
|
||||
.on('keyup.autocomplete', $.proxy(this.keyup, this))
|
||||
|
||||
if (this.eventSupported('keydown')) {
|
||||
this.$element.on('keydown', $.proxy(this.keydown, this))
|
||||
this.$element.on('keydown.autocomplete', $.proxy(this.keydown, this))
|
||||
}
|
||||
|
||||
this.$menu
|
||||
.on('click', $.proxy(this.click, this))
|
||||
.on('mouseenter', 'li', $.proxy(this.mouseenter, this))
|
||||
.on('mouseleave', 'li', $.proxy(this.mouseleave, this))
|
||||
.on('click.autocomplete', $.proxy(this.click, this))
|
||||
.on('mouseenter.autocomplete', 'li', $.proxy(this.mouseenter, this))
|
||||
.on('mouseleave.autocomplete', 'li', $.proxy(this.mouseleave, this))
|
||||
},
|
||||
|
||||
eventSupported: function(eventName) {
|
||||
|
|
@ -305,8 +310,20 @@
|
|||
mouseleave: function (e) {
|
||||
this.mousedover = false
|
||||
if (!this.focused && this.shown) this.hide()
|
||||
}
|
||||
},
|
||||
|
||||
destroy: function() {
|
||||
this.hide()
|
||||
|
||||
this.$element.removeData('autocomplete')
|
||||
this.$menu.remove()
|
||||
|
||||
this.$element.off('.autocomplete')
|
||||
this.$menu.off('.autocomplete')
|
||||
|
||||
this.$element = null
|
||||
this.$menu = null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Inspector autocomplete editor class.
|
||||
*
|
||||
* Depends on october.autocomplete.js
|
||||
*/
|
||||
+function ($) { "use strict";
|
||||
|
||||
var Base = $.oc.inspector.propertyEditors.string,
|
||||
BaseProto = Base.prototype
|
||||
|
||||
var AutocompleteEditor = function(inspector, propertyDefinition, containerCell, group) {
|
||||
Base.call(this, inspector, propertyDefinition, containerCell, group)
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype = Object.create(BaseProto)
|
||||
AutocompleteEditor.prototype.constructor = Base
|
||||
|
||||
AutocompleteEditor.prototype.dispose = function() {
|
||||
this.removeAutocomplete()
|
||||
|
||||
BaseProto.dispose.call(this)
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.build = function() {
|
||||
var container = document.createElement('div'),
|
||||
editor = document.createElement('input'),
|
||||
placeholder = this.propertyDefinition.placeholder !== undefined ? this.propertyDefinition.placeholder : '',
|
||||
value = this.inspector.getPropertyValue(this.propertyDefinition.property)
|
||||
|
||||
editor.setAttribute('type', 'text')
|
||||
editor.setAttribute('class', 'string-editor')
|
||||
editor.setAttribute('placeholder', placeholder)
|
||||
|
||||
container.setAttribute('class', 'autocomplete-container')
|
||||
|
||||
if (value === undefined) {
|
||||
value = this.propertyDefinition.default
|
||||
}
|
||||
|
||||
if (value === undefined) {
|
||||
value = ''
|
||||
}
|
||||
|
||||
editor.value = value
|
||||
|
||||
$.oc.foundation.element.addClass(this.containerCell, 'text autocomplete')
|
||||
|
||||
container.appendChild(editor)
|
||||
this.containerCell.appendChild(container)
|
||||
|
||||
if (this.propertyDefinition.items !== undefined) {
|
||||
this.buildAutoComplete(this.propertyDefinition.items)
|
||||
}
|
||||
else {
|
||||
this.loadDynamicItems()
|
||||
}
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.buildAutoComplete = function(items) {
|
||||
var input = this.getInput()
|
||||
|
||||
if (items === undefined) {
|
||||
items = []
|
||||
}
|
||||
|
||||
$(input).autocomplete({
|
||||
source: this.prepareItems(items),
|
||||
matchWidth: true
|
||||
})
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.removeAutocomplete = function() {
|
||||
var input = this.getInput()
|
||||
|
||||
$(input).autocomplete('destroy')
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.prepareItems = function(items) {
|
||||
var result = {}
|
||||
|
||||
if ($.isArray(items)) {
|
||||
for (var i = 0, len = items.length; i < len; i++) {
|
||||
result[items[i]] = items[i]
|
||||
}
|
||||
}
|
||||
else {
|
||||
result = items
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.supportsExternalParameterEditor = function() {
|
||||
return false
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.getContainer = function() {
|
||||
return this.getInput().parentNode
|
||||
}
|
||||
|
||||
//
|
||||
// Dynamic items
|
||||
//
|
||||
|
||||
AutocompleteEditor.prototype.showLoadingIndicator = function() {
|
||||
$(this.getContainer()).loadIndicator()
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.hideLoadingIndicator = function() {
|
||||
var $container = $(this.getContainer())
|
||||
|
||||
$container.loadIndicator('hide')
|
||||
$container.loadIndicator('destroy')
|
||||
|
||||
$container.removeClass('loading-indicator-container')
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.loadDynamicItems = function() {
|
||||
var container = this.getContainer(),
|
||||
data = this.inspector.getValues(),
|
||||
$form = $(container).closest('form')
|
||||
|
||||
$.oc.foundation.element.addClass(container, 'loading-indicator-container size-small')
|
||||
this.showLoadingIndicator()
|
||||
|
||||
$form.request('onInspectableGetOptions', {
|
||||
data: data,
|
||||
})
|
||||
.done(this.proxy(this.itemsRequestDone))
|
||||
.always(this.proxy(this.hideLoadingIndicator))
|
||||
}
|
||||
|
||||
AutocompleteEditor.prototype.itemsRequestDone = function(data, currentValue, initialization) {
|
||||
var loadedItems = {}
|
||||
|
||||
if (data.options) {
|
||||
for (var i = data.options.length-1; i >= 0; i--) {
|
||||
loadedItems[data.options[i].value] = data.options[i].title
|
||||
}
|
||||
}
|
||||
|
||||
this.buildAutoComplete(loadedItems)
|
||||
}
|
||||
|
||||
$.oc.inspector.propertyEditors.autocomplete = AutocompleteEditor
|
||||
}(window.jQuery);
|
||||
|
|
@ -293,6 +293,7 @@
|
|||
DropdownEditor.prototype.hideLoadingIndicator = function() {
|
||||
if (!Modernizr.touch) {
|
||||
this.indicatorContainer.loadIndicator('hide')
|
||||
this.indicatorContainer.loadIndicator('destroy')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -145,7 +145,10 @@
|
|||
}
|
||||
|
||||
SetEditor.prototype.hideLoadingIndicator = function() {
|
||||
$(this.getLink()).loadIndicator('hide')
|
||||
var $link = $(this.getLink())
|
||||
|
||||
$link.loadIndicator('hide')
|
||||
$link.loadIndicator('destroy')
|
||||
}
|
||||
|
||||
SetEditor.prototype.loadDynamicItems = function() {
|
||||
|
|
|
|||
|
|
@ -80,5 +80,9 @@
|
|||
this.inspector.setPropertyValue(this.propertyDefinition.property, value)
|
||||
}
|
||||
|
||||
StringEditor.prototype.onExternalPropertyEditorHidden = function() {
|
||||
this.focus()
|
||||
}
|
||||
|
||||
$.oc.inspector.propertyEditors.string = StringEditor
|
||||
}(window.jQuery);
|
||||
Loading…
Reference in New Issue