Files
notifications-admin/app/assets/javascripts/updateContent.js
Chris Hill-Scott 33b4138e79 Patch update sections of the page on AJAX
Currently, when we update a section of the page with AJAX we replace the
entire HTML of the section with the new HTML. This causes problems:
- if you’re trying to interact with that section of the page, eg by
  inpecting it, clicking or hovering an element
- (probably) for screenreaders trying to navigate a page which is
  changing more than is necessary

This commit replaces the call to `.html()` with a pretty clever library
called diffDOM[1]. DiffDOM works by taking a diff of the old element and
the new element, then doing a patch update, ie only modifying the parts
that have changed.

This is similar in concept to React’s virtual DOM, while still allowing
us to render all markup from one set of templates on the server-side.

1. https://github.com/fiduswriter/diffDOM
2016-04-27 10:08:57 +01:00

49 lines
1.1 KiB
JavaScript

(function(GOVUK, Modules) {
"use strict";
GOVUK.timeCache = {};
GOVUK.resultCache = {};
var dd = new diffDOM();
let getter = function(resource, interval, render) {
if (
GOVUK.resultCache[resource] &&
(Date.now() < GOVUK.timeCache[resource])
) {
render(GOVUK.resultCache[resource]);
} else {
GOVUK.timeCache[resource] = Date.now() + interval;
$.get(
resource,
response => render(GOVUK.resultCache[resource] = response)
);
}
};
let poller = (resource, key, $component, interval) => () => getter(
resource, interval, response => dd.apply(
$component.get(0),
dd.diff($component.get(0), $(response[key]).get(0))
)
);
Modules.UpdateContent = function() {
this.start = function(component) {
const $component = $(component);
interval = ($(component).data("interval-seconds") * 1000) || 1500;
setInterval(
poller($component.data('resource'), $component.data('key'), $component, interval),
interval / 5
);
};
};
})(window.GOVUK, window.GOVUK.Modules);