io-8.x-1.x-dev/modules/io_browser/js/src/io-browser.widget.js
modules/io_browser/js/src/io-browser.widget.js
/**
* @file
* Provides IO Browser widget utility functions.
*/
(function ($, Drupal, Sortable, _d) {
'use strict';
var _nick = 'ib';
var _root = '.' + _nick;
var _isNick = 'is-' + _nick;
var _idWidget = _nick + '-widget';
var _onWidget = _isNick + '-widget-on';
var _baseWidget = _root + '__widget';
var _selWidget = _baseWidget + ':not(.' + _onWidget + ')';
var _idSortable = _nick + '-sortable';
var _onSortable = _nick + '__sortable-on';
var _baseSortable = _root + '__sortable';
var _selSortable = _baseSortable + ':not(.' + _onSortable + ')';
var _isActive = _isNick + '-active';
var _isFocused = _isNick + '-focused';
var _selSubmit = '.js-form-managed-file .js-form-submit:not(.button--ib)';
var _cAjax = 'ibAjax';
Drupal.ioBrowser = Drupal.ioBrowser || {};
/**
* IO Browser widget utility functions.
*
* @param {HTMLElement} widget
* The IO Browser widget HTML element.
*/
function fbWidget(widget) {
var $widget = $(widget);
var $form = $widget.closest('form');
// var widgetId = $widget.attr('id');
// var $slider = $('.slick__slider', widget);
// var $sliderMain = $('.io--browser .slick__slider', widget);
// var $ibAction = $('.ib__header', widget);
// var $dots = $('.slick-dots', widget);
// var $grids = $('.blazy--grid', widget);
// var end = $widget.data('end') ? $widget.data('end') : 0;
// var initialized = $sliderMain.hasClass(_slickInitialized);
// We are allowed by Display style to use configurable Blazy Grid instead.
// We use JS since this class is added by theme level later, not module.
$('.media-library-item--grid', widget).removeClass('media-library-item--grid');
/**
* Update the view of the working widget.
*
* @name onUpdateView
*
* @param {jQuery.Event} e
* The event triggered, most likely a `click` event.
*/
function onUpdateView(e) {
e.preventDefault();
var $btn = $(e.currentTarget);
var handled = $btn.data('handled');
var target = $btn.data('target');
var $targetId = $widget.siblings('input[type*=hidden][name*="[target_id]"]');
if (target !== 'done') {
$widget.data('deltas', '');
}
$widget.toggleClass('is-ib-' + target);
$.each(['caption', 'crop', 'sort', 'done'], function (i, btn) {
if (target === 'done' || target !== btn) {
$widget.removeClass(_isNick + '-' + btn);
}
});
$('.button--ib').removeClass(_isActive);
$('.button--' + target, widget)[$widget.hasClass(_isNick + '-' + target) ? 'addClass' : 'removeClass'](_isActive);
var updateCount = function () {
var count = $widget.find('input[data-entity-id]').length;
$widget.attr('data-ib-count-items', count);
};
updateCount();
switch (target) {
// case 'crop':
// if (!handled && $sliderMain.length) {
// $sliderMain[0].slick.refresh();
// }
// break;
case 'remove':
var entityId = $btn.data('entityId') || $btn.closest('[data-entity-id]').data('entityId');
var ids = $targetId.val();
var existing = $widget.data('removedId') || '';
$targetId.val($.trim(ids.replace(entityId, '')));
$widget.data('removedId', existing + ' ' + entityId);
// rebuildSlick($btn);
$widget.find(_baseSortable + ' [data-entity-id="' + entityId + '"]').remove();
updateCount();
break;
case 'removeall':
$targetId.val('');
$widget.contents(':not(div[id*="ajax-wrapper"])').remove();
$widget.css('minHeight', 0);
// rebuildSlick($btn);
updateCount();
break;
case 'done':
updateCount();
break;
default:
break;
}
$btn.data('handled', !handled);
// Drupal.ioBrowser.jump(widgetId);
// cleanUp();
// updateWidgetHeight();
}
/**
* Fixes for Focal Point indicator conflict with draggable.
*
* @name focalPoint
function focalPoint() {
$('*[draggable!=true]', $sliderMain).unbind('dragstart');
$sliderMain.on('draggable mouseenter mousedown', '.focal-point-indicator', function (e) {
e.stopPropagation();
});
}
*/
/**
* Reveal alt and title for just in case required, but left empty.
*
* @name onRevealText
*
* @param {jQuery.Event} event
* The event triggered, most likely a `click` event.
*/
function onRevealText(event) {
var form = $form.length ? $form[0] : event.delegateTarget;
// var ibId = $('.is-ib-error', $form).attr('id');
// var $slider = $('.ib .slick__slider', $form);
var $text = $('.form-text.required', form);
if (!$text.length) {
return;
}
$text.each(function () {
var $that = $(this);
$that.removeClass('error');
if (!this.value) {
$that.addClass('error');
$that.closest(_baseWidget).addClass('is-ib-error is-ib-caption');
}
});
}
/**
* Reacts on Alt/ Title field clicks.
*
* @name onTextClick
*
* @param {jQuery.Event} e
* The event triggered, a `click` event.
*/
function onTextClick(e) {
$(e.target).parent().addClass(_isFocused);
}
/**
* Reacts on Alt/ Title field blur event.
*
* @name onTextBlur
*
* @param {jQuery.Event} e
* The event triggered, a `click` event.
*/
function onTextBlur(e) {
$(e.target).parent().removeClass(_isFocused);
}
// cleanUp();
// if ($widget.hasClass('is-ib-1')) {
// $('.slick__slide', widget).addClass('slick-current slick-active');
// }
// if (initialized && !$ibAction.find('.slick__arrow').length) {
// $sliderMain.siblings('.slick__arrow').appendTo($ibAction);
// }
// if (end > 1 && $('.focal-point-indicator', $sliderMain).length) {
// focalPoint();
// }
// @todo var removedIds = $widget.data('removedId');
// @todo if (removedIds) {
// @todo var ids = removedIds.split(' ');
// @todo $.each(ids, function (i, v) {
// @todo });
// @todo }
$widget.data('deltas', '');
var cBtn = 'click.btnIb';
var cAlt = 'click.altIb';
var cBlur = 'blur.altIb';
var sInput = '.js-form-type-textfield input';
$widget.off(cBtn).on(cBtn, '.button--ib', onUpdateView);
$widget.off(cAlt).on(cAlt, sInput, onTextClick);
$widget.off(cBlur).on(cBlur, sInput, onTextBlur);
onRevealText();
$form.on('click.btnDo', '#edit-submit', onRevealText);
// updateWidgetHeight();
$widget.addClass(_onWidget);
}
/**
* IO Browser sortable utility functions.
*
* @param {HTMLElement} elm
* The sortable container HTML element.
*/
function fnSortable(elm) {
var $elm = $(elm);
/**
* Sort the elements.
*
* @name sortItems
*
* @param {jQuery.Event} event
* The event triggered by a `sortable` event.
*/
function sortItems(event) {
var $target = $(event.item);
var $items = $('.ib__sortitem', elm);
var $widget = $target.closest(_baseWidget);
var eb = $target.closest('.is-ib-eb').length;
var ids = [];
var deltas = [];
var delta = 0;
var item;
var len = $items.length;
// Update the slick slides to match the new ordered elements.
for (var i = 0; i < len; i++) {
item = $items[i];
delta = $(item).data('rowId');
deltas[i] = delta;
$('.ib__weight', item).val(i);
$('.ib__weight option', item).removeAttr('selected');
$('.ib__weight option[value="' + i + '"]', item).prop('selected', true).siblings('option').prop('selected', false);
// $widget.find('.slick__slide.slide--' + delta).attr(_dataSlickIndex, i).attr('data-row-id', i);
$(item).attr('data-row-id', i);
if (eb) {
ids[i] = $(item).attr('data-entity-id');
}
}
$widget.data('deltas', deltas);
// Update entity browser target_id fields.
if (eb) {
$widget.siblings('input[type*=hidden][name*="[target_id]"]').val(ids.join(' '));
}
}
Sortable.create(elm, {
draggable: '.ib__sortitem',
// @todo filter: 'a, input, .button, .ib__action',
// @todo handle: '.ib__preview',
preventOnFilter: false,
onEnd: sortItems
});
$elm.addClass(_onSortable);
}
/**
* Attaches slick browser widget behavior to HTML element.
*
* @type {Drupal~behavior}
*/
Drupal.behaviors.ioBrowserWidget = {
attach: function (context) {
var me = Drupal.ioBrowser;
_d.once(fbWidget, _idWidget, _selWidget, context);
_d.once(fnSortable, _idSortable, _selSortable, context);
$(_selSubmit, context).on('mousedown.' + _cAjax, me.loading);
},
detach: function (context, setting, trigger) {
if (trigger === 'unload') {
$(_selSubmit, context).off('.' + _cAjax);
_d.once.removeSafely(_idWidget, _selWidget, context);
_d.once.removeSafely(_idSortable, _selSortable, context);
Drupal.ioBrowser.loaded();
}
}
};
})(jQuery, Drupal, Sortable, dBlazy);
