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

On the initial page load mouse events don't fire #426

Open
asyahubar opened this issue Aug 26, 2023 · 0 comments
Open

On the initial page load mouse events don't fire #426

asyahubar opened this issue Aug 26, 2023 · 0 comments

Comments

@asyahubar
Copy link

The bug
I have a quasar application where I need to use both QCalendarDay and QCalendarAgenda. On the initial page load, components seem to load just fine, visually it's ok but mouse events don't fire at all. The only error in the console I get is when I navigate to the page with my q-calendar components from some other pages. The error is:

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'offsetWidth') QTabs.js:181:1

This is the function on line 181 that causes the error:
qcalendar-error
q-calendar-error-trace

My theory
I assume you use QTabs for changing calendar view and on navigation the function recalculateScroll() is called before the component is mounted.
I use QTabs on another page in my application and don't get the same problem.

My component for q-calendar handling looks like this.

<template>
    <div>
            <QCalendarDay
                v-if="selectedCalendar === 'day'"
                ref="calendarDay"
                v-model="selectedDate"
                v-model:model-tasks="sessions"
                :selected-start-end-dates="startEndDates"
                :view="selectedView"
                :weekdays="[1, 2, 3, 4, 5, 6, 0]"
                :interval-minutes="15"
                :interval-count="96"
                :interval-height="15"
                time-clicks-clamped
                hour24Format
                animated
                bordered
                hoverable
                focusable
                @click-date="onClickDate"
                @click-time="onClickTime"
                @mousedown-time="onMouseDownTime"
                @mouseup-time="onMouseUpTime"
                @mousemove-time="onMouseMoveTime"
            >
            </QCalendarDay>

            <QCalendarAgenda
                v-if="selectedCalendar === 'agenda'"
                ref="calendarAgenda"
                v-model="selectedDate"
                v-model:model-tasks="sessions"
                :view="selectedView"
                :weekdays="[1, 2, 3, 4, 5, 6, 0]"
                :left-column-options="trainersColumn"
                :interval-minutes="15"
                :interval-count="96"
                :interval-height="15"
                column-options-id="id"
                column-options-label="label"
                time-clicks-clamped
                hour24Format
                animated
                bordered
                hoverable
                focusable
                @click-date="onClickDate"
            >
            </QCalendarAgenda>
    </div>
</template>
<script setup>
import {
    defineProps,
    defineEmits,
    defineExpose,
    computed,
    ref,
    watch,
} from "vue";
import { useI18n } from "vue-i18n";
import { useQuasar } from "quasar";
import { useMouse } from "src/composables/mouse";
import {
    QCalendarDay,
    QCalendarAgenda,
    today,
    getDateTime,
    getDayTimeIdentifier,
} from "@quasar/quasar-ui-qcalendar/src/index.js";

import "@quasar/quasar-ui-qcalendar/src/QCalendarVariables.sass";
import "@quasar/quasar-ui-qcalendar/src/QCalendarTransitions.sass";
import "@quasar/quasar-ui-qcalendar/src/QCalendar.sass";

const props = defineProps({
    selectedCalendar: {
        type: String,
        default: "day",
    },
    selectedView: {
        type: String,
        default: "week",
    },
    sessions: {
        type: Array,
        default: [],
    },
    startEndDates: Array,
});

const emit = defineEmits([
    "requestCreateSession",
    "update:startEndDates",
    "update:selectedDate",
]);

// Stores
const q = useQuasar();
const { t } = useI18n();

// Composables
const { isLeftClick } = useMouse();

// Additional
const trainersColumn = [
    {
        id: "trainers",
        label: t("sidebar.trainers"),
    },
];

// Data
const sessions = computed(() => props.sessions);
const calendarDay = ref(null);
const calendarAgenda = ref(null);
const selectedDate = ref(today());
const anchorTimestamp = ref(null);
const endTimestamp = ref(null);
const mouseDown = ref(false);

const startEndDates = computed(() => {
    const dates = [];
    const anchorDayTimeIdentifier = !!anchorTimestamp.value
        ? getDayTimeIdentifier(anchorTimestamp.value)
        : false;
    const endDayTimeIdentifier = !!endTimestamp.value
        ? getDayTimeIdentifier(endTimestamp.value)
        : false;

    if (!!anchorDayTimeIdentifier && !!endDayTimeIdentifier) {
        if (anchorDayTimeIdentifier <= endDayTimeIdentifier) {
            dates.push(
                getDateTime(anchorTimestamp.value),
                getDateTime(endTimestamp.value)
            );
        } else {
            dates.push(
                getDateTime(endTimestamp.value),
                getDateTime(anchorTimestamp.value)
            );
        }
    }

    return dates;
});

// Watchers
watch(startEndDates, (newDates, oldDates) => {
    emit("update:startEndDates", startEndDates);
});
watch(selectedDate, (newDate, oldDate) => {
    emit("update:selectedDate", newDate);
});

watch(calendarDay, () => {
    console.log('calendarDay', calendarDay.value)
})

// Methods
const setToday = () => {
    calendarDay.value.moveToToday();
    calendarAgenda.value.moveToToday();
};
const setPrev = () => {
    calendarDay.value.prev();
    calendarAgenda.value.prev();
};
const setNext = () => {
    calendarDay.value.next();
    calendarAgenda.value.next();
};

const onClickDate = (data) => {
    console.log("onClickDate", data);
};
const onClickTime = ({ scope }) => {
    console.log("onClickTime", scope);
};
const onMouseDownTime = ({ scope, event }) => {
    console.log("onMouseDownTime", { scope, event });
    if (isLeftClick(event)) {
        if (
            anchorTimestamp.value !== null &&
            endTimestamp.value !== null &&
            getDateTime(anchorTimestamp.value) ===
                getDateTime(endTimestamp.value)
        ) {
            endTimestamp.value = scope.timestamp;
            mouseDown.value = false;
        }
        mouseDown.value = true;
        anchorTimestamp.value = scope.timestamp;
        endTimestamp.value = scope.timestamp;
    }
};
const onMouseUpTime = ({ scope, event }) => {
    console.log("onMouseUpTime", { scope, event });
    if (isLeftClick(event)) {
        // mouse is up, capture last and cancel selection
        endTimestamp.value = scope.timestamp;
        mouseDown.value = false;
    }
    if (scope.timestamp.future) {
        emit("requestCreateSession");
    }
};
const onMouseMoveTime = ({ scope }) => {
    if (!!mouseDown.value) {
        endTimestamp.value = scope.timestamp;
    }
};

defineExpose({
    setToday,
    setPrev,
    setNext,
});
</script>

Please note that on calendar view change, ref value get changed and mouse events start to work but I expect them to work from the start.
My default calendar mode is day. So when I change to agenda, agenda works. And when I change the mode back to day, day also start to work.

My setup:

  • Vue3, script setup
  • Quasar: ^2.6.0
  • quasar-ui-qcalendar: ^4.0.0-beta.15
  • vue-router: ^4.0.0
  • vueRouterMode: history
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

No branches or pull requests

1 participant