Free up the term af-block to refer to something more specific than a container.
if ($item['#tag'] === 'af-field' || $item['#tag'] === 'af-form' || isset($item['af-fieldset'])) {
return TRUE;
}
- $editableClasses = ['af-block', 'af-text', 'af-button'];
+ $editableClasses = ['af-container', 'af-text', 'af-button'];
$classes = explode(' ', $item['class'] ?? '');
return (bool) array_intersect($editableClasses, $classes);
}
cursor: pointer;
}
-.af-block.af-layout-cols {
+.af-container.af-layout-cols {
display: flex;
}
-.af-block.af-layout-cols > * {
+.af-container.af-layout-cols > * {
flex: 1;
}
-.af-block.af-layout-inline > * {
+.af-container.af-layout-inline > * {
display: inline-block;
margin-right: .5em;
}
padding: 0 3px 3px;
}
-#afGuiEditor .af-gui-block {
+#afGuiEditor .af-gui-container {
border: 2px dashed transparent;
position: relative;
padding: 22px 3px 3px;
min-height: 40px;
}
-#afGuiEditor .af-gui-block-type-fieldset {
+#afGuiEditor .af-gui-container-type-fieldset {
box-shadow: 0 0 5px #bbbbbb;
}
-#afGuiEditor .af-gui-block:hover {
+#afGuiEditor .af-gui-container:hover {
border: 2px dashed #757575;
}
padding-top: 2px;
padding-bottom: 2px;
}
-#afGuiEditor .af-gui-add-block-button span {
+#afGuiEditor .af-gui-add-element-button span {
display: inline-block;
width: 18px;
height: 18px;
border: 2px dashed #0071bd;
color: #0071bd;
}
-#afGuiEditor .af-gui-add-block-button span i {
+#afGuiEditor .af-gui-add-element-button span i {
position: relative;
- top: -3px;
+ top: -2px;
}
#afGuiEditor .af-gui-layout-icon {
.af-gui-editing-content #afGuiEditor-palette .panel-body > * {
opacity: .5;
}
-#afGuiEditor.af-gui-editing-content .af-gui-block {
+#afGuiEditor.af-gui-editing-content .af-gui-container {
border: 2px solid transparent;
}
#afGuiEditor.af-gui-editing-content .af-gui-bar {
};
});
- angular.module('afGuiEditor').directive('afGuiBlock', function() {
+ angular.module('afGuiEditor').directive('afGuiContainer', function() {
return {
restrict: 'A',
- templateUrl: '~/afGuiEditor/block.html',
+ templateUrl: '~/afGuiEditor/container.html',
scope: {
- node: '=afGuiBlock',
+ node: '=afGuiContainer',
entityName: '='
},
require: '^^afGuiEditor',
$scope.editor = editor;
},
controller: function($scope) {
- var block = $scope.block = this;
+ var container = $scope.container = this;
var ts = $scope.ts = CRM.ts();
this.node = $scope.node;
if (node['af-fieldset']) {
return 'fieldset';
}
- var classes = splitClass(node['class']);
- if (_.contains(classes, 'af-block')) {
- return 'block';
- }
- if (_.contains(classes, 'af-text')) {
- return 'text';
- }
- if (_.contains(classes, 'af-button')) {
- return 'button';
- }
- if (_.contains(classes, 'af-markup')) {
- return 'markup';
- }
- return null;
+ var classes = splitClass(node['class']),
+ types = ['af-container', 'af-text', 'af-button', 'af-markup'],
+ type = _.intersection(types, classes);
+ return type.length ? type[0].replace('af-', '') : null;
};
- $scope.addBlock = function(type, props) {
+ $scope.addElement = function(type, props) {
var classes = type.split('.');
- var newBlock = _.defaults({
+ var element = _.defaults({
'#tag': classes.shift(),
'class': classes.join(' '),
}, props);
- if (classes[0] === 'af-block') {
- newBlock['#children'] = [];
- } else if (classes[0] === 'af-text' || classes[0] === 'af-button') {
- newBlock['#children'] = [{'#text': ts('Enter text')}];
+ if (_.includes(classes, 'af-container')) {
+ element['#children'] = [];
+ } else if (_.intersection(classes, ['af-text', 'af-button']).length) {
+ element['#children'] = [{'#text': ts('Enter text')}];
}
- // Add new block to the top, underneath the fieldset legend if present
+ // Add it to the top, underneath the fieldset legend if present
var pos = $scope.node['#children'].length && $scope.node['#children'][0]['#tag'] === 'legend' ? 1 : 0;
- $scope.node['#children'].splice(pos, 0, newBlock);
+ $scope.node['#children'].splice(pos, 0, element);
};
- this.removeBlock = function(node) {
- removeRecursive($scope.editor.scope.layout['#children'], {$$hashKey: node.$$hashKey});
+ this.removeElement = function(element) {
+ removeRecursive($scope.editor.scope.layout['#children'], {$$hashKey: element.$$hashKey});
};
$scope.isSelectedFieldset = function(entityName) {
};
$scope.tags = {
- div: ts('Block'),
+ div: ts('Container'),
fieldset: ts('Fieldset')
};
};
$scope.setLayout = function(val) {
- var classes = ['af-block'];
+ var classes = ['af-container'];
if (val !== 'af-layout-rows') {
classes.push(val);
}
node: '=afGuiField',
entityName: '='
},
- require: ['^^afGuiEditor', '^^afGuiBlock'],
+ require: ['^^afGuiEditor', '^^afGuiContainer'],
link: function($scope, element, attrs, ctrls) {
$scope.editor = ctrls[0];
- $scope.block = ctrls[1];
+ $scope.container = ctrls[1];
},
controller: function($scope) {
var ts = $scope.ts = CRM.ts();
$scope.deletedOptions.splice($index, 1);
$scope.options.push(option);
};
-
+
$scope.save = function() {
$scope.field.getSet('options', JSON.parse(angular.toJson($scope.options)));
$scope.close();
scope: {
node: '=afGuiText'
},
- require: '^^afGuiBlock',
- link: function($scope, element, attrs, block) {
- $scope.block = block;
+ require: '^^afGuiContainer',
+ link: function($scope, element, attrs, container) {
+ $scope.container = container;
},
controller: function($scope) {
var ts = $scope.ts = CRM.ts();
scope: {
node: '=afGuiMarkup'
},
- require: '^^afGuiBlock',
- link: function($scope, element, attrs, block) {
- $scope.block = block;
+ require: '^^afGuiContainer',
+ link: function($scope, element, attrs, container) {
+ $scope.container = container;
// CRM.wysiwyg doesn't work without a dom id
$scope.id = 'af-markup-editor-' + richtextId++;
- // When creating a new markup block, go straight to edit mode
+ // When creating a new markup container, go straight to edit mode
$timeout(function() {
if ($scope.node['#markup'] === false) {
$scope.edit();
$scope.close = function() {
CRM.wysiwyg.destroy('#' + $scope.id);
$('#afGuiEditor').removeClass('af-gui-editing-content');
- // If a newly-added block was canceled, just remove it
+ // If a newly-added wysiwyg was canceled, just remove it
if ($scope.node['#markup'] === false) {
- $scope.block.removeBlock($scope.node);
+ $scope.container.removeElement($scope.node);
} else {
$scope.editingMarkup = false;
}
scope: {
node: '=afGuiButton'
},
- require: '^^afGuiBlock',
- link: function($scope, element, attrs, block) {
- $scope.block = block;
+ require: '^^afGuiContainer',
+ link: function($scope, element, attrs, container) {
+ $scope.container = container;
},
controller: function($scope) {
var ts = $scope.ts = CRM.ts();
+++ /dev/null
-<li><a href ng-click="addBlock('div.af-block')">{{ ts('Add block') }}</a></li>
-<li><a href ng-click="addBlock('p.af-text')">{{ ts('Add text box') }}</a></li>
-<li><a href ng-click="addBlock('div.af-markup', {'#markup': false})">{{ ts('Add rich content') }}</a></li>
-<li><a href ng-click="addBlock('button.af-button.btn-primary', {'crm-icon': 'fa-check', 'ng-click': 'modelListCtrl.submit()'})">{{ ts('Add button') }}</a></li>
-<li role="separator" class="divider"></li>
-<li af-gui-menu-item-border="node"></li>
-<li af-gui-menu-item-background="node"></li>
-<li role="separator" class="divider"></li>
-<li><a href ng-click="block.removeBlock(node)"><span class="text-danger">{{ ts('Delete this block') }}</span></a></li>
</div>
</li>
<li role="separator" class="divider"></li>
-<li><a href ng-click="block.removeBlock(node)"><span class="text-danger">{{ ts('Delete this button') }}</span></a></li>
+<li><a href ng-click="container.removeElement(node)"><span class="text-danger">{{ ts('Delete this button') }}</span></a></li>
<div class="af-gui-bar">
<div class="form-inline pull-right">
<div class="btn-group pull-right" af-gui-menu>
- <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-block-button" data-toggle="dropdown" title="{{ ts('Configure') }}">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-element-button" data-toggle="dropdown" title="{{ ts('Configure') }}">
<span><i class="crm-i fa-gear"></i></span>
</button>
<ul class="dropdown-menu" ng-if="menu.open" ng-include="'~/afGuiEditor/button-menu.html'"></ul>
--- /dev/null
+<li><a href ng-click="addElement('div.af-container')">{{ ts('Add container') }}</a></li>
+<li><a href ng-click="addElement('p.af-text')">{{ ts('Add text box') }}</a></li>
+<li><a href ng-click="addElement('div.af-markup', {'#markup': false})">{{ ts('Add rich content') }}</a></li>
+<li><a href ng-click="addElement('button.af-button.btn-primary', {'crm-icon': 'fa-check', 'ng-click': 'modelListCtrl.submit()'})">{{ ts('Add button') }}</a></li>
+<li role="separator" class="divider"></li>
+<li ng-repeat="entity in editor.scope.entities">
+ <a href ng-click="addElement('fieldset.af-container', {'af-fieldset': entity.name})">{{ ts('Fieldset for %1', {1: entity.label}) }}</a>
+</li>
</form>
</div>
<div class="panel-body">
- <div af-gui-block="layout" entity-name="" />
+ <div af-gui-container="layout" entity-name="" />
</div>
</div>
--- /dev/null
+<li><a href ng-click="addElement('div.af-container')">{{ ts('Add container') }}</a></li>
+<li><a href ng-click="addElement('p.af-text')">{{ ts('Add text box') }}</a></li>
+<li><a href ng-click="addElement('div.af-markup', {'#markup': false})">{{ ts('Add rich content') }}</a></li>
+<li><a href ng-click="addElement('button.af-button.btn-primary', {'crm-icon': 'fa-check', 'ng-click': 'modelListCtrl.submit()'})">{{ ts('Add button') }}</a></li>
+<li role="separator" class="divider"></li>
+<li af-gui-menu-item-border="node"></li>
+<li af-gui-menu-item-background="node"></li>
+<li role="separator" class="divider"></li>
+<li><a href ng-click="container.removeElement(node)"><span class="text-danger">{{ ts('Delete this container') }}</span></a></li>
<div class="af-gui-bar" ng-if="node['#tag'] !== 'af-form'" ng-click="selectEntity()" >
- <span ng-if="block.getNodeType(node) == 'fieldset'">{{ editor.getEntity(entityName).label }}</span>
+ <span ng-if="container.getNodeType(node) == 'fieldset'">{{ editor.getEntity(entityName).label }}</span>
<span>{{ node['#tag'] }}</span>
<div class="form-inline pull-right" af-gui-menu>
<div class="btn-group btn-group-xs" role="group">
<i class="af-gui-layout-icon {{ opt }}" ></i>
</button>
</div>
- <select ng-model="node['#tag']" title="{{ ts('Block type') }}">
+ <select ng-model="node['#tag']" title="{{ ts('Container type') }}">
<option ng-repeat="(opt, label) in tags" value="{{ opt }}">{{ label }}</option>
</select>
- <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-block-button" data-toggle="dropdown" title="{{ ts('Add block') }}">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-element-button" data-toggle="dropdown" title="{{ ts('Add Element') }}">
<span><i class="crm-i fa-plus"></i></span>
</button>
- <ul class="dropdown-menu" ng-if="menu.open" ng-include="'~/afGuiEditor/block-menu.html'"></ul>
+ <ul class="dropdown-menu" ng-if="menu.open" ng-include="'~/afGuiEditor/container-menu.html'"></ul>
</div>
</div>
<div class="af-gui-bar" ng-if="node['#tag'] === 'af-form'" >
<div class="form-inline pull-right" af-gui-menu>
- <button type="button" class="btn btn-default btn-sm dropdown-toggle af-gui-add-canvas-button" data-toggle="dropdown" title="{{ ts('Add block') }}">
+ <button type="button" class="btn btn-default btn-sm dropdown-toggle af-gui-add-canvas-button" data-toggle="dropdown" title="{{ ts('Add Element') }}">
<span>Add <i class="crm-i fa-plus"></i></span>
</button>
- <ul class="dropdown-menu" ng-if="menu.open">
- <li><a href ng-click="addBlock('div.af-block')">{{ ts('Add block') }}</a></li>
- <li><a href ng-click="addBlock('p.af-text')">{{ ts('Add text box') }}</a></li>
- <li><a href ng-click="addBlock('div.af-markup', {'#markup': false})">{{ ts('Add rich content') }}</a></li>
- <li><a href ng-click="addBlock('button.af-button.btn-primary', {'crm-icon': 'fa-check', 'ng-click': 'modelListCtrl.submit()'})">{{ ts('Add button') }}</a></li>
- <li role="separator" class="divider"></li>
- <li ng-repeat="entity in editor.scope.entities">
- <a href ng-click="addBlock('fieldset.af-block', {'af-fieldset': entity.name})">{{ ts('Fieldset for %1', {1: entity.label}) }}</a>
- </li>
- </ul>
+ <ul class="dropdown-menu" ng-if="menu.open" ng-include="'~/afGuiEditor/canvas-menu.html'"></ul>
</div>
</div>
<div ui-sortable="{handle: '.af-gui-bar', update: onDrop, connectWith: '[ui-sortable]', cancel: 'input,textarea,button,select,option,a'}" ng-model="node['#children']" class="af-gui-layout {{ getLayout() }}">
<div ng-repeat="item in node['#children']" >
- <div ng-switch="block.getNodeType(item)">
- <div ng-switch-when="fieldset" af-gui-block="item" style="{{ item.style }}" class="af-gui-block af-gui-fieldset af-gui-block-type-{{ item['#tag'] }}" ng-class="{'af-entity-selected': isSelectedFieldset(item['af-fieldset'])}" entity-name="item['af-fieldset']" data-entity="{{ item['af-fieldset'] }}" />
- <div ng-switch-when="block" af-gui-block="item" style="{{ item.style }}" class="af-gui-block af-gui-block-type-{{ item['#tag'] }}" entity-name="entityName" />
+ <div ng-switch="container.getNodeType(item)">
+ <div ng-switch-when="fieldset" af-gui-container="item" style="{{ item.style }}" class="af-gui-container af-gui-fieldset af-gui-container-type-{{ item['#tag'] }}" ng-class="{'af-entity-selected': isSelectedFieldset(item['af-fieldset'])}" entity-name="item['af-fieldset']" data-entity="{{ item['af-fieldset'] }}" />
+ <div ng-switch-when="container" af-gui-container="item" style="{{ item.style }}" class="af-gui-container af-gui-container-type-{{ item['#tag'] }}" entity-name="entityName" />
<div ng-switch-when="field" af-gui-field="item" entity-name="entityName" />
<div ng-switch-when="text" af-gui-text="item" class="af-gui-element af-gui-text" />
<div ng-switch-when="markup" af-gui-markup="item" class="af-gui-markup" />
</li>
<li role="separator" class="divider"></li>
<li>
- <a href ng-click="block.removeBlock(node)" title="{{ ts('Remove field from form') }}">
+ <a href ng-click="container.removeElement(node)" title="{{ ts('Remove field from form') }}">
<span class="text-danger">{{ ts('Delete this field') }}</span>
</a>
</li>
<div class="af-gui-bar" title="{{ getEntity().label + ': ' + getDefn().title }}">
<div class="form-inline pull-right">
<div class="btn-group" af-gui-menu >
- <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-block-button" data-toggle="dropdown" title="{{ ts('Configure') }}">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-element-button" data-toggle="dropdown" title="{{ ts('Configure') }}">
<span><i class="crm-i fa-gear"></i></span>
</button>
<ul class="dropdown-menu dropdown-menu-right" ng-if="menu.open" ng-include="'~/afGuiEditor/field-menu.html'"></ul>
<li af-gui-menu-item-background="node"></li>
<li role="separator" class="divider"></li>
<li>
- <a href ng-click="block.removeBlock(node)"><span class="text-danger">{{ ts('Delete this content') }}</span></a>
+ <a href ng-click="container.removeElement(node)"><span class="text-danger">{{ ts('Delete this content') }}</span></a>
</li>
<div class="af-gui-bar">
<div class="form-inline pull-right">
<div class="btn-group pull-right" af-gui-menu>
- <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-block-button" data-toggle="dropdown" title="{{ ts('Configure') }}">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-element-button" data-toggle="dropdown" title="{{ ts('Configure') }}">
<span><i class="crm-i fa-gear"></i></span>
</button>
<ul class="dropdown-menu" ng-if="menu.open" ng-include="'~/afGuiEditor/markup-menu.html'"></ul>
<div class="af-gui-field-select-in-dropdown form-inline" ng-click="$event.stopPropagation()">
<label>{{ ts('Background:') }}</label>
<input type="color" class="form-control" ng-model="getSetBackgroundColor" ng-model-options="{getterSetter: true}"/>
- <a href class="" ng-click="getSetBackgroundColor(null)" ng-if="block.getStyles(node)['background-color']">
+ <a href class="" ng-click="getSetBackgroundColor(null)" ng-if="container.getStyles(node)['background-color']">
<i class="crm-i fa-times"></i>
</a>
</div>
</li>
<li role="separator" class="divider"></li>
<li>
- <a href ng-click="block.removeBlock(node)"><span class="text-danger">{{ ts('Delete this text') }}</span></a>
+ <a href ng-click="container.removeElement(node)"><span class="text-danger">{{ ts('Delete this text') }}</span></a>
</li>
<div class="af-gui-bar">
<div class="form-inline pull-right">
<div class="btn-group pull-right" af-gui-menu>
- <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-block-button" data-toggle="dropdown" title="{{ ts('Configure') }}">
+ <button type="button" class="btn btn-default btn-xs dropdown-toggle af-gui-add-element-button" data-toggle="dropdown" title="{{ ts('Configure') }}">
<span><i class="crm-i fa-gear"></i></span>
</button>
<ul class="dropdown-menu" ng-if="menu.open" ng-include="'~/afGuiEditor/text-menu.html'"></ul>
<fieldset af-fieldset="parent">
<legend class="af-text">About You</legend>
- <div class="af-block af-layout-inline">
+ <div class="af-container af-layout-inline">
<af-field name="first_name" />
<af-field name="last_name" />
</div>
<?php
return [
- 'html' => '<div class="af-block"><strong> New text!</strong><strong class="af-text"> Get a trim! </strong><af-field name="do_not_sms" defn="{label: \'Do not do any of the emailing\'}" /></div>',
- 'pretty' => '<div class="af-block">
+ 'html' => '<div class="af-container"><strong> New text!</strong><strong class="af-text"> Get a trim! </strong><af-field name="do_not_sms" defn="{label: \'Do not do any of the emailing\'}" /></div>',
+ 'pretty' => '<div class="af-container">
<strong> New text!</strong>
<strong class="af-text"> Get a trim!</strong>
<af-field name="do_not_sms" defn="{label: \'Do not do any of the emailing\'}" />
'stripped' => [
[
'#tag' => 'div',
- 'class' => 'af-block',
+ 'class' => 'af-container',
'#children' => [
['#tag' => 'strong', '#markup' => ' New text!'],
['#tag' => 'strong', 'class' => 'af-text', '#children' => [['#text' => " Get a trim!"]]],
'shallow' => [
[
'#tag' => 'div',
- 'class' => 'af-block',
+ 'class' => 'af-container',
'#children' => [
['#tag' => 'strong', '#markup' => ' New text!'],
['#tag' => 'strong', 'class' => 'af-text', '#children' => [['#text' => " Get a trim! "]]],
'deep' => [
[
'#tag' => 'div',
- 'class' => 'af-block',
+ 'class' => 'af-container',
'#children' => [
['#tag' => 'strong', '#children' => [['#text' => ' New text!']]],
['#tag' => 'strong', 'class' => 'af-text', '#children' => [['#text' => " Get a trim! "]]],