Suggestion T14502
Visible to All Users
Duplicate

We have closed this ticket because another page addresses its subject:

Add custom theme in theme's list

Theme Builder - How to copy a predefined theme and save it as a custom theme

created a year ago (modified a year ago)

Hello,

I have a questions about Themes. Can you help me?

  1. How to set theme what user selected from the dropdown as default? And how to change dropdown items order?
    Clipboard-File-1.png

  2. How to create new theme with new name? I mean…press on some button like "create new theme" then it will copy all variables from the selected theme and user can set new theme name, change theme and save it. This theme will be added to the dropdown with themes.

  3. How to set "default" theme as readonly?

  4. We have brand styles and I changed default theme. I've added new theme json and applied it to survey. But I see behavior like…user goes to themes tab and selects some other theme then he selects back the default theme and this theme is not in brand styles it has default survey values. How can I fix it?
    Clipboard-File-3.png

Comments (3)

    Hello Anton,
    Thank you for reaching out to us.

    How to set theme what user selected from the dropdown as default?

    You can save the name of a user selected theme and apply it on the second survey creator run. To load a theme to a survey creator, assign a theme object to Survey Creator's theme property.

    And how to change dropdown items order?

    A list of themes displayed within the Theme dropdown is determined by the PredefinedThemes object from "survey-creator-core" module. PredefinedThemes is an array of theme names available within a Survey Creator. You can rearrange items within this array. For instance, the following code sorts theme names in ascending order:

    JavaScript
    import { PredefinedThemes } from "survey-creator-core"; PredefinedThemes.sort();

    How to create new theme with new name? I mean…press on some button like "create new theme" then it will copy all variables from the selected theme and user can set new theme name, change theme and save it. This theme will be added to the dropdown with themes.

    Please refer to my reply in the following ticket for step-by-step instructions on how to programmatically define a custom theme and add it to a list of themes: Add custom theme in theme's list.

    View Demo

    How to set "default" theme as readonly?

    Would you please expand on this task. Do you wish to prevent users from modifying the Default theme?

    We have brand styles and I changed default theme. I've added new theme json and applied it to survey. But I see behavior like…user goes to themes tab and selects some other theme then he selects back the default theme and this theme is not in brand styles it has default survey values. How can I fix it?

    From what I gather, you implemented a custom theme and assigned it to a survey creator's theme property. Now, you wish to apply your custom theme when a user selects the Default theme in a list. Please confirm that.

      Would you please expand on this task. Do you wish to prevent users from modifying the Default theme? -yes. Default theme will be as a some fundamental. And User can create new theme using default (press on some button like "copy styles and create new theme" but he can not change default theme.

      From what I gather, you implemented a custom theme and assigned it to a survey creator's theme property. Now, you wish to apply your custom theme when a user selects the Default theme in a list. Please confirm that. - Not certainly in that way. I've changed survey default theme to follow our styles. But behavior like that…you can see it on your example. Open this page https://surveyjs.io/survey-creator/examples/change-form-theme/reactjs. Select some theme (not default). Go back to default theme. And check for example "Accent color" - it was changed. Expected (and this is my question) - "accent color" should be the same as it was and maybe some other settings (I didn't check all of them).

        Hello Anton,
        Thank you for the update. I appreciate your clarification.
        The first task is clear.
        Regarding the second task: it seems that you confirmed my assumptions. Please correct me if I'm wrong. You modified the Default theme and assigned a custom theme to creator.theme. Is that correct? Now, when a user activates the Themes tab, they see a customized theme and the Default theme selected within a list. However, if they change the theme and get back to Default, they'll actually see the Default theme colors, rather than your customized theme. So the question is how to modify the Default theme and allow users to apply a customized branded theme by selecting the Default item.

        To summarize, you would like to achieve the following tasks:

        • Set a particular (Default) theme read-only;
        • Use a custom theme as Default.

        I'll discuss these tasks with the development team. Please give me additional time. I'll update you as soon as I get any news.

        Thanks

        Answers approved by surveyjs Support

        created a year ago

        Hello Anton,
        I appreciate your patience. I created the following demo for your reference: View Demo. It shows how to achieve the following usage scenario.

        • Add a custom branding theme to a survey creator theme list.
        JavaScript
        import { customTheme } from "./custom-theme"; Themes["custom"] = customTheme.cssVariables; PredefinedThemes.unshift("custom"); let translation = localization.getLocale(""); translation.theme.names.custom = "Custom Theme (Default)";
        • Set this theme read-only.
          Disable theme builder editors when a user selects a 'custom' theme.
        JavaScript
        creator.onSurveyInstanceCreated.add((sender, options) => { if (options.reason === "theme_editor") { let themeSurvey = options.survey; themeSurvey.onValueChanged.add((sender, options) => { if (options.name === "themeName") { const isCustomThemeSelected = options.value === "custom"; sender.getAllQuestions().forEach((q) => { if (q.name !== "themeName") { q.readOnly = isCustomThemeSelected; } }); } }); } });
        • Create two custom toolbar actions: Copy Base Theme and Save Base Theme.
          The Copy Base Theme action creates a copy of the custom (base) theme.
        JavaScript
        creator.toolbar.actions.push( new Action({ id: "svd-copy-theme", iconName: "icon-duplicate_16x16", title: "Copy Base Theme", visible: new ComputedUpdater(() => creator.activeTab === "theme"), enabled: true, action: copyBaseThemeCallback }) ); const copyBaseThemeCallback = function () { const newThemeName = generateModifiedThemeName( "Base", modificationIndexRef.current ); // Themes - An array of themes used by a Survey Creator Themes[newThemeName] = customTheme.cssVariables; // PredefinedThemes contains a list of theme names for a theme selector dropdown PredefinedThemes.push(newThemeName); modificationIndexRef.current++; // Set a new theme to a survey creator creator.theme = { themeName: newThemeName, cssVariables: { ...Themes[newThemeName] } }; };

        The Save Base Theme action saves modifications made to a theme base copy. The originalThemesStorage is used to store predefined and custom theme definitions.

        JavaScript
        // Save all themes to a custom in-memory storage at the creator startup // Create a storage object to store original themes const originalThemesStorage = {}; const saveOriginalThemes = () => { for (const themeName in Themes) { originalThemesStorage[themeName] = { ...Themes[themeName] }; } }; saveOriginalThemes(); ... const saveThemeCallback = function () { // Get the current theme set to creator.theme const currentTheme = creator.theme; // Check if the theme name contains "-modified" if (currentTheme.themeName.endsWith("-modified")) { const originalThemeName = currentTheme.themeName.replace("-modified", ""); // Update the theme name within the Themes array Themes[originalThemeName] = currentTheme.cssVariables; // Save the theme to a custom theme storage originalThemesStorage[originalThemeName] = currentTheme.cssVariables; // Update the name within the PredefinedThemes list const themeIndex = PredefinedThemes.indexOf(currentTheme.themeName); if (themeIndex !== -1) { PredefinedThemes[themeIndex] = originalThemeName; } // Reset the theme name in creator.theme currentTheme.themeName = originalThemeName; } }; creator.toolbar.actions.push( new Action({ id: "svd-save-theme", iconName: "icon-save", title: "Save Base Theme", visible: new ComputedUpdater(() => creator.activeTab === "theme"), enabled: true, action: saveThemeCallback }) );

        A user can add a theme and save it: View Screencast.

        Please take note of the following issues I explored while building the demo:

        We'll work on those issues and update them as soon as we have any news to share.

        Besides, you're welcome to test the provided demo and share your feedback. We would be happy to enhance our Theme Builder to handle this usage scenario. So, please let me know if there is anything to improve/any functionality is missing.

        Thank you

        I look forward to your reply.