diff --git a/README.md b/README.md index 2bcb617..3dce0d7 100644 --- a/README.md +++ b/README.md @@ -92,6 +92,12 @@ The following attributes, set within *contentObjects.json*, configure the defaul **duration** (string): Optional text which follows **durationLabel** (e.g., `"2 mins"`). +**\_boxMenu** (object): The boxMenu object that contains value for **\_renderAsGroup**. + +>**\_renderAsGroup** (boolean): Enable this option to render items into a group on the menu. Groups can display a title, body, and instruction text. + +>Framework: Change the group content object type to `menu` and update the `_parentId` of the children content objects to match the group content object `_id`. Authoring Tool: Add a submenu and check the 'Enable as menu group?' setting. All users: If accessibility is required update the aria level values in config settings so the title heirarchy remains intact. +
Back to Top
### Accessibility diff --git a/example.json b/example.json index 632559a..0552701 100644 --- a/example.json +++ b/example.json @@ -46,3 +46,40 @@ "linkText": "View", "duration": "2 mins" } + + // contentObjects.json + // Render menu with grouped items + { + "_id": "co-00", + "_parentId": "course", + "_type": "menu", + "title": "Group 1", + "displayTitle": "Group 1", + "body": "Body", + "instruction": "Instruction", + "_boxMenu": { + "_renderAsGroup": true + } + }, + { + "_id": "co-100", + "_parentId": "co-00", + "_type": "page", + "_classes": "", + "_htmlClasses": "", + "title": "Title", + "displayTitle": "Title", + "body": "Body", + "instruction": "Instruction" + }, + { + "_id": "co-200", + "_parentId": "co-00", + "_type": "page", + "_classes": "", + "_htmlClasses": "", + "title": "Title", + "displayTitle": "Title", + "body": "Body", + "instruction": "Instruction" + } diff --git a/js/adapt-contrib-boxMenu.js b/js/adapt-contrib-boxMenu.js index 649e236..f319f8f 100644 --- a/js/adapt-contrib-boxMenu.js +++ b/js/adapt-contrib-boxMenu.js @@ -2,8 +2,9 @@ define([ 'core/js/adapt', 'core/js/models/menuModel', 'core/js/views/menuView', - "./adapt-contrib-boxMenuItemView" -], function(Adapt, MenuModel, MenuView, BoxMenuItemView) { + './adapt-contrib-boxMenuItemView', + './adapt-contrib-boxMenuGroupView' +], function(Adapt, MenuModel, MenuView, BoxMenuItemView, BoxMenuGroupView) { var BoxMenuView = MenuView.extend({ @@ -12,7 +13,7 @@ define([ this.setStyles(); this.listenTo(Adapt, { - "device:changed": this.onDeviceResize + 'device:changed': this.onDeviceResize }); }, @@ -20,6 +21,30 @@ define([ this.setStyles(); }, + addChildren: function() { + var nthChild = 0; + var models = this.model.getChildren().models; + this.childViews = {}; + models.forEach(function(model) { + if (!model.get('_isAvailable')) return; + + nthChild++; + model.set('_nthChild', nthChild); + + var ChildView = (model.get('_type') === 'menu' && model.get('_boxMenu') && model.get('_boxMenu')._renderAsGroup) ? + BoxMenuGroupView : + BoxMenuItemView; + + var $parentContainer = this.$(this.constructor.childContainer); + var childView = new ChildView({ model: model }); + + this.childViews[model.get('_id')] = childView; + + $parentContainer.append(childView.$el); + + }.bind(this)); + }, + setStyles: function() { this.setBackgroundImage(); this.setBackgroundStyles(); @@ -35,10 +60,10 @@ define([ var backgroundImage; switch (Adapt.device.screenSize) { - case "large": + case 'large': backgroundImage = backgroundImages._large; break; - case "medium": + case 'medium': backgroundImage = backgroundImages._medium; break; default: @@ -47,12 +72,12 @@ define([ if (backgroundImage) { this.$el - .addClass("has-bg-image") - .css("background-image", "url(" + backgroundImage + ")"); + .addClass('has-bg-image') + .css('background-image', 'url(' + backgroundImage + ')'); } else { this.$el - .removeClass("has-bg-image") - .css("background-image", ""); + .removeClass('has-bg-image') + .css('background-image', ''); } }, @@ -90,10 +115,10 @@ define([ var backgroundImage; switch (Adapt.device.screenSize) { - case "large": + case 'large': backgroundImage = backgroundImages._large; break; - case "medium": + case 'medium': backgroundImage = backgroundImages._medium; break; default: @@ -102,12 +127,12 @@ define([ if (backgroundImage) { $header - .addClass("has-bg-image") - .css("background-image", "url(" + backgroundImage + ")"); + .addClass('has-bg-image') + .css('background-image', 'url(' + backgroundImage + ')'); } else { $header - .removeClass("has-bg-image") - .css("background-image", ""); + .removeClass('has-bg-image') + .css('background-image', ''); } }, @@ -131,10 +156,10 @@ define([ var minimumHeight; switch (Adapt.device.screenSize) { - case "large": + case 'large': minimumHeight = minimumHeights._large; break; - case "medium": + case 'medium': minimumHeight = minimumHeights._medium; break; default: @@ -143,17 +168,16 @@ define([ if (minimumHeight) { $header - .addClass("has-min-height") - .css("min-height", minimumHeight + "px"); + .addClass('has-min-height') + .css('min-height', minimumHeight + 'px'); } else { $header - .removeClass("has-min-height") - .css("min-height", ""); + .removeClass('has-min-height') + .css('min-height', ''); } } }, { - childView: BoxMenuItemView, className: 'boxmenu', template: 'boxMenu' }); diff --git a/js/adapt-contrib-boxMenuGroupView.js b/js/adapt-contrib-boxMenuGroupView.js new file mode 100644 index 0000000..802ddd5 --- /dev/null +++ b/js/adapt-contrib-boxMenuGroupView.js @@ -0,0 +1,23 @@ +define([ + 'core/js/views/menuItemView', + './adapt-contrib-boxMenuItemView' +], function(MenuItemView, BoxMenuItemView) { + + var BoxMenuGroupView = MenuItemView.extend({ + + postRender: function() { + _.defer(this.addChildren.bind(this)); + this.$el.imageready(this.setReadyStatus.bind(this)); + this.$el.parents('.boxmenu__item-container').addClass('has-groups'); + } + + }, { + childContainer: '.js-group-children', + childView: BoxMenuItemView, + className: 'boxmenu-group', + template: 'boxMenuGroup' + }); + + return BoxMenuGroupView; + +}); diff --git a/js/adapt-contrib-boxMenuItemView.js b/js/adapt-contrib-boxMenuItemView.js index 7931e77..097b42d 100644 --- a/js/adapt-contrib-boxMenuItemView.js +++ b/js/adapt-contrib-boxMenuItemView.js @@ -1,5 +1,5 @@ define([ - "core/js/views/menuItemView" + 'core/js/views/menuItemView' ], function(MenuItemView) { var BoxMenuItemView = MenuItemView.extend({ diff --git a/less/boxMenu.less b/less/boxMenu.less index fa16f12..14fe683 100644 --- a/less/boxMenu.less +++ b/less/boxMenu.less @@ -5,7 +5,7 @@ .l-container-responsive(@device-width-large); } - &__item-container-inner { + &__item-container &__item-container-inner { display: flex; flex-wrap: wrap; .l-container-responsive(@device-width-large); diff --git a/less/boxMenuGroup.less b/less/boxMenuGroup.less new file mode 100644 index 0000000..f31dd20 --- /dev/null +++ b/less/boxMenuGroup.less @@ -0,0 +1,10 @@ +.boxmenu-group { + &__header-inner { + .l-container-responsive(@device-width-large); + } + + &__item-container-inner { + display: flex; + flex-wrap: wrap; + } +} diff --git a/properties.schema b/properties.schema index 59510dc..25dedac 100644 --- a/properties.schema +++ b/properties.schema @@ -194,7 +194,24 @@ } }, "contentobject": { - "type": "object" + "type": "object", + "properties": { + "_boxMenu": { + "type": "object", + "required": false, + "properties": { + "_renderAsGroup": { + "type": "boolean", + "required": false, + "default": false, + "title": "Enable as menu group?", + "inputType": "Checkbox", + "validators": [], + "help": "Enable this option to render items into a group on the menu. Groups can display a title, body, and instruction text." + } + } + } + } }, "article": { "type": "object" diff --git a/templates/boxMenuGroup.hbs b/templates/boxMenuGroup.hbs new file mode 100644 index 0000000..dd7f4fd --- /dev/null +++ b/templates/boxMenuGroup.hbs @@ -0,0 +1,47 @@ +{{import_globals}} + + diff --git a/templates/boxMenuItem.hbs b/templates/boxMenuItem.hbs index 11af40b..c7d39c4 100644 --- a/templates/boxMenuItem.hbs +++ b/templates/boxMenuItem.hbs @@ -52,5 +52,4 @@ -