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

Boolean question -- cannot render title as render #9658

Open
ArsenyYankovsky opened this issue Mar 27, 2025 · 2 comments
Open

Boolean question -- cannot render title as render #9658

ArsenyYankovsky opened this issue Mar 27, 2025 · 2 comments
Labels
enhancement user issue An issue or bug reported by users

Comments

@ArsenyYankovsky
Copy link

Describe the bug
First of all, I would like to preface that there are multiple bugs in this which I think are caused by one issue -- how boolean question handles title.

I'm creating a specialized question type and this is the look I want to achieve

Image

I can achieve this, but the title is only rendered once and doesn't change dynamically with the question.

Steps to reproduce

This is my specialized question type:

  collection.Instance.add({
    name: 'consent',
    title: 'Consent',
    iconName: 'icon-warning-24x24',
    questionJSON: {
      type: 'boolean',
      title: consentTypeList[0].defaultQuestionTitle,
      renderAs: 'checkbox',
      titleLocation: 'hidden',
    },
    inheritBaseProps: true,
    onPropertyChanged: (question, propertyName, newValue) => {
      // this fires but I cannot get an element
    },
    onAfterRender(question, el) {
      // this doesn't fire at all
    },
    onInit() {
      serializer.getProperty('consent', 'titleLocation').defaultValue = 'hidden'
      serializer.addProperty('consent', {
        name: 'consentType',
        displayName: 'Consent Type',
        type: 'dropdown',
        default: consentTypeList[0].value,
        category: 'general',
        choices: consentTypeList,
        visible: true,
        onSetValue: (question, value) => {
          const contactField = consentTypeList.find((item) => item.value === value)
          if (!question.title || defaultTitles.includes(question.title) || /question([0-9])+/i.test(question.title)) {
            // eslint-disable-next-line no-param-reassign
            question.title = contactField.defaultQuestionTitle
          }
          question.setPropertyValue('consentType', value)
        },
      })
    },
  })

Please note that I have to use both

serializer.getProperty('consent', 'titleLocation').defaultValue = 'hidden'

and

titleLocation: 'hidden',

to achieve this partially correct result. It renders the question title next to the checkbox, but it doesn't update the title when it's updated in the editor and uses a value sent into the questionJson.title.

Image

Expected behavior
When I change the question title -- it's reflected in both the editor and

Screenshots
If applicable, add screenshots to help explain your problem.

Please complete the following information:

  • Browser: chrome
  • Browser version: 134
  • JS framework/library: both React and Vanilla renderer
  • SurveyJS version: 2.0.2
  • Device: Mac
@ArsenyYankovsky
Copy link
Author

ArsenyYankovsky commented Mar 27, 2025

Ok, I found a very hacky workaround that uses label to replace the title in the rendered component.

  collection.Instance.add({
    name: 'consent',
    title: 'Consent',
    iconName: 'icon-warning-24x24',
    questionJSON: {
      type: 'boolean',
      title: consentTypeList[0].defaultQuestionTitle,
      renderAs: 'checkbox',
      titleLocation: 'hidden',
    },
    inheritBaseProps: true,
    onPropertyChanged: (question, propertyName, newValue) => {
      if (propertyName === 'title') {
        question.label = newValue
      } else if (propertyName === 'visibleIndex') {
        if (!question.title || /question([0-9])+/i.test(question.title)) {
          question.title = consentTypeList[0].defaultQuestionTitle
        }
        question.label = question.title
      }
    },
    onInit() {
      serializer.getProperty('consent', 'titleLocation').defaultValue = 'hidden'
      serializer.addProperty('consent', {
        name: 'consentType',
        displayName: 'Consent Type',
        type: 'dropdown',
        default: consentTypeList[0].value,
        category: 'general',
        choices: consentTypeList,
        visible: true,
        onSetValue: (question, value) => {
          const contactField = consentTypeList.find((item) => item.value === value)
          if (!question.title || defaultTitles.includes(question.title) || /question([0-9])+/i.test(question.title)) {
            // eslint-disable-next-line no-param-reassign
            question.title = contactField.defaultQuestionTitle
          }
          question.setPropertyValue('consentType', value)
        },
      })
    },
  })

I will still leave this issue open as I see that the label property is deprecated and would like a proper future-proof solution.

@JaneSjs JaneSjs self-assigned this Mar 28, 2025
@JaneSjs
Copy link
Contributor

JaneSjs commented Mar 28, 2025

Hello,
Please use the title property to assign a label for your Boolean question. When you work with a specialized question type, use the question.contentQuestion to access an inner Boolean question; use the question.contentQuestion.title property to update a Boolean question's title. Consider the following demo: View CodeSandbox.

export const surveyJSON = {
  elements: [
    {
      type: "consent",
      name: "Iconsent",
      title: "I consent to Your Company storing my data",
    },
  ],
};
...
import { ComponentCollection, Serializer } from "survey-core";

ComponentCollection.Instance.add({
  name: "consent",
  title: "Consent",
  iconName: "icon-warning-24x24",
  questionJSON: {
    type: "boolean",
    renderAs: "checkbox",
    titleLocation: "hidden",
  },
  inheritBaseProps: true,
  updateBooleanTitle(question) {
    question.contentQuestion.title = question.title;
  },
  onPropertyChanged(question, propertyName, newValue) {
    if (propertyName === "title") {
      this.updateBooleanTitle(question);
    }
  },
  onLoaded(question) {
    this.updateBooleanTitle(question);
  },
  onInit() {
    Serializer.getProperty("consent", "titleLocation").defaultValue = "hidden";
    //...
  },
});

Let me know if this configuration works for you.

@JaneSjs JaneSjs added user issue An issue or bug reported by users enhancement labels Mar 28, 2025
@JaneSjs JaneSjs removed their assignment Mar 31, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement user issue An issue or bug reported by users
Projects
None yet
Development

No branches or pull requests

2 participants