PluginProbe
Subscriptions for WooCommerce with Stripe Recurring Payments / 2.2.0
Subscriptions for WooCommerce with Stripe Recurring Payments v2.2.0
2.4.0 2.3.0 2.2.0 2.1.0 2.0.0 1.11.2 1.11.1 1.11.0 1.10.9 1.10.8 1.10.7 1.10.6 1.10.5 1.10.4 1.10.3 1.10.2 1.10.1 1.10.0 1.9.6 1.9.5 trunk 1.3.0 1.3.1 1.3.2 1.4.0 All 65 releases
subscription / assets / js / admin / cancellation-flow.js

cancellation-flow.js in Subscriptions for WooCommerce with Stripe Recurring Payments 2.2.0, at assets/js/admin/cancellation-flow.js

106 lines 3.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 /**
2 * Cancellation Flow - keep the Reasons tab's list in step with the editor.
3 *
4 * The list is rendered from the saved option, so on its own it only caught up
5 * on Save Changes: a reason added in "Manage reasons" disappeared from the page
6 * when the modal closed, which reads as "it was not added". It now mirrors the
7 * editor's `wpsubs:change` event (fired after every add, remove and reorder),
8 * and a note beside Save Changes says the change is not saved yet.
9 */
10 (function () {
11 "use strict";
12
13 var OPTION = "subscrpt_cancellation_reasons";
14
15 var preview = document.querySelector("[data-subscrpt-reason-preview]");
16 if (!preview) {
17 return;
18 }
19
20 var empty = document.querySelector("[data-subscrpt-reason-empty]");
21 var unsaved = document.querySelector("[data-subscrpt-unsaved]");
22 var auto = preview.querySelector("[data-subscrpt-reason-auto]");
23 var field = document.querySelector('input[name="' + OPTION + '"]');
24
25 /**
26 * A comparable fingerprint of a reason list: keys and labels, in order.
27 *
28 * @param {Array<{key?: string, label?: string}>} items Reason items.
29 * @return {string} Fingerprint.
30 */
31 function signature(items) {
32 return items
33 .map(function (item) {
34 // Tab and newline cannot occur in a saved label (sanitize_text_field).
35 return String(item.key || "") + "\t" + String(item.label || "").trim();
36 })
37 .join("\n");
38 }
39
40 // What is saved, read before the editor starts. The editor also fires
41 // `wpsubs:change` once while initialising, so "changed" has to mean
42 // "differs from this", not "an event arrived" - and undoing an edit hides
43 // the note again.
44 var saved = "";
45 try {
46 saved = signature(JSON.parse((field && field.value) || "[]"));
47 } catch (err) {
48 saved = "";
49 }
50
51 /**
52 * Whether an item is a typed "Other".
53 *
54 * The survey adds its own "Other" and the server drops a typed one on save,
55 * so the list leaves it out too rather than show a row that will not be kept.
56 *
57 * @param {{key?: string, label?: string}} item Editor item.
58 * @return {boolean} True for an "Other" entry.
59 */
60 function isOther(item) {
61 var key = String(item.key || "").toLowerCase();
62 var label = String(item.label || "")
63 .trim()
64 .toLowerCase();
65 return key === "other" || label === "other";
66 }
67
68 /**
69 * Re-render the list from the editor's items, keeping the automatic "Other" last.
70 *
71 * @param {Array<{key?: string, label?: string}>} items Editor items, in order.
72 * @return {void}
73 */
74 function render(items) {
75 var rows = items.filter(function (item) {
76 return item && String(item.label || "").trim() !== "" && !isOther(item);
77 });
78
79 Array.prototype.slice.call(preview.querySelectorAll("li:not([data-subscrpt-reason-auto])")).forEach(function (li) {
80 li.remove();
81 });
82
83 rows.forEach(function (item) {
84 var li = document.createElement("li");
85 li.textContent = String(item.label).trim();
86 preview.insertBefore(li, auto);
87 });
88
89 preview.hidden = rows.length === 0;
90 if (empty) {
91 empty.hidden = rows.length > 0;
92 }
93 if (unsaved) {
94 unsaved.hidden = signature(items) === saved;
95 }
96 }
97
98 document.addEventListener("wpsubs:change", function (e) {
99 var field = e.target && e.target.querySelector ? e.target.querySelector('input[name="' + OPTION + '"]') : null;
100 if (!field) {
101 return;
102 }
103 render((e.detail && e.detail.items) || []);
104 });
105 })();
106