Skip to content

Add custom widget ERROR TypeError: Cannot read property 'getType' of null #146

@npupiec

Description

@npupiec

Hi

when I try to add a new widget I get this error in the console ERROR TypeError: Cannot read property 'getType' of null.
The project is in Angular 7.
Versions:
"survey-angular": "1.1.4",
"survey-creator": "1.1.4",
"survey-knockout": "1.1.4",
"survey-pdf": "1.1.4",
"surveyjs-widgets": "1.1.4",

My code:
export var sort = {
name: "sort",
title: "Sort",
iconName: "",
widgetIsLoaded: function () {
return true;
},
isFit: function (question) {
return question.getType() === 'sort';
},
activatedByChanged: function (activatedBy) {
Survey.JsonObject.metaData.addClass("sort", [
{
name: "width",
visible: false
},
{
name: "useDisplayValuesInTitle",
visible: false
},
{
name: "useDisplayValuesInTitle",
visible: false
},
], null, "empty");

  Survey.JsonObject.metaData.addProperty("sort", {
    name: "sortables:itemvalues",
    default: [{
      value: "https://responsivedesign.is/wp-content/uploads/2014/10/be-inspired.svg",
      text: "item1"
    },
      {
        value: "https://crossweb.pl/upload/gallery/cycles/621/300x300/nlg2ymvo-lw2ht_a1r_ak4ka2wimesyqnq.png",
        text: "item2"
      },
      {
        value: "https://hackone.co/wp-content/uploads/2018/06/Logo-example-2-01-3.svg",
        text: "item3"
      }
    ],
  });

  Survey.JsonObject.metaData.addProperty("sort", {
    name: "answerType",
    choices: ["text", "images"],
    default: "text"
  });

  Survey.JsonObject.metaData.addProperty("sort", {
    name: "mode",
    choices: ["click&drag", "click"],
    default: "click"
  });

  Survey.JsonObject.metaData.addProperty("sort", {
    name: "showImageSubtitles:boolean",
    default: true
  });
},
isDefaultRender: false,
htmlTemplate: '<div></div>',
afterRender: function (question, el) {
  //--------------CONST AND FUNC DEFINITIONS--------------------//
  const shouldSort = question.mode != "click" ? true : false;
  let clickedSortTempAnswer = [];

  const initializeUserAnswers = function (answers) {
    const userAnswersElementWrapper = document.createElement("div");
    el.appendChild(userAnswersElementWrapper);
    const userAnswersElement = document.createElement("div");
    userAnswersElementWrapper.classList.add("user-answers-wrapper");
    userAnswersElement.classList.add("user-answers")
    if (question.answerType === "images") {
      userAnswersElement.classList.add("flex");
    }

    for (answer of answers) {
      for (sortable of question.sortables) {
        if (answer === sortable.text) {
          let answerElement = document.createElement('div');
          answerElement.dataset.question = question.name;
          answerElement.dataset.answer = answer;
          answerElement.classList.add("answer");

          if (question.answerType === 'text') {
            answerElement.innerText = sortable.text;
          } else if (question.answerType === 'images') {
            let imageElement = document.createElement('img');
            answerElement.appendChild(imageElement);
            imageElement.src = sortable.value;
            imageElement.classList.add("image-answer");

            if (question.showImageSubtitles) {
              let titleElement = document.createElement('span');
              titleElement.classList.add("answer-title");
              titleElement.innerText = sortable.text;
              answerElement.appendChild(titleElement);
            }
          }
          if (question.mode === "click") {
            answerElement.onclick = handleClickSort;

            if (typeof question.defaultValue !== 'undefined' && question.defaultValue.includes(sortable.text)) {
              const numberElement = document.createElement('p');
              answerElement.classList.add("disabled");
              numberElement.classList.add("answer-number");
              const index = question.defaultValue.indexOf(sortable.text);
              numberElement.innerText = index + 1;
              answerElement.appendChild(numberElement);
            }
          }
          userAnswersElement.appendChild(answerElement);
        }
      }
    }

    userAnswersElementWrapper.appendChild(userAnswersElement);
    el.appendChild(userAnswersElementWrapper);

    new Sortable(userAnswersElement, {
      group: {
        name: 'answers' + question.name,
        pull: false,
        put: false,
      },
      animation: 150,
      sort: shouldSort,
      onEnd: function () {
        const tempAnswer = [];
        for (answer of userAnswersElement.childNodes) {
          tempAnswer.push(answer.dataset.answer);
        }
        question.value = tempAnswer;
      }
    });
  }

  const handleClickSort = function (event) {
    const clickedElement = event.srcElement;
    clickedSortTempAnswer.push(clickedElement.dataset.answer);
    clickedElement.classList.add("disabled");
    question.value = clickedSortTempAnswer;

    const numberElement = document.createElement('p');
    numberElement.classList.add("answer-number")
    numberElement.innerText = clickedSortTempAnswer.length;
    clickedElement.appendChild(numberElement);
  }

  const handleReset = function () {
    const elements = el.getElementsByTagName('div');
    clickedSortTempAnswer = [];
    question.value = question.mode !== "click" ? sortablesTextsList : undefined;
    for (element of elements) {
      if (element.dataset.question === question.name) {
        const numberElements = element.getElementsByTagName('p');
        if (numberElements.length != 0) {
          numberElements[0].remove();
          element.classList.remove("disabled");
        }
      }
    }
  }

  //----------INIT-------------

  const sortablesTextsList = question.sortables.map(sortable => sortable.text);
  let answersToInitialize = []

  answersToInitialize = question.mode === "click" || (question.mode === "click&drag" && typeof question.defaultValue === 'undefined') ?
      sortablesTextsList : question.defaultValue;

  initializeUserAnswers(answersToInitialize);

  if (question.mode === 'click') {
    const resetButton = document.createElement('button');
    resetButton.innerText = "Reset";
    resetButton.onclick = handleReset;
    resetButton.classList.add("reset-button");
    el.appendChild(resetButton);
  }
},
willUnmount: function (question, el) {}

}
and I add to my component
SurveyKo.CustomWidgetCollection.Instance.addCustomWidget(widget.sort, 'customtype');

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions