vaadin-item #click event in lit template - web-component

I'm trying to build a page size selector for the vaadin-grid-pagination project and in doing so I came up with a design that uses the vaadin-dropdown-menu webcomponents and looks like this:
<vaadin-dropdown-menu label="Page Size">
<template>
<vaadin-list-box>
<vaadin-item #click="${event => this.setLimit(10)}">10</vaadin-item>
<vaadin-item #click="${event => this.setLimit(25)}">25</vaadin-item>
<vaadin-item #click="${event => this.setLimit(50)}">50</vaadin-item>
<vaadin-item #click="${event => this.setLimit(100)}">100</vaadin-item>
</vaadin-list-box>
</template>
</vaadin-dropdown-menu>
The problem I`m having is that the #click event doesn't seem to be fired. In a previous attempt I've used the shibui-dropdown webcomponent for achieving the same thing and that one worked fine, I was able to pass the value selected in the UI using the #click event.
Why I chose to go with the is that it has the look and feel of the general vaadin theme and would look better overall.
What am I doing wrong in not being able to trigger the #click event ?

Related

How to use MobX obervables to cause a 3rd party React Component (FullCalendar) to render?

I am trying to wrap FullCalendar React component with my own functional React component with useContext hook to access MobX store (I might use the store in other components eventually) and observer() to make it react to changes in the store. My component reacts as I would expect, but I have trouble making the FullCalendar component render after a change.
I've tried finding a solution, wrapping <FullCalendar> in <Observer>, playing with autorun() and reaction() but nothing worked. I have to be missing something
This sandbox https://codesandbox.io/s/mobx-fullcalendar-xejn9 shows a simplified version of my solution so far.
Clicking the button at the top adds an event to the observable store, which gets shown in a list below it. But the calendar doesn't show the new event.
Weirdly enough if I make a change in the code, save it, the CodeSandbox causes the render and the events show up in the calendar.
Thanks to #ADyson, I found a solution. Instead of passing a static list of events to the FullCalendar component
events={store.events}
I can pass an event fetching function. So in the most trivial case, I can just pass the events from the store to the successCallback function and it works.
events={(fetchInfo, successCallback, failureCallback) => {
successCallback(store.events);
}}
I've updated the CodeSandbox https://codesandbox.io/s/mobx-fullcalendar-xejn9 as well.

Meteor dynamic content without routing

What is best practice to change content on a page without creating a route?
BlazeLayout.render('mainLayout', { top: 'header', menu: 'menu', main: 'dashboard', bottom: 'footer' });
How can i hide/show template components inside the dashboard without creating a new route? Should this be done in helpers using some sort of if/else logic in the html and using helper for on button click? Let's say i want to show different content inside dashboard template based on button clicks (href).
Please provide a best practice and good solution that is easy with lots of components.
How can i hide/show template components inside the dashboard without
creating a new route? Should this be done in helpers using some sort
of if/else logic in the html and using helper for on button click?
You can do that but you should be aware of some points to keep your code clean and modular:
Try to wrap parts of your dashboard into own templates to keep the code clean
Use ReactiveDict in favor of many ReactiveVar instances
Wrap recurring parts in templates, too to reduce duplicate code
Register recurring helpers globally or in the most upper template of your Dashboard
Subscribe on the parent template to data that is shared across all parts of the dashboard and subscribe to local data in the respective components
Use autorun and subscription.ready() and display a loading indicator until the subscription is ready. Don't wait to have everything loaded before rendering as this may reduce the UX dramatically.
Let's say i want to show different content inside dashboard template
based on button clicks (href).
You can attach a data attribute to the button, that has a specific id of the target to be toggled:
<template name="dashboardComponent">
<a href class="toggleButton" data-target="targetId">My Link</a>
</template>
You can then read this id and toggle it's state in your ReactiveDict:
Template.dashboardComponent.events({
'click .toggleButton'(event, templateInstance) {
event.preventDefault();
// get the value of 'data-target'
const targetId = $(event.currentTarget).attr('data-target');
// get the current toggle state of target by targetId
const toggleState = templateInstance.state.get( targetId );
// toggle the state of target by targetId
templateInstance.state.set( targetId, !toggleState );
}
});
In your template you can then ask to render by simple if / else:
<template name="dashboardComponent">
<a href class="toggleButton" data-target="targetId">My Link</a>
{{#if visible 'targetId'}}
<div>target is visible</div>
{{/if}}
</template>
And your helper is returning the state:
Template.dashboardComponent.helpers({
visible(targetName) {
return Template.instance().state.get(targetName);
 }
});
There could be the problem of sharing the state between parent and child templates and I suggest you to avoid Session where possible. However as beginner it is a lot easier to first use Session and then work towards a more decoupled (parameterized templates) solution step by step.
Please provide a best practice and good solution that is easy with
lots of components.
This is a high demand and it is your competency to work towards both! However here is a short peek into this:
Best practice is what works for you plus can work for others in other use cases. Try to share your work with others to see where it will fail for their use case.
Using routes has the advantage, that you can use query parameters to save the current view state in the url. That adds the advantage, that on reloading the page or sharing via link, the page state can be fully restored.
easy with lots of components is a contradiction and I don't know if you expect some magical puff that solves this complexity for you. As a software engineer it is your competency to abstract the complexity into smaller pieces until you can solve the problem within certain boundaries.

Viewing Ractive events in browser console

I've been reading the RactiveJS docs on event management at https://ractive.js.org/get-started/tutorials/events/, and had a question around rendering of events:
Instead, the on- directive will bind a shared callback directly to the element using addEventListener when it is rendered.
Is it possible to see what the rendered event would look like? I know it won't appear within console, but it would be nice to see if there is a way of viewing an example of how a rendered event would appear.
What that portion of the tutorials meant to say is that the on-* directive doesn't render inline JS nor render on the DOM at all. It's a directive that simply signals Ractive what to do. Even if the template looks like this:
<button on-click="#global.alert( 'Activating!' )">Activate!</button>
What ends up in the DOM is a button with an event handler.
<button>Activate!</button>
Under the hood, the on-* is processed from the parsed template and is converted to something roughly similar to the following:
buttonReference.addEventListener('click', function(){
theGlobalDependingOnTheEnv.alert( 'Activating!' );
});

Execute route change before event function

I've got a list of menu items and each is an a tag. Inside those, I've got notification bubbles insides a div. When the notification div is clicked, I'd like to first follow the a tag (the hash is always to a Meteor route, using Iron Router) before it executes the click event attached to the div. Since reverse-propagation hasn't existed since the netscape days, I thought maybe that click event could store a function as a callback when the route changes? Has anyone tried to do something similar? Couldn't find anything in the Iron Router docs about it. I'm currently mitigating the problem with a few Session vars, but would like to clean it up.
Without seeing what your code is currently doing (or even better, a simplified example), I am guessing a bit at what you are trying to do. Maybe you have something like this:
<div id="bubblething">Click Me!</div>
With a click event:
'click #bubblething': function() {
// Do the bubble thing.
}
But the problem is you'd like to trigger the click event after you route but the click is happening to early. Would it be possible to change it to something more like this:
<div id="bubblething">Click Me!</div> //no <a> tag.
With the click event handling the actually routing first then moving on:
'click #bubblething': function(){
Router.go('/yourroute'); // First you route
{ ... } // Code to handle the notification bubble.
}
You may have to update your styling a bit do to the lack of am <a> tag but that should be pretty simple. The routing is handled by the click and then other things happen. You can parameterize this so that instead of calling an id you call a class and inject the route.

Identify Source Button of Modal Dialog

i got a simple scenario where i have an administrative list of DB-Entries. On click i call the remote-attribute and display the data.
Now the Modal Dialog contains Action-Buttons like "Delete", "Approve", "Nothing".
So whenever i click one of those buttons, i'd like to get the ID of the DB-Entry.
Going by this PullRequest on GitHub on Bootstrap 2.3 there was a relatedTarget attribute on the event. Apparently on v3 this has been removed. So i'm really wondering on how i should implement this kind of feature.
//Syntax Bootstrap v2.3
$('#modal').on('show.bs.modal', function(e){
console.log(e.relatedTarget);
});
//Syntax Bootstrap v3.0
????
A fiddle shouldn't really help to understand the question, but here's one anyways
Since i have identified buttons on the modal dialog, a functionality like this works. Though for some reason i feel for this to be a little messy and I'm still wondering if there's a different solution to this:
// Button to open the Modal Dialog
Foo
// Button inside the Modal view
delete
And then the JS to get the article ID on Delete-Button-Click:
$('#delete-article').on('click', function(){
var articleId = $('#modalDiv').data('bs.modal').options.articleId;
// artticleId = 1
});
Since i have to make another "query" onto the DOM, i feel for this method to be quite dirty. If there's any other way to get the data in a more performant way, I'd gladly take that information :)

Resources