Skip to content

Commit 2d48fca

Browse files
committed
Trigger a component update by triggering an event for a model element.
1 parent bd7aed4 commit 2d48fca

File tree

3 files changed

+86
-1
lines changed

3 files changed

+86
-1
lines changed

django_unicorn/static/unicorn/js/component.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,9 +518,28 @@ export class Component {
518518
}
519519
}
520520

521+
/**
522+
* Triggers the event's callback if it is defined.
523+
* @param {String} eventName The event name to trigger. Current options: "updated".
524+
*/
521525
triggerLifecycleEvent(eventName) {
522526
if (eventName in lifecycleEvents) {
523527
lifecycleEvents[eventName].forEach((cb) => cb(this));
524528
}
525529
}
530+
531+
/**
532+
* Manually trigger a model's `input` or `blur` event to force a component update.
533+
*
534+
* Useful when setting an element's value manually which won't trigger the correct event to fire.
535+
* @param {String} key Key of the element.
536+
*/
537+
trigger(key) {
538+
this.modelEls.forEach((element) => {
539+
if (element.key === key) {
540+
const eventType = element.model.isLazy ? "blur" : "input";
541+
element.el.dispatchEvent(new Event(eventType));
542+
}
543+
});
544+
}
526545
}

django_unicorn/static/unicorn/js/unicorn.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,3 +121,11 @@ export function addEventListener(eventName, callback) {
121121

122122
lifecycleEvents[eventName].push(callback);
123123
}
124+
125+
/**
126+
* Trigger a component update by dispatching an event for a particular element.
127+
*/
128+
export function trigger(componentNameOrKey, elementKey) {
129+
const component = getComponent(componentNameOrKey);
130+
component.trigger(elementKey);
131+
}

tests/js/component/models.test.js

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import test from "ava";
22
import { getComponent } from "../utils.js";
33

4+
class Event {
5+
constructor(type) {
6+
this.type = type;
7+
}
8+
}
9+
global.Event = Event;
10+
411
test("modelEls", (t) => {
512
const component = getComponent();
613

@@ -17,7 +24,7 @@ test("abbreviated name", (t) => {
1724
t.is(component.modelEls.length, 1);
1825
});
1926

20-
test("model.lazy has input and blur events ", (t) => {
27+
test("model.lazy has input and blur events", (t) => {
2128
const html = `
2229
<div unicorn:id="5jypjiyb" unicorn:name="text-inputs" unicorn:checksum="GXzew3Km">
2330
<input u:model.lazy='name'></input>
@@ -30,3 +37,54 @@ test("model.lazy has input and blur events ", (t) => {
3037

3138
t.is(element.events.length, 2);
3239
});
40+
41+
test("model trigger with invalid key", (t) => {
42+
t.plan(0);
43+
44+
const html = `
45+
<div unicorn:id="5jypjiyb" unicorn:name="text-inputs" unicorn:checksum="GXzew3Km">
46+
<input u:model.lazy='name' u:key='nameKey'></input>
47+
</div>`;
48+
const component = getComponent(html);
49+
const element = component.modelEls[0];
50+
51+
element.el.dispatchEvent = () => {
52+
t.pass();
53+
};
54+
55+
component.trigger("invalidNameKey");
56+
});
57+
58+
test("model.lazy trigger", (t) => {
59+
t.plan(1);
60+
61+
const html = `
62+
<div unicorn:id="5jypjiyb" unicorn:name="text-inputs" unicorn:checksum="GXzew3Km">
63+
<input u:model.lazy='name' u:key='nameKey'></input>
64+
</div>`;
65+
const component = getComponent(html);
66+
const element = component.modelEls[0];
67+
68+
element.el.dispatchEvent = (event) => {
69+
t.true(event.type === "blur");
70+
};
71+
72+
component.trigger("nameKey");
73+
});
74+
75+
test("model trigger", (t) => {
76+
t.plan(1);
77+
78+
const html = `
79+
<div unicorn:id="5jypjiyb" unicorn:name="text-inputs" unicorn:checksum="GXzew3Km">
80+
<input u:model='name' u:key='nameKey'></input>
81+
</div>`;
82+
const component = getComponent(html);
83+
const element = component.modelEls[0];
84+
85+
element.el.dispatchEvent = (event) => {
86+
t.true(event.type === "input");
87+
};
88+
89+
component.trigger("nameKey");
90+
});

0 commit comments

Comments
 (0)