373 lines
10 KiB
JavaScript
373 lines
10 KiB
JavaScript
/*
|
|
* Inspector set editor class.
|
|
*
|
|
* This class uses $.oc.inspector.propertyEditors.checkbox editor.
|
|
*/
|
|
+function ($) { "use strict";
|
|
|
|
var Base = $.oc.inspector.propertyEditors.base,
|
|
BaseProto = Base.prototype
|
|
|
|
var SetEditor = function(inspector, propertyDefinition, containerCell, group) {
|
|
this.editors = []
|
|
this.loadedItems = null
|
|
|
|
Base.call(this, inspector, propertyDefinition, containerCell, group)
|
|
}
|
|
|
|
SetEditor.prototype = Object.create(BaseProto)
|
|
SetEditor.prototype.constructor = Base
|
|
|
|
SetEditor.prototype.init = function() {
|
|
this.initControlGroup()
|
|
|
|
BaseProto.init.call(this)
|
|
}
|
|
|
|
SetEditor.prototype.dispose = function() {
|
|
this.disposeEditors()
|
|
this.disposeControls()
|
|
|
|
this.editors = null
|
|
|
|
BaseProto.dispose.call(this)
|
|
}
|
|
|
|
//
|
|
// Building
|
|
//
|
|
|
|
SetEditor.prototype.build = function() {
|
|
var link = document.createElement('a')
|
|
|
|
$.oc.foundation.element.addClass(link, 'trigger')
|
|
link.setAttribute('href', '#')
|
|
this.setLinkText(link)
|
|
|
|
$.oc.foundation.element.addClass(this.containerCell, 'trigger-cell')
|
|
|
|
this.containerCell.appendChild(link)
|
|
|
|
if (this.propertyDefinition.items !== undefined) {
|
|
this.loadStaticItems()
|
|
}
|
|
else {
|
|
this.loadDynamicItems()
|
|
}
|
|
}
|
|
|
|
SetEditor.prototype.loadStaticItems = function() {
|
|
var itemArray = []
|
|
|
|
for (var itemValue in this.propertyDefinition.items) {
|
|
itemArray.push({
|
|
value: itemValue,
|
|
title: this.propertyDefinition.items[itemValue]
|
|
})
|
|
}
|
|
|
|
for (var i = itemArray.length-1; i >=0; i--) {
|
|
this.buildItemEditor(itemArray[i].value, itemArray[i].title)
|
|
}
|
|
}
|
|
|
|
SetEditor.prototype.setLinkText = function(link, value) {
|
|
var value = (value !== undefined && value !== null) ? value
|
|
: this.getNormalizedValue(),
|
|
text = '[ ]'
|
|
|
|
if (value === undefined) {
|
|
value = this.propertyDefinition.default
|
|
}
|
|
|
|
if (value !== undefined && value.length !== undefined && value.length > 0 && typeof value !== 'string') {
|
|
var textValues = []
|
|
for (var i = 0, len = value.length; i < len; i++) {
|
|
textValues.push(this.valueToText(value[i]))
|
|
}
|
|
|
|
text = '[' + textValues.join(', ') + ']'
|
|
$.oc.foundation.element.removeClass(link, 'placeholder')
|
|
}
|
|
else {
|
|
text = this.propertyDefinition.placeholder
|
|
|
|
if ((typeof text === 'string' && text.length == 0) || text === undefined) {
|
|
text = '[ ]'
|
|
}
|
|
$.oc.foundation.element.addClass(link, 'placeholder')
|
|
}
|
|
|
|
link.textContent = text
|
|
}
|
|
|
|
SetEditor.prototype.buildItemEditor = function(value, text) {
|
|
var property = {
|
|
title: text,
|
|
itemType: 'property',
|
|
groupIndex: this.group.getGroupIndex()
|
|
},
|
|
newRow = this.createGroupedRow(property),
|
|
currentRow = this.containerCell.parentNode,
|
|
tbody = this.containerCell.parentNode.parentNode, // row / tbody
|
|
cell = document.createElement('td')
|
|
|
|
this.buildCheckbox(cell, value, text)
|
|
|
|
newRow.appendChild(cell)
|
|
tbody.insertBefore(newRow, currentRow.nextSibling)
|
|
}
|
|
|
|
SetEditor.prototype.buildCheckbox = function(cell, value, title) {
|
|
var property = {
|
|
property: value,
|
|
title: title,
|
|
default: this.isCheckedByDefault(value)
|
|
},
|
|
editor = new $.oc.inspector.propertyEditors.checkbox(this, property, cell, this.group)
|
|
|
|
this.editors.push[editor]
|
|
}
|
|
|
|
SetEditor.prototype.isCheckedByDefault = function(value) {
|
|
if (!this.propertyDefinition.default) {
|
|
return false
|
|
}
|
|
|
|
return this.propertyDefinition.default.indexOf(value) > -1
|
|
}
|
|
|
|
//
|
|
// Dynamic items
|
|
//
|
|
|
|
SetEditor.prototype.showLoadingIndicator = function() {
|
|
$(this.getLink()).loadIndicator()
|
|
}
|
|
|
|
SetEditor.prototype.hideLoadingIndicator = function() {
|
|
if (this.isDisposed()) {
|
|
return
|
|
}
|
|
|
|
var $link = $(this.getLink())
|
|
|
|
$link.loadIndicator('hide')
|
|
$link.loadIndicator('destroy')
|
|
}
|
|
|
|
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')
|
|
this.showLoadingIndicator()
|
|
|
|
data['inspectorProperty'] = this.getPropertyPath()
|
|
data['inspectorClassName'] = this.inspector.options.inspectorClass
|
|
|
|
$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()) {
|
|
// Handle the case when the asynchronous request finishes after
|
|
// the editor is disposed
|
|
return
|
|
}
|
|
|
|
this.loadedItems = {}
|
|
|
|
if (data.options) {
|
|
for (var i = data.options.length-1; i >= 0; i--) {
|
|
this.buildItemEditor(data.options[i].value, data.options[i].title)
|
|
|
|
this.loadedItems[data.options[i].value] = data.options[i].title
|
|
}
|
|
}
|
|
|
|
this.setLinkText(this.getLink())
|
|
}
|
|
|
|
//
|
|
// Helpers
|
|
//
|
|
|
|
SetEditor.prototype.getLink = function() {
|
|
return this.containerCell.querySelector('a.trigger')
|
|
}
|
|
|
|
SetEditor.prototype.getItemsSource = function() {
|
|
if (this.propertyDefinition.items !== undefined) {
|
|
return this.propertyDefinition.items
|
|
}
|
|
|
|
return this.loadedItems
|
|
}
|
|
|
|
SetEditor.prototype.valueToText = function(value) {
|
|
var source = this.getItemsSource()
|
|
|
|
if (!source) {
|
|
return value
|
|
}
|
|
|
|
for (var itemValue in source) {
|
|
if (itemValue == value) {
|
|
return source[itemValue]
|
|
}
|
|
}
|
|
|
|
return value
|
|
}
|
|
|
|
/*
|
|
* Removes items that don't exist in the defined items from
|
|
* the value.
|
|
*/
|
|
SetEditor.prototype.cleanUpValue = function(value) {
|
|
if (!value) {
|
|
return value
|
|
}
|
|
|
|
var result = [],
|
|
source = this.getItemsSource()
|
|
|
|
for (var i = 0, len = value.length; i < len; i++) {
|
|
var currentValue = value[i]
|
|
|
|
if (source[currentValue] !== undefined) {
|
|
result.push(currentValue)
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
SetEditor.prototype.getNormalizedValue = function() {
|
|
var value = this.inspector.getPropertyValue(this.propertyDefinition.property)
|
|
|
|
if (value === null) {
|
|
value = undefined
|
|
}
|
|
|
|
if (value === undefined) {
|
|
return value
|
|
}
|
|
|
|
if (value.length === undefined || typeof value === 'string') {
|
|
return undefined
|
|
}
|
|
|
|
return value
|
|
}
|
|
|
|
//
|
|
// Editor API methods
|
|
//
|
|
|
|
SetEditor.prototype.supportsExternalParameterEditor = function() {
|
|
return false
|
|
}
|
|
|
|
SetEditor.prototype.isGroupedEditor = function() {
|
|
return true
|
|
}
|
|
|
|
//
|
|
// Inspector API methods
|
|
//
|
|
// This editor creates checkbox editor and acts as a container Inspector
|
|
// for them. The methods in this section emulate and proxy some functionality
|
|
// of the Inspector.
|
|
//
|
|
|
|
SetEditor.prototype.getPropertyValue = function(checkboxValue) {
|
|
// When a checkbox requests the property value, we return
|
|
// TRUE if the checkbox value is listed in the current values of
|
|
// the set.
|
|
// For example, the available set items are [create, update], the
|
|
// current set value is [create] and checkboxValue is "create".
|
|
// The result of the method will be TRUE.
|
|
|
|
var value = this.getNormalizedValue()
|
|
|
|
if (value === undefined) {
|
|
return this.isCheckedByDefault(checkboxValue)
|
|
}
|
|
|
|
if (!value) {
|
|
return false
|
|
}
|
|
|
|
return value.indexOf(checkboxValue) > -1
|
|
}
|
|
|
|
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()
|
|
|
|
if (currentValue === undefined) {
|
|
currentValue = this.propertyDefinition.default
|
|
}
|
|
|
|
if (!currentValue) {
|
|
currentValue = []
|
|
}
|
|
|
|
var resultValue = [],
|
|
items = this.getItemsSource()
|
|
|
|
for (var itemValue in items) {
|
|
if (itemValue !== checkboxValue) {
|
|
if (currentValue.indexOf(itemValue) !== -1) {
|
|
resultValue.push(itemValue)
|
|
}
|
|
}
|
|
else {
|
|
if (isChecked) {
|
|
resultValue.push(itemValue)
|
|
}
|
|
}
|
|
}
|
|
|
|
this.inspector.setPropertyValue(this.propertyDefinition.property, this.cleanUpValue(resultValue))
|
|
this.setLinkText(this.getLink())
|
|
}
|
|
|
|
SetEditor.prototype.generateSequencedId = function() {
|
|
return this.inspector.generateSequencedId()
|
|
}
|
|
|
|
//
|
|
// Disposing
|
|
//
|
|
|
|
SetEditor.prototype.disposeEditors = function() {
|
|
for (var i = 0, len = this.editors.length; i < len; i++) {
|
|
var editor = this.editors[i]
|
|
|
|
editor.dispose()
|
|
}
|
|
}
|
|
|
|
SetEditor.prototype.disposeControls = function() {
|
|
var link = this.getLink()
|
|
|
|
if (this.propertyDefinition.items === undefined) {
|
|
$(link).loadIndicator('destroy')
|
|
}
|
|
|
|
link.parentNode.removeChild(link)
|
|
}
|
|
|
|
$.oc.inspector.propertyEditors.set = SetEditor
|
|
}(window.jQuery); |