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

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

Open
npupiec opened this issue Oct 18, 2019 · 1 comment
Open
Labels

Comments

@npupiec
Copy link

npupiec commented Oct 18, 2019

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');

@tsv2013 tsv2013 transferred this issue from surveyjs/survey-library Oct 18, 2019
@tsv2013
Copy link
Member

tsv2013 commented Oct 18, 2019

Could you provide us with a plunker (or other sandbox) minimal working sample? You can take this one https://plnkr.co/edit/HdnYE5?p=preview as a staring point

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants