Skip to content

Commit d8c9f41

Browse files
committed
v2.0
1 parent c9373fa commit d8c9f41

9 files changed

Lines changed: 319 additions & 374 deletions

File tree

LICENSE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
MIT License
1+
MIT License
22

3-
Copyright (c) 2021 Manuel Lõhmus
3+
Copyright (c) Manuel Lõhmus
44

55
Permission is hereby granted, free of charge, to any person obtaining a copy
66
of this software and associated documentation files (the "Software"), to deal

README.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ <h2 id="usage">Usage</h2>
172172
<h2 id="references">References</h2>
173173
<h2 id="license">License</h2>
174174
<p>This project is licensed under the MIT License.</p>
175-
<p>Copyright © 2024 Manuel Lõhmus</p>
175+
<p>Copyright © Manuel Lõhmus</p>
176176
<p><a href="https://www.paypal.com/donate?hosted_button_id=4ZHDGZVF64YZQ"><img src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif" alt="Donate" /></a></p>
177177
<p>Donations are welcome and will go towards further development of this project.</p>
178178
<br>

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ Here is also a [DEMO](https://manuel-lohmus.github.io/data-context-binding/demo.
158158

159159
This project is licensed under the MIT License.
160160

161-
Copyright &copy; 2024 Manuel Lõhmus
161+
Copyright &copy; Manuel Lõhmus
162162

163163
[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donate_SM.gif)](https://www.paypal.com/donate?hosted_button_id=4ZHDGZVF64YZQ)
164164

browser.js

Lines changed: 84 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-

2-
/** Copyright (c) 2024, Manuel Lõhmus (MIT License). */
1+
/** Copyright (c) Manuel Lõhmus (MIT License). */
32

43
"use strict";
54

@@ -30,6 +29,7 @@
3029
getvalue: { value: getValueBind, writable: true, configurable: false, enumerable: false },
3130
setvalue: { value: setValueBind, writable: true, configurable: false, enumerable: false },
3231
check: { value: checkBind, writable: true, configurable: false, enumerable: false },
32+
visible: { value: visibleBind, writable: true, configurable: false, enumerable: false },
3333
hidden: { value: hiddenBind, writable: true, configurable: false, enumerable: false },
3434
enabled: { value: enabledBind, writable: true, configurable: false, enumerable: false },
3535
disabled: { value: disabledBind, writable: true, configurable: false, enumerable: false },
@@ -104,9 +104,11 @@
104104

105105
bindElement(rootElement, rebinding);
106106

107-
rootElement.querySelectorAll("[bind]:not(template>*):not([link]>*),[onbind]:not(template>*):not([link]>*),[onunbind]:not(template>*):not([link]>*),[template]:not(template>*):not([link]>*),[templates]:not(template>*):not([link]>*),[rebinding]:not(template>*):not([link]>*),[link]:not(template>*):not([link]>*)")
107+
rootElement.querySelectorAll(`[bind],[onbind],[template],[templates],[rebinding],[link]`)
108108
.forEach(function (element) {
109109

110+
if (isParentTemplateOrLink(element)) { return; }
111+
110112
if (!element.contextValue || rebinding) {
111113

112114
Promise.resolve(1).then((function (element, rebinding) {
@@ -115,6 +117,19 @@
115117
})(element, rebinding));
116118
}
117119
});
120+
121+
function isParentTemplateOrLink(element) {
122+
123+
var parent = element.parentElement;
124+
125+
while (parent !== rootElement) {
126+
127+
if (parent.attributes.template || parent.attributes.link) { return true; }
128+
129+
parent = parent.parentElement;
130+
}
131+
return false;
132+
}
118133
}
119134

120135
function rebindAllElements(rootElement) {
@@ -136,7 +151,6 @@
136151
!element?.attributes?.template &&
137152
!element?.attributes?.templates &&
138153
!element?.attributes?.onbind &&
139-
!element?.attributes?.onunbind &&
140154
!element?.attributes?.bind &&
141155
!element?.attributes?.rebinding &&
142156
!element?.attributes?.link
@@ -155,7 +169,7 @@
155169

156170
if (element.bindingContext?.isActive) { element.bindingContext.isActive(false); } // for rebinding
157171

158-
if (element.attributes.link && !element.linked) {// if true then linked
172+
if (element.attributes.link) {
159173

160174
_link(element.attributes.link.value);
161175

@@ -164,14 +178,14 @@
164178

165179
var _bindingContext = bindingContext(element, rebinding);
166180

167-
if (!rebinding && element.attributes.template) {
181+
if (element.attributes.template) {
168182

169183
_template(element.attributes.template.value);
170184

171185
return;
172186
}
173187

174-
if (!rebinding && element.attributes.templates) {
188+
if (element.attributes.templates) {
175189

176190
_template(element.attributes.templates.value, true);
177191

@@ -185,14 +199,17 @@
185199

186200
function _link(path) {
187201

202+
if (element.linked) { return; }
203+
188204
var { CreateLink } = globalScope?.modules?.['ws-user'];
189205

190206
if (CreateLink) {
191207

208+
//element.setAttribute("linked", path);
209+
//element.removeAttribute("link");
210+
element.linked = true;
192211
element.wsLink = WsUser.CreateLink(path, element);
193-
element.wsLink.bindAllElements = function (elem) { bindAllElements(elem, rebinding); };
194-
element.setAttribute("linked", path);
195-
element.removeAttribute("link");
212+
element.wsLink.bindAllElements = function (elem, rebind = false) { bindAllElements(elem, rebind); };
196213
}
197214
}
198215

@@ -258,6 +275,8 @@
258275

259276
if (isMultiple) {
260277

278+
if (typeof _bindingContext.value !== 'object' || !_bindingContext.value) { return; }
279+
261280
let keys = Object.keys(_bindingContext.value);//.sort();
262281

263282
for (var i = 0; i < keys.length; i++) {
@@ -269,13 +288,13 @@
269288

270289
setTimeout(function () {
271290

272-
if (_bindingContext.source && typeof _bindingContext.source.on === "function") {
291+
if (_bindingContext.value && typeof _bindingContext.value.on === "function") {
273292

274-
_bindingContext.source.on(
293+
_bindingContext.value.on(
275294
"-",
276295
function addTemplate(event) {
277296

278-
if (event.eventName === "new") {
297+
if (event.eventName === "new" && (!isMultiple || isMultiple && event.propertyPath.length === 1)) {
279298

280299
return appendTemplate(event.propertyPath.at(-1), event.target);
281300
}
@@ -285,11 +304,11 @@
285304
element
286305
);
287306

288-
_bindingContext.source.on(
307+
_bindingContext.value.on(
289308
"-",
290309
function removeTemplate(event) {
291310

292-
if (event.eventName === "delete") {
311+
if (event.eventName === "delete" && (!isMultiple || isMultiple && event.propertyPath.length === 1)) {
293312

294313
element.querySelectorAll(`:scope > [path="${event.propertyPath.at(-1)}"]`).forEach(function (e) {
295314

@@ -307,12 +326,9 @@
307326
return;
308327
}
309328
}
310-
else {
311329

312-
return appendTemplate();
313-
}
330+
return appendTemplate();
314331

315-
return;
316332

317333
function appendTemplate(key, target) {
318334

@@ -392,11 +408,13 @@
392408
} catch (err) { return _error("[ bind ] ", err); }
393409
}
394410

395-
if (element.attributes.onbind && DataContextBinding.bind) {
411+
if (element.attributes.onbind) {
396412

397413
try {
398414

399-
_bind(DataContextBinding.bind("event", element.attributes.onbind.value));
415+
element.setAttribute('onblur', element.attributes.onbind.value);
416+
_bind(element.onblur);
417+
element.removeAttribute('onblur');
400418

401419
} catch (err) { return _error("[ onbind ] ", err); }
402420
}
@@ -405,24 +423,7 @@
405423

406424
function _bind(fnBind) {
407425

408-
if (_bindingContext.source === undefined) {
409-
410-
var event = { eventName: "unbind", target: undefined, propertyPath: [_bindingContext.property], oldValue: undefined, newValue: undefined };
411-
412-
element.setAttribute("unbinded", "");
413-
414-
fnBind.call(element, event);
415-
416-
if (element.attributes.onunbind && DataContextBinding.bind) {
417-
418-
try {
419-
420-
(DataContextBinding.bind("event", element.attributes.onunbind.value)).call(element, event);
421-
422-
} catch (err) { return _error("[ onunbind ] ", err); }
423-
}
424-
}
425-
else if (fnBind.call(element, { eventName: "bind", target: _bindingContext.source, propertyPath: [_bindingContext.property], oldValue: _bindingContext.value, newValue: _bindingContext.value })) {
426+
if (fnBind.call(element, { eventName: "bind", target: _bindingContext.source, propertyPath: [_bindingContext.property], oldValue: _bindingContext.value, newValue: _bindingContext.value })) {
426427

427428
if (_bindingContext.source && typeof _bindingContext.source.on === "function") {
428429

@@ -800,7 +801,7 @@
800801

801802
function innerHTMLBind(event) {
802803

803-
if (event.eventName === "unbind") {
804+
if (event?.eventName === "unbind") {
804805

805806
this.innerHTML = '';
806807
// I am dead!
@@ -817,8 +818,8 @@
817818

818819
if (event.eventName === "unbind") {
819820

820-
this.onchange = null;
821-
this.onkeydown = null;
821+
this.removeEventListener("change", change);
822+
this.removeEventListener("keydown", keydown);
822823

823824
this.value = '';
824825

@@ -831,20 +832,20 @@
831832
// Init
832833
if (event.eventName === "bind") {
833834

834-
this.onchange = function () { this.contextValue(this.value); };
835-
this.onkeydown = function (ev) { if (ev.keyCode === 27) { this.value = his.contextValue(); } };
835+
this.addEventListener("change", change);
836+
this.addEventListener("keydown", keydown);
836837
}
837838

838839
// I am alive!
839840
return true;
841+
842+
function change(ev) { if (this.contextValue !== undefined) { this.contextValue(this.value); } }
843+
function keydown(ev) { if (ev.keyCode === 27) { this.value = this.contextValue(); } }
840844
}
841845
function getValueBind(event) {
842846

843847
if (event.eventName === "unbind") {
844848

845-
this.onchange = null;
846-
this.onkeydown = null;
847-
848849
this.value = '';
849850

850851
// I am dead!
@@ -860,8 +861,8 @@
860861

861862
if (event.eventName === "unbind") {
862863

863-
this.onchange = null;
864-
this.onkeydown = null;
864+
this.removeEventListener("change", change);
865+
this.removeEventListener("keydown", keydown);
865866

866867
this.value = '';
867868

@@ -872,18 +873,21 @@
872873
// Init
873874
if (event.eventName === "bind") {
874875

875-
this.onchange = function () { this.contextValue(this.value); };
876-
this.onkeydown = function (ev) { if (ev.keyCode === 27) { this.value = this.contextValue(); } };
876+
this.addEventListener("change", change);
877+
this.addEventListener("keydown", keydown);
877878
}
878879

879880
// I am alive!
880881
return true;
882+
883+
function change(ev) { if (this.contextValue !== undefined) { this.contextValue(this.value); } }
884+
function keydown(ev) { if (ev.keyCode === 27) { this.value = this.contextValue(); } }
881885
}
882886
function checkBind(event) {
883887

884888
if (event.eventName === "unbind") {
885889

886-
this.onchange = null;
890+
this.removeEventListener("change", change);
887891

888892
// I am dead!
889893
return false;
@@ -895,11 +899,26 @@
895899
// Init
896900
if (event.eventName === "bind") {
897901

898-
this.onchange = function () { this.contextValue(this.checked); };
902+
this.addEventListener("change", change);
899903
}
900904

901905
// I am alive!
902906
return this.contextValue() === undefined ? false : true;
907+
908+
function change(ev) { if (this.contextValue() !== undefined) { this.contextValue(this.checked); } }
909+
}
910+
function visibleBind(event) {
911+
912+
if (event.eventName === "unbind") {
913+
914+
// I am dead!
915+
return false;
916+
}
917+
918+
this.contextValue() ? this.removeAttribute("hidden") : this.setAttribute("hidden", "");
919+
920+
// I am alive!
921+
return this.contextValue() === undefined ? false : true;
903922
}
904923
function hiddenBind(event) {
905924

@@ -918,6 +937,7 @@
918937

919938
if (event.eventName === "unbind") {
920939

940+
this.removeEventListener("change", change);
921941
// I am dead!
922942
return false;
923943
}
@@ -936,7 +956,7 @@
936956
_this.value = str;
937957
}, 50, this);
938958

939-
//TODO [ x ] I am dead!
959+
// I am dead!
940960
return this.bindingContext?.isActive();
941961
},
942962
// Set DOM element.
@@ -945,16 +965,21 @@
945965
this
946966
);
947967

948-
this.onchange = function () {
968+
this.addEventListener("change", change);
969+
}
970+
971+
// I am alive!
972+
return true;
973+
974+
function change(ev) {
975+
976+
if (this.contextValue !== undefined) {
949977
// Let's take the context of the data.
950978
this.contextValue()
951979
// We will overvalue the modified JSON string data.
952980
.overwritingData(this.value);
953-
};
981+
}
954982
}
955-
956-
// I am alive!
957-
return true;
958983
}
959984
function enabledBind(event) {
960985

0 commit comments

Comments
 (0)