Merge branch 'builder-ui' into develop

This commit is contained in:
alekseybobkov 2016-02-04 18:00:49 -08:00
commit f5e47ebc88
20 changed files with 994 additions and 76 deletions

View File

@ -484,6 +484,8 @@ div.control-scrollpad > .scrollpad-scrollbar[data-visible]{opacity:0.7}
div.control-scrollpad > .scrollpad-scrollbar[data-hidden]{display:none} div.control-scrollpad > .scrollpad-scrollbar[data-hidden]{display:none}
div.control-scrollpad[data-direction=horizontal] > .scrollpad-scrollbar{top:auto;left:0;width:auto;height:11px} div.control-scrollpad[data-direction=horizontal] > .scrollpad-scrollbar{top:auto;left:0;width:auto;height:11px}
div.control-scrollpad[data-direction=horizontal] > .scrollpad-scrollbar .drag-handle{right:auto;top:2px;height:7px;min-height:0;min-width:10px;width:auto} div.control-scrollpad[data-direction=horizontal] > .scrollpad-scrollbar .drag-handle{right:auto;top:2px;height:7px;min-height:0;min-width:10px;width:auto}
.autocomplete.dropdown-menu{background:white}
.autocomplete.dropdown-menu li a{padding:3px 12px}
@font-face{font-family:'Open Sans';src:url('../font/OpenSans-Light.eot');src:url('../font/OpenSans-Light.eot?#iefix') format('embedded-opentype'),url('../font/OpenSans-Light.svg#open_sanslight') format('svg'),url('../font/OpenSans-Light.woff') format('woff'),url('../font/OpenSans-Light.ttf') format('truetype');font-style:normal;font-weight:300} @font-face{font-family:'Open Sans';src:url('../font/OpenSans-Light.eot');src:url('../font/OpenSans-Light.eot?#iefix') format('embedded-opentype'),url('../font/OpenSans-Light.svg#open_sanslight') format('svg'),url('../font/OpenSans-Light.woff') format('woff'),url('../font/OpenSans-Light.ttf') format('truetype');font-style:normal;font-weight:300}
@font-face{font-family:'Open Sans';src:url('../font/OpenSans-Regular.eot');src:url('../font/OpenSans-Regular.eot?#iefix') format('embedded-opentype'),url('../font/OpenSans-Regular.svg#open_sansregular') format('svg'),url('../font/OpenSans-Regular.woff') format('woff'),url('../font/OpenSans-Regular.ttf') format('truetype');font-style:normal;font-weight:400} @font-face{font-family:'Open Sans';src:url('../font/OpenSans-Regular.eot');src:url('../font/OpenSans-Regular.eot?#iefix') format('embedded-opentype'),url('../font/OpenSans-Regular.svg#open_sansregular') format('svg'),url('../font/OpenSans-Regular.woff') format('woff'),url('../font/OpenSans-Regular.ttf') format('truetype');font-style:normal;font-weight:400}
@font-face{font-family:'Open Sans';src:url('../font/OpenSans-Semibold.eot');src:url('../font/OpenSans-Semibold.eot?#iefix') format('embedded-opentype'),url('../font/OpenSans-Semibold.svg#open_sanssemibold') format('svg'),url('../font/OpenSans-Semibold.woff') format('woff'),url('../font/OpenSans-Semibold.ttf') format('truetype');font-style:normal;font-weight:600} @font-face{font-family:'Open Sans';src:url('../font/OpenSans-Semibold.eot');src:url('../font/OpenSans-Semibold.eot?#iefix') format('embedded-opentype'),url('../font/OpenSans-Semibold.svg#open_sanssemibold') format('svg'),url('../font/OpenSans-Semibold.woff') format('woff'),url('../font/OpenSans-Semibold.ttf') format('truetype');font-style:normal;font-weight:600}
@ -789,16 +791,16 @@ html.csstransitions body.outer.preload .outer-form-container{-webkit-transform:s
.fancy-layout .control-tabs.master-tabs.scroll-after:after,.fancy-layout.control-tabs.master-tabs.scroll-after:after{color:#ffffff} .fancy-layout .control-tabs.master-tabs.scroll-after:after,.fancy-layout.control-tabs.master-tabs.scroll-after:after{color:#ffffff}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container{background:#d35400;padding-left:20px;padding-right:20px} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container{background:#d35400;padding-left:20px;padding-right:20px}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs{margin-left:-8px} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs{margin-left:-8px}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li{margin-left:-10px;top:1px} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li{margin-left:-8px;top:1px}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close{top:9px;right:-3px;left:auto;z-index:110} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close{top:9px;right:-3px;left:auto;z-index:110}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close i,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close i{top:4px;right:1px;color:rgba(255,255,255,0.3) !important;font:14px bold "Helvetica Neue",Helvetica,Arial,sans-serif} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close i,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close i{top:4px;right:1px;color:rgba(255,255,255,0.3) !important;font:14px bold "Helvetica Neue",Helvetica,Arial,sans-serif}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close i:hover,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close i:hover{color:#ffffff !important} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close i:hover,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li span.tab-close i:hover{color:#ffffff !important}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a{border-bottom:none;background:transparent;font-size:14px;color:rgba(255,255,255,0.35);padding:6px 0 0 0;overflow:visible} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a{border-bottom:none;background:transparent;font-size:14px;color:rgba(255,255,255,0.35);padding:6px 0 0 24px!important;overflow:visible}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title{position:relative;display:inline-block;padding:8px 5px 9px 5px;height:31px;font-size:13px;z-index:100;background-color:#b9530f} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title{position:relative;display:inline-block;padding:8px 5px 9px 5px;height:31px;font-size:13px;z-index:100;background-color:#b9530f}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:before,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:before,.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:after,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:after{content:' ';position:absolute;background:transparent url(../images/tab-shape.svg) no-repeat left -80px;width:20px;display:block;height:30px;top:0;z-index:100} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:before,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:before,.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:after,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:after{content:' ';position:absolute;background:transparent url(../images/tab-shape.svg) no-repeat left -80px;width:20px;display:block;height:30px;top:0;z-index:100}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:before,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:before{left:-20px} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:before,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:before{left:-20px}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:after,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:after{right:-20px;background-position:-80px -80px} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:after,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a > span.title:after{right:-20px;background-position:-80px -80px}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a:before,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a:before{z-index:110;position:relative;margin-right:-12px} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a:before,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a:before{z-index:110;position:absolute;top:15px;left:22px}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a[class*=icon] > span.title,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a[class*=icon] > span.title{padding-left:18px} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a[class*=icon] > span.title,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li a[class*=icon] > span.title{padding-left:18px}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li.active a,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li.active a{z-index:107;color:#ffffff} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li.active a,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li.active a{z-index:107;color:#ffffff}
.fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li.active span.tab-close i,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li.active span.tab-close i{color:#ffffff} .fancy-layout .control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li.active span.tab-close i,.fancy-layout.control-tabs.master-tabs > div > div.tabs-container > ul.nav-tabs > li.active span.tab-close i{color:#ffffff}
@ -856,7 +858,7 @@ html.csstransitions body.outer.preload .outer-form-container{-webkit-transform:s
.fancy-layout .control-tabs.primary-tabs > .tab-content > .tab-pane.pane-compact,.fancy-layout.control-tabs.primary-tabs > .tab-content > .tab-pane.pane-compact{padding:0} .fancy-layout .control-tabs.primary-tabs > .tab-content > .tab-pane.pane-compact,.fancy-layout.control-tabs.primary-tabs > .tab-content > .tab-pane.pane-compact{padding:0}
.fancy-layout .control-tabs.primary-tabs > .tab-content > .tab-pane .form-control,.fancy-layout.control-tabs.primary-tabs > .tab-content > .tab-pane .form-control{border-width:1px} .fancy-layout .control-tabs.primary-tabs > .tab-content > .tab-pane .form-control,.fancy-layout.control-tabs.primary-tabs > .tab-content > .tab-pane .form-control{border-width:1px}
.fancy-layout .control-tabs.primary-tabs.collapsed,.fancy-layout.control-tabs.primary-tabs.collapsed{display:none} .fancy-layout .control-tabs.primary-tabs.collapsed,.fancy-layout.control-tabs.primary-tabs.collapsed{display:none}
.fancy-layout .control-tabs > div.tab-content,.fancy-layout.control-tabs > div.tab-content{background:#f9f9f9} .fancy-layout .control-tabs.has-tabs > div.tab-content,.fancy-layout.control-tabs.has-tabs > div.tab-content{background:#f9f9f9}
.fancy-layout .control-tabs > div.tab-content > div.tab-pane,.fancy-layout.control-tabs > div.tab-content > div.tab-pane{padding:0} .fancy-layout .control-tabs > div.tab-content > div.tab-pane,.fancy-layout.control-tabs > div.tab-content > div.tab-pane{padding:0}
.fancy-layout .control-tabs > div.tab-content > div.tab-pane.padded-pane,.fancy-layout.control-tabs > div.tab-content > div.tab-pane.padded-pane{padding:15px 15px 0 15px} .fancy-layout .control-tabs > div.tab-content > div.tab-pane.padded-pane,.fancy-layout.control-tabs > div.tab-content > div.tab-pane.padded-pane{padding:15px 15px 0 15px}
.fancy-layout .form-tabless-fields{position:relative;background:#e67e22;padding:18px 23px 0 23px;-webkit-transition:all 0.5s;transition:all 0.5s} .fancy-layout .form-tabless-fields{position:relative;background:#e67e22;padding:18px 23px 0 23px;-webkit-transition:all 0.5s;transition:all 0.5s}

View File

@ -0,0 +1,7 @@
.autocomplete.dropdown-menu {
background: white;
li a {
padding: 3px 12px;
}
}

View File

@ -54,7 +54,7 @@
> ul.nav-tabs { > ul.nav-tabs {
margin-left: -8px; margin-left: -8px;
> li { > li {
margin-left: -10px; margin-left: -8px;
top: 1px; top: 1px;
span.tab-close{ span.tab-close{
@ -79,7 +79,7 @@
background: transparent; background: transparent;
font-size: 14px; font-size: 14px;
color: @color-fancy-master-tabs-inactive-text; color: @color-fancy-master-tabs-inactive-text;
padding: 6px 0 0 0; padding: 6px 0 0 24px!important;
overflow: visible; overflow: visible;
> span.title { > span.title {
@ -114,8 +114,9 @@
&:before { &:before {
z-index: 110; z-index: 110;
position: relative; position: absolute;
margin-right: -12px; top: 15px;
left: 22px;
} }
&[class*=icon] > span.title { &[class*=icon] > span.title {
@ -401,9 +402,13 @@
} }
} }
> div.tab-content { &.has-tabs {
background: @body-bg; > div.tab-content {
background: @body-bg;
}
}
> div.tab-content {
> div.tab-pane { > div.tab-pane {
padding: 0; padding: 0;

View File

@ -35,6 +35,7 @@
@import "controls/tree-path.less"; @import "controls/tree-path.less";
@import "controls/namevaluelist.less"; @import "controls/namevaluelist.less";
@import "controls/scrollpad.less"; @import "controls/scrollpad.less";
@import "controls/autocomplete.less";
// //
// October Storm UI // October Storm UI

View File

@ -33,7 +33,21 @@ trait InspectableContainer
$obj = new $className(null); $obj = new $className(null);
$methodName = 'get'.ucfirst($property).'Options'; // Nested properties have names like object.property.
// Convert them to Object.Property.
$propertyNameParts = explode('.', $property);
$propertyMethodName = '';
foreach ($propertyNameParts as $part) {
$part = trim($part);
if (!strlen($part)) {
continue;
}
$propertyMethodName .= ucfirst($part);
}
$methodName = 'get'.$propertyMethodName.'Options';
if (method_exists($obj, $methodName)) { if (method_exists($obj, $methodName)) {
$options = $obj->$methodName(); $options = $obj->$methodName();
} }
@ -53,4 +67,4 @@ trait InspectableContainer
'options' => $optionsArray 'options' => $optionsArray
]; ];
} }
} }

View File

@ -6,6 +6,7 @@ $.oc.table={}
var Table=function(element,options){this.el=element var Table=function(element,options){this.el=element
this.$el=$(element) this.$el=$(element)
this.options=options this.options=options
this.disposed=false
this.dataSource=null this.dataSource=null
this.cellProcessors={} this.cellProcessors={}
this.activeCellProcessor=null this.activeCellProcessor=null
@ -24,7 +25,9 @@ if(this.options.postback&&this.options.clientDataSourceClass=='client')
this.formSubmitHandler=this.onFormSubmit.bind(this) this.formSubmitHandler=this.onFormSubmit.bind(this)
this.navigation=null this.navigation=null
this.recordsAddedOrDeleted=0 this.recordsAddedOrDeleted=0
this.init()} this.disposeBound=this.dispose.bind(this)
this.init()
$.oc.foundation.controlUtils.markDisposable(element)}
Table.prototype.init=function(){this.createDataSource() Table.prototype.init=function(){this.createDataSource()
this.initCellProcessors() this.initCellProcessors()
this.navigation=new $.oc.table.helper.navigation(this) this.navigation=new $.oc.table.helper.navigation(this)
@ -41,6 +44,7 @@ throw new Error('The table client-side data source class "'+dataSourceClass+'" i
this.dataSource=new $.oc.table.datasource[dataSourceClass](this)} this.dataSource=new $.oc.table.datasource[dataSourceClass](this)}
Table.prototype.registerHandlers=function(){this.el.addEventListener('click',this.clickHandler) Table.prototype.registerHandlers=function(){this.el.addEventListener('click',this.clickHandler)
this.el.addEventListener('keydown',this.keydownHandler) this.el.addEventListener('keydown',this.keydownHandler)
this.$el.one('dispose-control',this.disposeBound)
document.addEventListener('click',this.documentClickHandler) document.addEventListener('click',this.documentClickHandler)
if(this.options.postback&&this.options.clientDataSourceClass=='client') if(this.options.postback&&this.options.clientDataSourceClass=='client')
this.$el.closest('form').bind('oc.beforeRequest',this.formSubmitHandler) this.$el.closest('form').bind('oc.beforeRequest',this.formSubmitHandler)
@ -307,7 +311,10 @@ return
if(this.activeCellProcessor&&this.activeCellProcessor.elementBelongsToProcessor(target)) if(this.activeCellProcessor&&this.activeCellProcessor.elementBelongsToProcessor(target))
return return
this.unfocusTable()} this.unfocusTable()}
Table.prototype.dispose=function(){this.unfocusTable() Table.prototype.dispose=function(){if(this.disposed){return}
this.disposed=true
this.disposeBound=true
this.unfocusTable()
this.dataSource.dispose() this.dataSource.dispose()
this.dataSource=null this.dataSource=null
this.unregisterHandlers() this.unregisterHandlers()

View File

@ -23,6 +23,7 @@
this.$el = $(element) this.$el = $(element)
this.options = options this.options = options
this.disposed = false
// //
// State properties // State properties
@ -77,11 +78,16 @@
// Number of records added or deleted during the session // Number of records added or deleted during the session
this.recordsAddedOrDeleted = 0 this.recordsAddedOrDeleted = 0
// Bound reference to dispose() - ideally the class should use the October foundation library base class
this.disposeBound = this.dispose.bind(this)
// //
// Initialization // Initialization
// //
this.init() this.init()
$.oc.foundation.controlUtils.markDisposable(element)
} }
// INTERNAL METHODS // INTERNAL METHODS
@ -136,6 +142,8 @@
Table.prototype.registerHandlers = function() { Table.prototype.registerHandlers = function() {
this.el.addEventListener('click', this.clickHandler) this.el.addEventListener('click', this.clickHandler)
this.el.addEventListener('keydown', this.keydownHandler) this.el.addEventListener('keydown', this.keydownHandler)
this.$el.one('dispose-control', this.disposeBound)
document.addEventListener('click', this.documentClickHandler) document.addEventListener('click', this.documentClickHandler)
if (this.options.postback && this.options.clientDataSourceClass == 'client') if (this.options.postback && this.options.clientDataSourceClass == 'client')
@ -822,6 +830,16 @@
// ============================ // ============================
Table.prototype.dispose = function() { Table.prototype.dispose = function() {
if (this.disposed) {
// Prevent errors when legacy code executes the dispose() method
// directly, bypassing $.oc.foundation.controlUtils.disposeControls(container)
return
}
this.disposed = true
this.disposeBound = true
// Remove an editor and commit the data if needed // Remove an editor and commit the data if needed
this.unfocusTable() this.unfocusTable()

View File

@ -9,6 +9,8 @@
BaseProto = Base.prototype BaseProto = Base.prototype
var AutocompleteEditor = function(inspector, propertyDefinition, containerCell, group) { var AutocompleteEditor = function(inspector, propertyDefinition, containerCell, group) {
this.autoUpdateTimeout = null
Base.call(this, inspector, propertyDefinition, containerCell, group) Base.call(this, inspector, propertyDefinition, containerCell, group)
} }
@ -16,6 +18,7 @@
AutocompleteEditor.prototype.constructor = Base AutocompleteEditor.prototype.constructor = Base
AutocompleteEditor.prototype.dispose = function() { AutocompleteEditor.prototype.dispose = function() {
this.clearAutoUpdateTimeout()
this.removeAutocomplete() this.removeAutocomplete()
BaseProto.dispose.call(this) BaseProto.dispose.call(this)
@ -63,10 +66,18 @@
items = [] items = []
} }
$(input).autocomplete({ var $input = $(input),
source: this.prepareItems(items), autocomplete = $input.data('autocomplete')
matchWidth: true
}) if (!autocomplete) {
$input.autocomplete({
source: this.prepareItems(items),
matchWidth: true
})
}
else {
autocomplete.source = this.prepareItems(items)
}
} }
AutocompleteEditor.prototype.removeAutocomplete = function() { AutocompleteEditor.prototype.removeAutocomplete = function() {
@ -110,6 +121,46 @@
$(this.getInput()).off('change', this.proxy(this.onInputKeyUp)) $(this.getInput()).off('change', this.proxy(this.onInputKeyUp))
} }
AutocompleteEditor.prototype.saveDependencyValues = function() {
this.prevDependencyValues = this.getDependencyValues()
}
AutocompleteEditor.prototype.getDependencyValues = function() {
var result = ''
for (var i = 0, len = this.propertyDefinition.depends.length; i < len; i++) {
var property = this.propertyDefinition.depends[i],
value = this.inspector.getPropertyValue(property)
if (value === undefined) {
value = '';
}
result += property + ':' + value + '-'
}
return result
}
AutocompleteEditor.prototype.onInspectorPropertyChanged = function(property, value) {
if (!this.propertyDefinition.depends || this.propertyDefinition.depends.indexOf(property) === -1) {
return
}
this.clearAutoUpdateTimeout()
if (this.prevDependencyValues === undefined || this.prevDependencyValues != dependencyValues) {
this.autoUpdateTimeout = setTimeout(this.proxy(this.loadDynamicItems), 200)
}
}
AutocompleteEditor.prototype.clearAutoUpdateTimeout = function() {
if (this.autoUpdateTimeout !== null) {
clearTimeout(this.autoUpdateTimeout)
this.autoUpdateTimeout = null
}
}
// //
// Dynamic items // Dynamic items
// //
@ -132,8 +183,14 @@
} }
AutocompleteEditor.prototype.loadDynamicItems = function() { AutocompleteEditor.prototype.loadDynamicItems = function() {
if (this.isDisposed()) {
return
}
this.clearAutoUpdateTimeout()
var container = this.getContainer(), var container = this.getContainer(),
data = this.inspector.getValues(), data = this.getRootSurface().getValues(),
$form = $(container).closest('form') $form = $(container).closest('form')
$.oc.foundation.element.addClass(container, 'loading-indicator-container size-small') $.oc.foundation.element.addClass(container, 'loading-indicator-container size-small')
@ -143,7 +200,7 @@
return return
} }
data['inspectorProperty'] = this.propertyDefinition.property data['inspectorProperty'] = this.getPropertyPath()
data['inspectorClassName'] = this.inspector.options.inspectorClass data['inspectorClassName'] = this.inspector.options.inspectorClass
$form.request('onInspectableGetOptions', { $form.request('onInspectableGetOptions', {

View File

@ -81,6 +81,14 @@
BaseEditor.prototype.onInspectorPropertyChanged = function(property, value) { BaseEditor.prototype.onInspectorPropertyChanged = function(property, value) {
} }
BaseEditor.prototype.notifyChildSurfacesPropertyChanged = function(property, value) {
if (!this.hasChildSurface()) {
return
}
this.childInspector.notifyEditorsPropertyChanged(property, value)
}
BaseEditor.prototype.focus = function() { BaseEditor.prototype.focus = function() {
} }
@ -92,6 +100,10 @@
return this.inspector.getRootSurface() return this.inspector.getRootSurface()
} }
BaseEditor.prototype.getPropertyPath = function() {
return this.inspector.getPropertyPath(this.propertyDefinition.property)
}
/** /**
* Updates displayed value in the editor UI. The value is already set * Updates displayed value in the editor UI. The value is already set
* in the Inspector and should be loaded from Inspector. * in the Inspector and should be loaded from Inspector.

View File

@ -1,5 +1,5 @@
/* /*
* Inspector text editor class. * Inspector dictionary editor class.
*/ */
+function ($) { "use strict"; +function ($) { "use strict";

View File

@ -306,7 +306,7 @@
DropdownEditor.prototype.loadDynamicOptions = function(initialization) { DropdownEditor.prototype.loadDynamicOptions = function(initialization) {
var currentValue = this.inspector.getPropertyValue(this.propertyDefinition.property), var currentValue = this.inspector.getPropertyValue(this.propertyDefinition.property),
data = this.inspector.getValues(), data = this.getRootSurface().getValues(),
self = this, self = this,
$form = $(this.getSelect()).closest('form') $form = $(this.getSelect()).closest('form')
@ -323,7 +323,7 @@
this.saveDependencyValues() this.saveDependencyValues()
} }
data['inspectorProperty'] = this.propertyDefinition.property data['inspectorProperty'] = this.getPropertyPath()
data['inspectorClassName'] = this.inspector.options.inspectorClass data['inspectorClassName'] = this.inspector.options.inspectorClass
this.showLoadingIndicator() this.showLoadingIndicator()

View File

@ -164,7 +164,7 @@
$.oc.foundation.element.addClass(link, 'loading-indicator-container size-small') $.oc.foundation.element.addClass(link, 'loading-indicator-container size-small')
this.showLoadingIndicator() this.showLoadingIndicator()
data['inspectorProperty'] = this.propertyDefinition.property data['inspectorProperty'] = this.getPropertyPath()
data['inspectorClassName'] = this.inspector.options.inspectorClass data['inspectorClassName'] = this.inspector.options.inspectorClass
$form.request('onInspectableGetOptions', { $form.request('onInspectableGetOptions', {
@ -309,6 +309,10 @@
} }
SetEditor.prototype.setPropertyValue = function(checkboxValue, isChecked) { SetEditor.prototype.setPropertyValue = function(checkboxValue, isChecked) {
// In this method the Set Editor mimics the Surface.
// It acts as a parent surface for the children checkboxes,
// watching changes in them and updating the link text.
var currentValue = this.getNormalizedValue() var currentValue = this.getNormalizedValue()
if (currentValue === undefined) { if (currentValue === undefined) {
@ -319,8 +323,10 @@
currentValue = [] currentValue = []
} }
var resultValue = [] var resultValue = [],
for (var itemValue in this.propertyDefinition.items) { items = this.getItemsSource()
for (var itemValue in items) {
if (itemValue !== checkboxValue) { if (itemValue !== checkboxValue) {
if (currentValue.indexOf(itemValue) !== -1) { if (currentValue.indexOf(itemValue) !== -1) {
resultValue.push(itemValue) resultValue.push(itemValue)

View File

@ -0,0 +1,543 @@
/*
* Inspector string list with autocompletion editor class.
*
* TODO: validation is not implemented in this editor. See the Dictionary editor for reference.
*/
+function ($) { "use strict";
var Base = $.oc.inspector.propertyEditors.popupBase,
BaseProto = Base.prototype
var StringListAutocomplete = function(inspector, propertyDefinition, containerCell, group) {
this.items = null
Base.call(this, inspector, propertyDefinition, containerCell, group)
}
StringListAutocomplete.prototype = Object.create(BaseProto)
StringListAutocomplete.prototype.constructor = Base
StringListAutocomplete.prototype.dispose = function() {
BaseProto.dispose.call(this)
}
StringListAutocomplete.prototype.init = function() {
BaseProto.init.call(this)
}
StringListAutocomplete.prototype.supportsExternalParameterEditor = function() {
return false
}
StringListAutocomplete.prototype.setLinkText = function(link, value) {
var value = value !== undefined ? value
: this.inspector.getPropertyValue(this.propertyDefinition.property)
if (value === undefined) {
value = this.propertyDefinition.default
}
this.checkValueType(value)
if (!value) {
value = this.propertyDefinition.placeholder
$.oc.foundation.element.addClass(link, 'placeholder')
if (!value) {
value = '[]'
}
link.textContent = value
}
else {
$.oc.foundation.element.removeClass(link, 'placeholder')
link.textContent = '[' + value.join(', ') + ']'
}
}
StringListAutocomplete.prototype.checkValueType = function(value) {
if (value && Object.prototype.toString.call(value) !== '[object Array]') {
this.throwError('The string list value should be an array.')
}
}
//
// Popup editor methods
//
StringListAutocomplete.prototype.getPopupContent = function() {
return '<form> \
<div class="modal-header"> \
<button type="button" class="close" data-dismiss="popup">&times;</button> \
<h4 class="modal-title">{{property}}</h4> \
</div> \
<div class="modal-body"> \
<div class="control-toolbar"> \
<div class="toolbar-item"> \
<div class="btn-group"> \
<button type="button" class="btn btn-primary \
oc-icon-plus" \
data-cmd="create-item">Add</button> \
<button type="button" class="btn btn-default \
empty oc-icon-trash-o" \
data-cmd="delete-item"></button> \
</div> \
</div> \
</div> \
<div class="form-group"> \
<div class="inspector-dictionary-container"> \
<div class="values"> \
<div class="control-scrollpad" \
data-control="scrollpad"> \
<div class="scroll-wrapper"> \
<table class=" \
no-offset-bottom \
inspector-dictionary-table"> \
</table> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
<div class="modal-footer"> \
<button type="submit" class="btn btn-primary">OK</button> \
<button type="button" class="btn btn-default" data-dismiss="popup">Cancel</button> \
</div> \
</form>'
}
StringListAutocomplete.prototype.configurePopup = function(popup) {
this.initAutocomplete()
this.buildItemsTable(popup.get(0))
this.focusFirstInput()
}
StringListAutocomplete.prototype.handleSubmit = function($form) {
return this.applyValues()
}
//
// Building and row management
//
StringListAutocomplete.prototype.buildItemsTable = function(popup) {
var table = popup.querySelector('table.inspector-dictionary-table'),
tbody = document.createElement('tbody'),
items = this.inspector.getPropertyValue(this.propertyDefinition.property)
if (items === undefined) {
items = this.propertyDefinition.default
}
if (items === undefined || this.getValueKeys(items).length === 0) {
var row = this.buildEmptyRow()
tbody.appendChild(row)
}
else {
for (var key in items) {
var row = this.buildTableRow(items[key])
tbody.appendChild(row)
}
}
table.appendChild(tbody)
this.updateScrollpads()
}
StringListAutocomplete.prototype.buildTableRow = function(value) {
var row = document.createElement('tr'),
valueCell = document.createElement('td')
this.createInput(valueCell, value)
row.appendChild(valueCell)
return row
}
StringListAutocomplete.prototype.buildEmptyRow = function() {
return this.buildTableRow(null)
}
StringListAutocomplete.prototype.createInput = function(container, value) {
var input = document.createElement('input'),
controlContainer = document.createElement('div')
input.setAttribute('type', 'text')
input.setAttribute('class', 'form-control')
input.value = value
controlContainer.appendChild(input)
container.appendChild(controlContainer)
}
StringListAutocomplete.prototype.setActiveCell = function(input) {
var activeCells = this.popup.querySelectorAll('td.active')
for (var i = activeCells.length-1; i >= 0; i--) {
$.oc.foundation.element.removeClass(activeCells[i], 'active')
}
var activeCell = input.parentNode.parentNode // input / div / td
$.oc.foundation.element.addClass(activeCell, 'active')
this.buildAutoComplete(input)
}
StringListAutocomplete.prototype.createItem = function() {
var activeRow = this.getActiveRow(),
newRow = this.buildEmptyRow(),
tbody = this.getTableBody(),
nextSibling = activeRow ? activeRow.nextElementSibling : null
tbody.insertBefore(newRow, nextSibling)
this.focusAndMakeActive(newRow.querySelector('input'))
this.updateScrollpads()
}
StringListAutocomplete.prototype.deleteItem = function() {
var activeRow = this.getActiveRow(),
tbody = this.getTableBody()
if (!activeRow) {
return
}
var nextRow = activeRow.nextElementSibling,
prevRow = activeRow.previousElementSibling,
input = this.getRowInputByIndex(activeRow, 0)
if (input) {
this.removeAutocomplete(input)
}
tbody.removeChild(activeRow)
var newSelectedRow = nextRow ? nextRow : prevRow
if (!newSelectedRow) {
newSelectedRow = this.buildEmptyRow()
tbody.appendChild(newSelectedRow)
}
this.focusAndMakeActive(newSelectedRow.querySelector('input'))
this.updateScrollpads()
}
StringListAutocomplete.prototype.applyValues = function() {
var tbody = this.getTableBody(),
dataRows = tbody.querySelectorAll('tr'),
link = this.getLink(),
result = []
for (var i = 0, len = dataRows.length; i < len; i++) {
var dataRow = dataRows[i],
valueInput = this.getRowInputByIndex(dataRow, 0),
value = $.trim(valueInput.value)
if (value.length == 0) {
continue
}
result.push(value)
}
this.inspector.setPropertyValue(this.propertyDefinition.property, result)
this.setLinkText(link, result)
}
//
// Helpers
//
StringListAutocomplete.prototype.getValueKeys = function(value) {
var result = []
for (var key in value) {
result.push(key)
}
return result
}
StringListAutocomplete.prototype.getActiveRow = function() {
var activeCell = this.popup.querySelector('td.active')
if (!activeCell) {
return null
}
return activeCell.parentNode
}
StringListAutocomplete.prototype.getTableBody = function() {
return this.popup.querySelector('table.inspector-dictionary-table tbody')
}
StringListAutocomplete.prototype.updateScrollpads = function() {
$('.control-scrollpad', this.popup).scrollpad('update')
}
StringListAutocomplete.prototype.focusFirstInput = function() {
var input = this.popup.querySelector('td input')
if (input) {
input.focus()
this.setActiveCell(input)
}
}
StringListAutocomplete.prototype.getEditorCell = function(cell) {
return cell.parentNode.parentNode // cell / div / td
}
StringListAutocomplete.prototype.getEditorRow = function(cell) {
return cell.parentNode.parentNode.parentNode // cell / div / td / tr
}
StringListAutocomplete.prototype.focusAndMakeActive = function(input) {
input.focus()
this.setActiveCell(input)
}
StringListAutocomplete.prototype.getRowInputByIndex = function(row, index) {
return row.cells[index].querySelector('input')
}
//
// Navigation
//
StringListAutocomplete.prototype.navigateDown = function(ev) {
var cell = this.getEditorCell(ev.currentTarget),
row = this.getEditorRow(ev.currentTarget),
nextRow = row.nextElementSibling
if (!nextRow) {
return
}
var newActiveEditor = nextRow.cells[cell.cellIndex].querySelector('input')
this.focusAndMakeActive(newActiveEditor)
}
StringListAutocomplete.prototype.navigateUp = function(ev) {
var cell = this.getEditorCell(ev.currentTarget),
row = this.getEditorRow(ev.currentTarget),
prevRow = row.previousElementSibling
if (!prevRow) {
return
}
var newActiveEditor = prevRow.cells[cell.cellIndex].querySelector('input')
this.focusAndMakeActive(newActiveEditor)
}
//
// Autocomplete
//
StringListAutocomplete.prototype.initAutocomplete = function() {
if (this.propertyDefinition.items !== undefined) {
this.items = this.prepareItems(this.propertyDefinition.items)
this.initializeAutocompleteForCurrentInput()
}
else {
this.loadDynamicItems()
}
}
StringListAutocomplete.prototype.initializeAutocompleteForCurrentInput = function() {
var activeElement = document.activeElement
if (!activeElement) {
return
}
var inputs = this.popup.querySelectorAll('td input.form-control')
if (!inputs) {
return
}
for (var i=inputs.length-1; i>=0; i--) {
if (inputs[i] === activeElement) {
this.buildAutoComplete(inputs[i])
return
}
}
}
StringListAutocomplete.prototype.buildAutoComplete = function(input) {
if (this.items === null) {
return
}
$(input).autocomplete({
source: this.items,
matchWidth: true,
menu: '<ul class="autocomplete dropdown-menu inspector-autocomplete"></ul>',
bodyContainer: true
})
}
StringListAutocomplete.prototype.removeAutocomplete = function(input) {
var $input = $(input)
if (!$input.data('autocomplete')) {
return
}
$input.autocomplete('destroy')
}
StringListAutocomplete.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
}
StringListAutocomplete.prototype.loadDynamicItems = function() {
if (this.isDisposed()) {
return
}
var data = this.getRootSurface().getValues(),
$form = $(this.popup).find('form')
if (this.triggerGetItems(data) === false) {
return
}
data['inspectorProperty'] = this.getPropertyPath()
data['inspectorClassName'] = this.inspector.options.inspectorClass
$form.request('onInspectableGetOptions', {
data: data,
})
.done(this.proxy(this.itemsRequestDone))
}
StringListAutocomplete.prototype.triggerGetItems = function(values) {
var $inspectable = this.getInspectableElement()
if (!$inspectable) {
return true
}
var itemsEvent = $.Event('autocompleteitems.oc.inspector')
$inspectable.trigger(itemsEvent, [{
values: values,
callback: this.proxy(this.itemsRequestDone),
property: this.inspector.getPropertyPath(this.propertyDefinition.property),
propertyDefinition: this.propertyDefinition
}])
if (itemsEvent.isDefaultPrevented()) {
return false
}
return true
}
StringListAutocomplete.prototype.itemsRequestDone = function(data) {
if (this.isDisposed()) {
// Handle the case when the asynchronous request finishes after
// the editor is disposed
return
}
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.items = this.prepareItems(loadedItems)
this.initializeAutocompleteForCurrentInput()
}
StringListAutocomplete.prototype.removeAutocompleteFromAllRows = function() {
var inputs = this.popup.querySelector('td input.form-control')
for (var i=inputs.length-1; i>=0; i--) {
this.removeAutocomplete(inputs[i])
}
}
//
// Event handlers
//
StringListAutocomplete.prototype.onPopupShown = function(ev, link, popup) {
BaseProto.onPopupShown.call(this,ev, link, popup)
popup.on('focus.inspector', 'td input', this.proxy(this.onFocus))
popup.on('blur.inspector', 'td input', this.proxy(this.onBlur))
popup.on('keydown.inspector', 'td input', this.proxy(this.onKeyDown))
popup.on('click.inspector', '[data-cmd]', this.proxy(this.onCommand))
}
StringListAutocomplete.prototype.onPopupHidden = function(ev, link, popup) {
popup.off('.inspector', 'td input')
popup.off('.inspector', '[data-cmd]', this.proxy(this.onCommand))
this.removeAutocompleteFromAllRows()
this.items = null
BaseProto.onPopupHidden.call(this, ev, link, popup)
}
StringListAutocomplete.prototype.onFocus = function(ev) {
this.setActiveCell(ev.currentTarget)
}
StringListAutocomplete.prototype.onBlur = function(ev) {
this.removeAutocomplete(ev.currentTarget)
}
StringListAutocomplete.prototype.onCommand = function(ev) {
var command = ev.currentTarget.getAttribute('data-cmd')
switch (command) {
case 'create-item' :
this.createItem()
break;
case 'delete-item' :
this.deleteItem()
break;
}
}
StringListAutocomplete.prototype.onKeyDown = function(ev) {
if (ev.keyCode == 40) {
return this.navigateDown(ev)
}
else if (ev.keyCode == 38) {
return this.navigateUp(ev)
}
}
$.oc.inspector.propertyEditors.stringListAutocomplete = StringListAutocomplete
}(window.jQuery);

View File

@ -23,10 +23,11 @@
var Base = $.oc.foundation.base, var Base = $.oc.foundation.base,
BaseProto = Base.prototype BaseProto = Base.prototype
var ExternalParameterEditor = function(inspector, propertyDefinition, containerCell) { var ExternalParameterEditor = function(inspector, propertyDefinition, containerCell, initialValue) {
this.inspector = inspector this.inspector = inspector
this.propertyDefinition = propertyDefinition this.propertyDefinition = propertyDefinition
this.containerCell = containerCell this.containerCell = containerCell
this.initialValue = initialValue
Base.call(this) Base.call(this)
@ -43,6 +44,7 @@
this.inspector = null this.inspector = null
this.propertyDefinition = null this.propertyDefinition = null
this.containerCell = null this.containerCell = null
this.initialValue = null
BaseProto.dispose.call(this) BaseProto.dispose.call(this)
} }
@ -108,18 +110,16 @@
} }
ExternalParameterEditor.prototype.setInitialValue = function() { ExternalParameterEditor.prototype.setInitialValue = function() {
var propertyValue = this.inspector.getPropertyValue(this.propertyDefinition.property) if (!this.initialValue) {
if (!propertyValue) {
return return
} }
if (typeof propertyValue !== 'string') { if (typeof this.initialValue !== 'string') {
return return
} }
var matches = [] var matches = []
if (matches = propertyValue.match(/^\{\{([^\}]+)\}\}$/)) { if (matches = this.initialValue.match(/^\{\{([^\}]+)\}\}$/)) {
var value = $.trim(matches[1]) var value = $.trim(matches[1])
if (value.length > 0) { if (value.length > 0) {
@ -209,15 +209,21 @@
ExternalParameterEditor.prototype.toggleEditorVisibility = function(show) { ExternalParameterEditor.prototype.toggleEditorVisibility = function(show) {
var container = this.getContainer(), var container = this.getContainer(),
children = container.children, children = container.children,
height = 0 height = 19
// Fixed value instead of trying to get the container cell height.
// If the editor is contained in initially hidden editor (collapsed group),
// the container cell will be unknown.
if (!show) { if (!show) {
/*
height = this.containerCell.getAttribute('data-inspector-cell-height') height = this.containerCell.getAttribute('data-inspector-cell-height')
if (!height) { if (!height) {
height = $(this.containerCell).height() height = $(this.containerCell).height()
this.containerCell.setAttribute('data-inspector-cell-height', height) this.containerCell.setAttribute('data-inspector-cell-height', height)
} }
*/
} }
for (var i = 0, len = children.length; i < len; i++) { for (var i = 0, len = children.length; i < len; i++) {

View File

@ -235,6 +235,7 @@
// //
if (property.property) { if (property.property) {
row.setAttribute('data-property', property.property) row.setAttribute('data-property', property.property)
row.setAttribute('data-property-path', this.getPropertyPath(property.property))
} }
this.applyGroupIndexAttribute(property, row, group) this.applyGroupIndexAttribute(property, row, group)
@ -364,7 +365,13 @@
var cell = row.querySelector('td'), var cell = row.querySelector('td'),
propertyDefinition = this.findPropertyDefinition(property), propertyDefinition = this.findPropertyDefinition(property),
editor = new $.oc.inspector.externalParameterEditor(this, propertyDefinition, cell) initialValue = this.getPropertyValue(property)
if (initialValue === undefined) {
initialValue = propertyEditor.getUndefinedValue()
}
var editor = new $.oc.inspector.externalParameterEditor(this, propertyDefinition, cell, initialValue)
this.externalParameterEditors.push(editor) this.externalParameterEditors.push(editor)
} }
@ -536,7 +543,8 @@
this.markPropertyChanged(property, false) this.markPropertyChanged(property, false)
} }
this.notifyEditorsPropertyChanged(property, value) var propertyPath = this.getPropertyPath(property)
this.getRootSurface().notifyEditorsPropertyChanged(propertyPath, value)
if (this.options.onChange !== null) { if (this.options.onChange !== null) {
this.options.onChange(property, value) this.options.onChange(property, value)
@ -553,11 +561,19 @@
return value return value
} }
Surface.prototype.notifyEditorsPropertyChanged = function(property, value) { Surface.prototype.notifyEditorsPropertyChanged = function(propertyPath, value) {
// Editors use this event to watch changes in properties
// they depend on. All editors should be notified, including
// editors in nested surfaces. The property name is passed as a
// path object.property (if the property is nested), so that
// property depenencies could be defined as
// ['property', 'object.property']
for (var i = 0, len = this.editors.length; i < len; i++) { for (var i = 0, len = this.editors.length; i < len; i++) {
var editor = this.editors[i] var editor = this.editors[i]
editor.onInspectorPropertyChanged(property, value) editor.onInspectorPropertyChanged(propertyPath, value)
editor.notifyChildSurfacesPropertyChanged(propertyPath, value)
} }
} }
@ -573,7 +589,8 @@
} }
Surface.prototype.markPropertyChanged = function(property, changed) { Surface.prototype.markPropertyChanged = function(property, changed) {
var row = this.tableContainer.querySelector('tr[data-property="'+property+'"]') var propertyPath = this.getPropertyPath(property),
row = this.tableContainer.querySelector('tr[data-property-path="'+propertyPath+'"]')
if (changed) { if (changed) {
$.oc.foundation.element.addClass(row, 'changed') $.oc.foundation.element.addClass(row, 'changed')

View File

@ -22,6 +22,18 @@
// Inspector // Inspector
// -------------------------------------------------- // --------------------------------------------------
.inspector-autocomplete-list() {
background: white;
font-size: 12px;
z-index: 100000; // It's safe to set z-index any high value for drop-downs
li a {
padding: 5px 12px;
white-space: normal;
word-wrap: break-word;
}
}
.inspector-fields { .inspector-fields {
min-width: 220px; min-width: 220px;
border-collapse: collapse; border-collapse: collapse;
@ -131,13 +143,7 @@
} }
ul.dropdown-menu { ul.dropdown-menu {
background: white; .inspector-autocomplete-list();
font-size: 12px;
li a {
padding: 5px 12px;
white-space: normal;
}
} }
.loading-indicator { .loading-indicator {
@ -579,7 +585,8 @@ div.inspector-dictionary-container {
} }
} }
span { span, a {
text-decoration: none;
position: absolute; position: absolute;
top: 12px; top: 12px;
float: none; float: none;
@ -619,6 +626,10 @@ div.inspector-dictionary-container {
} }
} }
ul.autocomplete.dropdown-menu.inspector-autocomplete {
.inspector-autocomplete-list();
}
.select2-dropdown { .select2-dropdown {
&.ocInspectorDropdown { &.ocInspectorDropdown {
font-size: 12px; font-size: 12px;

View File

@ -181,6 +181,7 @@ div.control-popover {
float: none; float: none;
color: #ffffff; color: #ffffff;
cursor: pointer; cursor: pointer;
text-decoration: none;
&:hover { &:hover {
.opacity(1); .opacity(1);

View File

@ -3416,7 +3416,8 @@ if(!this.parentSurface){this.focusFirstEditor()}}
Surface.prototype.moveToContainer=function(newContainer){this.container=newContainer Surface.prototype.moveToContainer=function(newContainer){this.container=newContainer
this.container.appendChild(this.tableContainer)} this.container.appendChild(this.tableContainer)}
Surface.prototype.buildRow=function(property,group){var row=document.createElement('tr'),th=document.createElement('th'),titleSpan=document.createElement('span'),description=this.buildPropertyDescription(property) Surface.prototype.buildRow=function(property,group){var row=document.createElement('tr'),th=document.createElement('th'),titleSpan=document.createElement('span'),description=this.buildPropertyDescription(property)
if(property.property){row.setAttribute('data-property',property.property)} if(property.property){row.setAttribute('data-property',property.property)
row.setAttribute('data-property-path',this.getPropertyPath(property.property))}
this.applyGroupIndexAttribute(property,row,group) this.applyGroupIndexAttribute(property,row,group)
$.oc.foundation.element.addClass(row,this.getRowCssClass(property,group)) $.oc.foundation.element.addClass(row,this.getRowCssClass(property,group))
this.applyHeadColspan(th,property) this.applyHeadColspan(th,property)
@ -3462,7 +3463,9 @@ for(var i=0,len=rows.length;i<len;i++){var row=rows[i],property=row.getAttribute
if($.oc.foundation.element.hasClass(row,'no-external-parameter')||!property){continue} if($.oc.foundation.element.hasClass(row,'no-external-parameter')||!property){continue}
var propertyEditor=this.findPropertyEditor(property) var propertyEditor=this.findPropertyEditor(property)
if(propertyEditor&&!propertyEditor.supportsExternalParameterEditor()){continue} if(propertyEditor&&!propertyEditor.supportsExternalParameterEditor()){continue}
var cell=row.querySelector('td'),propertyDefinition=this.findPropertyDefinition(property),editor=new $.oc.inspector.externalParameterEditor(this,propertyDefinition,cell) var cell=row.querySelector('td'),propertyDefinition=this.findPropertyDefinition(property),initialValue=this.getPropertyValue(property)
if(initialValue===undefined){initialValue=propertyEditor.getUndefinedValue()}
var editor=new $.oc.inspector.externalParameterEditor(this,propertyDefinition,cell,initialValue)
this.externalParameterEditors.push(editor)}} this.externalParameterEditors.push(editor)}}
Surface.prototype.applyGroupIndexAttribute=function(property,row,group,isGroupedControl){if(property.itemType=='group'||isGroupedControl){row.setAttribute('data-group-index',this.getGroupManager().getGroupIndex(group)) Surface.prototype.applyGroupIndexAttribute=function(property,row,group,isGroupedControl){if(property.itemType=='group'||isGroupedControl){row.setAttribute('data-group-index',this.getGroupManager().getGroupIndex(group))
row.setAttribute('data-parent-group-index',this.getGroupManager().getGroupIndex(group.parentGroup))} row.setAttribute('data-parent-group-index',this.getGroupManager().getGroupIndex(group.parentGroup))}
@ -3510,17 +3513,19 @@ Surface.prototype.setPropertyValue=function(property,value,supressChangeEvents,f
else{if(this.values[property]!==undefined){delete this.values[property]}} else{if(this.values[property]!==undefined){delete this.values[property]}}
if(!supressChangeEvents){if(this.originalValues[property]===undefined||!this.comparePropertyValues(this.originalValues[property],value)){this.markPropertyChanged(property,true)} if(!supressChangeEvents){if(this.originalValues[property]===undefined||!this.comparePropertyValues(this.originalValues[property],value)){this.markPropertyChanged(property,true)}
else{this.markPropertyChanged(property,false)} else{this.markPropertyChanged(property,false)}
this.notifyEditorsPropertyChanged(property,value) var propertyPath=this.getPropertyPath(property)
this.getRootSurface().notifyEditorsPropertyChanged(propertyPath,value)
if(this.options.onChange!==null){this.options.onChange(property,value)}} if(this.options.onChange!==null){this.options.onChange(property,value)}}
if(forceEditorUpdate){var editor=this.findPropertyEditor(property) if(forceEditorUpdate){var editor=this.findPropertyEditor(property)
if(editor){editor.updateDisplayedValue(value)}} if(editor){editor.updateDisplayedValue(value)}}
return value} return value}
Surface.prototype.notifyEditorsPropertyChanged=function(property,value){for(var i=0,len=this.editors.length;i<len;i++){var editor=this.editors[i] Surface.prototype.notifyEditorsPropertyChanged=function(propertyPath,value){for(var i=0,len=this.editors.length;i<len;i++){var editor=this.editors[i]
editor.onInspectorPropertyChanged(property,value)}} editor.onInspectorPropertyChanged(propertyPath,value)
editor.notifyChildSurfacesPropertyChanged(propertyPath,value)}}
Surface.prototype.makeCellActive=function(cell){var tbody=cell.parentNode.parentNode.parentNode,cells=tbody.querySelectorAll('tr td') Surface.prototype.makeCellActive=function(cell){var tbody=cell.parentNode.parentNode.parentNode,cells=tbody.querySelectorAll('tr td')
for(var i=0,len=cells.length;i<len;i++){$.oc.foundation.element.removeClass(cells[i],'active')} for(var i=0,len=cells.length;i<len;i++){$.oc.foundation.element.removeClass(cells[i],'active')}
$.oc.foundation.element.addClass(cell,'active')} $.oc.foundation.element.addClass(cell,'active')}
Surface.prototype.markPropertyChanged=function(property,changed){var row=this.tableContainer.querySelector('tr[data-property="'+property+'"]') Surface.prototype.markPropertyChanged=function(property,changed){var propertyPath=this.getPropertyPath(property),row=this.tableContainer.querySelector('tr[data-property-path="'+propertyPath+'"]')
if(changed){$.oc.foundation.element.addClass(row,'changed')} if(changed){$.oc.foundation.element.addClass(row,'changed')}
else{$.oc.foundation.element.removeClass(row,'changed')}} else{$.oc.foundation.element.removeClass(row,'changed')}}
Surface.prototype.findPropertyEditor=function(property){for(var i=0,len=this.editors.length;i<len;i++){if(this.editors[i].getPropertyName()==property){return this.editors[i]}} Surface.prototype.findPropertyEditor=function(property){for(var i=0,len=this.editors.length;i<len;i++){if(this.editors[i].getPropertyName()==property){return this.editors[i]}}
@ -4085,9 +4090,12 @@ BaseEditor.prototype.build=function(){return null}
BaseEditor.prototype.isDisposed=function(){return this.disposed} BaseEditor.prototype.isDisposed=function(){return this.disposed}
BaseEditor.prototype.registerHandlers=function(){} BaseEditor.prototype.registerHandlers=function(){}
BaseEditor.prototype.onInspectorPropertyChanged=function(property,value){} BaseEditor.prototype.onInspectorPropertyChanged=function(property,value){}
BaseEditor.prototype.notifyChildSurfacesPropertyChanged=function(property,value){if(!this.hasChildSurface()){return}
this.childInspector.notifyEditorsPropertyChanged(property,value)}
BaseEditor.prototype.focus=function(){} BaseEditor.prototype.focus=function(){}
BaseEditor.prototype.hasChildSurface=function(){return this.childInspector!==null} BaseEditor.prototype.hasChildSurface=function(){return this.childInspector!==null}
BaseEditor.prototype.getRootSurface=function(){return this.inspector.getRootSurface()} BaseEditor.prototype.getRootSurface=function(){return this.inspector.getRootSurface()}
BaseEditor.prototype.getPropertyPath=function(){return this.inspector.getPropertyPath(this.propertyDefinition.property)}
BaseEditor.prototype.updateDisplayedValue=function(value){} BaseEditor.prototype.updateDisplayedValue=function(value){}
BaseEditor.prototype.getPropertyName=function(){return this.propertyDefinition.property} BaseEditor.prototype.getPropertyName=function(){return this.propertyDefinition.property}
BaseEditor.prototype.getUndefinedValue=function(){return this.propertyDefinition.default===undefined?undefined:this.propertyDefinition.default} BaseEditor.prototype.getUndefinedValue=function(){return this.propertyDefinition.default===undefined?undefined:this.propertyDefinition.default}
@ -4260,12 +4268,12 @@ this.createPlaceholder(select)
this.createOptions(select,this.propertyDefinition.options) this.createOptions(select,this.propertyDefinition.options)
if(value===undefined){value=this.propertyDefinition.default} if(value===undefined){value=this.propertyDefinition.default}
select.value=value} select.value=value}
DropdownEditor.prototype.loadDynamicOptions=function(initialization){var currentValue=this.inspector.getPropertyValue(this.propertyDefinition.property),data=this.inspector.getValues(),self=this,$form=$(this.getSelect()).closest('form') DropdownEditor.prototype.loadDynamicOptions=function(initialization){var currentValue=this.inspector.getPropertyValue(this.propertyDefinition.property),data=this.getRootSurface().getValues(),self=this,$form=$(this.getSelect()).closest('form')
if(currentValue===undefined){currentValue=this.propertyDefinition.default} if(currentValue===undefined){currentValue=this.propertyDefinition.default}
var callback=function dropdownOptionsRequestDoneClosure(data){self.hideLoadingIndicator() var callback=function dropdownOptionsRequestDoneClosure(data){self.hideLoadingIndicator()
self.optionsRequestDone(data,currentValue,true)} self.optionsRequestDone(data,currentValue,true)}
if(this.propertyDefinition.depends){this.saveDependencyValues()} if(this.propertyDefinition.depends){this.saveDependencyValues()}
data['inspectorProperty']=this.propertyDefinition.property data['inspectorProperty']=this.getPropertyPath()
data['inspectorClassName']=this.inspector.options.inspectorClass data['inspectorClassName']=this.inspector.options.inspectorClass
this.showLoadingIndicator() this.showLoadingIndicator()
if(this.triggerGetOptions(data,callback)===false){return} if(this.triggerGetOptions(data,callback)===false){return}
@ -4445,7 +4453,7 @@ $link.loadIndicator('destroy')}
SetEditor.prototype.loadDynamicItems=function(){var link=this.getLink(),data=this.inspector.getValues(),$form=$(link).closest('form') SetEditor.prototype.loadDynamicItems=function(){var link=this.getLink(),data=this.inspector.getValues(),$form=$(link).closest('form')
$.oc.foundation.element.addClass(link,'loading-indicator-container size-small') $.oc.foundation.element.addClass(link,'loading-indicator-container size-small')
this.showLoadingIndicator() this.showLoadingIndicator()
data['inspectorProperty']=this.propertyDefinition.property data['inspectorProperty']=this.getPropertyPath()
data['inspectorClassName']=this.inspector.options.inspectorClass data['inspectorClassName']=this.inspector.options.inspectorClass
$form.request('onInspectableGetOptions',{data:data,}).done(this.proxy(this.itemsRequestDone)).always(this.proxy(this.hideLoadingIndicator))} $form.request('onInspectableGetOptions',{data:data,}).done(this.proxy(this.itemsRequestDone)).always(this.proxy(this.hideLoadingIndicator))}
SetEditor.prototype.itemsRequestDone=function(data,currentValue,initialization){if(this.isDisposed()){return} SetEditor.prototype.itemsRequestDone=function(data,currentValue,initialization){if(this.isDisposed()){return}
@ -4479,8 +4487,8 @@ return value.indexOf(checkboxValue)>-1}
SetEditor.prototype.setPropertyValue=function(checkboxValue,isChecked){var currentValue=this.getNormalizedValue() SetEditor.prototype.setPropertyValue=function(checkboxValue,isChecked){var currentValue=this.getNormalizedValue()
if(currentValue===undefined){currentValue=this.propertyDefinition.default} if(currentValue===undefined){currentValue=this.propertyDefinition.default}
if(!currentValue){currentValue=[]} if(!currentValue){currentValue=[]}
var resultValue=[] var resultValue=[],items=this.getItemsSource()
for(var itemValue in this.propertyDefinition.items){if(itemValue!==checkboxValue){if(currentValue.indexOf(itemValue)!==-1){resultValue.push(itemValue)}} for(var itemValue in items){if(itemValue!==checkboxValue){if(currentValue.indexOf(itemValue)!==-1){resultValue.push(itemValue)}}
else{if(isChecked){resultValue.push(itemValue)}}} else{if(isChecked){resultValue.push(itemValue)}}}
this.inspector.setPropertyValue(this.propertyDefinition.property,this.cleanUpValue(resultValue)) this.inspector.setPropertyValue(this.propertyDefinition.property,this.cleanUpValue(resultValue))
this.setLinkText(this.getLink())} this.setLinkText(this.getLink())}
@ -4806,6 +4814,190 @@ for(var i=0,len=arrayValue.length;i<len;i++){var currentValue=$.trim(arrayValue[
if(currentValue.length>0){resultValue.push(currentValue)}}} if(currentValue.length>0){resultValue.push(currentValue)}}}
this.inspector.setPropertyValue(this.propertyDefinition.property,resultValue)} this.inspector.setPropertyValue(this.propertyDefinition.property,resultValue)}
$.oc.inspector.propertyEditors.stringList=StringListEditor}(window.jQuery);+function($){"use strict";var Base=$.oc.inspector.propertyEditors.popupBase,BaseProto=Base.prototype $.oc.inspector.propertyEditors.stringList=StringListEditor}(window.jQuery);+function($){"use strict";var Base=$.oc.inspector.propertyEditors.popupBase,BaseProto=Base.prototype
var StringListAutocomplete=function(inspector,propertyDefinition,containerCell,group){this.items=null
Base.call(this,inspector,propertyDefinition,containerCell,group)}
StringListAutocomplete.prototype=Object.create(BaseProto)
StringListAutocomplete.prototype.constructor=Base
StringListAutocomplete.prototype.dispose=function(){BaseProto.dispose.call(this)}
StringListAutocomplete.prototype.init=function(){BaseProto.init.call(this)}
StringListAutocomplete.prototype.supportsExternalParameterEditor=function(){return false}
StringListAutocomplete.prototype.setLinkText=function(link,value){var value=value!==undefined?value:this.inspector.getPropertyValue(this.propertyDefinition.property)
if(value===undefined){value=this.propertyDefinition.default}
this.checkValueType(value)
if(!value){value=this.propertyDefinition.placeholder
$.oc.foundation.element.addClass(link,'placeholder')
if(!value){value='[]'}
link.textContent=value}
else{$.oc.foundation.element.removeClass(link,'placeholder')
link.textContent='['+value.join(', ')+']'}}
StringListAutocomplete.prototype.checkValueType=function(value){if(value&&Object.prototype.toString.call(value)!=='[object Array]'){this.throwError('The string list value should be an array.')}}
StringListAutocomplete.prototype.getPopupContent=function(){return'<form> \
<div class="modal-header"> \
<button type="button" class="close" data-dismiss="popup">&times;</button> \
<h4 class="modal-title">{{property}}</h4> \
</div> \
<div class="modal-body"> \
<div class="control-toolbar"> \
<div class="toolbar-item"> \
<div class="btn-group"> \
<button type="button" class="btn btn-primary \
oc-icon-plus" \
data-cmd="create-item">Add</button> \
<button type="button" class="btn btn-default \
empty oc-icon-trash-o" \
data-cmd="delete-item"></button> \
</div> \
</div> \
</div> \
<div class="form-group"> \
<div class="inspector-dictionary-container"> \
<div class="values"> \
<div class="control-scrollpad" \
data-control="scrollpad"> \
<div class="scroll-wrapper"> \
<table class=" \
no-offset-bottom \
inspector-dictionary-table"> \
</table> \
</div> \
</div> \
</div> \
</div> \
</div> \
</div> \
<div class="modal-footer"> \
<button type="submit" class="btn btn-primary">OK</button> \
<button type="button" class="btn btn-default" data-dismiss="popup">Cancel</button> \
</div> \
</form>'}
StringListAutocomplete.prototype.configurePopup=function(popup){this.initAutocomplete()
this.buildItemsTable(popup.get(0))
this.focusFirstInput()}
StringListAutocomplete.prototype.handleSubmit=function($form){return this.applyValues()}
StringListAutocomplete.prototype.buildItemsTable=function(popup){var table=popup.querySelector('table.inspector-dictionary-table'),tbody=document.createElement('tbody'),items=this.inspector.getPropertyValue(this.propertyDefinition.property)
if(items===undefined){items=this.propertyDefinition.default}
if(items===undefined||this.getValueKeys(items).length===0){var row=this.buildEmptyRow()
tbody.appendChild(row)}
else{for(var key in items){var row=this.buildTableRow(items[key])
tbody.appendChild(row)}}
table.appendChild(tbody)
this.updateScrollpads()}
StringListAutocomplete.prototype.buildTableRow=function(value){var row=document.createElement('tr'),valueCell=document.createElement('td')
this.createInput(valueCell,value)
row.appendChild(valueCell)
return row}
StringListAutocomplete.prototype.buildEmptyRow=function(){return this.buildTableRow(null)}
StringListAutocomplete.prototype.createInput=function(container,value){var input=document.createElement('input'),controlContainer=document.createElement('div')
input.setAttribute('type','text')
input.setAttribute('class','form-control')
input.value=value
controlContainer.appendChild(input)
container.appendChild(controlContainer)}
StringListAutocomplete.prototype.setActiveCell=function(input){var activeCells=this.popup.querySelectorAll('td.active')
for(var i=activeCells.length-1;i>=0;i--){$.oc.foundation.element.removeClass(activeCells[i],'active')}
var activeCell=input.parentNode.parentNode
$.oc.foundation.element.addClass(activeCell,'active')
this.buildAutoComplete(input)}
StringListAutocomplete.prototype.createItem=function(){var activeRow=this.getActiveRow(),newRow=this.buildEmptyRow(),tbody=this.getTableBody(),nextSibling=activeRow?activeRow.nextElementSibling:null
tbody.insertBefore(newRow,nextSibling)
this.focusAndMakeActive(newRow.querySelector('input'))
this.updateScrollpads()}
StringListAutocomplete.prototype.deleteItem=function(){var activeRow=this.getActiveRow(),tbody=this.getTableBody()
if(!activeRow){return}
var nextRow=activeRow.nextElementSibling,prevRow=activeRow.previousElementSibling,input=this.getRowInputByIndex(activeRow,0)
if(input){this.removeAutocomplete(input)}
tbody.removeChild(activeRow)
var newSelectedRow=nextRow?nextRow:prevRow
if(!newSelectedRow){newSelectedRow=this.buildEmptyRow()
tbody.appendChild(newSelectedRow)}
this.focusAndMakeActive(newSelectedRow.querySelector('input'))
this.updateScrollpads()}
StringListAutocomplete.prototype.applyValues=function(){var tbody=this.getTableBody(),dataRows=tbody.querySelectorAll('tr'),link=this.getLink(),result=[]
for(var i=0,len=dataRows.length;i<len;i++){var dataRow=dataRows[i],valueInput=this.getRowInputByIndex(dataRow,0),value=$.trim(valueInput.value)
if(value.length==0){continue}
result.push(value)}
this.inspector.setPropertyValue(this.propertyDefinition.property,result)
this.setLinkText(link,result)}
StringListAutocomplete.prototype.getValueKeys=function(value){var result=[]
for(var key in value){result.push(key)}
return result}
StringListAutocomplete.prototype.getActiveRow=function(){var activeCell=this.popup.querySelector('td.active')
if(!activeCell){return null}
return activeCell.parentNode}
StringListAutocomplete.prototype.getTableBody=function(){return this.popup.querySelector('table.inspector-dictionary-table tbody')}
StringListAutocomplete.prototype.updateScrollpads=function(){$('.control-scrollpad',this.popup).scrollpad('update')}
StringListAutocomplete.prototype.focusFirstInput=function(){var input=this.popup.querySelector('td input')
if(input){input.focus()
this.setActiveCell(input)}}
StringListAutocomplete.prototype.getEditorCell=function(cell){return cell.parentNode.parentNode}
StringListAutocomplete.prototype.getEditorRow=function(cell){return cell.parentNode.parentNode.parentNode}
StringListAutocomplete.prototype.focusAndMakeActive=function(input){input.focus()
this.setActiveCell(input)}
StringListAutocomplete.prototype.getRowInputByIndex=function(row,index){return row.cells[index].querySelector('input')}
StringListAutocomplete.prototype.navigateDown=function(ev){var cell=this.getEditorCell(ev.currentTarget),row=this.getEditorRow(ev.currentTarget),nextRow=row.nextElementSibling
if(!nextRow){return}
var newActiveEditor=nextRow.cells[cell.cellIndex].querySelector('input')
this.focusAndMakeActive(newActiveEditor)}
StringListAutocomplete.prototype.navigateUp=function(ev){var cell=this.getEditorCell(ev.currentTarget),row=this.getEditorRow(ev.currentTarget),prevRow=row.previousElementSibling
if(!prevRow){return}
var newActiveEditor=prevRow.cells[cell.cellIndex].querySelector('input')
this.focusAndMakeActive(newActiveEditor)}
StringListAutocomplete.prototype.initAutocomplete=function(){if(this.propertyDefinition.items!==undefined){this.items=this.prepareItems(this.propertyDefinition.items)
this.initializeAutocompleteForCurrentInput()}
else{this.loadDynamicItems()}}
StringListAutocomplete.prototype.initializeAutocompleteForCurrentInput=function(){var activeElement=document.activeElement
if(!activeElement){return}
var inputs=this.popup.querySelectorAll('td input.form-control')
if(!inputs){return}
for(var i=inputs.length-1;i>=0;i--){if(inputs[i]===activeElement){this.buildAutoComplete(inputs[i])
return}}}
StringListAutocomplete.prototype.buildAutoComplete=function(input){if(this.items===null){return}
$(input).autocomplete({source:this.items,matchWidth:true,menu:'<ul class="autocomplete dropdown-menu inspector-autocomplete"></ul>',bodyContainer:true})}
StringListAutocomplete.prototype.removeAutocomplete=function(input){var $input=$(input)
if(!$input.data('autocomplete')){return}
$input.autocomplete('destroy')}
StringListAutocomplete.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}
StringListAutocomplete.prototype.loadDynamicItems=function(){if(this.isDisposed()){return}
var data=this.getRootSurface().getValues(),$form=$(this.popup).find('form')
if(this.triggerGetItems(data)===false){return}
data['inspectorProperty']=this.getPropertyPath()
data['inspectorClassName']=this.inspector.options.inspectorClass
$form.request('onInspectableGetOptions',{data:data,}).done(this.proxy(this.itemsRequestDone))}
StringListAutocomplete.prototype.triggerGetItems=function(values){var $inspectable=this.getInspectableElement()
if(!$inspectable){return true}
var itemsEvent=$.Event('autocompleteitems.oc.inspector')
$inspectable.trigger(itemsEvent,[{values:values,callback:this.proxy(this.itemsRequestDone),property:this.inspector.getPropertyPath(this.propertyDefinition.property),propertyDefinition:this.propertyDefinition}])
if(itemsEvent.isDefaultPrevented()){return false}
return true}
StringListAutocomplete.prototype.itemsRequestDone=function(data){if(this.isDisposed()){return}
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.items=this.prepareItems(loadedItems)
this.initializeAutocompleteForCurrentInput()}
StringListAutocomplete.prototype.removeAutocompleteFromAllRows=function(){var inputs=this.popup.querySelector('td input.form-control')
for(var i=inputs.length-1;i>=0;i--){this.removeAutocomplete(inputs[i])}}
StringListAutocomplete.prototype.onPopupShown=function(ev,link,popup){BaseProto.onPopupShown.call(this,ev,link,popup)
popup.on('focus.inspector','td input',this.proxy(this.onFocus))
popup.on('blur.inspector','td input',this.proxy(this.onBlur))
popup.on('keydown.inspector','td input',this.proxy(this.onKeyDown))
popup.on('click.inspector','[data-cmd]',this.proxy(this.onCommand))}
StringListAutocomplete.prototype.onPopupHidden=function(ev,link,popup){popup.off('.inspector','td input')
popup.off('.inspector','[data-cmd]',this.proxy(this.onCommand))
this.removeAutocompleteFromAllRows()
this.items=null
BaseProto.onPopupHidden.call(this,ev,link,popup)}
StringListAutocomplete.prototype.onFocus=function(ev){this.setActiveCell(ev.currentTarget)}
StringListAutocomplete.prototype.onBlur=function(ev){this.removeAutocomplete(ev.currentTarget)}
StringListAutocomplete.prototype.onCommand=function(ev){var command=ev.currentTarget.getAttribute('data-cmd')
switch(command){case'create-item':this.createItem()
break;case'delete-item':this.deleteItem()
break;}}
StringListAutocomplete.prototype.onKeyDown=function(ev){if(ev.keyCode==40){return this.navigateDown(ev)}
else if(ev.keyCode==38){return this.navigateUp(ev)}}
$.oc.inspector.propertyEditors.stringListAutocomplete=StringListAutocomplete}(window.jQuery);+function($){"use strict";var Base=$.oc.inspector.propertyEditors.popupBase,BaseProto=Base.prototype
var DictionaryEditor=function(inspector,propertyDefinition,containerCell,group){this.keyValidationSet=null var DictionaryEditor=function(inspector,propertyDefinition,containerCell,group){this.keyValidationSet=null
this.valueValidationSet=null this.valueValidationSet=null
Base.call(this,inspector,propertyDefinition,containerCell,group)} Base.call(this,inspector,propertyDefinition,containerCell,group)}
@ -4980,10 +5172,12 @@ break;}}
DictionaryEditor.prototype.onKeyDown=function(ev){if(ev.keyCode==40){return this.navigateDown(ev)} DictionaryEditor.prototype.onKeyDown=function(ev){if(ev.keyCode==40){return this.navigateDown(ev)}
else if(ev.keyCode==38){return this.navigateUp(ev)}} else if(ev.keyCode==38){return this.navigateUp(ev)}}
$.oc.inspector.propertyEditors.dictionary=DictionaryEditor}(window.jQuery);+function($){"use strict";var Base=$.oc.inspector.propertyEditors.string,BaseProto=Base.prototype $.oc.inspector.propertyEditors.dictionary=DictionaryEditor}(window.jQuery);+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)} var AutocompleteEditor=function(inspector,propertyDefinition,containerCell,group){this.autoUpdateTimeout=null
Base.call(this,inspector,propertyDefinition,containerCell,group)}
AutocompleteEditor.prototype=Object.create(BaseProto) AutocompleteEditor.prototype=Object.create(BaseProto)
AutocompleteEditor.prototype.constructor=Base AutocompleteEditor.prototype.constructor=Base
AutocompleteEditor.prototype.dispose=function(){this.removeAutocomplete() AutocompleteEditor.prototype.dispose=function(){this.clearAutoUpdateTimeout()
this.removeAutocomplete()
BaseProto.dispose.call(this)} 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) 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('type','text')
@ -5000,7 +5194,9 @@ if(this.propertyDefinition.items!==undefined){this.buildAutoComplete(this.proper
else{this.loadDynamicItems()}} else{this.loadDynamicItems()}}
AutocompleteEditor.prototype.buildAutoComplete=function(items){var input=this.getInput() AutocompleteEditor.prototype.buildAutoComplete=function(items){var input=this.getInput()
if(items===undefined){items=[]} if(items===undefined){items=[]}
$(input).autocomplete({source:this.prepareItems(items),matchWidth:true})} var $input=$(input),autocomplete=$input.data('autocomplete')
if(!autocomplete){$input.autocomplete({source:this.prepareItems(items),matchWidth:true})}
else{autocomplete.source=this.prepareItems(items)}}
AutocompleteEditor.prototype.removeAutocomplete=function(){var input=this.getInput() AutocompleteEditor.prototype.removeAutocomplete=function(){var input=this.getInput()
$(input).autocomplete('destroy')} $(input).autocomplete('destroy')}
AutocompleteEditor.prototype.prepareItems=function(items){var result={} AutocompleteEditor.prototype.prepareItems=function(items){var result={}
@ -5013,17 +5209,30 @@ AutocompleteEditor.prototype.registerHandlers=function(){BaseProto.registerHandl
$(this.getInput()).on('change',this.proxy(this.onInputKeyUp))} $(this.getInput()).on('change',this.proxy(this.onInputKeyUp))}
AutocompleteEditor.prototype.unregisterHandlers=function(){BaseProto.unregisterHandlers.call(this) AutocompleteEditor.prototype.unregisterHandlers=function(){BaseProto.unregisterHandlers.call(this)
$(this.getInput()).off('change',this.proxy(this.onInputKeyUp))} $(this.getInput()).off('change',this.proxy(this.onInputKeyUp))}
AutocompleteEditor.prototype.saveDependencyValues=function(){this.prevDependencyValues=this.getDependencyValues()}
AutocompleteEditor.prototype.getDependencyValues=function(){var result=''
for(var i=0,len=this.propertyDefinition.depends.length;i<len;i++){var property=this.propertyDefinition.depends[i],value=this.inspector.getPropertyValue(property)
if(value===undefined){value='';}
result+=property+':'+value+'-'}
return result}
AutocompleteEditor.prototype.onInspectorPropertyChanged=function(property,value){if(!this.propertyDefinition.depends||this.propertyDefinition.depends.indexOf(property)===-1){return}
this.clearAutoUpdateTimeout()
if(this.prevDependencyValues===undefined||this.prevDependencyValues!=dependencyValues){this.autoUpdateTimeout=setTimeout(this.proxy(this.loadDynamicItems),200)}}
AutocompleteEditor.prototype.clearAutoUpdateTimeout=function(){if(this.autoUpdateTimeout!==null){clearTimeout(this.autoUpdateTimeout)
this.autoUpdateTimeout=null}}
AutocompleteEditor.prototype.showLoadingIndicator=function(){$(this.getContainer()).loadIndicator()} AutocompleteEditor.prototype.showLoadingIndicator=function(){$(this.getContainer()).loadIndicator()}
AutocompleteEditor.prototype.hideLoadingIndicator=function(){if(this.isDisposed()){return} AutocompleteEditor.prototype.hideLoadingIndicator=function(){if(this.isDisposed()){return}
var $container=$(this.getContainer()) var $container=$(this.getContainer())
$container.loadIndicator('hide') $container.loadIndicator('hide')
$container.loadIndicator('destroy') $container.loadIndicator('destroy')
$container.removeClass('loading-indicator-container')} $container.removeClass('loading-indicator-container')}
AutocompleteEditor.prototype.loadDynamicItems=function(){var container=this.getContainer(),data=this.inspector.getValues(),$form=$(container).closest('form') AutocompleteEditor.prototype.loadDynamicItems=function(){if(this.isDisposed()){return}
this.clearAutoUpdateTimeout()
var container=this.getContainer(),data=this.getRootSurface().getValues(),$form=$(container).closest('form')
$.oc.foundation.element.addClass(container,'loading-indicator-container size-small') $.oc.foundation.element.addClass(container,'loading-indicator-container size-small')
this.showLoadingIndicator() this.showLoadingIndicator()
if(this.triggerGetItems(data)===false){return} if(this.triggerGetItems(data)===false){return}
data['inspectorProperty']=this.propertyDefinition.property data['inspectorProperty']=this.getPropertyPath()
data['inspectorClassName']=this.inspector.options.inspectorClass data['inspectorClassName']=this.inspector.options.inspectorClass
$form.request('onInspectableGetOptions',{data:data,}).done(this.proxy(this.itemsRequestDone)).always(this.proxy(this.hideLoadingIndicator))} $form.request('onInspectableGetOptions',{data:data,}).done(this.proxy(this.itemsRequestDone)).always(this.proxy(this.hideLoadingIndicator))}
AutocompleteEditor.prototype.triggerGetItems=function(values){var $inspectable=this.getInspectableElement() AutocompleteEditor.prototype.triggerGetItems=function(values){var $inspectable=this.getInspectableElement()
@ -5163,9 +5372,10 @@ $.oc={}
if($.oc.inspector===undefined) if($.oc.inspector===undefined)
$.oc.inspector={} $.oc.inspector={}
var Base=$.oc.foundation.base,BaseProto=Base.prototype var Base=$.oc.foundation.base,BaseProto=Base.prototype
var ExternalParameterEditor=function(inspector,propertyDefinition,containerCell){this.inspector=inspector var ExternalParameterEditor=function(inspector,propertyDefinition,containerCell,initialValue){this.inspector=inspector
this.propertyDefinition=propertyDefinition this.propertyDefinition=propertyDefinition
this.containerCell=containerCell this.containerCell=containerCell
this.initialValue=initialValue
Base.call(this) Base.call(this)
this.init()} this.init()}
ExternalParameterEditor.prototype=Object.create(BaseProto) ExternalParameterEditor.prototype=Object.create(BaseProto)
@ -5175,6 +5385,7 @@ this.unregisterHandlers()
this.inspector=null this.inspector=null
this.propertyDefinition=null this.propertyDefinition=null
this.containerCell=null this.containerCell=null
this.initialValue=null
BaseProto.dispose.call(this)} BaseProto.dispose.call(this)}
ExternalParameterEditor.prototype.init=function(){this.tooltipText='Click to enter the external parameter name to load the property value from' ExternalParameterEditor.prototype.init=function(){this.tooltipText='Click to enter the external parameter name to load the property value from'
this.build() this.build()
@ -5200,11 +5411,10 @@ while(this.containerCell.firstChild){var child=this.containerCell.firstChild
container.appendChild(child)} container.appendChild(child)}
container.appendChild(editor) container.appendChild(editor)
this.containerCell.appendChild(container)} this.containerCell.appendChild(container)}
ExternalParameterEditor.prototype.setInitialValue=function(){var propertyValue=this.inspector.getPropertyValue(this.propertyDefinition.property) ExternalParameterEditor.prototype.setInitialValue=function(){if(!this.initialValue){return}
if(!propertyValue){return} if(typeof this.initialValue!=='string'){return}
if(typeof propertyValue!=='string'){return}
var matches=[] var matches=[]
if(matches=propertyValue.match(/^\{\{([^\}]+)\}\}$/)){var value=$.trim(matches[1]) if(matches=this.initialValue.match(/^\{\{([^\}]+)\}\}$/)){var value=$.trim(matches[1])
if(value.length>0){this.showEditor(true) if(value.length>0){this.showEditor(true)
this.getInput().value=value this.getInput().value=value
this.inspector.setPropertyValue(this.propertyDefinition.property,null,true,true)}}} this.inspector.setPropertyValue(this.propertyDefinition.property,null,true,true)}}}
@ -5239,10 +5449,8 @@ link.setAttribute('data-original-title',this.tooltipText)
this.getInput().setAttribute('tabindex','-1') this.getInput().setAttribute('tabindex','-1')
this.toggleEditorVisibility(true) this.toggleEditorVisibility(true)
setTimeout(this.proxy(this.hideEditor),200)} setTimeout(this.proxy(this.hideEditor),200)}
ExternalParameterEditor.prototype.toggleEditorVisibility=function(show){var container=this.getContainer(),children=container.children,height=0 ExternalParameterEditor.prototype.toggleEditorVisibility=function(show){var container=this.getContainer(),children=container.children,height=19
if(!show){height=this.containerCell.getAttribute('data-inspector-cell-height') if(!show){}
if(!height){height=$(this.containerCell).height()
this.containerCell.setAttribute('data-inspector-cell-height',height)}}
for(var i=0,len=children.length;i<len;i++){var element=children[i] for(var i=0,len=children.length;i<len;i++){var element=children[i]
if($.oc.foundation.element.hasClass(element,'external-editor')){continue} if($.oc.foundation.element.hasClass(element,'external-editor')){continue}
if(show){$.oc.foundation.element.removeClass(element,'hide')} if(show){$.oc.foundation.element.removeClass(element,'hide')}

View File

@ -1211,7 +1211,7 @@ div.control-popover .popover-head p{font-size:13px;font-weight:100;margin:10px 0
div.control-popover .popover-head p:empty{display:none} div.control-popover .popover-head p:empty{display:none}
div.control-popover .popover-head .close{float:none;position:absolute;right:11px;top:12px;color:#ffffff;outline:none;opacity:0.4;filter:alpha(opacity=40)} div.control-popover .popover-head .close{float:none;position:absolute;right:11px;top:12px;color:#ffffff;outline:none;opacity:0.4;filter:alpha(opacity=40)}
div.control-popover .popover-head .close:hover{opacity:1;filter:alpha(opacity=100)} div.control-popover .popover-head .close:hover{opacity:1;filter:alpha(opacity=100)}
div.control-popover .popover-head .inspector-move-to-container{opacity:0.4;filter:alpha(opacity=40);position:absolute;top:12px;right:26px;float:none;color:#ffffff;cursor:pointer} div.control-popover .popover-head .inspector-move-to-container{opacity:0.4;filter:alpha(opacity=40);position:absolute;top:12px;right:26px;float:none;color:#ffffff;cursor:pointer;text-decoration:none}
div.control-popover .popover-head .inspector-move-to-container:hover{opacity:1;filter:alpha(opacity=100);color:#ffffff} div.control-popover .popover-head .inspector-move-to-container:hover{opacity:1;filter:alpha(opacity=100);color:#ffffff}
div.control-popover .popover-head .inspector-move-to-container:before{-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)} div.control-popover .popover-head .inspector-move-to-container:before{-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}
div.control-popover.placement-bottom .popover-head:before{content:'';display:block;width:0;height:0;border-left:7.5px solid transparent;border-right:7.5px solid transparent;border-bottom:8px solid #d35400;left:15px;top:-8px} div.control-popover.placement-bottom .popover-head:before{content:'';display:block;width:0;height:0;border-left:7.5px solid transparent;border-right:7.5px solid transparent;border-bottom:8px solid #d35400;left:15px;top:-8px}
@ -2460,8 +2460,8 @@ table.table.data tr.list-tree-level-10 td.list-cell-index-1{padding-left:125px}
.inspector-fields td.text.active{background:#ffffff;border-left:1px solid #c8cccd} .inspector-fields td.text.active{background:#ffffff;border-left:1px solid #c8cccd}
.inspector-fields td.autocomplete{padding:0} .inspector-fields td.autocomplete{padding:0}
.inspector-fields td.autocomplete .autocomplete-container input[type=text]{padding:5px 12px} .inspector-fields td.autocomplete .autocomplete-container input[type=text]{padding:5px 12px}
.inspector-fields td.autocomplete .autocomplete-container ul.dropdown-menu{background:white;font-size:12px} .inspector-fields td.autocomplete .autocomplete-container ul.dropdown-menu{background:white;font-size:12px;z-index:100000}
.inspector-fields td.autocomplete .autocomplete-container ul.dropdown-menu li a{padding:5px 12px;white-space:normal} .inspector-fields td.autocomplete .autocomplete-container ul.dropdown-menu li a{padding:5px 12px;white-space:normal;word-wrap:break-word}
.inspector-fields td.autocomplete .autocomplete-container .loading-indicator span{margin-top:-12px;right:10px;left:auto} .inspector-fields td.autocomplete .autocomplete-container .loading-indicator span{margin-top:-12px;right:10px;left:auto}
.inspector-fields td.trigger-cell{padding:0 !important} .inspector-fields td.trigger-cell{padding:0 !important}
.inspector-fields td.trigger-cell a.trigger{display:block;padding:5px 12px 7px 12px;overflow:hidden;min-height:29px;text-overflow:ellipsis;color:#333333;text-decoration:none} .inspector-fields td.trigger-cell a.trigger{display:block;padding:5px 12px 7px 12px;overflow:hidden;min-height:29px;text-overflow:ellipsis;color:#333333;text-decoration:none}
@ -2531,13 +2531,15 @@ div.inspector-dictionary-container table.inspector-dictionary-table tbody tr:las
.inspector-header h3{font-size:14px;font-weight:600;margin-top:0;margin-bottom:0;padding-right:15px;line-height:130%} .inspector-header h3{font-size:14px;font-weight:600;margin-top:0;margin-bottom:0;padding-right:15px;line-height:130%}
.inspector-header p{font-size:13px;font-weight:100;margin:10px 0 0 0} .inspector-header p{font-size:13px;font-weight:100;margin:10px 0 0 0}
.inspector-header p:empty{display:none} .inspector-header p:empty{display:none}
.inspector-header span{position:absolute;top:12px;float:none;color:#ffffff;cursor:pointer;opacity:0.4;filter:alpha(opacity=40)} .inspector-header span,.inspector-header a{text-decoration:none;position:absolute;top:12px;float:none;color:#ffffff;cursor:pointer;opacity:0.4;filter:alpha(opacity=40)}
.inspector-header span:hover{opacity:1;filter:alpha(opacity=100);color:#ffffff} .inspector-header span:hover,.inspector-header a:hover{opacity:1;filter:alpha(opacity=100);color:#ffffff}
.inspector-header .detach{right:26px} .inspector-header .detach{right:26px}
.inspector-header .close{right:11px;font-size:21px} .inspector-header .close{right:11px;font-size:21px}
.inspector-container:empty{display:none} .inspector-container:empty{display:none}
.inspector-container .control-scrollpad{position:absolute} .inspector-container .control-scrollpad{position:absolute}
.inspector-field-comment:empty{display:none} .inspector-field-comment:empty{display:none}
ul.autocomplete.dropdown-menu.inspector-autocomplete{background:white;font-size:12px;z-index:100000}
ul.autocomplete.dropdown-menu.inspector-autocomplete li a{padding:5px 12px;white-space:normal;word-wrap:break-word}
.select2-dropdown.ocInspectorDropdown{font-size:12px;-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important;border:none !important} .select2-dropdown.ocInspectorDropdown{font-size:12px;-webkit-border-radius:0 !important;-moz-border-radius:0 !important;border-radius:0 !important;border:none !important}
.select2-dropdown.ocInspectorDropdown > .select2-results > .select2-results__options{font-size:12px} .select2-dropdown.ocInspectorDropdown > .select2-results > .select2-results__options{font-size:12px}
.select2-dropdown.ocInspectorDropdown > .select2-results > li > div{padding:5px 12px 5px} .select2-dropdown.ocInspectorDropdown > .select2-results > li > div{padding:5px 12px 5px}

View File

@ -68,6 +68,7 @@
=require js/inspector.editor.objectlist.js =require js/inspector.editor.objectlist.js
=require js/inspector.editor.object.js =require js/inspector.editor.object.js
=require js/inspector.editor.stringlist.js =require js/inspector.editor.stringlist.js
=require js/inspector.editor.stringlistautocomplete.js
=require js/inspector.editor.dictionary.js =require js/inspector.editor.dictionary.js
=require js/inspector.editor.autocomplete.js =require js/inspector.editor.autocomplete.js
=require js/inspector.helpers.js =require js/inspector.helpers.js