Added support for components in partials
This commit is contained in:
parent
a9eecfecd5
commit
9a05a408c9
|
|
@ -13618,6 +13618,71 @@ html.cssanimations .fancy-layout .form-tabless-fields .loading-indicator-contain
|
||||||
.inspector-fields td select {
|
.inspector-fields td select {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
.inspector-fields td div.external-param-editor-container {
|
||||||
|
position: relative;
|
||||||
|
padding-right: 30px;
|
||||||
|
}
|
||||||
|
.inspector-fields td div.external-param-editor-container div.external-editor {
|
||||||
|
bottom: 0;
|
||||||
|
margin: -5px -12px;
|
||||||
|
right: 30px;
|
||||||
|
left: auto;
|
||||||
|
top: 0;
|
||||||
|
position: absolute;
|
||||||
|
-webkit-transition: left 0.2s;
|
||||||
|
transition: left 0.2s;
|
||||||
|
-webkit-transform: translateZ(0);
|
||||||
|
-ms-transform: translateZ(0);
|
||||||
|
transform: translateZ(0);
|
||||||
|
will-change: transform;
|
||||||
|
}
|
||||||
|
.inspector-fields td div.external-param-editor-container div.external-editor div.controls {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
.inspector-fields td div.external-param-editor-container div.external-editor div.controls a {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
|
width: 30px;
|
||||||
|
color: #2b3e50;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.inspector-fields td div.external-param-editor-container div.external-editor div.controls a i {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
left: 10px;
|
||||||
|
top: 4px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
.inspector-fields td div.external-param-editor-container div.external-editor div.controls input {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-right: 12px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
.inspector-fields td div.external-param-editor-container.editor-visible div.external-editor div.controls input {
|
||||||
|
background: #f2f2f2;
|
||||||
|
}
|
||||||
|
.inspector-fields td.active div.external-param-editor-container div.external-editor div.controls input {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
.inspector-fields td.dropdown div.external-param-editor-container div.external-editor {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
bottom: auto;
|
||||||
|
}
|
||||||
.inspector-fields th {
|
.inspector-fields th {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@
|
||||||
* - placeholder - placholder text, for text and dropdown properties
|
* - placeholder - placholder text, for text and dropdown properties
|
||||||
* - depends - a list of properties the property depend on, for dropdown lists
|
* - depends - a list of properties the property depend on, for dropdown lists
|
||||||
* - options - an option list for dropdown lists, optional. If not provided the options are loaded with AJAX.
|
* - options - an option list for dropdown lists, optional. If not provided the options are loaded with AJAX.
|
||||||
|
* - noExternalParameter - disables the external parameter feature for the property.
|
||||||
* Example of the configuration string (a single property):
|
* Example of the configuration string (a single property):
|
||||||
* [{"property":"max-width","title":"Max width","type":"string"}]
|
* [{"property":"max-width","title":"Max width","type":"string"}]
|
||||||
*
|
*
|
||||||
|
|
@ -36,6 +37,10 @@
|
||||||
* The inspector uses this field to read and write field values. The field value is a JSON string, an object with keys matching property
|
* The inspector uses this field to read and write field values. The field value is a JSON string, an object with keys matching property
|
||||||
* names and values matching property values.
|
* names and values matching property values.
|
||||||
*
|
*
|
||||||
|
* Any HTML element that wraps the inspectable element can have the data-inspector-external-parameters property that enables the external
|
||||||
|
* parameters support. External parameters saved with the special syntax {{paramName}}. The external parameter feature can be disabled
|
||||||
|
* on per-property basis with the noExternalParameter option.
|
||||||
|
*
|
||||||
* Events
|
* Events
|
||||||
* - change - the event is triggered on the inspectable element when it's properties are updated.
|
* - change - the event is triggered on the inspectable element when it's properties are updated.
|
||||||
* - showing.oc.inspector - triggered before the Inspector is displayed. Allows to cancel the action with e.preventDefault()
|
* - showing.oc.inspector - triggered before the Inspector is displayed. Allows to cancel the action with e.preventDefault()
|
||||||
|
|
@ -96,10 +101,10 @@
|
||||||
data-dismiss="popover" \
|
data-dismiss="popover" \
|
||||||
aria-hidden="true">×</button> \
|
aria-hidden="true">×</button> \
|
||||||
</div> \
|
</div> \
|
||||||
<form> \
|
<form autocomplete="off"> \
|
||||||
<table class="inspector-fields {{#tableClass}}{{/tableClass}}"> \
|
<table class="inspector-fields {{#tableClass}}{{/tableClass}}"> \
|
||||||
{{#properties}} \
|
{{#properties}} \
|
||||||
<tr id="{{#propFormat}}{{property}}{{/propFormat}}" \
|
<tr id="{{#propFormat}}{{property}}{{/propFormat}}" data-property="{{property}}" \
|
||||||
{{#dataGroupIndex}}{{/dataGroupIndex}} \
|
{{#dataGroupIndex}}{{/dataGroupIndex}} \
|
||||||
class="{{#cellClass}}{{/cellClass}}"> \
|
class="{{#cellClass}}{{/cellClass}}"> \
|
||||||
<th {{#colspan}}{{/colspan}}><div><div><span class="title-element" title="{{title}}"> \
|
<th {{#colspan}}{{/colspan}}><div><div><span class="title-element" title="{{title}}"> \
|
||||||
|
|
@ -156,6 +161,9 @@
|
||||||
if (this.itemType == 'property' && this.groupIndex !== undefined)
|
if (this.itemType == 'property' && this.groupIndex !== undefined)
|
||||||
result += self.groupExpanded(this.group) ? ' expanded' : ' collapsed'
|
result += self.groupExpanded(this.group) ? ' expanded' : ' collapsed'
|
||||||
|
|
||||||
|
if (this.itemType == 'property' && this.noExternalParameter)
|
||||||
|
result += ' no-external-parameter'
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -211,7 +219,7 @@
|
||||||
width: 400
|
width: 400
|
||||||
})
|
})
|
||||||
|
|
||||||
self.$el.on('hiding.oc.popover', function(e){self.onBeforeHide(e)})
|
self.$el.on('hiding.oc.popover', function(e){return self.onBeforeHide(e)})
|
||||||
self.$el.on('hide.oc.popover', function(){self.cleanup()})
|
self.$el.on('hide.oc.popover', function(){self.cleanup()})
|
||||||
self.$el.addClass('inspector-open')
|
self.$el.addClass('inspector-open')
|
||||||
|
|
||||||
|
|
@ -225,12 +233,15 @@
|
||||||
self.editors[0].focus()
|
self.editors[0].focus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (self.$el.closest('[data-inspector-external-parameters]').length > 0)
|
||||||
|
self.initExternalParameterEditor(self.$el.data('oc.popover').$container)
|
||||||
|
|
||||||
$.each(self.editors, function(){
|
$.each(self.editors, function(){
|
||||||
if (this.init !== undefined)
|
if (this.init !== undefined)
|
||||||
this.init()
|
this.init()
|
||||||
})
|
})
|
||||||
|
|
||||||
$('[data-toggle=tooltip]', self.$el.data('oc.popover').$container).tooltip({placement: 'auto right', container: 'body'})
|
$('[data-toggle=tooltip]', self.$el.data('oc.popover').$container).tooltip({placement: 'auto right', container: 'body', delay: 500})
|
||||||
|
|
||||||
var $container = self.$el.data('oc.popover').$container
|
var $container = self.$el.data('oc.popover').$container
|
||||||
$container.on('click', 'tr.group', function(){
|
$container.on('click', 'tr.group', function(){
|
||||||
|
|
@ -248,6 +259,145 @@
|
||||||
displayPopover()
|
displayPopover()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initializes the external parameter editors for properties that support this feature.
|
||||||
|
*/
|
||||||
|
Inspector.prototype.initExternalParameterEditor = function($container) {
|
||||||
|
var self = this
|
||||||
|
|
||||||
|
$('table.inspector-fields tr', $container).each(function(){
|
||||||
|
if (!$(this).hasClass('no-external-parameter')) {
|
||||||
|
var property = $(this).data('property'),
|
||||||
|
$td = $('td', this),
|
||||||
|
$editorContainer = $('<div class="external-param-editor-container"></div>'),
|
||||||
|
$editor = $(
|
||||||
|
'<div class="external-editor"> \
|
||||||
|
<div class="controls"> \
|
||||||
|
<input type="text" tabindex="-1"/> \
|
||||||
|
<a href="#" tabindex="-1"> \
|
||||||
|
<i class="oc-icon-terminal"></i> \
|
||||||
|
</a> \
|
||||||
|
</div> \
|
||||||
|
</div>')
|
||||||
|
|
||||||
|
$editorContainer.append($td.children())
|
||||||
|
$editorContainer.append($editor)
|
||||||
|
$td.append($editorContainer)
|
||||||
|
|
||||||
|
var $editorLink = $('a', $editor)
|
||||||
|
|
||||||
|
$editorLink.click(function() {
|
||||||
|
return self.toggleExternalParameterEditor($(this))
|
||||||
|
})
|
||||||
|
.attr('title', 'Click to enter the external parameter name to load the property value from')
|
||||||
|
.tooltip({'container': 'body', delay: 500})
|
||||||
|
|
||||||
|
var $input = $editor.find('input'),
|
||||||
|
propertyValue = self.propertyValues[property]
|
||||||
|
|
||||||
|
$input.on('focus', function(){
|
||||||
|
var $field = $(this)
|
||||||
|
|
||||||
|
$('td', $field.closest('table')).removeClass('active')
|
||||||
|
$field.closest('td').addClass('active')
|
||||||
|
})
|
||||||
|
|
||||||
|
$input.on('change', function(){
|
||||||
|
self.markPropertyChanged(property, true)
|
||||||
|
})
|
||||||
|
|
||||||
|
var matches = []
|
||||||
|
if (matches = propertyValue.match(/^\{\{([^\}]+)\}\}$/)) {
|
||||||
|
var value = $.trim(matches[1])
|
||||||
|
|
||||||
|
if (value.length > 0) {
|
||||||
|
self.showExternalParameterEditor($editorContainer, $editor, $editorLink, $td, true)
|
||||||
|
$editor.find('input').val(value)
|
||||||
|
self.writeProperty(property, null, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
Inspector.prototype.showExternalParameterEditor = function($container, $editor, $editorLink, $cell, noAnimation) {
|
||||||
|
var position = $editor.position()
|
||||||
|
$('input', $editor).focus()
|
||||||
|
|
||||||
|
if (!noAnimation) {
|
||||||
|
$editor.css({
|
||||||
|
'left': position.left + 'px',
|
||||||
|
'right': 0
|
||||||
|
})
|
||||||
|
} else
|
||||||
|
$editor.css('right', 0)
|
||||||
|
|
||||||
|
setTimeout(function(){
|
||||||
|
$editor.css('left', 0)
|
||||||
|
$cell.scrollTop(0)
|
||||||
|
}, 0)
|
||||||
|
|
||||||
|
$container.addClass('editor-visible')
|
||||||
|
$editorLink.attr('data-original-title', 'Click to enter the property value')
|
||||||
|
this.toggleCellEditorVisibility($cell, false)
|
||||||
|
$editor.find('input').attr('tabindex', 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
Inspector.prototype.toggleExternalParameterEditor = function($editorLink) {
|
||||||
|
var $container = $editorLink.closest('.external-param-editor-container'),
|
||||||
|
$editor = $('.external-editor', $container),
|
||||||
|
$cell = $editorLink.closest('td'),
|
||||||
|
self = this
|
||||||
|
|
||||||
|
$editorLink.tooltip('hide')
|
||||||
|
|
||||||
|
if (!$container.hasClass('editor-visible')) {
|
||||||
|
self.showExternalParameterEditor($container, $editor, $editorLink, $cell)
|
||||||
|
} else {
|
||||||
|
var left = $container.width()
|
||||||
|
|
||||||
|
$editor.css('left', left + 'px')
|
||||||
|
setTimeout(function(){
|
||||||
|
$editor.css({
|
||||||
|
'left': 'auto',
|
||||||
|
'right': '30px'
|
||||||
|
})
|
||||||
|
$container.removeClass('editor-visible')
|
||||||
|
$container.closest('td').removeClass('active')
|
||||||
|
}, 200)
|
||||||
|
$editorLink.attr('data-original-title', 'Click to enter the external parameter name to load the property value from')
|
||||||
|
$editor.find('input').attr('tabindex', -1)
|
||||||
|
self.toggleCellEditorVisibility($cell, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
Inspector.prototype.toggleCellEditorVisibility = function($cell, show) {
|
||||||
|
var $container = $('.external-param-editor-container', $cell)
|
||||||
|
|
||||||
|
$container.children().each(function(){
|
||||||
|
var $el = $(this)
|
||||||
|
|
||||||
|
if ($el.hasClass('external-editor'))
|
||||||
|
return
|
||||||
|
|
||||||
|
if (show)
|
||||||
|
$el.removeClass('hide')
|
||||||
|
else {
|
||||||
|
var height = $cell.data('inspector-cell-height')
|
||||||
|
|
||||||
|
if (!height) {
|
||||||
|
height = $cell.height()
|
||||||
|
$cell.data('inspector-cell-height', height)
|
||||||
|
}
|
||||||
|
|
||||||
|
$container.css('height', height + 'px')
|
||||||
|
$el.addClass('hide')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Creates group nodes in the property set
|
* Creates group nodes in the property set
|
||||||
*/
|
*/
|
||||||
|
|
@ -379,17 +529,22 @@
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
Inspector.prototype.writeProperty = function(property, value) {
|
Inspector.prototype.writeProperty = function(property, value, noChangedStatusUpdate) {
|
||||||
this.propertyValues[property] = value
|
this.propertyValues[property] = value
|
||||||
this.propertyValuesField.val(JSON.stringify(this.propertyValues))
|
this.propertyValuesField.val(JSON.stringify(this.propertyValues))
|
||||||
|
|
||||||
if (this.originalPropertyValues[property] === undefined || this.originalPropertyValues[property] != value) {
|
if (this.originalPropertyValues[property] === undefined || this.originalPropertyValues[property] != value) {
|
||||||
this.$el.trigger('change')
|
if (!noChangedStatusUpdate) {
|
||||||
this.markPropertyChanged(property, true)
|
this.$el.trigger('change')
|
||||||
} else
|
this.markPropertyChanged(property, true)
|
||||||
this.markPropertyChanged(property, false)
|
}
|
||||||
|
} else {
|
||||||
|
if (!noChangedStatusUpdate)
|
||||||
|
this.markPropertyChanged(property, false)
|
||||||
|
}
|
||||||
|
|
||||||
this.$el.trigger('propertyChanged.oc.Inspector', [property])
|
if (!noChangedStatusUpdate)
|
||||||
|
this.$el.trigger('propertyChanged.oc.Inspector', [property])
|
||||||
|
|
||||||
return value
|
return value
|
||||||
}
|
}
|
||||||
|
|
@ -412,6 +567,7 @@
|
||||||
|
|
||||||
var editor = new $.oc.inspector.editors[editorClass](editorId, this, data)
|
var editor = new $.oc.inspector.editors[editorClass](editorId, this, data)
|
||||||
this.editors.push(editor)
|
this.editors.push(editor)
|
||||||
|
editor.inspectorCellId = editorId
|
||||||
|
|
||||||
return editor.renderEditor()
|
return editor.renderEditor()
|
||||||
}
|
}
|
||||||
|
|
@ -429,11 +585,40 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
Inspector.prototype.onBeforeHide = function(e) {
|
Inspector.prototype.onBeforeHide = function(e) {
|
||||||
|
var $container = this.$el.data('inspector-container'),
|
||||||
|
externalParamErrorFound = false,
|
||||||
|
self = this
|
||||||
|
|
||||||
$.each(this.editors, function() {
|
$.each(this.editors, function() {
|
||||||
this.applyValue()
|
if (!self.editorExternalPropertyEnabled(this))
|
||||||
|
this.applyValue()
|
||||||
|
else {
|
||||||
|
var $cell = $('#'+this.inspectorCellId, $container),
|
||||||
|
$extPropEditorContainer = $cell.find('.external-param-editor-container'),
|
||||||
|
$input = $extPropEditorContainer.find('.external-editor input'),
|
||||||
|
val = $.trim($input.val())
|
||||||
|
|
||||||
|
if (val.length == 0) {
|
||||||
|
alert('Please enter external parameter name for the '+this.fieldDef.title+' property.')
|
||||||
|
externalParamErrorFound = true
|
||||||
|
setTimeout(function(){
|
||||||
|
$input.focus()
|
||||||
|
}, 0)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
self.writeProperty(this.fieldDef.property, '{{ '+val+' }}')
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
var eH = $.Event('hiding.oc.inspector')
|
if (externalParamErrorFound) {
|
||||||
|
e.preventDefault()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
var eH = $.Event('hiding.oc.inspector'),
|
||||||
|
ispector = this
|
||||||
|
|
||||||
this.$el.trigger(eH, [{values: this.propertyValues}])
|
this.$el.trigger(eH, [{values: this.propertyValues}])
|
||||||
if (eH.isDefaultPrevented()) {
|
if (eH.isDefaultPrevented()) {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
|
|
@ -441,6 +626,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
$.each(this.editors, function() {
|
$.each(this.editors, function() {
|
||||||
|
if (ispector.editorExternalPropertyEnabled(this))
|
||||||
|
return true
|
||||||
|
|
||||||
if (this.validate === undefined)
|
if (this.validate === undefined)
|
||||||
return true
|
return true
|
||||||
|
|
||||||
|
|
@ -458,10 +646,17 @@
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
|
|
||||||
var $contianer = this.$el.data('inspector-container')
|
|
||||||
$('[data-toggle=tooltip]', this.$el.data('oc.popover').$container).tooltip('hide')
|
$('[data-toggle=tooltip]', this.$el.data('oc.popover').$container).tooltip('hide')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Inspector.prototype.editorExternalPropertyEnabled = function(editor) {
|
||||||
|
var $container = this.$el.data('inspector-container'),
|
||||||
|
$cell = $('#'+editor.inspectorCellId, $container),
|
||||||
|
$extPropEditorContainer = $cell.find('.external-param-editor-container')
|
||||||
|
|
||||||
|
return $extPropEditorContainer.hasClass('editor-visible')
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// EDITOR DEFINITIONS
|
// EDITOR DEFINITIONS
|
||||||
// ==================
|
// ==================
|
||||||
|
|
@ -474,6 +669,7 @@
|
||||||
* - validate(), optional, validates the value and returns the validation error message
|
* - validate(), optional, validates the value and returns the validation error message
|
||||||
* - applyValue(), applies the editor value
|
* - applyValue(), applies the editor value
|
||||||
* - focus(), focuses the editor input element, if applicable
|
* - focus(), focuses the editor input element, if applicable
|
||||||
|
* - init(), sets the initial editor value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// STRING EDITOR
|
// STRING EDITOR
|
||||||
|
|
@ -483,7 +679,7 @@
|
||||||
this.inspector = inspector
|
this.inspector = inspector
|
||||||
this.fieldDef = fieldDef
|
this.fieldDef = fieldDef
|
||||||
this.editorId = editorId
|
this.editorId = editorId
|
||||||
this.selector = '#'+this.editorId+' input'
|
this.selector = '#'+this.editorId+' input.string-editor'
|
||||||
|
|
||||||
var self = this
|
var self = this
|
||||||
$(document).on('focus', this.selector, function() {
|
$(document).on('focus', this.selector, function() {
|
||||||
|
|
@ -498,6 +694,11 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InspectorEditorString.prototype.init = function() {
|
||||||
|
var value = $.trim(this.inspector.readProperty(this.fieldDef.property))
|
||||||
|
$(this.selector).val(value)
|
||||||
|
}
|
||||||
|
|
||||||
InspectorEditorString.prototype.applyValue = function() {
|
InspectorEditorString.prototype.applyValue = function() {
|
||||||
this.inspector.writeProperty(this.fieldDef.property, $.trim($(this.selector).val()))
|
this.inspector.writeProperty(this.fieldDef.property, $.trim($(this.selector).val()))
|
||||||
}
|
}
|
||||||
|
|
@ -505,11 +706,10 @@
|
||||||
InspectorEditorString.prototype.renderEditor = function() {
|
InspectorEditorString.prototype.renderEditor = function() {
|
||||||
var data = {
|
var data = {
|
||||||
id: this.editorId,
|
id: this.editorId,
|
||||||
value: $.trim(this.inspector.readProperty(this.fieldDef.property)),
|
|
||||||
placeholder: this.fieldDef.placeholder !== undefined ? this.fieldDef.placeholder : ''
|
placeholder: this.fieldDef.placeholder !== undefined ? this.fieldDef.placeholder : ''
|
||||||
}
|
}
|
||||||
|
|
||||||
return Mustache.render('<td class="text" id="{{id}}"><input type="text" value="{{value}}" placeholder="{{placeholder}}"/></td>', data)
|
return Mustache.render('<td class="text" id="{{id}}"><input type="text" class="string-editor" placeholder="{{placeholder}}"/></td>', data)
|
||||||
}
|
}
|
||||||
|
|
||||||
InspectorEditorString.prototype.validate = function() {
|
InspectorEditorString.prototype.validate = function() {
|
||||||
|
|
@ -525,6 +725,7 @@
|
||||||
|
|
||||||
InspectorEditorString.prototype.focus = function() {
|
InspectorEditorString.prototype.focus = function() {
|
||||||
$(this.selector).focus()
|
$(this.selector).focus()
|
||||||
|
$(this.selector).closest('td').scrollLeft(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
$.oc.inspector.editors.inspectorEditorString = InspectorEditorString;
|
$.oc.inspector.editors.inspectorEditorString = InspectorEditorString;
|
||||||
|
|
@ -550,14 +751,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
InspectorEditorCheckbox.prototype.renderEditor = function() {
|
InspectorEditorCheckbox.prototype.renderEditor = function() {
|
||||||
var isChecked = this.inspector.readProperty(this.fieldDef.property)
|
|
||||||
|
|
||||||
if (isChecked == '0' || isChecked == 'false')
|
|
||||||
isChecked = false
|
|
||||||
|
|
||||||
var data = {
|
var data = {
|
||||||
id: this.editorId,
|
id: this.editorId,
|
||||||
checked: isChecked ? 'checked' : null,
|
|
||||||
cbId: this.editorId + '-cb',
|
cbId: this.editorId + '-cb',
|
||||||
title: this.fieldDef.title
|
title: this.fieldDef.title
|
||||||
}
|
}
|
||||||
|
|
@ -565,6 +760,15 @@
|
||||||
return Mustache.render(this.getTemplate(), data)
|
return Mustache.render(this.getTemplate(), data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InspectorEditorCheckbox.prototype.init = function() {
|
||||||
|
var isChecked = this.inspector.readProperty(this.fieldDef.property)
|
||||||
|
|
||||||
|
if (isChecked == '0' || isChecked == 'false')
|
||||||
|
isChecked = false
|
||||||
|
|
||||||
|
$(this.selector).prop(checked, isChecked)
|
||||||
|
}
|
||||||
|
|
||||||
InspectorEditorCheckbox.prototype.focus = function() {
|
InspectorEditorCheckbox.prototype.focus = function() {
|
||||||
$(this.selector).closest('div').focus()
|
$(this.selector).closest('div').focus()
|
||||||
}
|
}
|
||||||
|
|
@ -576,7 +780,7 @@
|
||||||
custom-checkbox nolabel"> \
|
custom-checkbox nolabel"> \
|
||||||
<input type="checkbox" \
|
<input type="checkbox" \
|
||||||
value="1" \
|
value="1" \
|
||||||
{{checked}} id="{{cbId}}"/> \
|
id="{{cbId}}"/> \
|
||||||
<label for="{{cbId}}">{{title}}</label> \
|
<label for="{{cbId}}">{{title}}</label> \
|
||||||
</div> \
|
</div> \
|
||||||
</td> \
|
</td> \
|
||||||
|
|
@ -594,6 +798,7 @@
|
||||||
this.editorId = editorId
|
this.editorId = editorId
|
||||||
this.selector = '#'+this.editorId+' select'
|
this.selector = '#'+this.editorId+' select'
|
||||||
this.dynamicOptions = this.fieldDef.options ? false : true
|
this.dynamicOptions = this.fieldDef.options ? false : true
|
||||||
|
this.initialization = false
|
||||||
|
|
||||||
var self = this
|
var self = this
|
||||||
|
|
||||||
|
|
@ -603,7 +808,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
InspectorEditorDropdown.prototype.applyValue = function() {
|
InspectorEditorDropdown.prototype.applyValue = function() {
|
||||||
this.inspector.writeProperty(this.fieldDef.property, $(this.selector).val())
|
this.inspector.writeProperty(this.fieldDef.property, $(this.selector).val(), this.initialization)
|
||||||
}
|
}
|
||||||
|
|
||||||
InspectorEditorDropdown.prototype.renderEditor = function() {
|
InspectorEditorDropdown.prototype.renderEditor = function() {
|
||||||
|
|
@ -678,7 +883,7 @@
|
||||||
this.indicatorContainer.addClass('loading-indicator-container').addClass('size-small').addClass('transparent')
|
this.indicatorContainer.addClass('loading-indicator-container').addClass('size-small').addClass('transparent')
|
||||||
}
|
}
|
||||||
|
|
||||||
this.loadOptions()
|
this.loadOptions(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.fieldDef.depends)
|
if (this.fieldDef.depends)
|
||||||
|
|
@ -721,7 +926,7 @@
|
||||||
this.indicatorContainer.loadIndicator('hide')
|
this.indicatorContainer.loadIndicator('hide')
|
||||||
}
|
}
|
||||||
|
|
||||||
InspectorEditorDropdown.prototype.loadOptions = function() {
|
InspectorEditorDropdown.prototype.loadOptions = function(initialization) {
|
||||||
var $form = $(this.selector).closest('form'),
|
var $form = $(this.selector).closest('form'),
|
||||||
data = this.inspector.propertyValues,
|
data = this.inspector.propertyValues,
|
||||||
$select = $(this.selector),
|
$select = $(this.selector),
|
||||||
|
|
@ -755,7 +960,9 @@
|
||||||
else
|
else
|
||||||
$('option:first-child', $select).attr("selected", "selected");
|
$('option:first-child', $select).attr("selected", "selected");
|
||||||
|
|
||||||
|
self.initialization = initialization
|
||||||
$select.trigger('change')
|
$select.trigger('change')
|
||||||
|
self.initialization = false
|
||||||
|
|
||||||
self.hideLoadingIndicator()
|
self.hideLoadingIndicator()
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,92 @@
|
||||||
select {
|
select {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.external-param-editor-container {
|
||||||
|
position: relative;
|
||||||
|
padding-right: 30px;
|
||||||
|
|
||||||
|
div.external-editor {
|
||||||
|
bottom: 0;
|
||||||
|
margin: -5px -12px;
|
||||||
|
right: 30px;
|
||||||
|
left: auto;
|
||||||
|
top: 0;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
.transition(left 0.2s);
|
||||||
|
.transform( ~'translateZ(0)');
|
||||||
|
will-change: transform;
|
||||||
|
|
||||||
|
div.controls {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
a {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
display: inline-block;
|
||||||
|
height: 100%;
|
||||||
|
width: 30px;
|
||||||
|
color: #2b3e50;
|
||||||
|
outline: none;
|
||||||
|
|
||||||
|
i {
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
left: 10px;
|
||||||
|
top: 4px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
border: none;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-right: 12px;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.editor-visible {
|
||||||
|
div.external-editor {
|
||||||
|
div.controls {
|
||||||
|
input {
|
||||||
|
background: @color-inspector-bg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
div.external-param-editor-container {
|
||||||
|
div.external-editor {
|
||||||
|
div.controls {
|
||||||
|
input {
|
||||||
|
background: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.dropdown div.external-param-editor-container div.external-editor {
|
||||||
|
height: 100%;
|
||||||
|
margin: 0;
|
||||||
|
bottom: auto;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
|
|
|
||||||
|
|
@ -580,7 +580,7 @@
|
||||||
|
|
||||||
var $componentList = $('#cms-master-tabs > div.tab-content > .tab-pane.active .control-componentlist .layout')
|
var $componentList = $('#cms-master-tabs > div.tab-content > .tab-pane.active .control-componentlist .layout')
|
||||||
if ($componentList.length == 0) {
|
if ($componentList.length == 0) {
|
||||||
alert('Components can be added only to pages and layouts.')
|
alert('Components can be added only to pages, partials and layouts.')
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -183,36 +183,4 @@ abstract class ComponentBase extends Extendable
|
||||||
|
|
||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a page link to another page. Allows mapping to the other page's
|
|
||||||
* component properties for the purpose of extracting URL routing parameters.
|
|
||||||
* @param string $page Page name or page file name
|
|
||||||
* @param string $class Component class name
|
|
||||||
* @param array $mappings ['componentProperty' => 'routed value']
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
// protected function makePageLink($page, $class, $mappings = [])
|
|
||||||
// {
|
|
||||||
// if (!isset($this->pageLinkCache[$page.$class])) {
|
|
||||||
// $this->pageLinkCache[$page.$class] = $this->getOtherPageComponent($page, $class);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!$component = $this->pageLinkCache[$page.$class])
|
|
||||||
// return null;
|
|
||||||
|
|
||||||
// $params = [];
|
|
||||||
// foreach ($mappings as $property => $value) {
|
|
||||||
|
|
||||||
// if (!$param = $component->property($property))
|
|
||||||
// continue;
|
|
||||||
|
|
||||||
// if (substr($param, 0, 1) == ':')
|
|
||||||
// $param = substr($param, 1);
|
|
||||||
|
|
||||||
// $params[$param] = $value;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return $this->pageUrl($page, $params);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,13 @@ class ComponentHelpers
|
||||||
$result = [];
|
$result = [];
|
||||||
|
|
||||||
$property = [
|
$property = [
|
||||||
'property' => 'oc.alias',
|
'property' => 'oc.alias',
|
||||||
'title' => Lang::get('cms::lang.component.alias'),
|
'title' => Lang::get('cms::lang.component.alias'),
|
||||||
'description' => Lang::get('cms::lang.component.alias_description'),
|
'description' => Lang::get('cms::lang.component.alias_description'),
|
||||||
'type' => 'string',
|
'type' => 'string',
|
||||||
'validationPattern' => '^[a-zA-Z]+[0-9a-z\_]*$',
|
'validationPattern' => '^[a-zA-Z]+[0-9a-z\_]*$',
|
||||||
'validationMessage' => Lang::get('cms::lang.component.validation_message')
|
'validationMessage' => Lang::get('cms::lang.component.validation_message'),
|
||||||
|
'noExternalParameter' => true
|
||||||
];
|
];
|
||||||
$result[] = $property;
|
$result[] = $property;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,8 @@ class Controller extends BaseController
|
||||||
|
|
||||||
protected static $instance = null;
|
protected static $instance = null;
|
||||||
|
|
||||||
|
protected $partialComponentStack = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the controller.
|
* Creates the controller.
|
||||||
* @param \Cms\Classes\Theme $theme Specifies the CMS theme.
|
* @param \Cms\Classes\Theme $theme Specifies the CMS theme.
|
||||||
|
|
@ -391,6 +393,8 @@ class Controller extends BaseController
|
||||||
{
|
{
|
||||||
$manager = ComponentManager::instance();
|
$manager = ComponentManager::instance();
|
||||||
|
|
||||||
|
$properties = $this->setComponentPropertiesFromParameters($properties, []);
|
||||||
|
|
||||||
if ($addToLayout) {
|
if ($addToLayout) {
|
||||||
if (!$componentObj = $manager->makeComponent($name, $this->layoutObj, $properties)) {
|
if (!$componentObj = $manager->makeComponent($name, $this->layoutObj, $properties)) {
|
||||||
throw new CmsException(Lang::get('cms::lang.component.not_found', ['name'=>$name]));
|
throw new CmsException(Lang::get('cms::lang.component.not_found', ['name'=>$name]));
|
||||||
|
|
@ -664,6 +668,8 @@ class Controller extends BaseController
|
||||||
*/
|
*/
|
||||||
public function renderPartial($name, $parameters = [], $throwException = true)
|
public function renderPartial($name, $parameters = [], $throwException = true)
|
||||||
{
|
{
|
||||||
|
$vars = $this->vars;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Alias @ symbol for ::
|
* Alias @ symbol for ::
|
||||||
*/
|
*/
|
||||||
|
|
@ -748,12 +754,63 @@ class Controller extends BaseController
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Run partial functions (only for real partials)
|
||||||
|
*/
|
||||||
|
|
||||||
|
if ($partial instanceof \Cms\Classes\Partial) {
|
||||||
|
$manager = ComponentManager::instance();
|
||||||
|
|
||||||
|
foreach ($partial->settings['components'] as $component => $properties) {
|
||||||
|
list($name, $alias) = strpos($component, ' ') ?
|
||||||
|
explode(' ', $component) : array($component, $component);
|
||||||
|
|
||||||
|
$properties = $this->setComponentPropertiesFromParameters($properties, $parameters, []);
|
||||||
|
|
||||||
|
if (!$componentObj = $manager->makeComponent($name, $this->pageObj, $properties))
|
||||||
|
throw new CmsException(Lang::get('cms::lang.component.not_found', ['name'=>$name]));
|
||||||
|
|
||||||
|
$componentObj->alias = $alias;
|
||||||
|
$parameters[$alias] = $partial->components[$alias] = $componentObj;
|
||||||
|
|
||||||
|
array_push($this->partialComponentStack, [
|
||||||
|
'name' => $alias,
|
||||||
|
'obj' => $componentObj
|
||||||
|
]);
|
||||||
|
|
||||||
|
$componentObj->init();
|
||||||
|
$componentObj->onInit(); // Deprecated: Remove ithis line if year >= 2015
|
||||||
|
}
|
||||||
|
|
||||||
|
CmsException::mask($this->page, 300);
|
||||||
|
$parser = new CodeParser($partial);
|
||||||
|
$partialObj = $parser->source($this->page, $this->layout, $this);
|
||||||
|
CmsException::unmask();
|
||||||
|
|
||||||
|
CmsException::mask($partial, 300);
|
||||||
|
$partialObj->onStart();
|
||||||
|
$partial->runComponents();
|
||||||
|
$partialObj->onEnd();
|
||||||
|
CmsException::unmask();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Render the parital
|
||||||
|
*/
|
||||||
CmsException::mask($partial, 400);
|
CmsException::mask($partial, 400);
|
||||||
$this->loader->setObject($partial);
|
$this->loader->setObject($partial);
|
||||||
$template = $this->twig->loadTemplate($partial->getFullPath());
|
$template = $this->twig->loadTemplate($partial->getFullPath());
|
||||||
$result = $template->render(array_merge($this->vars, $parameters));
|
|
||||||
CmsException::unmask();
|
|
||||||
|
|
||||||
|
$result = $template->render(array_merge($this->vars, $parameters));
|
||||||
|
CmsException::unmask($this->partialComponentStack);
|
||||||
|
|
||||||
|
if ($partial instanceof \Cms\Classes\Partial) {
|
||||||
|
if ($this->partialComponentStack) {
|
||||||
|
array_pop($this->partialComponentStack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->vars = $vars;
|
||||||
$this->componentContext = null;
|
$this->componentContext = null;
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
@ -961,6 +1018,11 @@ class Controller extends BaseController
|
||||||
return $this->layout->components[$name];
|
return $this->layout->components[$name];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach ($this->partialComponentStack as $componentInfo) {
|
||||||
|
if ($componentInfo['name'] == $name)
|
||||||
|
return $componentInfo['obj'];
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1017,50 +1079,32 @@ class Controller extends BaseController
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a basic component object for another page, useful for extracting properties.
|
* Sets component property values from partial parameters.
|
||||||
* @param string $page Page name or page file name
|
* The property values should be defined as {{ param }}.
|
||||||
* @param string $class Component class name
|
* @param array &$properties Specifies the component properties loaded from the partial.
|
||||||
* @return ComponentBase
|
* @param array $parameters Specifies the partial parameters.
|
||||||
|
* @return Returns updated properties.
|
||||||
*/
|
*/
|
||||||
// public function getOtherPageComponent($page, $class)
|
protected function setComponentPropertiesFromParameters(&$properties, $parameters)
|
||||||
// {
|
{
|
||||||
// $class = Str::normalizeClassName($class);
|
$result = [];
|
||||||
// $theme = $this->getTheme();
|
|
||||||
// $manager = ComponentManager::instance();
|
|
||||||
// $componentObj = new $class;
|
|
||||||
|
|
||||||
// if (($page = Page::loadCached($theme, $page)) && isset($page->settings['components'])) {
|
$routerParameters = $this->router->getParameters();
|
||||||
// foreach ($page->settings['components'] as $component => $properties) {
|
|
||||||
// list($name, $alias) = strpos($component, ' ') ?
|
|
||||||
// explode(' ', $component) :
|
|
||||||
// array($component, $component)
|
|
||||||
// ;
|
|
||||||
// if ($manager->resolve($name) == $class) {
|
|
||||||
// $componentObj->setProperties($properties);
|
|
||||||
// $componentObj->alias = $alias;
|
|
||||||
// return $componentObj;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (!isset($page->settings['layout']))
|
foreach ($properties as $propertyName=>$propertyValue) {
|
||||||
// return null;
|
$matches = [];
|
||||||
|
if (preg_match('/^\{\{([^\}]+)\}\}$/', $propertyValue, $matches)) {
|
||||||
|
$paramName = trim($matches[1]);
|
||||||
|
|
||||||
// $layout = $page->settings['layout'];
|
if ( substr($paramName, 0, 1) == ':' ) {
|
||||||
// if (($layout = Layout::loadCached($theme, $layout)) && isset($layout->settings['components'])) {
|
$paramName = substr($paramName, 1);
|
||||||
// foreach ($layout->settings['components'] as $component => $properties) {
|
$result[$propertyName] = array_key_exists($paramName, $routerParameters) ? $routerParameters[$paramName] : null;
|
||||||
// list($name, $alias) = strpos($component, ' ') ?
|
} else
|
||||||
// explode(' ', $component) :
|
$result[$propertyName] = array_key_exists($paramName, $parameters) ? $parameters[$paramName] : null;
|
||||||
// array($component, $component)
|
} else
|
||||||
// ;
|
$result[$propertyName] = $propertyValue;
|
||||||
// if ($manager->resolve($name) == $class) {
|
}
|
||||||
// $componentObj->setProperties($properties);
|
|
||||||
// $componentObj->alias = $alias;
|
|
||||||
// return $componentObj;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// return null;
|
return $result;
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,4 +17,13 @@ class Partial extends CmsCompoundObject
|
||||||
{
|
{
|
||||||
return 'partials';
|
return 'partials';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns name of a PHP class to us a parent for the PHP class created for the object's PHP section.
|
||||||
|
* @return mixed Returns the class name or null.
|
||||||
|
*/
|
||||||
|
public function getCodeClassParent()
|
||||||
|
{
|
||||||
|
return '\Cms\Classes\PartialCode';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<?php namespace Cms\Classes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parent class for PHP classes created for partial PHP sections.
|
||||||
|
*
|
||||||
|
* @package october\cms
|
||||||
|
* @author Alexey Bobkov, Samuel Georges
|
||||||
|
*/
|
||||||
|
class PartialCode extends CodeBase
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
@ -14,6 +14,8 @@ fields:
|
||||||
path: partial_toolbar
|
path: partial_toolbar
|
||||||
cssClass: collapse-visible
|
cssClass: collapse-visible
|
||||||
|
|
||||||
|
components: Cms\FormWidgets\Components
|
||||||
|
|
||||||
secondaryTabs:
|
secondaryTabs:
|
||||||
stretch: true
|
stretch: true
|
||||||
fields:
|
fields:
|
||||||
|
|
@ -21,4 +23,10 @@ secondaryTabs:
|
||||||
tab: cms::lang.editor.markup
|
tab: cms::lang.editor.markup
|
||||||
stretch: true
|
stretch: true
|
||||||
type: codeeditor
|
type: codeeditor
|
||||||
language: twig
|
language: twig
|
||||||
|
|
||||||
|
code:
|
||||||
|
tab: cms::lang.editor.code
|
||||||
|
stretch: true
|
||||||
|
type: codeeditor
|
||||||
|
language: php
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,8 @@ class Index extends Controller
|
||||||
$this->addJs('/modules/cms/assets/js/october.cmspage.js', 'core');
|
$this->addJs('/modules/cms/assets/js/october.cmspage.js', 'core');
|
||||||
$this->addJs('/modules/cms/assets/js/october.dragcomponents.js', 'core');
|
$this->addJs('/modules/cms/assets/js/october.dragcomponents.js', 'core');
|
||||||
$this->addJs('/modules/cms/assets/js/october.tokenexpander.js', 'core');
|
$this->addJs('/modules/cms/assets/js/october.tokenexpander.js', 'core');
|
||||||
|
$this->addJs('/modules/backend/formwidgets/codeeditor/assets/js/codeeditor.js', 'core');
|
||||||
|
|
||||||
$this->addCss('/modules/cms/assets/css/october.components.css', 'core');
|
$this->addCss('/modules/cms/assets/css/october.components.css', 'core');
|
||||||
|
|
||||||
// Preload Ace editor modes explicitly, because they could be changed dynamically
|
// Preload Ace editor modes explicitly, because they could be changed dynamically
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,12 @@
|
||||||
<?= Form::open([
|
<?php
|
||||||
'class' => 'layout',
|
$formConfig = [
|
||||||
'data-change-monitor' => 'true',
|
'class' => 'layout',
|
||||||
'data-window-close-confirm' => e(trans('backend::lang.form.confirm_tab_close'))
|
'data-change-monitor' => 'true',
|
||||||
]) ?>
|
'data-window-close-confirm' => e(trans('backend::lang.form.confirm_tab_close')),
|
||||||
|
'data-inspector-external-parameters' => true
|
||||||
|
];
|
||||||
|
|
||||||
|
echo Form::open($formConfig) ?>
|
||||||
<?= $form->render() ?>
|
<?= $form->render() ?>
|
||||||
|
|
||||||
<input type="hidden" value="<?= ($templateType) ?>" name="templateType" />
|
<input type="hidden" value="<?= ($templateType) ?>" name="templateType" />
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue