Unobtrusive vanilla JS toolset for Phoenix framework
A compact port of jquery-ujs for Phoenix framework (the library is agnostic, so you can use it with other backends as well). The library does not requires jQuery and covers only essential needs:
- non-'GET' links (POST, PUT, PATCH, DELETE, etc)
- confirmation and/or remote request on clicking link or submitting form
- refreshing CSRF inputs in forms (fix browser form caching)
npm i --save phoenix_ujsIf your js build system supports commonjs require and/or import methods (Brunch, Webpack, Browserify) add the next code at the top of your main js file:
var UJS = require("phoenix_ujs"); // or import "phoenix_ujs";For other cases you can use one of the package files:
~ : ls node_modules/phoenix_ujs ujs.js # browser version ujs.min.js # minified browser version ujs.cjs.js # commonjs version (used in `require` by default) ujs.es.js # ES6 versionTo setup your backend - open layout file and add next at the top of the :
<html> <head> <!-- example for Phoenix.HTML 2.7.1+ --> <%= csrf_meta_tag() %> <!-- example for Phoenix.HTML 2.7.0 and below--> <meta name="csrf-token" content="<%= get_csrf_token() %>"/> <!-- also meta tag can contain the next setting-attributes: csrf-param="_csrf_token" csrf-header="x-csrf-token" method-param="_method" --><!-- to specify non-get method add `ujs-method` --> <a href="/request/post" ujs-method="post">Make a POST request</a> <a href="/request/delete" ujs-method="delete">Make a DELETE request</a> <a href="/request/patch" ujs-method="patch">Make a PATCH request</a><!-- add confirmation with `ujs-confirm` --> <a href="/request/get" ujs-confirm="Are you sure?">Ask confirmation to open link</a> <a href="/request/post" ujs-confirm="Are you sure?" ujs-method="post">Ask confirmation to make a POST request</a> <form action="/request/post" method="POST" ujs-confirm="Are you sure?"> <!-- ask confirmation when form is submitting --> </form><!-- make an ajax request on click if `ujs-remote` is present --> <!-- the next event will be triggered: ajax:beforeSend - event before AJAX call. AJAX request can be canceled if handler will return `false` ajax:success - a success response (2xx status code) ajax:error - an error response (4xx, 5xx status code) ajax:complete - an response received with any status --> <a href="/request/patch" ujs-method="patch" ujs-remote>Patch remotely</a> <form action="/request/post" method="POST" ujs-remote> <!-- AJAX form submitting --> </form>The library exports module (window.UJS in browser version) with the next properties:
confirm- the confirmation function which accepts a message as the first argument. You can override it for your needscsrf- a CSRF configuration object:token- a current CSRF token. You can skip the meta tag in the header and put the token in runtimeheader- a header used for CSRF requestsparam- a query/form param used for CSRF requests
xhr- the AJAX contructor
var UJS = require("phoenix_ujs"); UJS.xhr(url, method, options); // a simple get request // all ajax events (ajax:beforeSend, ajax:success, ...) will be triggered on document UJS.xhr("/api/ping", "GET", { success: function(xhr) { console.log("pong"); } }); UJS.xhr("/api/posts", "POST", { type: 'json', // convert data into json, set Content-Type & Accept headers data: { post: { title: "The first post", body: "Hello world!" } }, // the request's payload success: function(xhr) { alert("The post has been published"); } });options accepts the next params:
headers- additional headerstarget- js event target (by default - document)beforeSend- the callback before xhr executed. It passes the config with xhr & options properties.return falsewill stop the ajax requestsuccess- the success callback (200 <= status_code < 300)error- the error callback (status_code >= 400)complete- the complete callback (any status_code)type- indicated additional processings;- "json" - converts data into json string, sets Content-Type & Accept headers to
application/json - "text" - sets Content-Type & Accept headers to
text/plain - Array(2..3) - sets Content-Type - the first array's element, sets Accept - the second array's element and process data with the third element (if it's exist)
- "json" - converts data into json string, sets Content-Type & Accept headers to
Each ajax request triggers the following events:
ajax:beforeSendis triggered before making an ajax call. In this event you can cancel the ajax request:
document.addEventListener('ajax:beforeSend', function(e) { if(e.target.nodeName === 'I') { // if <i> triggered an ajax request - stop the ajax e.preventDefault(); } else { e.data.xhr.setRequestHeader('my-vendor-header', e.data.options.someValue); } });ajax:successis triggered after getting an response and response is 2xx.
document.addEventListener('ajax:success', function(e) { console.log(e.data.xhr.responseText); });ajax:erroris triggered after getting an response and response is 4xx or 5xx.
document.addEventListener('ajax:error', function(e) { console.error(e.data.xhr.responseText); });ajax:completeis triggered after any response:
document.addEventListener('ajax:complete', function(e) { console.log(e.data.xhr.responseText); });- executing a response js code. It's highly recommended to not do it, but if you need - there's an example:
document.addEventListener('ajax:success', function(e) { if(e.target && e.target.hasAttribute('ujs-eval')) { eval(e.data.xhr.responseText); } });<a href="/some/url" ujs-method="get" ujs-remote ujs-eval>Eval the server code</a>If you're working on a project with old browsers support (IE 9-, Android 2.x, etc) - the library will not work unless you add a polyfill for FormData. For example this one https://www.npmjs.com/package/js-polyfills
- tests
- examples