surveyjs / survey-library

Free JavaScript form builder library with integration for React, Angular, Vue, jQuery, and Knockout.
https://surveyjs.io/form-library
MIT License
4.18k stars 808 forks source link

Error: The property 'inputMask' in class 'text' is unknown. #1776

Closed csgchristian closed 5 years ago

csgchristian commented 5 years ago

Are you requesting a feature, reporting a bug or asking a question?

Asking a question

What is the current behavior?

When I add the inputMask property into my surveyJSON in the JSON Editor, it refuses to save the survey with this property.

What is the expected behavior?

This property should be saved, as it is usable by the surveyjs widgets.

How would you reproduce the current behavior (if this is a bug)?

Open the surveyJS editor, add a text question, navigate to the JSON Editor tab, add a property with the key inputMask to the text question. The surveyJS editor will not save this property.

csgchristian commented 5 years ago

In case this is important, I am using Angular 7, and I am on the latest version of survey-creator

andrewtelnov commented 5 years ago

@csgchristian We do not have inputMask property in text question. You may probably added a custom widget that itroduced this property and forgot to add this custom widget for SurveyJS Library, on survey runner page.

Thank you, Andrew

csgchristian commented 5 years ago

@andrewtelnov the property works if I manually update the survey JSON in the database, as the widget is loaded on the survey runner page.

Is it possible to also tell the editor that this property exists so I do not need to update the JSON in the database manually?

I am using the currency inputMask from this example: https://surveyjs.io/Examples/Library?id=custom-widget-inputmask

andrewtelnov commented 5 years ago

@csgchristian You have to register the custom widget for the creator. Please look at this example. You may simply to add the missing property on the Creator(Editor) page as: SurveyCretor.Serializer.addProperty("text", {name: "inputMask"});. It will work as well.

Thank you, Andrew

csgchristian commented 5 years ago

Am I doing this wrong? I'm receiving a type error.

import * as SurveyCreator from 'survey-creator';

export class Test {
    creator: SurveyCreator.SurveyCreator;

    ngOnInit() {
        this.creator = new SurveyCreator.SurveyCreator('surveyEditorContainer', editorOptions);
        this.creator.text = JSON.stringify(this.json);

        // ERROR: Property 'Serializer' does not exist on type
        SurveyCreator.Serializer.addProperty("text", {name: "inputMask"})
    }
}

Thanks, Christian

andrewtelnov commented 5 years ago

You should add Survey knockout version on your page for creator.

import * as SurveyCreator from 'survey-creator';
import * as SurveyKO from 'survey-knockout';

//It should performs one time
SurveyKO.Serializer.addProperty("text", {name: "inputMask"})

export class Test {
    creator: SurveyCreator.SurveyCreator;

    ngOnInit() {
        this.creator = new SurveyCreator.SurveyCreator('surveyEditorContainer', editorOptions);
        this.creator.text = JSON.stringify(this.json);

    }
}

Thank you, Andrew

csgchristian commented 5 years ago

This example does not work either, since both survey-creator and survey-knockout have implemented the same component 'survey'

ERROR Error: "Uncaught (in promise): Error: Component survey is already registered
./node_modules/knockout/build/output/knockout-latest.js
csgchristian commented 5 years ago

Note: I also tried only importing the Serializer class

import * as SurveyCreator from 'survey-creator';
import { Serializer } from 'survey-knockout';

Serializer.addProperty("text", {name: "inputMask"});

This still throws the same error as above.

andrewtelnov commented 5 years ago

@csgchristian Please make sure to use the latest version (1.1.1) the current version.

Thank you, Andrew

csgchristian commented 5 years ago

Here are my surveyjs versions:

    "survey-angular": "^1.1.1",
    "survey-creator": "^1.1.1",
    "survey-knockout": "^1.1.1",
    "surveyjs-widgets": "^1.1.1",

I receive this error: ERROR Error: "Uncaught (in promise): Error: Component survey is already registered ./node_modules/knockout/build/output/knockout-latest.js /node_modules/survey-knockout/survey.ko.js/

Using this code:

import * as SurveyCreator from 'survey-creator';
import * as SurveyKO from 'survey-knockout';

SurveyKO.Serializer.addProperty("text", {name: "inputMask"});

I am on Angular7.

andrewtelnov commented 5 years ago

@csgchristian Here is the working example

Thank you, Andrew

csgchristian commented 5 years ago

I'm baffled as to how this is working in stackblitz. When I build it locally I get the same error as before, but it works in stackblitz.

Error: Component survey is already registered

./node_modules/knockout/build/output/knockout-latest.js

// Both of these create a survey component
./node_modules/survey-creator/node_modules/survey-knockout/survey.ko.js/
./node_modules/survey-knockout/survey.ko.js/

It appears survey-creator references survey-knockout, so importing survey-knockout in the angular component calls it to be referenced twice, therefore attempting to register the survey component twice. I cannot figure out a way around this.

This user seems to have had the same issue in React: https://github.com/surveyjs/surveyjs_react_quickstart/issues/5

csgchristian commented 5 years ago

Alright, so I figured out how to fix the error I was getting (although I'm still not sure why I was getting it in the first place, when the stackblitz project was unaffected)

I added:

  "baseUrl": "",
    "paths": {
      "survey-knockout": ["../node_modules/survey-knockout"]
    },

To my tsconfig.json, to ensure both survey-creator and survey-knockout reference the same class file. Now everything is working.