Files
mixtape/zero.Web.UI/App/directives/all.js
T

219 lines
4.6 KiB
JavaScript

import Strings from 'zero/helpers/strings.js';
import Localization from 'zero/helpers/localization.js';
import Sortable from 'sortablejs';
import * as ClickOutsideHelpers from './clickoutside.js';
import { Resizable as ResizableHelper } from './resizable.js';
/**
* Localizes the given property and sets the inner-text of the node to its result
*/
export var localize = (el, binding) =>
{
if (binding.value !== binding.oldValue || !el.innerText)
{
const hasValue = !!binding.value;
const isObject = typeof binding.value === 'object';
let key = hasValue ? (isObject ? binding.value.key : binding.value) : null;
let options = hasValue && isObject ? binding.value : null;
const result = hasValue ? Localization.localize(key, options) : '';
// set content as html
if (binding.arg === 'html')
{
el.innerHTML = result;
}
// set title
else if (binding.arg === 'title')
{
el.title = result;
}
// set attribute
else if (binding.arg)
{
el.setAttribute(binding.arg, result);
}
// set content as plain text
else
{
el.innerText = result;
}
}
};
/**
* Sets the placeholder to the desired string or executes a function which gets the placeholder string
*/
export var placeholder = (el, binding) =>
{
if (binding.value !== binding.oldValue || !el.innerText)
{
const hasValue = !!binding.value;
const isObject = typeof binding.value === 'object';
let value = hasValue ? (isObject ? binding.value.placeholder : binding.value) : null;
let result = null;
if (isObject && typeof value === 'function')
{
if (typeof binding.value.model === 'undefined')
{
// TODO throw warning
return;
}
result = value(binding.value.model);
}
else
{
result = value;
}
result = hasValue ? Localization.localize(result) : '';
el.setAttribute('placeholder', result);
}
};
/**
* Outputs a formatted date
*/
export var date = (el, binding) =>
{
if (binding.value !== binding.oldValue)
{
if (!binding.value)
{
el.innerHTML = '-';
return;
}
el.innerHTML = Strings.date(binding.value);
}
};
/**
* Enables sorting of a list
*/
export var sortable = (el, binding) =>
{
if (binding.value === binding.oldValue)
{
return;
}
let sortable = new Sortable(el, binding.value || {});
};
/**
* Outputs a filesize
*/
export var filesize = (el, binding) =>
{
if (binding.value !== binding.oldValue)
{
el.innerText = Strings.filesize(binding.value);
}
};
/**
* Outputs a currency
*/
export var currency = (el, binding) =>
{
if (binding.value !== binding.oldValue)
{
el.innerHTML = Strings.currency(binding.value);
}
};
/**
* resize an element
*/
export var resizable = {
bind(el, binding)
{
let resizable = new ResizableHelper(el, binding.value);
resizable.listen();
}
};
/**
* Limits an element to a maximum number of text lines (can be toggled with click)
*/
export var maxLines = (el, binding) =>
{
if (binding.value !== binding.oldValue)
{
if (!el.__zero_maxlines)
{
el.__zero_maxlines = true;
el.addEventListener('click', e =>
{
el.classList.toggle('is-expanded');
});
}
el.classList.add('ui-maxlines');
el.style.webkitLineClamp = +binding.value > 0 ? +binding.value : null;
}
};
/**
* resize an element
*/
export var clickOutside = {
bind(el, binding, vNode)
{
if (!ClickOutsideHelpers.validate(binding)) return;
// Define Handler and cache it on the element
function handler(e)
{
if (!vNode.context) return;
// some components may have related popup item, on which we shall prevent the click outside event handler.
var elements = e.path || (e.composedPath && e.composedPath());
elements && elements.length > 0 && elements.unshift(e.target);
if (el.contains(e.target) || ClickOutsideHelpers.isPopup(vNode.context.popupItem, elements) || !el.__vueClickOutside__)
{
return;
}
el.__vueClickOutside__.callback(e);
}
// add Event Listeners
el.__vueClickOutside__ = {
handler: handler,
callback: binding.value
};
setTimeout(() =>
{
!ClickOutsideHelpers.isServer(vNode) && document.addEventListener('click', handler);
}, 200);
},
update(el, binding)
{
if (ClickOutsideHelpers.validate(binding))
{
el.__vueClickOutside__.callback = binding.value;
}
},
unbind(el, binding, vNode)
{
!ClickOutsideHelpers.isServer(vNode) && document.removeEventListener('click', el.__vueClickOutside__.handler);
delete el.__vueClickOutside__;
}
};