Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Feature/hierarchical content #7227

Open
wants to merge 6 commits into
base: 3.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
158 changes: 158 additions & 0 deletions app/src/js/widgets/fields/fieldParentId.js
@@ -0,0 +1,158 @@
/* eslint no-console: ["error", { allow: ["error"] }] */
/**
* @param {Object} $ - Global jQuery object
* @param {Object} bolt - The Bolt module
*/
(function ($) {
'use strict';

/**
* Parent ID field widget.
*
* @license http://opensource.org/licenses/mit-license.php MIT License
* @author mrenigma
*
* @class parentId
* @memberOf jQuery.widget.bolt
* @extends jQuery.widget.bolt.baseField
*/
$.widget('bolt.fieldParentId', $.bolt.baseField, /** @lends jQuery.widget.bolt.parentId.prototype */ {
/**
* Default options.
*
* @property {string|null} contentId - Content Id
* @property {string} key - The field key
* @property {string} slug - Content slug
* @property {Array} uses - Fields used to automatically generate a slug
*/
options : {
contentId : null,
key : ''
},

/**
* The constructor of the slug field widget.
*
* @private
*/
_create : function () {
var self = this, fieldset = this.element;

/**
* Refs to UI elements of this widget.
*
* @type {Object}
* @name _ui
* @memberOf jQuery.widget.bolt.parentId.prototype
* @private
*
* @property {Object} form - The form this input is part of
* @property {Object} group - Group container
* @property {Object} data - Data field
* @property {Object} uses - Collection of uses fields
*/
this._ui = {
form : this.element.closest('form'),
group : fieldset.find('.input-group'),
data : fieldset.find('input'),
uses : $()
};

/**
* A timeout.
*
* @type {number}
* @name _timeout
* @memberOf jQuery.widget.bolt.parentId.prototype
* @private
*/
this._timeout = 0;

// Bind events.
this._on({
'click li.lock' : function (event) {
event.preventDefault();
this._setMode(mode.lock);
},
'click li.link' : function (event) {
event.preventDefault();
this._setMode(mode.link);
},
'click li.edit' : function (event) {
event.preventDefault();
this._setMode(mode.edit);
this.element.find('input').focus();
},
'focusout input' : function () {
if (this._mode === mode.edit) {
this._setMode(mode.lock);
}
}
});
},

/**
* Cleanup.
*
* @private
*/
_destroy : function () {
clearTimeout(this._timeout);
},

/**
* Build the slug using the fields described in the uses parameter.
*
* @private
*/
_buildSlug : function () {
var self = this, term = '', value;

console.log(self);

$.each(self.options.uses, function (i, field) {
value = $('#' + field).val();

if (value) {
term += (typeof value === 'object' ? value.join(' ') : value) + ' ';
}
});

clearTimeout(self._timeout);
self._timeout = setTimeout(function () {
self._getUri(term.trim());
}, 200);
},

/**
* Get URI for slug from remote.
*
* @private
* @param {string} text - New slug text
*/
_getUri : function (text) {
var self = this, data = {
title : text,
contenttypeslug : self.options.slug,
id : self.options.contentId,
slugfield : self.options.key,
fulluri : false
};

self._ui.group.addClass('loading');

$.get(self._ui.data.data('createSlugUrl'), data)
.done(function (uri) {
if (self._mode === mode.link) {
self._ui.data.val(uri);
}
})
.fail(function () {
console.error('Failed to get URI for ' + self.options.slug + '/' + self.options.contentId);
})
.always(function () {
self._ui.group.removeClass('loading');
});
}
});
})(jQuery, Bolt);
81 changes: 81 additions & 0 deletions app/view/js/parent-change.js
@@ -0,0 +1,81 @@
/* global hierarchies */
(function ($) {
'use strict';

var $parent = $('#parent');
var id = $('#id').val();

var getOption = function (key) {
var option;

for (var i = 0; i < hierarchies.length; i += 1) {
if (hierarchies[i].key === key) {
option = hierarchies[i];
option.index = i + 1;

break;
}
}

return option;
};

$parent.on('change', function () {
var val = $(this).val();
var $prefix = $('.bolt-field-slug .input-group-addon');
var hierarchy = getOption(val);

if (typeof hierarchies !== 'undefined' && typeof hierarchy !== 'undefined') {
$prefix.text(hierarchy.path);
} else if (typeof hierarchies !== 'undefined' && hierarchies.length && hierarchies[0].prefix !== null) {
$prefix.text('/' + hierarchies[0].prefix || '/');
} else if (val === '') {
$prefix.text('/');
}
});

// Remove this site from the list
$parent.find('option[value="' + id + '"]').attr('disabled', true);

if (typeof hierarchies !== 'undefined') {
// Order the options based on the hierarchies output
var $options = [];
var i;
var $option = null;

for (i = 0; i < hierarchies.length; i += 1) {
// Reset the option
$option = null;

hierarchies[i].index = i + 1;

// Find the option
$option = $parent.find('option[value="' + hierarchies[i].key + '"]');

// Check if option is the current item
if (id === hierarchies[i].key) {
$(this).attr('disabled', true);
}

// Add dashes to text
var count = (hierarchies[i].path.replace(hierarchies[i].prefix, '').match(/\//g) || []).length - 2;
var dashedText = '';

for (var j = 0; j < count; j++) {
dashedText += '- '
}

dashedText += $option.text();

$option.text(dashedText);

// Add to array of all the options
$options.push($option);
}

// Add the ordered options from the field back in to the field
$parent.append($options);
}

$parent.trigger('change');
})(jQuery);
12 changes: 11 additions & 1 deletion app/view/twig/_base/_listing.twig
@@ -1,5 +1,6 @@
{% import '@bolt/_macro/_macro.twig' as macro %}
{% from '@bolt/_buic/_moment.twig' import buic_moment %}
{% from '@bolt/_sub/_sub-items.twig' import sub_items_list %}
{% from _self import tbody_beg, tbody_end %}

{% macro tbody_beg(local, modifiable) %}
Expand Down Expand Up @@ -129,7 +130,13 @@ row_header: prop.extended and (prop.first or (prop.has_groupname and prop.ne
{#
# DATA ROW
#}
<tr {% if content.status!='published' %}class="dim"{% endif %}{% if modifiable %} id="item_{{ content.id }}"{% endif %}>
{% if content.parentid is empty or content.parentid == 0 %}
{% if counter is not defined %}
{% set counter = 0 %}
{% endif %}

{% set colour = cycle(['odd', 'even'], counter) %}
<tr class="{{ colour }}{% if content.status!='published' %}dim{% endif %}"{% if modifiable %} id="item_{{ content.id }}"{% endif %}>

{### BLOCK: ID ###}
{% block listing_id %}
Expand Down Expand Up @@ -324,6 +331,9 @@ row_header: prop.extended and (prop.first or (prop.has_groupname and prop.ne
{% endblock %}
</tr>

{{ sub_items_list(content, permissions, '-', colour, compact, thumbsize, excerptlength) }}
{% endif %}

{% if prop.last %}
{{ tbody_end(internal.selection_toolbar|default()) }}
{% endif %}
7 changes: 6 additions & 1 deletion app/view/twig/_sub/_record_list.twig
Expand Up @@ -28,7 +28,11 @@
>
{% endif %}
<table class="{{ extra_classes }} dashboardlisting listing">
{% set counter = 0 %}
{% for content in multiplecontent %}
{% if content.parentid is empty or content.parentid == 0 %}
{% set counter = counter + 1 %}
{% endif %}
{% set editable = permissions.edit %}
{% if editable %}
{% set any_editable = true %}
Expand All @@ -49,7 +53,8 @@
'internal': {
'selection_toolbar': selection_toolbar
},
'filter': filter
'filter': filter,
'counter': counter
} %}
{{ include(includes, listing_vars) }}

Expand Down