8000 Add checkId() for PyButton and PyInputBox, add id check for tags with… · sarvjeetdev/pyscript@eba42ad · GitHub
[go: up one dir, main page]

Skip to content

Commit eba42ad

Browse files
authored
Add checkId() for PyButton and PyInputBox, add id check for tags with pys- Event handlers (pyscript#400)
* Add id generation to PyButton and PyInputBox components * Refactor init handlers and add check for id
1 parent ca909b4 commit eba42ad

File tree

3 files changed

+28
-13
lines changed

3 files changed

+28
-13
lines changed

pyscriptjs/src/components/pybutton.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export class PyButton extends BaseEvalElement {
3737
}
3838

3939
connectedCallback() {
40+
this.checkId();
4041
this.code = htmlDecode(this.innerHTML);
4142
this.mount_name = this.id.split('-').join('_');
4243
this.innerHTML = '';

pyscriptjs/src/components/pyinputbox.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export class PyInputBox extends BaseEvalElement {
1717
}
1818

1919
connectedCallback() {
20+
this.checkId();
2021
this.code = htmlDecode(this.innerHTML);
2122
this.mount_name = this.id.split('-').join('_');
2223
this.innerHTML = '';

pyscriptjs/src/components/pyscript.ts

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,36 @@ export class PyScript extends BaseEvalElement {
127127
}
128128
}
129129

130-
/** Initialize all elements with py-onClick handlers attributes */
130+
/** Defines all possible pys-on* and their corresponding event types */
131+
const pysAttributeToEvent: Map<string, string> = new Map<string, string>([
132+
["pys-onClick", "click"],
133+
["pys-onKeyDown", "keydown"]
134+
]);
135+
136+
/** Initialize all elements with pys-on* handlers attributes */
131137
async function initHandlers() {
132138
console.log('Collecting nodes...');
133139
const pyodide = await pyodideReadyPromise;
134-
let matches: NodeListOf<HTMLElement> = document.querySelectorAll('[pys-onClick]');
135-
let output;
136-
let source;
140+
for (const pysAttribute of pysAttributeToEvent.keys()) {
141+
await createElementsWithEventListeners(pyodide, pysAttribute);
142+
}
143+
}
144+
145+
/** Initializes an element with the given pys-on* attribute and its handler */
146+
async function createElementsWithEventListeners(pyodide: any, pysAttribute: string) {
147+
const matches: NodeListOf<HTMLElement> = document.querySelectorAll(`[${pysAttribute}]`);
137148
for (const el of matches) {
138-
const handlerCode = el.getAttribute('pys-onClick');
139-
source = `Element("${el.id}").element.onclick = ${handlerCode}`;
140-
output = await pyodide.runPythonAsync(source);
149+
if (el.id.length === 0) {
150+
throw new TypeError(`<${el.tagName.toLowerCase()}> must have an id attribute, when using the ${pysAttribute} attribute`)
151+
}
152+
const handlerCode = el.getAttribute(pysAttribute);
153+
const event = pysAttributeToEvent.get(pysAttribute);
154+
const source = `
155+
from pyodide import create_proxy
156+
Element("${el.id}").element.addEventListener("${event}", create_proxy(${handlerCode}))
157+
`;
158+
await pyodide.runPythonAsync(source);
159+
141160

142161
// TODO: Should we actually map handlers in JS instead of Python?
143162
// el.onclick = (evt: any) => {
@@ -154,12 +173,6 @@ async function initHandlers() {
154173
// }
155174
}
156175

157-
matches = document.querySelectorAll('[pys-onKeyDown]');
158-
for (const el of matches) {
159-
const handlerCode = el.getAttribute('pys-onKeyDown');
160-
source = `Element("${el.id}").element.addEventListener("keydown", ${handlerCode})`;
161-
output = await pyodide.runPythonAsync(source);
162-
}
163176
}
164177

165178
/** Mount all elements with attribute py-mount into the Python namespace */

0 commit comments

Comments
 (0)
0