Skip to content
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

RFC: (WIP) Override rendering a button for each day #183

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

happycollision
Copy link

@happycollision happycollision commented Dec 2, 2018

I am using ep-calendar for a project I am working on. I use it to display multiple events in a day, with each event being a link to the event page.

Since ep-calendar renders a button by default for each day, I couldn't get the inner links for each event link to work reliably in Firefox (et cetera) because the button element itself would not allow clicks through to nested links. Makes sense.

I added the class names for the day to the public api and added an option to yield without rendering the button so I could construct the day from scratch in my app. Something like this might be out of the scope of your project, but I you like it, I am more than happy to change a few things to make it feel more at home and have an api you agree with. Now the API looks like this:

<PowerCalendar as |epc|>
  {{!-- There is now a `yeildAll` argument... perhaps a better name should be used? --}}
  <epc.days @yieldAll={{true}} as |day|>
    {{#if day.isCurrentMonth}}
      {{!-- And I also yield `classNames` in the hash so they can still be applied --}}
      <div class="div-instead-of-button {{day.classNames}}">

        {{!-- The changes above mean that I can add multiple clickable things inside each day now. --}}
        <div class="events-with-clickable-buttons">
          {{#each (compute (action eventsForDate) day.date) key="id" as |event|}}
            <button class="a-button-i-can-still-click"
              onclick={{action 'goToEvent' event.id}}>
              {{ event.title }}: {{moment-format event.time 'ha'}}
            </button>
          {{/each}}
        </div>

      </div>
    {{else}}
      <div class={{day.classNames}}></div>
    {{/if}}
  </epc.days>
</PowerCalendar>

@happycollision happycollision changed the title RFC: Override rendering a button for each day RFC: (WIP) Override rendering a button for each day Dec 2, 2018
@raualvron
Copy link

raualvron commented Mar 15, 2019

The same issue here.

{{#power-calendar as |calendar|}}
  {{calendar.nav}}
  {{#calendar.days as |day|}}
    {{inner-component day=day}}
  {{/calendar.days}}
{{/power-calendar}}

inner-component.js

import Component from '@ember/component';

export default Component.extend({
    click: function () {
        console.log('Clicked on inner component');
    }
});

The click event on Firefox is not fired.
@cibernox Could you have a look at this issue and fix please?

@cibernox
Copy link
Owner

Sorry to everyone on this issue, I've just had a baby and I've been super-busy lately.

While I like the idea of allowing to customize the buttons, i'll give it some though over the next days to see if this approach is the best.

For the time being, @raualvron , I have a couple solutions for your issue:

The cause is that when a button is disabled (and days of a calendar without an onSelect action are disabled), firefox stops the propagation of click events.

In Ember, when you define an event like this:

export default Component.extend({
    click: function () {
        console.log('Clicked on inner component');
    }
});

in reality the event handler is in the root of the app and you're just using event delegation, but since in this case firefox is preventing the bubbling, the event never reaches the root of the app.

If you bind your event directly in the template of inner-component it will work

<div onclick={{action "doSomething"}}>Inner component stuff here</div>

Alternatively, it will also work if you bind the event directly:

export default Component.extend({
  didInsertElement() {
    this.element.addEventListener('click', e => {
      this.doSomething();
    });
  }
});

Or, another alternative, add an onSelect action to your calendar, even one that does nothing at all:

{{#power-calendar onSelect=(action "doNothing") as |calendar|}}
  {{calendar.nav}}
  {{#calendar.days as |day|}}
    {{inner-component day=day}}
  {{/calendar.days}}
{{/power-calendar}}
actions: {
  doNothing() { /* intentionally empty */ }
}

Choose the solution you think it's best for you.

@happycollision Regarding overriding the buttons, that is possible already today but it's a bit more involved. It requires creating your own custom days component (you can name it anything, p.e custom-calendar-days). You can make it inherit from the default days component but make it have a different template.

Example:

// app/components/custom-calendar-days.js
import DaysComponent from 'ember-power-calendar/components/power-calendar/days';

export default DaysComponent.extend();

For the template, copy the template from here and make the changes you want. For instance, in here I'm changing the buttons for {{link-to}}s.

{{!-- app/templates/components/custom-calendar-days.hbs --}}
<div class="ember-power-calendar-row ember-power-calendar-weekdays">
  {{#each weekdaysNames as |wdn|}}
    <div class="ember-power-calendar-weekday">{{wdn}}</div>
  {{/each}}
</div>
{{! template-lint-disable invalid-interactive }}
<div class="ember-power-calendar-day-grid" onkeydown={{action "onKeyDown" calendar}}>
  {{#each weeks key='id' as |week|}}
    <div class="ember-power-calendar-row ember-power-calendar-week" data-missing-days={{week.missingDays}}>
      {{#each week.days key='id' as |day|}}
        {{#link-to "some-route" day.id class=(ember-power-calendar-day-classes day calendar weeks dayClass)}}{{day.number}}{{/link-to}}
      {{/each}}
    </div>
  {{/each}}
</div>

Then, you can just invoke {{power-calendar}} letting it know that you want to use your own custom days component

<PowerCalendar @daysComponent="custom-calendar-days" as |epc|>
...
</PowerCalendar>

This approach is a bit more involved but lets you customize almost anything you want.

@happycollision
Copy link
Author

First, congratulations! My first is on his way soon and we are very excited.

Second, thanks for answering even after all this time! It was worth the wait. ;-) I’ll give that a shot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants