@pi0/framework7
Version:
Full featured mobile HTML framework for building iOS & Android apps
233 lines (216 loc) • 7.61 kB
JavaScript
/* eslint indent: ["off"] */
import $ from 'dom7';
import Utils from '../../utils/utils';
import Modal from '../modal/modal-class';
class Actions extends Modal {
constructor(app, params) {
const extendedParams = Utils.extend({
toPopover: app.params.actions.convertToPopover,
on: {},
}, params);
// Extends with open/close Modal methods;
super(app, extendedParams);
const actions = this;
actions.params = extendedParams;
// Buttons
let groups;
if (actions.params.buttons) {
groups = actions.params.buttons;
if (!Array.isArray(groups[0])) groups = [groups];
}
actions.groups = groups;
// Find Element
let $el;
if (actions.params.el) {
$el = $(actions.params.el);
} else if (actions.params.content) {
$el = $(actions.params.content);
} else if (actions.params.buttons) {
if (actions.params.toPopover) {
actions.popoverHtml = actions.renderPopover();
}
actions.actionsHtml = actions.render();
}
if ($el && $el.length > 0 && $el[0].f7Modal) {
return $el[0].f7Modal;
}
if ($el && $el.length === 0 && !(actions.actionsHtml || actions.popoverHtml)) {
return actions.destroy();
}
// Backdrop
let $backdropEl = app.root.children('.actions-backdrop');
if ($backdropEl.length === 0) {
$backdropEl = $('<div class="actions-backdrop"></div>');
app.root.append($backdropEl);
}
const originalOpen = actions.open;
const originalClose = actions.close;
let popover;
function buttonOnClick(e) {
const buttonEl = this;
let buttonIndex;
let groupIndex;
if ($(buttonEl).hasClass('item-link')) {
buttonIndex = $(buttonEl).parents('li').index();
groupIndex = $(buttonEl).parents('.list').index();
} else {
buttonIndex = $(buttonEl).index();
groupIndex = $(buttonEl).parents('.actions-group').index();
}
const button = groups[groupIndex][buttonIndex];
if (button.onClick) button.onClick(actions, e);
if (actions.params.onClick) actions.params.onClick(actions, e);
if (button.close !== false) actions.close();
}
actions.open = function open(animate) {
let convertToPopover = false;
if (actions.params.toPopover && actions.params.targetEl) {
// Popover
if (app.device.ios && app.device.ipad) {
convertToPopover = true;
} else if (app.width >= 768) {
convertToPopover = true;
}
}
if (convertToPopover) {
popover = app.popover.create({
content: actions.popoverHtml,
targetEl: actions.params.targetEl,
});
popover.open(animate);
popover.once('popoverOpened', () => {
popover.$el.find('.item-link').each((groupIndex, buttonEl) => {
$(buttonEl).on('click', buttonOnClick);
});
});
popover.once('popoverClosed', () => {
popover.$el.find('.item-link').each((groupIndex, buttonEl) => {
$(buttonEl).on('click', buttonOnClick);
});
Utils.nextTick(() => {
popover.destroy();
popover = undefined;
});
});
} else {
actions.$el = $(actions.actionsHtml);
actions.$el[0].f7Modal = actions;
actions.$el.find('.actions-button').each((groupIndex, buttonEl) => {
$(buttonEl).on('click', buttonOnClick);
});
actions.once('actionsClosed', () => {
actions.$el.find('.list-button').each((groupIndex, buttonEl) => {
$(buttonEl).off('click', buttonOnClick);
});
});
originalOpen.call(actions, animate);
}
return actions;
};
actions.close = function close(animate) {
if (popover) {
popover.close(animate).once('popoverClose', () => {
popover.destroy();
popover = undefined;
});
} else {
originalClose.call(actions, animate);
}
return actions;
};
Utils.extend(actions, {
app,
$el,
el: $el ? $el[0] : undefined,
$backdropEl,
backdropEl: $backdropEl[0],
type: 'actions',
});
if ($el) {
$el[0].f7Modal = actions;
}
return actions;
}
render() {
const actions = this;
if (actions.params.render) return actions.params.render.call(actions, actions);
const { groups } = actions;
return `
<div class="actions-modal${actions.params.grid ? ' actions-grid' : ''}">
${groups.map(group =>
`<div class="actions-group">
${group.map((button) => {
const buttonClasses = [`actions-${button.label ? 'label' : 'button'}`];
const { color, bg, bold, disabled, label, text, icon } = button;
if (color) buttonClasses.push(`color-${color}`);
if (bg) buttonClasses.push(`bg-${color}`);
if (bold) buttonClasses.push('actions-button-bold');
if (disabled) buttonClasses.push('disabled');
if (label) {
return `<div class="${buttonClasses.join(' ')}">${text}</div>`;
}
return `
<div class="${buttonClasses.join(' ')}">
${icon ? `<div class="actions-button-media">${icon}</div>` : ''}
<div class="actions-button-text">${text}</div>
</div>`.trim();
}).join('')}
</div>`).join('')}
</div>
`.trim();
}
renderPopover() {
const actions = this;
if (actions.params.renderPopover) return actions.params.renderPopover.call(actions, actions);
const { groups } = actions;
return `
<div class="popover popover-from-actions">
<div class="popover-inner">
${groups.map(group => `
<div class="list">
<ul>
${group.map((button) => {
const itemClasses = [];
const { color, bg, bold, disabled, label, text, icon } = button;
if (color) itemClasses.push(`color-${color}`);
if (bg) itemClasses.push(`bg-${bg}`);
if (bold) itemClasses.push('popover-from-actions-bold');
if (disabled) itemClasses.push('disabled');
if (label) {
itemClasses.push('popover-from-actions-label');
return `<li class="${itemClasses.join(' ')}">${text}</li>`;
}
itemClasses.push('item-link');
if (icon) {
itemClasses.push('item-content');
return `
<li>
<a class="${itemClasses.join(' ')}">
<div class="item-media">
${icon}
</div>
<div class="item-inner">
<div class="item-title">
${text}
</div>
</div>
</a>
</li>
`;
}
itemClasses.push('list-button');
return `
<li>
<a href="#" class="list-button ${itemClasses.join(' ')}">${text}</a>
</li>
`;
}).join('')}
</ul>
</div>
`).join('')}
</div>
</div>
`.trim();
}
}
export default Actions;