Open metaturso opened 2 years ago
@andrewtelnov Can you offer any advice on how to create and integrate custom question components that SurveyJS can load without using the widget feature?
No hand holding required, we only need a few pointers and we'll be happy to fill in the blanks. Thanks.
Hi @andrewtelnov, following the official third-party React component integration guide, mutati mutandis and using surveyjs-library sources as a reference, I keep hitting a problem when extending either BaseVue
or QuestionVue<T>
imported with:
import { BaseVue, QuestionVue } from "survey-vue-ui"
export class CustomTypeA extends BaseVue {}
// or
export class CustomTypeB extends extends QuestionVue<CustomTypeBModel>
The problem manifests as a runtime error along the lines of:
Uncaught TypeError: class heritage survey_vue_ui__WEBPACK_IMPORTED_MODULE_4__.BaseVue is not an object or null
Uncaught TypeError: class heritage survey_vue_ui__WEBPACK_IMPORTED_MODULE_3__.QuestionVue is not an object or null
I suppose this is because the package doesn't include the full class declarations? If that's the problem, would it be possible to ship those declarations to enable third-party developers to better integrate SurveyJS with their VueJS applications?
The problem happens with survey-core=1.9.54 and survey-vue-ui=1.9.54.
@RomanTsukanov would it be possible to adapt the third-party component guide to cover Vue components integration?
Are you requesting a feature, reporting a bug or asking a question?
Asking a question: What is the correct approach to declare a custom Vue component as a new question type? I've tried custom widgets and registering a native question type, but I got stuck.
Desiderata: I want to create a custom file upload question based on VueFileAgent component. [^1]
What is the current behavior?
Custom Widget handler can't render Vue components.
The SurveyJS documentation states in Create Custom Widget that "[...] you want to create a new Custom Widget [to] create a new question, typically using an existing third-party JavaScript widget/library.".
So far I've seen examples of overriding an existing question type (
empty
orcomment
) with a short snippet of HTML, for example:This is approach is fine for simple form controls. But I can't see a way to scale it up to render a Vue component. So much so that I wonder if Widgets are the right approach to declaring a custom Vue component as a new question type?
Is the documentation failing to mention that I should pre-render the component into the
htmlTemplate
string? If not that, should I render a simple HTML element and attach the Vue component to that? For example, to me this seem like a plausible approach:Then again, I don't think this is the right way either. Using this template string falls apart with surveys that contain multiple instances of this custom question type.
I've concluded that a widget isn't the right way to declare a custom Vue component as a new question type. If you disagree, would you mind pointing me in the right direction? [^2]
Custom SurveyJS question type can't extend
QuestionVue
My next attempt was to reverse-engineer and hook into the SurveyJS native question registration and resolution process.
I've created a minimal working example. Here's an excerpt:
This works but it's far from a complete integration. There are a couple hurdles I couldn't overcome by myself.
Firstly, I couldn't declare my component class as
class FileAgentQuestion extends QuestionVue<QuestionFileAgentModel>
because I only have theQuestionVue
class declaration, not an implementation. This type of error isn't obvious to me:I suppose that the runtime version of
survey-core
andsurvey-vue-ui
don't include those implementation. Unless I'm doing something painfully wrong?I'm using
Vue.extend
as a fall back, but I'd much rather extend one of the baseVueQuestion
components to avoid duplicating the setup and integration code. This is the biggest blocker. As far as I understand, I must extend a base question components to tie the class with the rest of SurveJS data-flow and make the new question configurable and its value accessible to theSurvey
instance.Secondly, because the component is registered using strings, the
import
is marked as unused and trimmed during build. I guess I couldimport "FileAgentQuestion.vue"
for side-effects in my entrypoint. Or import the symbols and register them in my entrypoint or root component so they count as one usage. I suppose that SurveyJS' build process bundles each question into the final artifact. I could configure my Webpack to do the same and get rid of the import altogether. Isn't it possible to register the type instead?What do you suggest I do?
What is the expected behavior?
SurveyJS should have a mechanism to register a new question type that renders a custom Vue (or React, or Angular) component.
I'm not a fan of the custom widget approach. It's clunky and inflexible. I would like to declare my Vue component as close as possible to a "native" SurveyJS question type.
How would you reproduce the current behavior (if this is a bug)?
Sample repository.
Version used
[^1]: There are two reasons that I've intentionally avoided declaring my new question type as a
renderAs
variant of the nativefile
question. [^2]: I can't includevue-template-compiler
as a runtime dependency.