Fixing various grid bugs with the new structure

This commit is contained in:
per ploug
2014-06-26 23:36:04 +02:00
parent 7edd7cbd8a
commit 49a374dbca
8 changed files with 352 additions and 327 deletions

View File

@@ -241,7 +241,7 @@
// CONTROL PLACEHOLDER
// -------------------------
.usky-grid .usky-control-placeholder {
min-height: 100px;
min-height: 50px;
position: relative;
text-align: center;
text-align: -moz-center;

View File

@@ -1,7 +1,7 @@
<div class="umb-property">
<div class="control-group umb-control-group" ng-class="{error: !formValid()}">
<div class="control-group umb-control-group" ng-class="{error: !formValid(), hidelabel:hideLabel=='true'}">
<div class="umb-el-wrap">
<label class="control-label" for="{{alias}}">
<label ng-if="hideLabel!=='true'" class="control-label" for="{{alias}}">
{{labelstring}}
<small>{{description}}</small>
</label>

View File

@@ -1,4 +1,4 @@
<div
unique-id="control.uniqueId"
unique-id="control.$uniqueId"
value="control.value"
grid-rte configuration="model.config.rte"></div>

View File

@@ -2,326 +2,330 @@ angular.module("umbraco")
.controller("Umbraco.PropertyEditors.GridController",
function ($scope, $http, assetsService, $rootScope, dialogService, gridService, mediaResource, imageHelper, $timeout) {
var gridConfigPath = $scope.model.config.items.gridConfigPath;
// Grid status variables
$scope.currentRow = null;
$scope.currentCell = null;
$scope.currentToolsControl = null;
$scope.currentControl = null;
$scope.openRTEToolbarId = null;
if(!gridConfigPath){
gridConfigPath = "views/propertyeditors/grid/grid.default.config.js";
}
// *********************************************
// Sortable options
// *********************************************
assetsService.loadJs(gridConfigPath).then(function(){
$scope.sortableOptions = {
distance: 10,
cursor: "move",
placeholder: 'ui-sortable-placeholder',
handle: '.cell-tools-move',
start: function (e, ui) {
ui.item.find('.mceNoEditor').each(function () {
tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'));
// Grid config
$scope.uSkyGridConfig = uSkyGridConfig;
});
},
stop: function (e, ui) {
ui.item.find('.mceNoEditor').each(function () {
tinyMCE.execCommand('mceAddEditor', false, $(this).attr('id'));
});
}
};
// Grid status variables
$scope.currentRow = null;
$scope.currentCell = null;
$scope.currentToolsControl = null;
$scope.currentControl = null;
// *********************************************
// Template management functions
// *********************************************
$scope.addTemplate = function (template) {
$scope.model.value = angular.copy(template);
//default row data
_.forEach($scope.model.value.sections, function(section){
$scope.initSection(section);
});
};
// *********************************************
// Row management function
// *********************************************
$scope.setCurrentRow = function (row) {
$scope.currentRow = row;
};
$scope.disableCurrentRow = function () {
$scope.currentRow = null;
};
$scope.getAllowedLayouts = function(column){
var layouts = $scope.model.config.items.layouts;
if(column.allowed && column.allowed.length > 0){
return _.filter(layouts, function(layout){
return _.indexOf(column.allowed, layout.name) >= 0;
});
}else{
return layouts;
}
};
$scope.addRow = function (column, layout) {
//copy the selected layout into the rows collection
var row = angular.copy(layout);
column.rows.push(row);
};
$scope.removeRow = function (section, $index) {
if (section.rows.length > 0) {
section.rows.splice($index, 1);
$scope.openRTEToolbarId = null;
gridService.getGridEditors().then(function(response){
$scope.availableEditors = response.data;
$scope.initContent();
}
};
// *********************************************
// Cell management functions
// *********************************************
$scope.setCurrentCell = function (cell) {
$scope.currentCell = cell;
};
$scope.disableCurrentCell = function (cell) {
$scope.currentCell = null;
};
$scope.cellPreview = function(cell){
if(cell && cell.$allowedEditors){
var editor = cell.$allowedEditors[0];
return editor.icon;
}else{
return "icon-layout";
}
};
// *********************************************
// Control management functions
// *********************************************
$scope.setCurrentControl = function (Control) {
$scope.currentControl = Control;
};
$scope.disableCurrentControl = function (Control) {
$scope.currentControl = null;
};
$scope.setCurrentToolsControl = function (Control) {
$scope.currentToolsControl = Control;
};
$scope.disableCurrentToolsControl = function (Control) {
$scope.currentToolsControl = null;
};
$scope.setCurrentRemoveControl = function (Control) {
$scope.currentRemoveControl = Control;
};
$scope.disableCurrentRemoveControl = function (Control) {
$scope.currentRemoveControl = null;
};
$scope.setCurrentMoveControl = function (Control) {
$scope.currentMoveControl = Control;
};
$scope.disableCurrentMoveControl = function (Control) {
$scope.currentMoveControl = null;
};
$scope.setUniqueId = function (cell, index) {
var date = new Date();
var components = [
date.getYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds()
];
return components.join("");
};
$scope.addControl = function (editor, cell, index){
var newControl = {
value: null,
editor: editor
};
if (index === undefined) {
index = cell.controls.length;
}
//populate control
$scope.initControl(newControl, index+1);
cell.controls.splice(index + 1, 0, newControl);
};
$scope.addTinyMce = function(cell){
var rte = $scope.getEditor("rte");
$scope.addControl(rte, cell);
};
$scope.getEditor = function(alias){
return _.find($scope.availableEditors, function(editor){return editor.alias === alias});
};
$scope.removeControl = function (cell, $index) {
cell.controls.splice($index, 1);
};
$scope.percentage = function(spans){
return ((spans/12)*100).toFixed(1);
};
// *********************************************
// INITIALISATION
// these methods are called from ng-init on the template
// so we can controll their first load data
//
// intialisation sets non-saved data like percentage sizing, allowed editors and
// other data that should all be pre-fixed with $ to strip it out on save
// *********************************************
// *********************************************
// Init template + sections
// *********************************************
$scope.initContent = function() {
var clear = true;
if ($scope.model.value && $scope.model.value.sections && $scope.model.value.sections.length > 0) {
_.forEach($scope.model.value.sections, function(section){
$scope.initSection(section);
//we do this to ensure that the grid can be reset by deleting the last row
if(section.rows.length > 0){
clear = false;
}
});
// *********************************************
// Sortable options
// *********************************************
}
$scope.sortableOptions = {
distance: 10,
cursor: "move",
placeholder: 'ui-sortable-placeholder',
handle: '.cell-tools-move',
start: function (e, ui) {
ui.item.find('.mceNoEditor').each(function () {
tinyMCE.execCommand('mceRemoveEditor', false, $(this).attr('id'));
if(clear){
$scope.model.value = undefined;
}
};
});
},
stop: function (e, ui) {
ui.item.find('.mceNoEditor').each(function () {
tinyMCE.execCommand('mceAddEditor', false, $(this).attr('id'));
});
}
};
$scope.initSection = function(section){
section.$percentage = $scope.percentage(section.grid);
// *********************************************
// Template management functions
// *********************************************
var layouts = $scope.model.config.items.layouts;
$scope.checkContent = function() {
var isEmpty = true;
if ($scope.model.value &&
$scope.model.value.sections) {
angular.forEach($scope.model.value.sections, function (value, key) {
if ( value.rows && value.rows.length > 0) {
isEmpty = false;
}
});
}
if(section.allowed && section.allowed.length > 0){
return _.filter(layouts, function(layout){
section.$allowedLayouts = _.indexOf(section.allowed, layout.name) >= 0;
});
}else{
section.$allowedLayouts = layouts;
}
if (isEmpty)
{
$scope.model.value = undefined;
}
};
if(!section.rows){
section.rows = [];
}else{
_.forEach(section.rows, function(row){
$scope.initRow(row);
});
}
};
$scope.addTemplate = function (template) {
$scope.model.value = angular.copy(template);
//default row data
_.forEach($scope.model.value.sections, function(section){
section.rows = [];
// *********************************************
// Init layout / row
// *********************************************
$scope.initRow = function(row){
if(!row.areas){
row.areas = [];
}
//set a disposable unique ID
row.$uniqueId = $scope.setUniqueId();
//populate with data
_.forEach(row.areas, function(area){
if(!area.controls){
area.controls = [];
}else{
_.forEach(area.controls, function(control, index){
$scope.initControl(control, index);
});
};
// *********************************************
// Row management function
// *********************************************
$scope.setCurrentRow = function (row) {
$scope.currentRow = row;
};
$scope.disableCurrentRow = function () {
$scope.currentRow = null;
};
}
$scope.getAllowedLayouts = function(column){
var layouts = $scope.model.config.items.layouts;
area.$percentage = $scope.percentage(area.grid);
if(column.allowed && column.allowed.length > 0){
return _.filter(layouts, function(layout){
return _.indexOf(column.allowed, layout.name) >= 0;
});
}else{
return layouts;
}
};
$scope.addRow = function (column, layout) {
//copy the selected layout into the rows collection
var row = angular.copy(layout);
column.rows.push(row);
};
$scope.removeRow = function (column, $index) {
if (column.rows.length > 0) {
column.rows.splice($index, 1);
$scope.openRTEToolbarId = null;
$scope.checkContent();
}
};
// *********************************************
// Cell management functions
// *********************************************
$scope.setCurrentCell = function (cell) {
$scope.currentCell = cell;
};
$scope.disableCurrentCell = function (cell) {
$scope.currentCell = null;
};
$scope.cellPreview = function(cell){
if(cell && cell.$allowedEditors){
var editor = cell.$allowedEditors[0];
return editor.icon;
}else{
return "icon-layout";
}
};
// *********************************************
// Control management functions
// *********************************************
$scope.setCurrentControl = function (Control) {
$scope.currentControl = Control;
};
$scope.disableCurrentControl = function (Control) {
$scope.currentControl = null;
};
$scope.setCurrentToolsControl = function (Control) {
$scope.currentToolsControl = Control;
};
$scope.disableCurrentToolsControl = function (Control) {
$scope.currentToolsControl = null;
};
$scope.setCurrentRemoveControl = function (Control) {
$scope.currentRemoveControl = Control;
};
$scope.disableCurrentRemoveControl = function (Control) {
$scope.currentRemoveControl = null;
};
$scope.setCurrentMoveControl = function (Control) {
$scope.currentMoveControl = Control;
};
$scope.disableCurrentMoveControl = function (Control) {
$scope.currentMoveControl = null;
};
$scope.setUniqueId = function (cell, index) {
var date = new Date();
var components = [
date.getYear(),
date.getMonth(),
date.getDate(),
date.getHours(),
date.getMinutes(),
date.getSeconds(),
date.getMilliseconds()
];
return components.join("");
};
$scope.addControl = function (editor, cell, index){
var newId = $scope.setUniqueId();
var newControl = {
$uniqueId: newId,
value: null,
editor: editor
};
if (index === undefined) {
index = cell.controls.length;
}
//populate control
$scope.initControl(newControl, index+1);
cell.controls.splice(index + 1, 0, newControl);
};
$scope.addTinyMce = function(cell){
var rte = $scope.getEditor("rte");
$scope.addControl(rte, cell);
};
$scope.getEditor = function(alias){
return _.find($scope.availableEditors, function(editor){return editor.alias === alias});
};
$scope.removeControl = function (cell, $index) {
cell.controls.splice($index, 1);
};
$scope.percentage = function(spans){
return ((spans/12)*100).toFixed(1);
};
// *********************************************
// Init grid
// *********************************************
$scope.checkContent();
// *********************************************
// INITIALISATION
// these methods are called from ng-init on the template
// so we can controll their first load data
//
// intialisation sets non-saved data like percentage sizing, allowed editors and
// other data that should all be pre-fixed with $ to strip it out on save
// *********************************************
// *********************************************
// Init template + sections
// *********************************************
$scope.initSection = function(section){
section.$percentage = $scope.percentage(section.grid);
var layouts = $scope.model.config.items.layouts;
if(section.allowed && sectionn.allowed.length > 0){
return _.filter(layouts, function(layout){
section.$allowedLayouts = _.indexOf(section.allowed, layout.name) >= 0;
});
}else{
section.$allowedLayouts = layouts;
}
};
// *********************************************
// Init layout / row
// *********************************************
$scope.initRow = function(row){
if(!row.areas){
row.areas = [];
}
//set a disposable unique ID
row.$uniqueId = $scope.setUniqueId();
//populate with data
_.forEach(row.areas, function(area){
if(!area.controls){
area.controls = [];
}
area.$percentage = $scope.percentage(area.grid);
if(!area.allowed){
area.$allowedEditors = $scope.availableEditors;
area.$allowsRTE = true;
}else{
area.$allowedEditors = _.filter($scope.availableEditors, function(editor){
return _.indexOf(area.allowed, editor.alias) >= 0;
});
if(_.indexOf(area.allowed,"rte")>=0){
area.$allowsRTE = true;
}
}
if(!area.allowed){
area.$allowedEditors = $scope.availableEditors;
area.$allowsRTE = true;
}else{
area.$allowedEditors = _.filter($scope.availableEditors, function(editor){
return _.indexOf(area.allowed, editor.alias) >= 0;
});
};
// *********************************************
// Init control
// *********************************************
$scope.initControl = function(control, index){
control.$index = index;
//if its a path
if(_.indexOf(control.editor.view, "/") >= 0){
control.$editorPath = control.editor.view;
}else{
//use convention
control.$editorPath = "views/propertyeditors/grid/editors/" + control.editor.view + ".html";
if(_.indexOf(area.allowed,"rte")>=0){
area.$allowsRTE = true;
}
};
}
});
};
// *********************************************
// asset styles
// *********************************************
// Init control
// *********************************************
//assetsService.loadCss("/App_Plugins/Lecoati.uSky.Grid/lib/jquery-ui-1.10.4.custom/css/ui-lightness/jquery-ui-1.10.4.custom.min.css");
//assetsService.loadCss($scope.model.config.items.approvedBackgroundCss);
$scope.initControl = function(control, index){
control.$index = index;
control.$uniqueId = $scope.setUniqueId();
if(!control.$editorPath){
//if its a path
if(_.indexOf(control.editor.view, "/") >= 0){
control.$editorPath = control.editor.view;
}else{
//use convention
control.$editorPath = "views/propertyeditors/grid/editors/" + control.editor.view + ".html";
}
}
};
gridService.getGridEditors().then(function(response){
$scope.availableEditors = response.data;
$scope.contentReady = true;
// *********************************************
// Init grid
// *********************************************
$scope.initContent();
});
});

View File

@@ -1,6 +1,6 @@
<div ng-controller="Umbraco.PropertyEditors.GridController" class="usky-grid">
<div ng-if="contentReady">
<!-- Template picker -->
<div class="uSky-templates tb" ng-show="!model.value || model.value == ''">
<div class="tr">
@@ -141,7 +141,6 @@
selectedControl:currentControl == control}"
ng-mouseover="setCurrentControl(control)"
ng-mouseleave="disableCurrentControl(control)"
ng-init="initControl(control, $index)"
class="usky-control">
<!-- Filled cell tools -->
@@ -191,6 +190,7 @@
ng-include="control.$editorPath"
class="usky-cell usky-cell-{{control.editor.view}}">
</div>
</div>
<!-- Controls repeat end -->
@@ -246,4 +246,6 @@
<!-- column repeat end -->
</div>
</div>
</div>
</div>

View File

@@ -12,7 +12,6 @@ angular.module("umbraco")
}
]
},
{
name: "2 column",
sections: [
@@ -24,7 +23,6 @@ angular.module("umbraco")
}
]
},
{
name: "2 column reversed",
sections: [
@@ -45,7 +43,7 @@ angular.module("umbraco")
areas: [
{
grid: 12,
editors: ["Headline","subHeadline"]
editors: ["headline"]
}
]
},
@@ -60,9 +58,7 @@ angular.module("umbraco")
}
]
}
],
gridConfigPath: "views/propertyeditors/grid/config/grid.default.config.js"
]
};

View File

@@ -97,15 +97,38 @@
<div ng-if="currentSection.allowAll === false">
<hr />
<ul class="unstyled">
<li ng-repeat="layout in model.value.layouts">
<label>
<input type="checkbox"
checklist-model="currentSection.allowed"
checklist-value="layout.name"> {{layout.name}}
</label>
</li>
</ul>
<div class="control-group uSky-templates-rows">
<ul class="unstyled"
ui-sortable
ng-model="model.value.templates">
<li ng-repeat="layout in model.value.layouts">
<input type="checkbox"
checklist-model="currentSection.allowed"
checklist-value="layout.name"
style="float: left; margin-right: 10px;">
<div class="uSky-templates-row" style="float: left">
<a href class="tb mainTbpt">
<div class="tr">
<div style="width:{{ percentage(area.grid); }}%" class="middle mainTdpt td" ng-repeat="area in layout.areas">
<i class="icon {{areaPreview(area)}}"></i>
</div>
</div>
</a>
</div>
<div>
{{layout.name}}<br/>
<small>{{layout.areas.length}} configurable areas</small><br/>
</div>
<br style="clear: both"/>
</li>
</ul>
</div>
</div>
</umb-control-group>
@@ -180,7 +203,7 @@
<input type="text" class="" ng-model="currentLayout.name" />
</umb-control-group>
<umb-control-group label="Areas" hide-label="false" description="Choose an area from the layout to edit">
<umb-control-group label="Layout areas" hide-label="false" description="Choose an area from the layout to edit">
<div class="uSky-templates-template"
style="margin: 0; width: 350px; position: relative;">
<div class="tb" style="height: 70px; border-width: 2px; padding: 2px">
@@ -226,7 +249,7 @@
ng-model="currentArea.allowAll"
ng-checked="currentArea.allowed === undefined"
ng-change="toggleCollection(currentArea.allowed, currentArea.allowAll)" />
Allow all layouts
Allow all editors
</label>
</li>
</ul>

View File

@@ -8,20 +8,20 @@
<div class="uSky-grid @(onlyOneColumn > 1 ? "container" : "")">
<div class="row clearfix">
@foreach (var column in Model.columns)
@foreach (var section in Model.sections)
{
<div class="col-md-@column.grid column">
@foreach (var row in column.rows)
<div class="col-md-@section.grid column">
@foreach (var row in section.rows)
{
<div class="gridrow_@row.uniqueId" >
<div class="container">
<div class="row clearfix">
@foreach (var cell in row.cells)
@foreach (var area in row.areas)
{
<div class="col-md-@cell.model.grid column">
<div class="col-md-@area.grid column">
@foreach (var control in cell.controls)
@foreach (var control in area.controls)
{
if (control != null && control.editor != null && control.editor.view != null)
{