Het toevoegen van event listeners in JS op nog niet gegenereerde HTML
Ik heb namelijk een script gemaakt, waar in gebruik maak van een Signature library. Hier mee kan de gebruiker in een <canvas> z'n handtekening zetten, en opslaan als base64_encoded in een hidden input:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const canvas = document.getElementById("signature");
canvas.width = 400;
const signaturePad = new SignaturePad(canvas);
const clearBtn = document.getElementById('clear');
const saveBtn = document.getElementById('save');
const signatureInput = document.getElementById('signature-field');
clearBtn.addEventListener('click', e => {
e.preventDefault();
signaturePad.clear();
signatureInput.value = '';
});
saveBtn.addEventListener('click', e => {
e.preventDefault();
let signatureImg = signaturePad.toDataURL();
signatureInput.value = signatureImg;
});
canvas.width = 400;
const signaturePad = new SignaturePad(canvas);
const clearBtn = document.getElementById('clear');
const saveBtn = document.getElementById('save');
const signatureInput = document.getElementById('signature-field');
clearBtn.addEventListener('click', e => {
e.preventDefault();
signaturePad.clear();
signatureInput.value = '';
});
saveBtn.addEventListener('click', e => {
e.preventDefault();
let signatureImg = signaturePad.toDataURL();
signatureInput.value = signatureImg;
});
Dit gebeurt allemaal in een formulier en werkt zoals toebehoren. Helaas heb ik ook wat lastigers, als je namelijk een 'Samen' abonnement wilt afsluiten, dan zou hij in het de lege div `#second-person-bank-data` Ook een signaturePad van de canvas moeten maken, met een clear button en een save button, zoals in het voorbeeld hier boven.
Helaas is het me zowel met jQuery delegate en JS mutation observers niet gelukt. Weet iemand hier meer over en hoe ik dit beter kan oplossen in de aankomende tijd?
Hier is de mutation observer die ik heb geprobeert.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//p2
var target = document.querySelector('#second-person-bank-data');
// create an observer instance
var observer = new MutationObserver(function (mutations) {
//loop through the detected mutations(added controls)
mutations.forEach(function (mutation) {
//addedNodes contains all detected new controls
if (mutation && mutation.addedNodes) {
mutation.addedNodes.forEach(function (elm) {
if (elm && elm.id=="signature-p2") {
const canavas2 = elm;
const signaturePad2 = new SignaturePad(canavas2);
const clearBtn2 = document.getElementById('clear2');
const saveBtn2 = document.getElementById('save2');
const signatureInput2 = document.getElementById('signature-field-p2');
clearBtn2.addEventListener('click', e => {
e.preventDefault();
signaturePad2.clear();
signatureInput2.value = '';
});
saveBtn2.addEventListener('click', e => {
e.preventDefault();
let signatureImg2 = signaturePad.toDataURL();
signatureInput2.value = signatureImg2;
});
}
});
}
});
});
// pass in the target node, as well as the observer options
observer.observe(target, {
childList: true
});
var target = document.querySelector('#second-person-bank-data');
// create an observer instance
var observer = new MutationObserver(function (mutations) {
//loop through the detected mutations(added controls)
mutations.forEach(function (mutation) {
//addedNodes contains all detected new controls
if (mutation && mutation.addedNodes) {
mutation.addedNodes.forEach(function (elm) {
if (elm && elm.id=="signature-p2") {
const canavas2 = elm;
const signaturePad2 = new SignaturePad(canavas2);
const clearBtn2 = document.getElementById('clear2');
const saveBtn2 = document.getElementById('save2');
const signatureInput2 = document.getElementById('signature-field-p2');
clearBtn2.addEventListener('click', e => {
e.preventDefault();
signaturePad2.clear();
signatureInput2.value = '';
});
saveBtn2.addEventListener('click', e => {
e.preventDefault();
let signatureImg2 = signaturePad.toDataURL();
signatureInput2.value = signatureImg2;
});
}
});
}
});
});
// pass in the target node, as well as the observer options
observer.observe(target, {
childList: true
});
P.S. Ik dit is die signature library: https://github.com/szimek/signature_pad
Gewijzigd op 31/01/2022 18:40:44 door Jorn Reed
Ga je nog vertellen welke library je hebt gebruikt?
Ad Fundum op 31/01/2022 18:37:54:
Ga je nog vertellen welke library je hebt gebruikt?
Excuus! Heb het er bij gezet.
https://github.com/szimek/signature_pad/blob/master/docs/js/app.js
De documentatie van de library is sumier, maar in de laatste regel van de demo wordt app.js geladen, die de HTML-element bindt op basis van de data-id: Gewijzigd op 31/01/2022 22:30:55 door Ad Fundum
Alleen is dat helaas niet voor mij het geval. Mijn nummer 1 signaturePad, werkt perfect. Maar de andere die doet het uiteraard niet, omdat die signature JS voor de 2e signaturePad geladen word op HTML wat in het begin nog niet bestaat. Daar zoek ik een gepaste oplossing voor. Het is jammer dat ik nu geen JS framework gebruik, dus moet het maar met puur JS/jQuery.
Het enige dat het nog niet doet is interpolatie met Bezier-curven, maar dat maakt mij ook niet uit.
Hierdoor kon ik wel makkelijk zelf de HTML ID's bepalen en meer dan 1 invoerveld maken.
Inspiratie had ik van:
- https://stackoverflow.com/questions/2368784/draw-on-html5-canvas-using-a-mouse
- https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Taking_still_photos
Als je zelf de techniek uitzoekt (is niet super ingewikkeld) kan je met die tweede link dus ook makkelijk een foto-veld maken voor in een html formulier. Nog iets dat ik ook nodig had.
Ad Fundum op 02/02/2022 15:03:25:
Ik heb het zelf opgelost zonder library met een paar events op een canvas zodat je er met muis en touch op kan tekenen. Met een functie om de canvas naar een bitmap te zetten zodat het kan worden meegenomen in een HTML formulier.
Het enige dat het nog niet doet is interpolatie met Bezier-curven, maar dat maakt mij ook niet uit.
Hierdoor kon ik wel makkelijk zelf de HTML ID's bepalen en meer dan 1 invoerveld maken.
Inspiratie had ik van:
- https://stackoverflow.com/questions/2368784/draw-on-html5-canvas-using-a-mouse
- https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Taking_still_photos
Als je zelf de techniek uitzoekt (is niet super ingewikkeld) kan je met die tweede link dus ook makkelijk een foto-veld maken voor in een html formulier. Nog iets dat ik ook nodig had.
Het enige dat het nog niet doet is interpolatie met Bezier-curven, maar dat maakt mij ook niet uit.
Hierdoor kon ik wel makkelijk zelf de HTML ID's bepalen en meer dan 1 invoerveld maken.
Inspiratie had ik van:
- https://stackoverflow.com/questions/2368784/draw-on-html5-canvas-using-a-mouse
- https://developer.mozilla.org/en-US/docs/Web/API/WebRTC_API/Taking_still_photos
Als je zelf de techniek uitzoekt (is niet super ingewikkeld) kan je met die tweede link dus ook makkelijk een foto-veld maken voor in een html formulier. Nog iets dat ik ook nodig had.
Ah oke, de code ziet er niet heel erg lastig uit. Maar werkt deze code dan ook bijv. op een canvas die nog gerendert moet worden? Want ik heb een stappen formulier, als je -18 bent, dan moet ik een signaturepad renderen voor de ouder/voogd.
De JavaScript events hangen dan direct aan het canvas, en je kan meerdere canvassen maken. Misschien kan je iets doen met CSS display:hidden; doen voor het canvas welke op dat moment niet nodig is, of logica inbouwen op de server dat de handtekening hoort bij de leeftijd van de persoon. Uiteindelijk is de techniek voor beide handtekeningen hetzelfde.