diff --git a/src/pat/date-picker/date-picker.js b/src/pat/date-picker/date-picker.js index 98abaa4e7..85142b5f6 100644 --- a/src/pat/date-picker/date-picker.js +++ b/src/pat/date-picker/date-picker.js @@ -5,6 +5,7 @@ import logging from "../../core/logging"; import Parser from "../../core/parser"; import dom from "../../core/dom"; import events from "../../core/events"; +import store from "../../core/store"; import utils from "../../core/utils"; const log = logging.getLogger("date-picker"); @@ -30,6 +31,9 @@ parser.addAlias("behaviour", "behavior"); * "weekdaysShort": ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"] * } */ +export const storage = store.session("pat-date-picker"); + + export default Base.extend({ name: "date-picker", trigger: ".pat-date-picker", @@ -184,11 +188,18 @@ export default Base.extend({ } if (this.options.i18n) { - try { - const response = await fetch(this.options.i18n); - config.i18n = await response.json(); - } catch { - log.error(`date-picker could not load i18n for ${this.options.i18n}`); + let i18n = storage.get(this.options.i18n); + if (!i18n) { + try { + const response = await fetch(this.options.i18n); + i18n = await response.json(); + storage.set(this.options.i18n, i18n); + } catch { + log.error(`date-picker could not load i18n for ${this.options.i18n}`); + } + } + if (i18n) { + config.i18n = i18n; } } this.pikaday = new Pikaday(config); diff --git a/src/pat/date-picker/date-picker.test.js b/src/pat/date-picker/date-picker.test.js index dbb0d926f..ada0b8070 100644 --- a/src/pat/date-picker/date-picker.test.js +++ b/src/pat/date-picker/date-picker.test.js @@ -1,5 +1,6 @@ import $ from "jquery"; import events from "../../core/events"; +import { storage } from "./date-picker"; import pattern from "./date-picker"; import pattern_auto_submit from "../auto-submit/auto-submit"; import utils from "../../core/utils"; @@ -142,46 +143,89 @@ describe("pat-date-picker", function () { }); describe("5 - Date picker with i18n", function () { - describe("with proper json URL", function () { - it("properly localizes the months and weekdays", async () => { - global.fetch = jest.fn().mockImplementation(mock_fetch_i18n); - document.body.innerHTML = - ''; - const el = document.querySelector("input[type=date]"); - pattern.init(el); - await utils.timeout(1); // wait a tick for async to settle. - const display_el = document.querySelector("time"); - display_el.click(); - - const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore - expect(month.textContent).toBe("Oktober"); - - global.fetch.mockClear(); - delete global.fetch; - }); + it("with proper json URL properly localizes the months and weekdays", async () => { + global.fetch = jest.fn().mockImplementation(mock_fetch_i18n); + document.body.innerHTML = + ''; + const el = document.querySelector("input[type=date]"); + pattern.init(el); + await utils.timeout(1); // wait a tick for async to settle. + const display_el = document.querySelector("time"); + display_el.click(); + + const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore + expect(month.textContent).toBe("Oktober"); + + // Clear the storage + storage.clear(); + // Reset mock + global.fetch.mockClear(); + delete global.fetch; }); - describe("with bogus json URL", function () { - it("falls back to default (english) month and weekday labels ", async () => { - // Simulate failing getJSON call - global.fetch = jest.fn().mockImplementation(() => { - throw "error"; - }); - - document.body.innerHTML = - ''; - const el = document.querySelector("input[type=date]"); - pattern.init(el); - await utils.timeout(1); // wait a tick for async to settle. - const display_el = document.querySelector("time"); - display_el.click(); - - const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore - expect(month.textContent).toBe("October"); - - global.fetch.mockClear(); - delete global.fetch; + it("stores i18n results", async () => { + global.fetch = jest.fn().mockImplementation(mock_fetch_i18n); + document.body.innerHTML = ` + + + `; + const els = document.querySelectorAll("input[type=date]"); + pattern.init(els[0]); + await utils.timeout(1); // wait a tick for async to settle. + expect(global.fetch).toHaveBeenCalledTimes(1); + + // Initializing the other pattern should not lead to another AJAX call. + + // NOTE: in a real environment where multiple instances are + // initialized at once on the same page, before the ajax call has + // been completed, each instance will do an AJAX call. After that, + // when navigating to other pages with other date picker instance + // the cached value should be used and no more AJAX calls should be + // made. + + pattern.init(els[1]); + await utils.timeout(1); // wait a tick for async to settle. + expect(global.fetch).toHaveBeenCalledTimes(1); + + // Clear the storage + storage.clear(); + // Reset mock + global.fetch.mockClear(); + delete global.fetch; + }); + + it("with bogus json URL falls back to default (english) month and weekday labels ", async () => { + // Simulate failing getJSON call + global.fetch = jest.fn().mockImplementation(() => { + throw "error"; }); + + document.body.innerHTML = + ''; + const el = document.querySelector("input[type=date]"); + console.log(document.body.innerHTML); + pattern.init(el); + await utils.timeout(1); // wait a tick for async to settle. + console.log(document.body.innerHTML); + const display_el = document.querySelector("time"); + display_el.click(); + + const month = document.querySelector('.pika-lendar .pika-select-month option[selected="selected"]'); // prettier-ignore + expect(month.textContent).toBe("October"); + + // Reset mock + global.fetch.mockClear(); + delete global.fetch; }); });