Skip to main content
Version: 1.0.0

The window.yui object

When a YSCP plugin is active, a window.yui JavaScript object is available on every page with some very handy helper functions.

yui.getCookie(name)

As the name implies, getCookie() is a convenient way to get a given cookie value.

yui.setCookie(name, value, days, skipSetDomain)

The first two arguments of the setCookie method are required. The third and fourth arguments days and skipSetDomain are optional.

skipSetDomain will, as the name suggests, skip setting the domain on the cookie. CraftCms is inconsistent in its backend behavior, not always setting the domain on the cookie.

As a result, you end up with two cookies, if you were to set yui-messages without setting skipSetDomain to true.

info

By default, cookies are only saved when the visitor has given their consent.

yui.setSessionCookie(name, value, skipSetDomain)

The first two arguments of the setCookie method are required. The third argument skipSetDomain is optional.

This method is identical to yui.setCookie with the difference, that the cookie will have no expiry set, so it will be deleted when no more windows or tags with the site are opened in the browser.

yui.getBrowserStorage()

The getBrowserStorage method returns either the native localStorage, if it is available, or tries to fall back to the sessionStorage object.

If neither is available (most notably with IOS Safari in private mode), a warning is logged to the console and false is returned.

Example usage:

const browserStorage = yui.getBrowserStorage();

// Checking the object
if (browserStorage) {
// Get the item value from the storage by a key
const dummyVariable = browserStorage.getItem('dummy-key');

// Save data to the storage (key/value pairs)
browserStorage.setItem('dummy-key', 'dummy value');

// Remove an item from the storage by a key
browserStorage.removeItem('dummy-key');
}

yui.postForm(postParams)

The postForm method first creates a new <form> element, then adds hidden fields for a given data object, and finally submits the created form. It automatically adds the uenc and the crsf parameters (uenc is often used by YUI to redirect the visitor back to the page).

The argument postParams is an object with form configuration:

{
action: "the form action url to post to",
data: {
field_a: "value A",
field_b: "value B"
},
skipUenc: false,
}

Example: post form data by clicking a link (using Alpine.js)

<a href="#" @click.prevent="yui.postForm({
action: 'https://example.test/custom_quote/move/inQuote/',
data: { id: '<?= $escaper->escapeJs($block->getQuoteId()) ?>' }
})">Request a Quote</a>

yui.getFormToken()

The getFormToken method returns the current csrf token value. It is fetched directly from the csrf cookie, or generated when that cookie does not exist.

yui.trapFocus(Element rootElement)

The trapFocus method causes keyboard tab navigation to iterate only over focusable elements inside the given root element. The first focusable element is selected automatically. To release the focus, use yui.releaseFocus(rootElement). Alternatively the rootElement can be hidden or removed from page.

yui.releaseFocus(Element rootElement)

The releaseFocus method removes the focus trap initiated by yui.trapFocus.

yui.formatPrice(value, showSign, options)

The formatPrice method formats and returns the given value using the current currency. The showSign argument is optional. If it is set to true, a + or - symbol is always rendered.

Otherwise, by default only - is rendered for negative values.

Since 0.16.2 an optional options = {} parameter is accepted that is passed to the NumberFormat constructor. It can be used to enforce a minimum or maximum number of fraction digits (amongst other things). This is possible with a small override function in a custom theme, as shown in this example:

<script>
(() => {
const origFormatPrice = yui.formatPrice;
yui.formatPrice = function (value, showSign, options = {}) {
options.maximumFractionDigits = 0; // remove fractions
return origFormatPrice.call(null, value, showSign, options);
}
})()
</script>

yui.str(string, ...args)

The str function replaces positional parameters like %1 with the additional argument in the matching position. The first additional argument replaces %1, the second %2, and so on.

Example:

yui.str('%2 %1 %3', 'a', 'b', 'c') // => "b a c"

To insert a literal % symbol followed by a number duplicate the %. For example %%2 is returned as %2.

The behavior of yui.str is similar to the CraftCms PHP function Craft::t() in regard to the positional parameters. This allows using some translation phrases with positional parameters in PHP and in JavaScript.

// JavaScript
yui.str('Welcome %1', customer.firstName);
// PHP
Craft::t('yui', 'Welcome %1', [$customer->getFirstname()])

yui.strf(string, ...args)

The strf function replaces positional parameters like %0 in the first argument with additional arguments in the matching position. The first additional argument replaces %0, the second %1, and so on.

Example:

yui.strf('%1 %0 %2', 'a', 'b', 'c') // => "b a c"

To insert a literal % symbol followed by a number duplicate the %. For example %%2 is returned as %2.

yui.str vs yui.strf

yui.strf is almost identical to yui.str, except that for yui.strf the first additional argument replaces %0, while for yui.str it replaces %1.

In general, using yui.str is preferable, because it behaves similar to the CraftCms PHP function Craft::t(), which also uses %1 to refer to the first additional argument. This means existing translation phrases which are also used with the PHP function Craft::t() may be reused with yui.str.

yui.replaceDomElement(targetSelector, content)

The replaceDomElement method replaces the DOM element specified by targetSelector with the innerHTML of the same selector from the string content.

This is useful to replace a part of the page with the same part from an HTML response to an Ajax request. The function extracts <script> tags from the returned content and adds them to the page head to ensure they are executed.

Example:

window.fetch(url, {
method: 'POST',
body: payload
})
.then(result => result.text())
.then(body => {
yui.replaceDomElement('#maincontent', body)
})
.catch(error => {
console.error(error);
window.location.reload()
})

yui.activateScripts(node)

The yui.activateScripts method takes an Element instance as an argument, extracts all script child elements and adds them to the document head, so they are parsed by the browser.

The activateScripts method is useful when part of the page is updated with an HTML snippet from an Ajax request. The browser will not process <script> tags in the new content. To ensure scripts are processed, pass the new content as an Element to activateScripts before it is injected into the page.

Example:

const contentNode = document.createElement('div');
contentNode.innerHTML = htmlSnippet;
yui.activateScripts(contentNode)
// Inject the new content into the page
document.querySelector(targetSelector).replaceWith(contentNode);

yui.getUenc()

The getUenc method is intended to be used to supply the value for the uenc query arguments that is commonly used in YUI. It allows YUI to redirect the visitor back to the previous page.

"body": "crsf=" + yui.getFormToken() + "&uenc=" + yui.getUenc(),

The method returns a properly encoded version of window.location.href. Besides base64 encoding the current URL, it also takes care of the special characters +. / and =.

yui.postLog(message, output, type)

Sends a log message through fetch to the system logger. The messages are shown in the CraftCms admin under the plugins Logs section.

Example:

try {
// Code executed
} catch (error) {
yui.postLog(error.message)
}

yui.alpineInitialized(callback)

The alpineInitialized method takes a callback argument that is executed after Alpine.js is loaded and initialized, regardless of the Alpine version. It can be a useful alternative to the document load event, which can be triggered before Alpine is initialized on cached pages in mobile Safari.

With Alpine.js v3, it is the same as using

window.addEventListener('alpine:initialized', callback, {once: true})

With Alpine.js v2, the callback is executed using

const initAlpine = window.deferLoadingAlpine || ((startAlpine) => startAlpine())
window.deferLoadingAlpine = (startAlpine) => {
initAlpine(startAlpine)
Promise.resolve().then(() => callback())
}