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

Support dash-name slot names, for use with script tags #7078

Closed
lemmel opened this issue Aug 2, 2022 · 18 comments
Closed

Support dash-name slot names, for use with script tags #7078

lemmel opened this issue Aug 2, 2022 · 18 comments
Assignees
Milestone

Comments

@lemmel
Copy link

lemmel commented Aug 2, 2022

Hi

following the closing of fullcalendar/fullcalendar-vue#185, the silence on Stack, and the fact that it is either a bug or a feature (namely not available without using all webpack/etc mecanism) not advertised as such, I post a shorted example code of the wrong behaviour.

So when using only vanilla JS, there is no obvious way to make the library to run; here are the interresting parts and further below are available the errors and the full example demonstrating the problem.

  • I use only regular JS (no webpack, npm, and so on), then I use the CDNs:
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.12/vue.global.min.js" integrity="sha512-CLrLddI89KM+4mefYP8PbruyeARQAoQVwajhryM9hwM5bAeEFdtBwk0Wy6A9HlVeXyszFtXqOzg1Qy/A+Fwglg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.css" integrity="sha256-5veQuRbWaECuYxwap/IOE/DAwNxgm4ikX7nrgsqYp88=" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.js" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/locales-all.js" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/@fullcalendar/vue3@5.11.1/dist/main.global.js" crossorigin="anonymous"></script>
  • as I don't use webpack (etc), I start the project this way:
    const QApp = {
      el: '#q-app',
      data: function() {
        return {
          calendarOptions: {},
          currentEvents: []
        }
      },
      methods: {}
    }
    window.addEventListener('load', (event) => {
        const app = Vue.createApp(QApp)
        app.component('FullCalendar', FullCalendar)
        app.mount('#q-app')
    });
  • and finally, here is the html:
    <div id="q-app">
        <template>
            <full-calendar
            class='demo-app-calendar'
            :options='calendarOptions'
            >
                <template v-slot:eventContent='arg'>
                    <b>{{ arg.timeText }}</b>
                    <i>{{ arg.event.title }}</i>
                </template>
            </full-calendar>
        </template>
    </div>

I have already big projects using CDNs that mix several libraries, so at first I thought to simply use the regular fullcalendar, but when I tried to customize the eventContent handler, the returned html that included some vue components aren't detected by Vue. That is the reason why I turned to fullcalendar-vue.



Has someone an idea of how I should do use this project ? Or perhaps how I can make Vue to detect the Components that are in the return of the eventContent handler with the regular fullcalendar ?





Full error stack:

vue.global.min.js:1 You are running a development build of Vue.
Make sure to use the production build (*.prod.js) when deploying for production.
vue.global.min.js:1 [Vue warn]: Property "__b" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "type" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "constructor" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "type" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "props" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "type" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Unhandled error during execution of render function 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 Uncaught TypeError: Cannot read properties of undefined (reading 'is')
    at j$2 (main.js:61:6988)
    at I$1 (main.js:61:6369)
    at m (main.js:61:2205)
    at I$1 (main.js:61:6186)
    at Proxy.N (main.js:61:8331)
    at mn (vue.global.min.js:1:18544)
    at _e.fn (vue.global.min.js:1:55566)
    at _e.run (vue.global.min.js:1:5996)
    at a (vue.global.min.js:1:55975)
    at I (vue.global.min.js:1:54056)
vue.global.min.js:1 [Vue warn]: Property "type" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "props" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "key" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "key" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "type" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Property "props" was accessed during render but is not defined on instance. 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Unhandled error during execution of render function 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
vue.global.min.js:1 [Vue warn]: Unhandled error during execution of scheduler flush. This is likely a Vue internals bug. Please open an issue at https://new-issue.vuejs.org/?repo=vuejs/vue-next 
  at <FullCalendar class="demo-app-calendar" options= Object > 
  at <App>
_i @ vue.global.min.js:1
main.js:61 Uncaught (in promise) TypeError: Cannot convert undefined or null to object
    at slice (<anonymous>)
    at j$2 (main.js:61:7077)
    at I$1 (main.js:61:6369)
    at m (main.js:61:2205)
    at I$1 (main.js:61:6186)
    at Proxy.N (main.js:61:8331)
    at mn (vue.global.min.js:1:18544)
    at _e.fn (vue.global.min.js:1:55566)
    at _e.run (vue.global.min.js:1:5996)
    at xi (vue.global.min.js:1:75573)

And the full code demonstrating the problem:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>HTML5 : Hello World Example</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.12/vue.global.min.js" integrity="sha512-CLrLddI89KM+4mefYP8PbruyeARQAoQVwajhryM9hwM5bAeEFdtBwk0Wy6A9HlVeXyszFtXqOzg1Qy/A+Fwglg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.css" integrity="sha256-5veQuRbWaECuYxwap/IOE/DAwNxgm4ikX7nrgsqYp88=" crossorigin="anonymous">
        <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.js" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/locales-all.js" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/@fullcalendar/vue3@5.11.1/dist/main.global.js" crossorigin="anonymous"></script>
    </head>
    <body>
        <div id="q-app">
            <template>
                <full-calendar
                class='demo-app-calendar'
                :options='calendarOptions'
                >
                    <template v-slot:eventContent='arg'>
                        <b>{{ arg.timeText }}</b>
                        <i>{{ arg.event.title }}</i>
                    </template>
                </full-calendar>
            </template>
        </div>
<script>

let todayStr = new Date().toISOString().replace(/T.*$/, '') // YYYY-MM-DD of today

var bar = null
const QApp = {
  el: '#q-app',
  data: function() {
    return {
      calendarOptions: {
        headerToolbar: {
          left: 'prev,next today',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek,timeGridDay'
        },
        initialView: 'dayGridMonth',
        initialEvents: [
            {id: '54545454',title: 'All-day event',start: todayStr},
            {id: '98989898',title: 'Timed event',start: todayStr + 'T12:00:00'}
        ],
      }
    }
  },
  methods: {}
}
window.addEventListener('load', (event) => {
    const app = Vue.createApp(QApp)
    app.component('FullCalendar', FullCalendar)
    app.mount('#q-app')
});
</script>

</body>
</html>
@lemmel
Copy link
Author

lemmel commented Aug 2, 2022

I did find a way to make it run, but as I'm not a webpack/etc user I don't know what it is reason.

To load the component, one must do something like this:

currentComponent.component('fullcalendar', FullCalendarVue.default)

I found it by reading the source code and finding that the component is exported with:

var FullCalendarVue = (function (exports, vue, core) {
    'use strict';
// [...]
    exports.default = FullCalendar;
// [...]
    return exports;
}({}, Vue, FullCalendar));

Well, now that is the slot eventContent that doesn't work.

PS : full running code exemple (except the eventContent part)

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>HTML5 : Hello World Example</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.12/vue.global.min.js" integrity="sha512-CLrLddI89KM+4mefYP8PbruyeARQAoQVwajhryM9hwM5bAeEFdtBwk0Wy6A9HlVeXyszFtXqOzg1Qy/A+Fwglg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.css" integrity="sha256-5veQuRbWaECuYxwap/IOE/DAwNxgm4ikX7nrgsqYp88=" crossorigin="anonymous">
        <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.js" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/locales-all.js" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/@fullcalendar/vue3@5.11.1/dist/main.global.js" crossorigin="anonymous"></script>
    </head>
    <body>
        <div id="q-app">
            <fullcalendar
                class='demo-app-calendar'
                :options='calendarOptions'
            >
                <template v-slot:eventContent='arg'>
                    <b>{{ arg.timeText }}</b>
                    <i>{{ arg.event.title }}</i>
                </template>
            </fullcalendar>
        </div>
<script>

let todayStr = new Date().toISOString().replace(/T.*$/, '') // YYYY-MM-DD of today

const QApp = {
  el: '#q-app',
  data: function() {
    return {
      calendarOptions: {
        headerToolbar: {
          left: 'prev,next today',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek,timeGridDay'
        },
        initialView: 'dayGridMonth',
        initialEvents: [
            {id: '54545454',title: 'All-day event',start: todayStr},
            {id: '98989898',title: 'Timed event',start: todayStr + 'T12:00:00'}
        ],
      }
    }
  },
  methods: {}
}
window.addEventListener('load', (event) => {
    const app = Vue.createApp(QApp)
    app.component('fullcalendar', FullCalendarVue.default)
    app.mount('#q-app')
});
</script>

</body>
</html>

@acerix
Copy link
Member

acerix commented Aug 4, 2022

Would you be able to post a runnable, stripped-down demonstration of the bug? Would really appreciate it because the time saved reproducing will be time spent fixing.

@acerix acerix closed this as completed Aug 4, 2022
@lemmel
Copy link
Author

lemmel commented Aug 22, 2022

Here is "a public demonstration of the bug" : https://codepen.io/lemmel/pen/mdxoOBv

@acerix acerix changed the title fullcalendar-vue not vanilla JS compatible (through only CDNs and with no webpack/etc) Vue features like event slots do not work when initialized by script tags Aug 22, 2022
@lemmel
Copy link
Author

lemmel commented Aug 29, 2022

Hi,

as you have confirmed the problem, maybe the ticket should be reopened as it would be more visible (even to your team ?!?) and I would received notifications: I discovered the changes you have done when I was ready to re-submit the ticket as I wasn't sure that you knew I had added a link to a codepen.

Well, just a suggestion as I'm satisfied enough knowing that you're working on this; the matter is not as urgent as before (others priorities currently), so I can read the ticket later :-)

@acerix
Copy link
Member

acerix commented Aug 29, 2022

Sorry, I meant to reopen it.

@acerix acerix reopened this Aug 29, 2022
@chrisbarless
Copy link

I'm getting this same error, but I'm not using Vue... what is the purpose of the code on line 61?

@lemmel
Copy link
Author

lemmel commented Dec 1, 2022

I'm sorry: what line 61? Could you copy/past it ?

@chrisbarless
Copy link

I'm sorry: what line 61? Could you copy/past it ?

Sorry for the lack of specificity. I couldn't find a built file

https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.js

If you look in the main build file here, around line 61 there is a large minified section. i guess it probably does some kind of cross browser initialization or whatever. but I got the exact same error as you. i'm using script tags but not the vue library.

It's all on one line, but the error for me comes from this part. the d.is
document.createElement(_,d.is&&d)

@lemmel
Copy link
Author

lemmel commented Dec 3, 2022

I'm sorry but I don't quite understand the problem; furthermore this is the repo of the vue component, so not the right place.

Here is simple code that runs, uses fullcalendar and uses cdn for delivery:

<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='utf-8' />
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.css" integrity="sha256-jLWPhwkAHq1rpueZOKALBno3eKP3m4IMB131kGhAlRQ=" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.3/main.min.js" integrity="sha256-7PzqE1MyWa/IV5vZumk1CVO6OQbaJE4ns7vmxuUP/7g=" crossorigin="anonymous"></script>
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        var calendarEl = document.getElementById('calendar');

        var calendar = new FullCalendar.Calendar(calendarEl, {
            initialView: 'dayGridMonth',
            initialDate: '2022-12-07',
            headerToolbar: {
            left: 'prev,next today',
            center: 'title',
            right: 'dayGridMonth,timeGridWeek,timeGridDay'
            },
            events: [
            {
                title: 'All Day Event',
                start: '2022-12-01'
            },
            {
                title: 'Long Event',
                start: '2022-12-07',
                end: '2022-12-10'
            },
            {
                groupId: '999',
                title: 'Repeating Event',
                start: '2022-12-09T16:00:00'
            },
            {
                groupId: '999',
                title: 'Repeating Event',
                start: '2022-12-16T16:00:00'
            },
            {
                title: 'Conference',
                start: '2022-12-11',
                end: '2022-12-13'
            },
            {
                title: 'Meeting',
                start: '2022-12-12T10:30:00',
                end: '2022-12-12T12:30:00'
            },
            {
                title: 'Lunch',
                start: '2022-12-12T12:00:00'
            },
            {
                title: 'Meeting',
                start: '2022-12-12T14:30:00'
            },
            {
                title: 'Birthday Party',
                start: '2022-12-13T07:00:00'
            },
            {
                title: 'Click for Google',
                url: 'http://google.com/',
                start: '2022-12-28'
            }
            ]
        });

        calendar.render();
    });
    </script>
  </head>
  <body>
    <div id='calendar'></div>
  </body>
</html>

I hope that it helps.

@arshaw
Copy link
Member

arshaw commented Dec 3, 2022

@lemmel , this problem is happening because case-sensitive attributes are not allow in HTML. so v-slot:eventContent is interpreted as v-slot:eventcontent which fullcalendar doesn't know to look for.

The solution will entail writing it as v-slot:event-content and then having fullcalendar know to look for the name with dashes.

@lemmel
Copy link
Author

lemmel commented Dec 3, 2022

@arshaw I know this rule and I already tested it.

Unfortunately as you can see in this pen that changing the case doesn't solve the problem: https://codepen.io/lemmel/pen/wvXQyBb

The title should be between several X.

PS: here is the full code showing it:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>HTML5 : Hello World Example</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/3.2.12/vue.global.min.js" integrity="sha512-CLrLddI89KM+4mefYP8PbruyeARQAoQVwajhryM9hwM5bAeEFdtBwk0Wy6A9HlVeXyszFtXqOzg1Qy/A+Fwglg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.css" integrity="sha256-5veQuRbWaECuYxwap/IOE/DAwNxgm4ikX7nrgsqYp88=" crossorigin="anonymous">
        <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.js" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/locales-all.js" crossorigin="anonymous"></script>
        <script src="https://cdn.jsdelivr.net/npm/@fullcalendar/vue3@5.11.1/dist/main.global.js" crossorigin="anonymous"></script>
    </head>
    <body>
        <div id="q-app">
            <fullcalendar
                class='demo-app-calendar'
                :options='calendarOptions'
            >
                <template v-slot:event-content='arg'>
                    <b>{{ arg.timeText }}</b>
                    <i>XXX{{ arg.event.title }}XXXX</i>
                </template>
            </fullcalendar>
        </div>
<script>

let todayStr = new Date().toISOString().replace(/T.*$/, '') // YYYY-MM-DD of today

const QApp = {
  el: '#q-app',
  data: function() {
    return {
      calendarOptions: {
        headerToolbar: {
          left: 'prev,next today',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek,timeGridDay'
        },
        initialView: 'dayGridMonth',
        initialEvents: [
            {id: '54545454',title: 'All-day event',start: todayStr},
            {id: '98989898',title: 'Timed event',start: todayStr + 'T12:00:00'}
        ],
      }
    }
  },
  methods: {}
}
window.addEventListener('load', (event) => {
    const app = Vue.createApp(QApp)
    app.component('fullcalendar', FullCalendarVue.default)
    app.mount('#q-app')
});
</script>

</body>
</html>

@arshaw
Copy link
Member

arshaw commented Dec 9, 2022

@lemmel, I was saying that more as a note-to-self because this needs to be fixed in the source code of the vue connector.

I'd need to massage slot names that have dash-case into camelCase at this point in the code:
https://github.com/fullcalendar/fullcalendar-vue/blob/v6.0.0-vue3beta.4/src/FullCalendar.ts#L27

@arshaw arshaw changed the title Vue features like event slots do not work when initialized by script tags Support dash-name slot names, for use with script tags Dec 9, 2022
@arshaw arshaw transferred this issue from fullcalendar/fullcalendar-vue Dec 15, 2022
@SwanValues
Copy link

I spent a lot of time on it.
@arshaw Has the problem been solved?
@lemmel I changed the 'eventContent' of the fullcalendar.js file to 'eventcontent', that can be fixed.

@lemmel
Copy link
Author

lemmel commented Feb 3, 2023

@SwanValues I don't understand what you said; is it a question, a fact, something else ?
Is it a solution ? If it is, then I don't understand it.

@SwanValues
Copy link

@lemmel sorry,my english is poor.
because case-sensitive attributes are not allow in HTML. so v-slot:eventContent is interpreted as v-slot:eventcontent which fullcalendar doesn't know to look for.
fullcalendar looks for v-slot:eventContent with eventContent, so I've replaced all 'eventContent' in Fullcalendar.js with 'eventcontent'

@lemmel
Copy link
Author

lemmel commented Feb 6, 2023

Ok, did that correct the problem ?

Even though it may seems to correct the behaviour, it may not be a "good solution" as

  • Fullcalendar must behave like any other vue library
  • it may breaks something else

Futhermore, we should not alter the official Fullcalendar's code as it would mean that we will be forced to maintain my own version.
If you think that the fix is good, then perhaps you could run the tests, and if it is really ok, submit a PR: https://github.com/fullcalendar/fullcalendar/blob/main/CONTRIBUTING.md

@arshaw arshaw added this to the upcoming-release milestone Feb 8, 2023
@arshaw
Copy link
Member

arshaw commented Feb 8, 2023

I'll try to implement this fix for the new release

@arshaw
Copy link
Member

arshaw commented Mar 21, 2023

This has been implemented in v6.1.5

Updated repro: https://codepen.io/arshaw/pen/OJoBQyB

@arshaw arshaw closed this as completed Mar 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

No branches or pull requests

5 participants