mirror of
https://github.com/getgrav/grav-plugin-admin.git
synced 2025-11-04 20:36:03 +01:00
Working inside lists
This commit is contained in:
@@ -6,244 +6,279 @@ import $ from 'jquery';
|
||||
* License: GPLv2
|
||||
*/
|
||||
|
||||
$(function() {
|
||||
var defaults = {
|
||||
'mode': 'dialog', // show overlay 'dialog' panel or slide down 'inline' panel
|
||||
'closeOnPick': true, // whether to close panel after picking or 'no'
|
||||
'save': 'class', // save icon 'class' or 'code'
|
||||
'size': '',
|
||||
'classes': {
|
||||
'launcher': '', // extra classes for launcher buttons
|
||||
'clear': 'remove-times', // extra classes for button that removes preview and clears field
|
||||
'highlight': '', // extra classes when highlighting an icon
|
||||
'close': '' // extra classes for close button
|
||||
},
|
||||
'iconSets': { // example data structure. Used to specify which launchers will be created
|
||||
'genericon': 'Genericon', // create a launcher to pick genericon icons
|
||||
'fa': 'FontAwesome' // create a launcher to pick fontawesome icons
|
||||
}
|
||||
};
|
||||
|
||||
'use strict';
|
||||
class QL_Icon_Picker {
|
||||
|
||||
var defaults = {
|
||||
'mode': 'dialog', // show overlay 'dialog' panel or slide down 'inline' panel
|
||||
'closeOnPick': true, // whether to close panel after picking or 'no'
|
||||
'save': 'class', // save icon 'class' or 'code'
|
||||
'size': '',
|
||||
'classes': {
|
||||
'launcher': '', // extra classes for launcher buttons
|
||||
'clear': 'remove-times', // extra classes for button that removes preview and clears field
|
||||
'highlight': '', // extra classes when highlighting an icon
|
||||
'close': '' // extra classes for close button
|
||||
},
|
||||
'iconSets': { // example data structure. Used to specify which launchers will be created
|
||||
'genericon': 'Genericon', // create a launcher to pick genericon icons
|
||||
'fa': 'FontAwesome' // create a launcher to pick fontawesome icons
|
||||
}
|
||||
};
|
||||
|
||||
function QL_Icon_Picker(element, options) {
|
||||
constructor(element, options) {
|
||||
this.iconSet = '';
|
||||
this.iconSetName = '';
|
||||
this.$field = '';
|
||||
this.element = element;
|
||||
this.settings = $.extend({}, defaults, options);
|
||||
this._defaults = defaults;
|
||||
this.init();
|
||||
}
|
||||
|
||||
QL_Icon_Picker.prototype = {
|
||||
init() {
|
||||
var $brick = $(this.element);
|
||||
var pickerId = $brick.data('pickerid');
|
||||
var $preview = $('<div class="icon-preview icon-preview-' + pickerId + '" />');
|
||||
|
||||
iconSet: '',
|
||||
iconSetName: '',
|
||||
$field: '',
|
||||
this.$field = $brick.find('input');
|
||||
|
||||
init: function() {
|
||||
// Add preview area
|
||||
this.makePreview($brick, pickerId, $preview);
|
||||
|
||||
var $brick = $(this.element);
|
||||
var pickerId = $brick.data('pickerid');
|
||||
var $preview = $('<div class="icon-preview icon-preview-' + pickerId + '" />');
|
||||
// Make button to clear field and remove preview
|
||||
this.makeClear(pickerId, $preview);
|
||||
|
||||
this.$field = $brick.find('input');
|
||||
// Make buttons that open the panel of icons
|
||||
this.makeLaunchers($brick, pickerId);
|
||||
|
||||
// Add preview area
|
||||
this.makePreview($brick, pickerId, $preview);
|
||||
// Prepare display styles, inline and dialog
|
||||
this.makeDisplay($brick);
|
||||
}
|
||||
|
||||
// Make button to clear field and remove preview
|
||||
this.makeClear(pickerId, $preview);
|
||||
makePreview($brick, pickerId, $preview) {
|
||||
var $icon = $('<i />');
|
||||
var iconValue = this.$field.val();
|
||||
|
||||
// Make buttons that open the panel of icons
|
||||
this.makeLaunchers($brick, pickerId);
|
||||
|
||||
// Prepare display styles, inline and dialog
|
||||
this.makeDisplay($brick);
|
||||
},
|
||||
|
||||
makePreview: function($brick, pickerId, $preview) {
|
||||
var $icon = $('<i />');
|
||||
var iconValue = this.$field.val();
|
||||
|
||||
$preview.prependTo($brick);
|
||||
$icon.prependTo($preview);
|
||||
if (iconValue !== '') {
|
||||
$preview.addClass('icon-preview-on');
|
||||
$icon.addClass(iconValue);
|
||||
}
|
||||
},
|
||||
|
||||
makeClear: function(pickerId, $preview) {
|
||||
var base = this;
|
||||
var $clear = $('<a class="remove-icon ' + base.settings.classes.clear + '" />');
|
||||
|
||||
// Hide button to remove icon and preview and append it to preview area
|
||||
$clear.hide().prependTo($preview);
|
||||
// If there's a icon saved in the field, show remove icon button
|
||||
if (base.$field.val() !== '') {
|
||||
$clear.show();
|
||||
}
|
||||
|
||||
$preview.on('click', '.remove-icon', function(e) {
|
||||
e.preventDefault();
|
||||
base.$field.val('');
|
||||
$preview.removeClass('icon-preview-on').find('i').removeClass();
|
||||
$(this).hide();
|
||||
});
|
||||
},
|
||||
|
||||
makeDisplay: function($brick) {
|
||||
var base = this;
|
||||
var close = base.settings.classes.close;
|
||||
var $body = $('body');
|
||||
|
||||
var $close = $('<a href="#" class="icon-picker-close"/>');
|
||||
|
||||
if (base.settings.mode === 'inline') {
|
||||
$brick.find('.icon-set').append($close).removeClass('dialog').addClass('inline ' + base.settings.size).parent().addClass('icon-set-wrap');
|
||||
} else if (base.settings.mode === 'dialog') {
|
||||
$('.icon-set').addClass('dialog ' + base.settings.size);
|
||||
if ($('.icon-picker-overlay').length <= 0) {
|
||||
$body.append('<div class="icon-picker-overlay"/>').append($close);
|
||||
}
|
||||
}
|
||||
$body
|
||||
.on('click', '.icon-picker-close, .icon-picker-overlay', function(e) {
|
||||
e.preventDefault();
|
||||
base.closePicker($brick, $(base.iconSet), base.settings.mode);
|
||||
})
|
||||
.on('mouseenter mouseleave', '.icon-picker-close', function(e) {
|
||||
if (e.type === 'mouseenter') {
|
||||
$(this).addClass(close);
|
||||
} else {
|
||||
$(this).removeClass(close);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
makeLaunchers: function($brick) {
|
||||
var base = this;
|
||||
var dataIconSets = $brick.data('iconsets');
|
||||
var iconSet;
|
||||
|
||||
if (typeof dataIconSets === 'undefined') {
|
||||
dataIconSets = base.settings.iconSets;
|
||||
}
|
||||
for (iconSet in dataIconSets) {
|
||||
if (dataIconSets.hasOwnProperty(iconSet)) {
|
||||
$brick.append('<a class="launch-icons ' + base.settings.classes.launcher + '" data-icons="' + iconSet + '">' + dataIconSets[iconSet] + '</a>');
|
||||
}
|
||||
}
|
||||
|
||||
$brick.find('.launch-icons').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var $self = $(this);
|
||||
var theseIcons = $self.data('icons');
|
||||
|
||||
base.iconSetName = theseIcons;
|
||||
base.iconSet = '.' + theseIcons + '-set';
|
||||
|
||||
// Initialize picker
|
||||
base.iconPick($brick);
|
||||
|
||||
// Show icon picker
|
||||
base.showPicker($brick, $(base.iconSet), base.settings.mode);
|
||||
});
|
||||
},
|
||||
|
||||
iconPick: function($brick) {
|
||||
var base = this;
|
||||
var highlight = 'icon-highlight ' + base.settings.classes.highlight;
|
||||
|
||||
$(base.iconSet).on('click', 'li', function(e) {
|
||||
e.preventDefault();
|
||||
var $icon = $(this);
|
||||
var icon = $icon.data(base.settings.save);
|
||||
|
||||
// Mark as selected
|
||||
$('.icon-selected').removeClass('icon-selected');
|
||||
$icon.addClass('icon-selected');
|
||||
|
||||
// Save icon value to field
|
||||
base.$field.val(icon);
|
||||
|
||||
// Close icon picker
|
||||
if (base.settings.closeOnPick) {
|
||||
base.closePicker($brick, $icon.closest(base.iconSet), base.settings.mode);
|
||||
}
|
||||
|
||||
// Set preview
|
||||
base.setPreview($icon.data('class'));
|
||||
|
||||
// Broadcast event passing the selected icon.
|
||||
$('body').trigger('iconselected.queryloop', icon);
|
||||
});
|
||||
$(base.iconSet).on('mouseenter mouseleave', 'li', function(e) {
|
||||
if (e.type === 'mouseenter') {
|
||||
$(this).addClass(highlight);
|
||||
} else {
|
||||
$(this).removeClass(highlight);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
showPicker: function($brick, $icons, mode) {
|
||||
if (mode === 'inline') {
|
||||
$('.icon-set').removeClass('inline-open');
|
||||
$brick.find($icons).toggleClass('inline-open');
|
||||
} else if (mode === 'dialog') {
|
||||
$('.icon-picker-close, .icon-picker-overlay').addClass('make-visible');
|
||||
$icons.addClass('dialog-open');
|
||||
}
|
||||
|
||||
$icons.find('.icon-selected').removeClass('icon-selected');
|
||||
var selectedIcon = this.$field.val().replace(' ', '.');
|
||||
if (selectedIcon !== '') {
|
||||
if (this.settings.save === 'class') {
|
||||
$icons.find('.' + selectedIcon).addClass('icon-selected');
|
||||
} else {
|
||||
$icons.find('[data-code="' + selectedIcon + '"]').addClass('icon-selected');
|
||||
}
|
||||
}
|
||||
// Broadcast event when the picker is shown passing the picker mode.
|
||||
$('body').trigger('iconpickershow.queryloop', mode);
|
||||
},
|
||||
|
||||
closePicker: function($brick, $icons, mode) {
|
||||
// Remove event so they don't fire from a different picker
|
||||
$(this.iconSet).off('click', 'li');
|
||||
|
||||
if (mode === 'inline') {
|
||||
$brick.find($icons).removeClass('inline-open');
|
||||
} else if (mode === 'dialog') {
|
||||
$('.icon-picker-close, .icon-picker-overlay').removeClass('make-visible');
|
||||
$icons.removeClass('dialog-open');
|
||||
}
|
||||
// Broadcast event when the picker is closed passing the picker mode.
|
||||
$('body').trigger('iconpickerclose.queryloop', mode);
|
||||
},
|
||||
|
||||
setPreview: function(preview) {
|
||||
var $preview = $(this.element).find('.icon-preview');
|
||||
|
||||
$preview.addClass('icon-preview-on').find('i').removeClass()
|
||||
.addClass(this.iconSetName)
|
||||
.addClass(preview);
|
||||
$preview.find('a').show();
|
||||
$preview.prependTo($brick);
|
||||
$icon.prependTo($preview);
|
||||
if (iconValue !== '') {
|
||||
$preview.addClass('icon-preview-on');
|
||||
$icon.addClass(iconValue);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
$.fn.qlIconPicker = function(options) {
|
||||
this.each(function() {
|
||||
if (!$.data(this, 'plugin_qlIconPicker')) {
|
||||
$.data(this, 'plugin_qlIconPicker', new QL_Icon_Picker(this, options));
|
||||
makeClear(pickerId, $preview) {
|
||||
var base = this;
|
||||
var $clear = $('<a class="remove-icon ' + base.settings.classes.clear + '" />');
|
||||
|
||||
// Hide button to remove icon and preview and append it to preview area
|
||||
$clear.hide().prependTo($preview);
|
||||
// If there's a icon saved in the field, show remove icon button
|
||||
if (base.$field.val() !== '') {
|
||||
$clear.show();
|
||||
}
|
||||
|
||||
$preview.on('click', '.remove-icon', function(e) {
|
||||
e.preventDefault();
|
||||
base.$field.val('');
|
||||
$preview.removeClass('icon-preview-on').find('i').removeClass();
|
||||
$(this).hide();
|
||||
});
|
||||
}
|
||||
|
||||
makeDisplay($brick) {
|
||||
var base = this;
|
||||
var close = base.settings.classes.close;
|
||||
var $body = $('body');
|
||||
|
||||
var $close = $('<a href="#" class="icon-picker-close"/>');
|
||||
|
||||
if (base.settings.mode === 'inline') {
|
||||
$brick.find('.icon-set').append($close).removeClass('dialog').addClass('inline ' + base.settings.size).parent().addClass('icon-set-wrap');
|
||||
} else if (base.settings.mode === 'dialog') {
|
||||
$('.icon-set').addClass('dialog ' + base.settings.size);
|
||||
if ($('.icon-picker-overlay').length <= 0) {
|
||||
$body.append('<div class="icon-picker-overlay"/>').append($close);
|
||||
}
|
||||
}
|
||||
$body
|
||||
.on('click', '.icon-picker-close, .icon-picker-overlay', function(e) {
|
||||
e.preventDefault();
|
||||
base.closePicker($brick, $(base.iconSet), base.settings.mode);
|
||||
})
|
||||
.on('mouseenter mouseleave', '.icon-picker-close', function(e) {
|
||||
if (e.type === 'mouseenter') {
|
||||
$(this).addClass(close);
|
||||
} else {
|
||||
$(this).removeClass(close);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
makeLaunchers($brick) {
|
||||
var base = this;
|
||||
var dataIconSets = $brick.data('iconsets');
|
||||
var iconSet;
|
||||
|
||||
if (typeof dataIconSets === 'undefined') {
|
||||
dataIconSets = base.settings.iconSets;
|
||||
}
|
||||
for (iconSet in dataIconSets) {
|
||||
if (dataIconSets.hasOwnProperty(iconSet)) {
|
||||
$brick.append('<a class="launch-icons ' + base.settings.classes.launcher + '" data-icons="' + iconSet + '">' + dataIconSets[iconSet] + '</a>');
|
||||
}
|
||||
}
|
||||
|
||||
$brick.find('.launch-icons').on('click', function(e) {
|
||||
e.preventDefault();
|
||||
var $self = $(this);
|
||||
var theseIcons = $self.data('icons');
|
||||
|
||||
base.iconSetName = theseIcons;
|
||||
base.iconSet = '.' + theseIcons + '-set';
|
||||
|
||||
// Initialize picker
|
||||
base.iconPick($brick);
|
||||
|
||||
// Show icon picker
|
||||
base.showPicker($brick, $(base.iconSet), base.settings.mode);
|
||||
});
|
||||
}
|
||||
|
||||
iconPick($brick) {
|
||||
var base = this;
|
||||
var highlight = 'icon-highlight ' + base.settings.classes.highlight;
|
||||
|
||||
$(base.iconSet).on('click', 'li', function(e) {
|
||||
e.preventDefault();
|
||||
var $icon = $(this);
|
||||
var icon = $icon.data(base.settings.save);
|
||||
|
||||
// Mark as selected
|
||||
$('.icon-selected').removeClass('icon-selected');
|
||||
$icon.addClass('icon-selected');
|
||||
|
||||
// Save icon value to field
|
||||
base.$field.val(icon);
|
||||
|
||||
// Close icon picker
|
||||
if (base.settings.closeOnPick) {
|
||||
base.closePicker($brick, $icon.closest(base.iconSet), base.settings.mode);
|
||||
}
|
||||
|
||||
// Set preview
|
||||
base.setPreview($icon.data('class'));
|
||||
|
||||
// Broadcast event passing the selected icon.
|
||||
$('body').trigger('iconselected.queryloop', icon);
|
||||
});
|
||||
$(base.iconSet).on('mouseenter mouseleave', 'li', function(e) {
|
||||
if (e.type === 'mouseenter') {
|
||||
$(this).addClass(highlight);
|
||||
} else {
|
||||
$(this).removeClass(highlight);
|
||||
}
|
||||
});
|
||||
return this;
|
||||
};
|
||||
}
|
||||
|
||||
$('.icon-picker').qlIconPicker({
|
||||
'save': 'class'
|
||||
showPicker($brick, $icons, mode) {
|
||||
if (mode === 'inline') {
|
||||
$('.icon-set').removeClass('inline-open');
|
||||
$brick.find($icons).toggleClass('inline-open');
|
||||
} else if (mode === 'dialog') {
|
||||
$('.icon-picker-close, .icon-picker-overlay').addClass('make-visible');
|
||||
$icons.addClass('dialog-open');
|
||||
}
|
||||
|
||||
$icons.find('.icon-selected').removeClass('icon-selected');
|
||||
var selectedIcon = this.$field.val().replace(' ', '.');
|
||||
if (selectedIcon !== '') {
|
||||
if (this.settings.save === 'class') {
|
||||
$icons.find('.' + selectedIcon).addClass('icon-selected');
|
||||
} else {
|
||||
$icons.find('[data-code="' + selectedIcon + '"]').addClass('icon-selected');
|
||||
}
|
||||
}
|
||||
// Broadcast event when the picker is shown passing the picker mode.
|
||||
$('body').trigger('iconpickershow.queryloop', mode);
|
||||
}
|
||||
|
||||
closePicker($brick, $icons, mode) {
|
||||
// Remove event so they don't fire from a different picker
|
||||
$(this.iconSet).off('click', 'li');
|
||||
|
||||
if (mode === 'inline') {
|
||||
$brick.find($icons).removeClass('inline-open');
|
||||
} else if (mode === 'dialog') {
|
||||
$('.icon-picker-close, .icon-picker-overlay').removeClass('make-visible');
|
||||
$icons.removeClass('dialog-open');
|
||||
}
|
||||
// Broadcast event when the picker is closed passing the picker mode.
|
||||
$('body').trigger('iconpickerclose.queryloop', mode);
|
||||
}
|
||||
|
||||
setPreview(preview) {
|
||||
var $preview = $(this.element).find('.icon-preview');
|
||||
|
||||
$preview.addClass('icon-preview-on').find('i').removeClass()
|
||||
.addClass(this.iconSetName)
|
||||
.addClass(preview);
|
||||
$preview.find('a').show();
|
||||
}
|
||||
};
|
||||
|
||||
export default class IconpickerField {
|
||||
|
||||
constructor(options) {
|
||||
this.items = $();
|
||||
this.options = Object.assign({}, this.defaults, options);
|
||||
|
||||
$('[data-grav-iconpicker]').each((index, element) => this.addItem(element));
|
||||
$('body').on('mutation._grav', this._onAddedNodes.bind(this));
|
||||
}
|
||||
|
||||
_onAddedNodes(event, target/* , record, instance */) {
|
||||
let fields = $(target).find('[data-grav-iconpicker]');
|
||||
if (!fields.length) { return; }
|
||||
|
||||
fields.each((index, field) => {
|
||||
field = $(field);
|
||||
if (!~this.items.index(field)) {
|
||||
this.addItem(field);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
addItem(element) {
|
||||
element = $(element);
|
||||
this.items = this.items.add(element);
|
||||
|
||||
$.fn.qlIconPicker = function(options) {
|
||||
this.each(function() {
|
||||
if (!$.data(this, 'plugin_qlIconPicker')) {
|
||||
$.data(this, 'plugin_qlIconPicker', new QL_Icon_Picker(this, options));
|
||||
}
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
$('.icon-picker').qlIconPicker({
|
||||
'save': 'class'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export let Instance = new IconpickerField();
|
||||
|
||||
$.fn.qlIconPicker = function(options) {
|
||||
this.each(function() {
|
||||
if (!$.data(this, 'plugin_qlIconPicker')) {
|
||||
$.data(this, 'plugin_qlIconPicker', new QL_Icon_Picker(this, options));
|
||||
}
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
$('.icon-picker').qlIconPicker({
|
||||
'save': 'class'
|
||||
});
|
||||
|
||||
36
themes/grav/js/admin.min.js
vendored
36
themes/grav/js/admin.min.js
vendored
File diff suppressed because one or more lines are too long
54
themes/grav/js/vendor.min.js
vendored
54
themes/grav/js/vendor.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -2,6 +2,13 @@
|
||||
{% set originalValue = originalValue is defined ? originalValue : value %}
|
||||
{% set value = (value is null ? field.default : value) %}
|
||||
|
||||
{% block global_attributes %}
|
||||
data-grav-iconpicker
|
||||
data-name="{{field.name}}"
|
||||
data-value="{{value}}"
|
||||
{{ parent() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block input %}
|
||||
<div class="form-list-wrapper {{ field.size }}" data-type="collection">
|
||||
<div class="icon-picker" data-pickerid="fa" data-iconsets='{"fa":"Pick FontAwesome"}'>
|
||||
|
||||
Reference in New Issue
Block a user