-
-
Notifications
You must be signed in to change notification settings - Fork 113
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dealing with eventing #4
Comments
(updated above) |
you didn't understand correctly, events are set as functions, no stringification at all |
To expand, this: <select onchange="${evt.onchange}">
${makeOptions(someData)}
</select> will do The quotes are explained in the README Are needed for parsing, but all attributes starting win More details in here: P.S. very sad you thought I'm that stupid 😝 |
Added a F.A.Q. about it, so others won't think stringification is what happens. |
hmmm... must be doing something wrong. |
I'll test the quotes in other attributes but I think that's automatically sanitized when you You can start simple with other tests too like tick or article |
Ok, will try again, because I ended up with this... which was kinda sad: const evt = {
onchange: "return updateTotals(event);",
}; But if you are saying that actual function should work there, then will try to figure out why it's not. In dev tools, it looked it was copying the function text. In case you are interested: https://gist.github.com/marcoscaceres/f896268dd86186fde47a71c7c3c6e674 |
ah, I see what I did wrong now... it's because You should probably make a note about that (i.e., how to combine multiple template strings). |
you don't combine multiple template strings because It's different from anything you've used before so I rather would like to understand, with a little example, what are you trying to do. Remember, each template needs a node to be rendered in, even a document fragment would do |
So, what I'm trying to do is pretty simple. I have a table of shopping items, and when I change the number of items, I want the the total to reflect that. Here is literally the table (which is populated nicely): So when I pick the number of items in the select, I want to detect the "onchange". I was hoping to do that on the |
This is the data: const inventoryData = [
{
colors: "Bright yellow",
img: "images/faux.jpg",
price: "100",
ref: "3046/023/322",
sizes: ["m"],
title: "Faux Leather Jacket",
},
{
colors: "Bright yellow",
img: "images/double.jpg",
price: "90",
ref: "6254/022/382",
sizes: ["s", "m", "l"],
title: "Double Faced Coat",
},
]; Now, I was hoping to be able to bind the event on the "select" elements, which are dynamically created. But, I guess I can add the event listener directly on the |
I don't have time now but will check later. It looks like you should be able to do that anyway. See if this answer somehow helps you solve your issue too: Also bear in mind this project was born yesterday, there are surely things to simplify or improve. |
I know, which is why I'm excited about it. Please don't think I'm criticizing it in any way - honestly just trying to get my little thing working and hopefully will be helpful to you in seeing how people use it. |
absolutely! |
I don't know if this is what you were looking for, but it works for me. var render = hyperHTML.wire();
var events = {
onchange: function (e) {
console.log(items.find(function (item) {
return e.target.value === item.ref;
}));
}
};
var items = [
{
colors: "Bright yellow",
img: "images/faux.jpg",
price: "100",
ref: "3046/023/322",
sizes: ["m"],
title: "Faux Leather Jacket",
},
{
colors: "Bright yellow",
img: "images/double.jpg",
price: "90",
ref: "6254/022/382",
sizes: ["s", "m", "l"],
title: "Double Faced Coat",
},
];
var select = update(
render,
items,
events
);
document.body.appendChild(select);
function update(render, items, events) {
return render`
<select onchange="${events.onchange}">${items.map(item => `
<option value="${item.ref}">
${item.title}
</option>
`)}</select>
`;
} |
Will try it. What I'm looking for is the ability to "nest" renderers, so that I can generate It would be helpful to include such an example (if you haven't added it already), as it's going to be fairly common. |
Beter example than this for tables it's hard to imagine: |
Please note not only TRs are dynamic, but TDs per TRs are dynamic too and concatenated through wires. 😉 |
The example is good (in that it proves that it can be done!), but it suffers from being complicated by mixing multiple template strings and calls to render (it makes the code fragile and potentially hard to maintain - in that it makes it hard to tell where one render starts and another ends, etc). Now, it might just be a matter of stylistic preference, but I would expect: const render = (arr, i) => arr[i] || (arr[i] = hyperHTML.wire());
const renderTABLE = hyperHTML.bind(document.body);
function updateTable(dbs) {
renderTABLE`
<table class="table table-striped latest-data">
<tbody>${dbs.map(((db, i) => toTableRow(render, db, i)}</tbody>
</table>`;
}
function toTableRow(render, data){
return render`<tr><td>data.whatever</td> <td>${makeOtherThing(data.otherThing)}</tr>`;
}
function makeOtherThing(otherThing){
return ???`<input onclick="${otherThing.onclick}">`
} And if |
OK, it took a while, but I've finally understood your issue. So, there are two solutions to your problem, the one that comes with unbeatable performance, and the one good enough for 90% of use cases. PerformanceEverything you render through hyperHTML should be cached because it might be recycled. const render = (arr, i) => arr[i] || (arr[i] = hyperHTML.wire());
const TABLE = hyperHTML.bind(document.body);
const TRs = [];
const THINGs = [];
function updateTable(dbs) {
TABLE`
<table class="table table-striped latest-data">
<tbody>${dbs.map(toTableRow)}</tbody>
</table>`;
}
function toTableRow(data, i){
return render(TRs, i)`
<tr>
<td>
${data.whatever}
</td>
<td>${makeOtherThing(data.otherThing, i)}</td>
</tr>`;
}
function makeOtherThing(otherThing, i){
return render(THINGs, i)`
<a
onclick="${otherThing.onclick}"
href="${otherThing.link}"
>
${otherThing.name}
</a>`;
}
function onclick(e) {
e.preventDefault();
alert(this.textContent);
}
updateTable([{
whatever: 'Whatever 1',
otherThing: {
link: '#whatever-1',
name: 'This is another thing 1',
onclick: onclick
}
}, {
whatever: 'Whatever 2',
otherThing: {
link: '#whatever-2',
name: 'This is another thing 2',
onclick: onclick
}
}]); Good enough, who caresIf you want function makeOtherThing(otherThing, i){
return hyperHTML.wire()`
<a
onclick="${otherThing.onclick}"
href="${otherThing.link}"
>
${otherThing.name}
</a>`;
} That's it. |
Actually, for the sake of documentation, this is the "let it go" version: const updateTable = dbs => hyperHTML.bind(document.body)`
<table class="table table-striped latest-data">
<tbody>${dbs.map(toTableRow)}</tbody>
</table>
`;
const toTableRow = data => hyperHTML.wire()`
<tr>
<td>
${data.whatever}
</td>
<td>${makeOtherThing(data.otherThing)}</td>
</tr>
`;
const makeOtherThing = otherThing => hyperHTML.wire()`
<a
onclick="${otherThing.onclick}"
href="${otherThing.link}"
>
${otherThing.name}
</a>
`;
function onclick(e) {
e.preventDefault();
alert(this.textContent);
}
updateTable([{
whatever: 'Whatever 1',
otherThing: {
link: '#whatever-1',
name: 'This is another thing 1',
onclick: onclick
}
}, {
whatever: 'Whatever 2',
otherThing: {
link: '#whatever-2',
name: 'This is another thing 2',
onclick: onclick
}
}]); |
FYI this discussion inspired me an improvement to the |
Awesome! Will try to plug in the above into the thing I'm working on. I'll send you a link to it once I have it working so you can have a look. There might be more common patterns that can come out of it. |
FYI, |
If I'm understanding correctly (from the forms example), the eventing depends on stringification ... that means that it's super fragile and things like closures are, obviously, forgotten. It seems like the only way to slightly hack around this is to put functions on the Window object so:
Doesn't really work, because it gets transpiled to:
Because it's now just declaring a function, and not calling it.
Would become:
Maybe there is no way around this?
The text was updated successfully, but these errors were encountered: