Tätä skriptiä ei tulisi asentaa suoraan. Se on kirjasto muita skriptejä varten sisällytettäväksi metadirektiivillä // @require https://update.greasyfork.org/scripts/454586/1182771/Online%20IDE%20DDS%20Create.js
.
let createdListeners = [];
const create = {
actionMenu: (options = {}) => {
const classAm = options.class || ``;
const trigger = options.trigger || {};
const dataAlignment = options[`data-alignment`] || `start`;
if (!options.trigger) {
options.trigger = {};
}
if (!options.trigger.class) {
options.trigger.class = `dds__button--secondary`;
}
if (!options.trigger.text) {
options.trigger.text = `Actions`;
}
const id = options.id || `actionMenu${create.random()}`;
const useChevron = options.useChevron || false;
const noo = {};
noo.actionMenu = create.element(`div`, {
id: id,
class: `dds__action-menu ${classAm}`,
'data-trigger': `#${id}--trigger`,
'data-dds': `action-menu`,
'data-alignment': dataAlignment,
});
noo.trigger = create.element(`button`, {
id: noo.actionMenu.getAttribute(`data-trigger`).replace(`#`, ''),
type: `button`,
class: `dds__button ${trigger.class}`,
});
noo.trigger.appendChild(create.element(`span`, {
class: `ddsc__action-menu__trigger-label`,
text: trigger.text
}));
if (useChevron) {
const handleActionClick = (e) => {
e.target.querySelector(`.dds__icon`).classList.toggle(`action-rotated`);
}
noo.chevron = create.element(`i`, {
class: `dds__icon dds__icon--chevron-down action-chevron`,
});
noo.trigger.appendChild(noo.chevron);
create.listener(`#${id}`, `ddsActionMenuOpenEvent`, handleActionClick);
create.listener(`#${id}`, `ddsActionMenuCloseEvent`, handleActionClick);
}
noo.container = create.element(`div`, {
class: `dds__action-menu__container`,
tabindex: `-1`,
role: `presentation`,
'aria-hidden': `true`,
});
noo.menu = create.element(`div`, {
class: `dds__action-menu__menu`,
role: `menu`,
tabindex: `-1`,
});
noo.menuLi = create.element(`li`, {
role: `presentation`,
});
noo.group = create.element(`span`, {
id: `${id}--group`
});
noo.groupUl = create.element(`ul`, {
id: `${id}--groupUl`,
class: `ddsc__action-menu--groupUl`,
role: `group`,
'aria-labelledby': noo.group.getAttribute(`id`)
});
noo.actionMenu.appendChild(noo.trigger);
noo.actionMenu.appendChild(noo.container);
noo.container.appendChild(noo.menu);
noo.menu.appendChild(noo.menuLi);
noo.menuLi.appendChild(noo.group);
noo.group.appendChild(noo.groupUl);
// Adding a method to the element doesn't seem to be work
// const observerDefs = [
// {
// selector: `#${id}`,
// callback: (elem) => {
// elem.addItem = (itemOptions) => {
// document.getElementById(`${id}--groupUl`).appendChild(create.actionMenuItem(itemOptions));
// };
// }
// }
// ];
// createObserver(observerDefs);
return noo.actionMenu;
},
actionMenuItem: (options = {}) => {
const noo = {};
const label = options.text || `Item Text`;
const asOption = options[`data-value`] != null || false;
const dataValue = options[`data-value`] || undefined;
const itemClass = options.class || ``;
const id = `${label.replace(/[^0-9a-zA-Z]+/, ``)}_${create.random()}`;
noo.item = create.element(`li`, {
class: asOption ? `dds__action-menu__option` : `dds__action-menu__item`,
role: `none`,
});
noo.itemButton = create.element(`button`, {
id: id,
type: `button`,
class: itemClass,
role: asOption ? `menuitemcheckbox` : `menuitem`,
tabindex: `-1`,
'aria-disabled': `false`,
'aria-checked': `false`,
'data-value': dataValue,
});
noo.itemSvg = create.element(`svg`, {
class: `dds__action-menu__icon`,
'aria-hidden': `true`,
});
noo.itemSvgUse = create.element(`use`, {
'xlink:href': `#dds__icon--copy-alt`,
});
noo.itemText = create.element(`span`, {
class: `ddsc__action-menu__span`,
text: label,
});
noo.item.appendChild(noo.itemButton);
noo.itemButton.appendChild(noo.itemSvg);
noo.itemButton.appendChild(noo.itemText);
noo.itemSvg.appendChild(noo.itemSvgUse);
if (options.onclick) {
create.listener(`#${id}`, `click`, options.onclick);
}
return noo.item;
},
button: (options = {}) => {
const noo = {};
const id = options.id || `button_${create.random()}`;
const chevron = options.chevron || {};
const bClass = options.class || ``;
const bText = options.text || `Button`;
const iconIsString = options.icon && typeof options.icon === `string`;
const iconObjectName = !iconIsString && options.icon ? options.icon.name : undefined;
const iconObjectClass = !iconIsString && options.icon && options.icon.class ? options.icon.class : ``;
const bIcon = {
name: iconIsString ? options.icon : iconObjectName,
class: iconObjectClass
};
noo.button = create.element(`button`, {
id: id,
class: `dds__button ${bClass}`,
type: `button`,
text: bText,
});
if (bIcon.name) {
noo.icon = create.element(`i`, {
class: `dds__icon dds__icon--${bIcon.name} ${bIcon.class}`,
'aria-hidden': `true`,
});
if (options.icon.class.indexOf(`--end`) > -1) {
noo.button.appendChild(noo.icon);
} else {
noo.button.prepend(noo.icon);
}
}
if (options.onclick) {
create.listener(`#${id}`, `click`, options.onclick);
}
if (chevron.use) {
const handleActionClick = (e) => {
document.getElementById(id).querySelector(`.dds__icon`).classList.toggle(`action-rotated`);
}
noo.chevron = create.element(`i`, {
class: `dds__icon dds__icon--chevron-down action-chevron`,
});
noo.button.appendChild(noo.chevron);
create.listener(chevron.open.selector, chevron.open.event, handleActionClick);
create.listener(chevron.close.selector, chevron.close.event, handleActionClick);
}
return noo.button;
},
badge: (options = {}) => {
const noo = {};
const id = options.id || `badge_${create.random()}`;
const label = options.label || ``;
const componentClass = options.class || ``;
noo.component = create.element(`span`, {
id: id,
class: `dds__badge ${componentClass}`,
});
noo.label = create.element(`span`, {
class: `dds__badge__label`,
text: label,
});
noo.component.appendChild(noo.label);
return noo.component;
},
element: (nodeType, props) => {
const domNode = document.createElement(nodeType);
if (props && "object" === typeof props) {
for (const prop in props) {
if (prop === "html") {
domNode.innerHTML = props[prop];
} else if (prop === "text") {
domNode.textContent = props[prop];
} else {
if (prop.slice(0, 5) === "aria_" || prop.slice(0, 4) === "data_") {
const attr = prop.slice(0, 4) + "-" + prop.slice(5);
domNode.setAttribute(attr, props[prop]);
} else {
domNode.setAttribute(prop, props[prop]);
}
}
// Set attributes on the element if passed
if (["role", "aria-label"].includes(prop)) domNode.setAttribute(prop, props[prop]);
}
}
return domNode;
},
checkbox: (options = {}) => {
const noo = {};
const id = options.id || `checkbox_${create.random()}`;
const label = options.label || ``;
const componentClass = options.class || ``;
const getCheckboxEl = () => {
const thisCheckbox = document.getElementById(noo.input.id);
if (!thisCheckbox) {
console.error(`Element #${noo.input.id} was not found`);
return;
}
return thisCheckbox;
}
// create new components
noo.component = create.element(`div`, {
id: id,
class: `dds__checkxbox ${componentClass}`,
});
noo.label = create.element(`label`, {
id: `${id}--label`,
class: `dds__checkbox__label`,
for: `${id}--input`,
});
noo.input = create.element(`input`, {
type: `checkbox`,
tabindex: `0`,
id: `${id}--input`,
name: `${id}--name`,
class: `dds__checkbox__input`,
});
if (options.value) noo.input.value = options.value;
if (options.checked) noo.input.setAttribute(`checked`, options.checked);
if (options.required) noo.input.setAttribute(`required`, true);
noo.content = create.element(`span`, {
id: `${id}--content`,
html: label,
});
noo.error = create.element(`div`, {
id: `${id}--error`,
class: `dds__invalid-feedback`,
text: options.error,
});
// append new elements together
noo.component.appendChild(noo.label);
noo.component.appendChild(noo.error);
noo.label.appendChild(noo.input);
noo.label.appendChild(noo.content);
// add methods
noo.component.indeterminate = (state) => {
// must return to verify this method
if (!state) {
console.error(`indeterminate: must pass state`);
return;
}
const thisCheckbox = getCheckboxEl();
thisCheckbox.indeterminate = state;
thisCheckbox.setAttribute(`aria-checked`, state ? `mixed` : `false`);
};
noo.component.check = (state = true) => {
const thisCheckbox = getCheckboxEl();
thisCheckbox.checked = state;
thisCheckbox.setAttribute(`aria-checked`, state);
};
if (options.onclick) {
create.listener(`#${noo.input.id}`, `change`, options.onclick);
}
// return base component
return noo.component;
},
dropdown: (options = {}) => {
const noo = {};
const id = options.id || `dropdown_${create.random()}`;
const componentClass = options.class || ``;
const selection = options.selection || `single`;
const dropdownLabel = options.label || ``;
const selectAllLabel = options.selectAllLabel || `Select All`;
const autocomplete = options.autocomplete ? 'on' : `off`;
noo.component = create.element(`div`, {
id: id,
class: `dds__dropdown ${componentClass}`,
'data-dds': `dropdown`,
'data-selection': selection,
'data-select-all-label': selectAllLabel,
});
noo.container = create.element(`div`, {
class: `dds__dropdown__input-container`,
});
noo.label = create.element(`label`, {
id: `${id}--label`,
for: `${id}--input`,
html: dropdownLabel,
});
noo.wrapper = create.element(`div`, {
class: `dds__dropdown__input-wrapper`,
role: `combobox`,
'aria-haspopup': `listbox`,
'aria-controls': `${id}--popup`,
'aria-expanded': false,
});
noo.input = create.element(`input`, {
id: `${id}--input`,
name: `${id}--name`,
type: `text`,
class: `dds__dropdown__input-field`,
autocomplete: autocomplete,
'aria-labelledby': `${id}--label ${id}--helper`,
'aria-expanded': false,
'aria-controls': `${id}--list`,
placeholder: options.placeholder || ``,
});
noo.feedback = create.element(`i`, {
class: `dds__icon dds__icon--alert-notice dds__dropdown__feedback__icon`,
'aria-hidden': true,
});
noo.helper = create.element(`small`, {
id: `${id}--helper`,
class: `dds__input-text__helper ${!options.helper ? `dds__d-none` : ``}`,
text: options.helper,
});
noo.error = create.element(`div`, {
id: `${id}--error`,
class: `dds__invalid-feedback ${!options.error ? `dds__d-none` : ``}`,
text: options.error,
});
noo.popup = create.element(`div`, {
id: `${id}--popup`,
class: `dds__dropdown__popup dds__dropdown__popup--hidden`,
role: `presentation`,
tabindex: `-1`,
});
noo.list = create.element(`ul`, {
id: `${id}--list`,
tabindex: `-1`,
role: `listbox`,
class: `dds__dropdown__list`,
});
noo.component.appendChild(noo.container);
noo.container.appendChild(noo.label);
noo.component.appendChild(noo.wrapper);
noo.wrapper.appendChild(noo.input);
noo.wrapper.appendChild(noo.feedback);
noo.wrapper.appendChild(noo.helper);
noo.wrapper.appendChild(noo.error);
noo.component.appendChild(noo.popup);
noo.popup.appendChild(noo.list);
return noo.component;
},
dropdownItem: (options = {}) => {
const noo = {};
const label = options.text || `Item Text`;
const dataValue = options[`data-value`] || undefined;
const id = options.id || `${label.replace(/[^0-9a-zA-Z]+/, ``)}_${create.random()}`;
const isSelected = options.selected == `true` ? true : false;
noo.item = create.element(`li`, {
class: `dds__dropdown__item`,
role: `option`,
});
noo.itemButton = create.element(`button`, {
id: id,
type: `button`,
class: `dds__dropdown__item-option`,
role: `option`,
tabindex: `-1`,
'data-selected': isSelected,
});
if (dataValue) {
noo.itemButton.setAttribute('data-value', dataValue);
}
noo.itemText = create.element(`span`, {
class: `dds__dropdown__item-label`,
text: label,
});
noo.item.appendChild(noo.itemButton);
noo.itemButton.appendChild(noo.itemText);
if (options.onclick) {
create.listener(`#${id}`, `click`, options.onclick);
}
return noo.item;
},
listener: function (selector, event, handler) {
let rootElement = document.querySelector('body');
const listenerId = `${selector}__${event}`;
const listenerExists = createdListeners.includes(listenerId);
const listenerInstance = function (evt) {
var targetElement = evt.target;
while (targetElement != null) {
if (targetElement.matches(selector)) {
handler(evt);
return;
}
targetElement = targetElement.parentElement;
}
};
if (!listenerExists) {
createdListeners.push(listenerId);
rootElement.addEventListener(event, listenerInstance, true);
}
},
popover: (options = {}) => {
const noo = {};
const id = options.id || `popover_${create.random()}`;
const dataTrigger = options['data-trigger'] || undefined;
const dataPlacement = options['data-placement'] || `bottom-end`;
const classPo = options.class || ``;
const callback = options.callback || undefined;
const arrow = options.arrow === undefined ? true : options.arrow;
const close = options.close === undefined ? true : options.close;
if (!dataTrigger) {
console.error(`Send a data-trigger with a value like "#your-element-id"`);
return;
}
if (!arrow) {
// if (dataPlacement.indexOf(`bottom`) > -1) {
// create.style(`#${id} { top: -12px;}`);
// } else if (dataPlacement.indexOf(`top`) > -1) {
// create.style(`#${id} { top: 12px;}`);
// } else if (dataPlacement.indexOf(`left`) > -1) {
// create.style(`#${id} { left: 12px;}`);
// } else if (dataPlacement.indexOf(`right`) > -1) {
// create.style(`#${id} { left: -12px;}`);
// }
create.style(`#${id} .dds__popover__pointer { display: none !important;}`);
}
if (!close) {
create.style(`#${id} .dds__popover__close { display: none !important;}`);
}
if (!options.title) {
create.style(`#${id} .dds__popover__header { display: none !important;}`);
}
noo.popover = create.element(`div`, {
id: id,
class: `dds__popover ${classPo}`,
role: `dialog`,
'aria-labelledby': `${id}--title`,
'data-placement': dataPlacement,
'data-dds': `popover`,
'data-trigger': dataTrigger,
});
noo.content = create.element(`div`, {
class: `dds__popover__content`,
});
noo.header = create.element(`div`, {
class: `dds__popover__header`,
});
noo.headline = create.element(`h6`, {
id: `${id}--title`,
class: `dds__popover__headline`,
text: options.title,
});
noo.body = create.element(`div`, {
class: `dds__popover__body`,
text: options.body,
});
if (callback) {
callback(noo.body);
}
noo.popover.appendChild(noo.content);
noo.content.appendChild(noo.header);
noo.content.appendChild(noo.body);
noo.header.appendChild(noo.headline);
return noo.popover;
},
radioButton: (options = {}) => {
const noo = {};
const id = options.id || `radiobutton_${create.random()}`;
const componentClass = options.class || ``;
const legend = options.legend || ``;
noo.radioset = create.element(`fieldset`, {
class: `dds__fieldset dds__radio-button-group ${componentClass}`,
role: `radiogroup`,
});
if (options.required) {
noo.radioset.setAttribute(`required`, true);
noo.radioset.setAttribute(`aria-required`, true);
}
noo.legend = create.element(`legend`, {
text: legend,
})
if (legend) noo.radioset.appendChild(noo.legend);
options.buttons.forEach((radio, rIndex) => {
const radioClass = radio.class || ``;
const radioValue = radio.value || ``;
const radioLabel = radio.label || ``;
noo.button = create.element(`div`, {
class: `dds__radio-button ${radioClass}`,
});
noo.input = create.element(`input`, {
class: `dds__radio-button__input`,
type: `radio`,
name: `${id}--button-name`,
id: `${id}--button${rIndex}`,
value: radioValue,
});
noo.label = create.element(`label`, {
class: `dds__radio-button__label`,
id: `${id}--button-label${rIndex}`,
for: `${id}--button${rIndex}`,
text: radioLabel,
});
noo.button.appendChild(noo.input);
noo.button.appendChild(noo.label);
noo.radioset.appendChild(noo.button);
});
noo.error = create.element(`div`, {
id: `${id}--error`,
class: `dds__invalid-feedback`,
text: options.error || ``,
});
noo.radioset.appendChild(noo.error);
return noo.radioset;
},
random: (min = 100000000, max = 999999999) => {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min) + min);
},
style: (styles) => {
/* Create style document */
var css = document.createElement('style');
css.type = 'text/css';
if (css.styleSheet)
css.styleSheet.cssText = styles;
else
css.appendChild(document.createTextNode(styles));
/* Append style to the tag name */
document.getElementsByTagName("head")[0].appendChild(css);
},
tag: (options = {}) => {
const noo = {};
const id = options.id || `textinput_${create.random()}`;
const componentClass = options.class || ``;
const dismiss = options.dismiss == `true` || `false`;
noo.tag = create.element(`div`, {
id: id,
class: `dds__tag ${componentClass}`,
'data-dds': `tag`,
'data-dismiss': options.dismiss || false,
'data-sr-dismiss': options.dismiss ? `dismiss` : ``,
});
noo.button = create.element(`button`, {
type: `button`,
text: options.label || `Tag`,
});
noo.tag.appendChild(noo.button);
if (options.onclick) {
create.listener(`#${id}`, `click`, options.onclick);
}
return noo.tag;
},
textInput: (options = {}) => {
const noo = {};
const id = options.id || `textinput_${create.random()}`;
const componentClass = options.class || ``;
const icon = options.icon || ``;
const iconStart = options.iconStart || true;
noo.container = create.element(`div`, {
id: id,
class: `dds__input-text__container ${componentClass}`,
});
noo.label = create.element(`label`, {
id: `${id}--label`,
for: `${id}--input`,
text: options.label,
});
noo.wrapper = create.element(`div`, {
class: `dds__input-text__wrapper`,
});
noo.input = create.element(`input`, {
id: `${id}--input`,
type: `text`,
class: `dds__input-text ${icon ? iconStart ? `dds__has__icon--start` : ` dds__has__icon--end` : ``}`,
name: `${id}--input`,
placeholder: options.placeholder || ``,
'aria-labelledby': `${id}--label ${id}--helper`,
});
if (options.required) {
noo.input.setAttribute(`required`, true);
}
if (options[`max-length`]) {
noo.input.setAttribute(`max-length`, options[`max-length`]);
}
noo.icon = create.element(`i`, {
class: `dds__icon dds__icon--${icon || `search`} dds__input-text__icon--${iconStart ? `start` : `end`}`,
'aria-hidden': true,
});
noo.helper = create.element(`small`, {
id: `${id}--helper`,
class: `dds__input-text__helper ${!options.helper ? `dds__d-none` : ``}`,
text: options.helper,
});
noo.error = create.element(`div`, {
id: `${id}--error`,
class: `dds__invalid-feedback ${!options.error ? `dds__d-none` : ``}`,
text: options.error,
});
if (!options.helper) {
create.style(`#${id} { margin-top: -12px; margin-bottom: 9px;}`);
}
noo.container.appendChild(noo.label);
noo.container.appendChild(noo.wrapper);
noo.wrapper.appendChild(noo.input);
if (icon) noo.wrapper.appendChild(noo.icon);
noo.wrapper.appendChild(noo.helper);
noo.wrapper.appendChild(noo.error);
return noo.container;
},
tooltip: (options = {}) => {
const noo = {};
const id = options.id || `tooltip_${create.random()}`;
const componentClass = options.class || ``;
const icon = options.icon ? `dds__icon--${options.icon.replace('dds__icon--', '')}` : `dds__icon--alert-info-cir`;
const title = options.title || ``;
const tip = options.tip || `No options.tip was found.`;
noo.container = create.element(`span`, {});
noo.anchor = create.element(`a`, {
id: `anchor-${id}`,
href: `javascript:void(0);`,
class: `dds__link--standalone ${componentClass}`,
'aria-describedby': `tooltip-${id}`,
});
noo.anchorSr = create.element(`span`, {
id: `anchorSr-${id}`,
class: `dds__sr-only`,
text: `tooltip`,
});
noo.anchorIcon = create.element(`i`, {
id: `anchorIcon-${id}`,
class: `dds__icon ${icon}`,
});
noo.tooltip = create.element(`div`, {
id: id,
class: `dds__tooltip`,
role: `tooltip`,
'data-dds': `tooltip`,
'data-trigger': `#anchor-${id}`,
});
noo.body = create.element(`div`, {
class: `dds__tooltip__body`,
text: tip
});
noo.bodyTitle = create.element(`h6`, {
class: `dds__tooltip__title`,
text: title,
});
noo.container.appendChild(noo.anchor);
noo.anchor.appendChild(noo.anchorSr);
noo.anchor.appendChild(noo.anchorIcon);
noo.container.appendChild(noo.tooltip);
noo.tooltip.appendChild(noo.body);
noo.body.prepend(noo.bodyTitle);
return noo.container;
},
}