Runtime Toolbox Customization


                        



const options = { showLogicTab: true };            
                var creator = new SurveyCreator.SurveyCreator(options);
            
                
                    ReactDOM.render(
                    <React.StrictMode>
                        <SurveyCreator.SurveyCreatorComponent creator={creator} />
                    </React.StrictMode>,
                    document.getElementById("creatorElement")
                    );
                

creator.onDefineElementMenuItems.add(function(editor, options) {
  if(options.obj.isPage) return;
  const objToAdd = options.obj;
  options.items.unshift({
    id: "addtosharedrepo",
    title: "Save as Toolbox Item",
    iconName: "icon-toolbox",
    iconSize: 16,
    action: () => { addIntoCustomItems(objToAdd); }
  });
});


// Create and configure a custom button
const customizeToolboxAction = new Survey.Action({
    id: "toolbox-customization",
    iconName: "icon-toolbox", 
    title: "Customize Toolbox",
    visible: new Survey.ComputedUpdater(() => {
        return creator.activeTab === "designer";
    }),
    showTitle: false, 
    enabled: true, 
    action: function() { showToolboxCustomization(); }
});

// Add the custom button to the top toolbar
creator.toolbarItems.push(customizeToolboxAction);

// Add the custom button to the bottom toolbar (visible only on mobile devices)
creator.footerToolbar.actions.push(customizeToolboxAction);
creator.toolbox.showTitleOnCategoryChange = false;


var allToolboxItems = [];

//You have to replace getCustomItems/setCustomItems functions with the code that get/set data in the database
function getCustomItems() {
    var res = window.localStorage.getItem("sharedquestions");
    if(!res) return {};
    return JSON.parse(res);
}
function setCustomItems(items) {
    var str = JSON.stringify(items);
    window.localStorage.setItem("sharedquestions", str);
}

function addIntoCustomItems(element) {
    var json = new Survey.JsonObject().toJsonObject(element);
    json.type = element.getType();
    var item = { id: element.name, name: element.name, iconName: 'icon-' + element.getType(), title: element.title,
        json: json, isCopied: false, isUsed: isItemUsed(element.name), isStandard: false, category: "Custom questions" };
    var items = getCustomItems();
    items[item.name] = item;
    setCustomItems(items);
    creator.toolbox.addItem(item);
}
function removeCustomItem(name) {
    var items = getCustomItems();
    for(var i = 0; i < allToolboxItems.length; i++){
      if (allToolboxItems[i].name == name) {
        allToolboxItems[i].isUsed = false;
      }
    }
    delete items[name];
    setCustomItems(items);
    var container = document.getElementById("customItems");
    var div = document.getElementById("toobaritem_" + name);
    container.removeChild(div);
}

function isItemUsed(name) {
    var toolboxItem = creator.toolbox.getItemByName(name);
    return !!toolboxItem && toolboxItem.visible;
}

function addToolBoxItemIntoList(container, item) {
    allToolboxItems.push(item);
    var div = document.createElement("div");
    div.id = "toobaritem_" + item.name;
    var checkbox = document.createElement('input');
    checkbox.type = "checkbox";
    checkbox.name = item.name;
    checkbox.checked = item.isUsed;
    checkbox.id = item.name;
    checkbox.dataItem = item;
    checkbox.onchange = function() {this.dataItem.isUsed = this.checked; }

    var label = document.createElement('label')
    label.style.marginLeft = "5px";
    label.htmlFor = item.name;
    label.appendChild(document.createTextNode(item.title));

    var removeButton = null;
    if(!item.isStandard) {
        removeButton = document.createElement("button");
        removeButton.style.marginLeft = "7px";
        removeButton.appendChild(document.createTextNode("Remove"));
        removeButton.onclick = function() { removeCustomItem(item.name) };
    }

    div.appendChild(checkbox);
    div.appendChild(label);
    if(removeButton) {
        div.appendChild(removeButton);
    }

    container.appendChild(div);
}

function createDefaultItem(typeName) {
    var question = Survey.ElementFactory.Instance.createElement(typeName, "q1");
    if(!question) {
        question = Survey.Serializer.createClass(typeName);
    }
    var json = new Survey.JsonObject().toJsonObject(question);
    json.type = question.getType();
    return { id: typeName, name: typeName, iconName: 'icon-' + typeName, title: SurveyCreator.localization.getString('qt.' + typeName),
        json: json, isCopied: false, isUsed: isItemUsed(typeName), isStandard: true };
}

function loadAllToolboxItems() {
    allToolboxItems = [];
    var container = document.getElementById("standardItems");
    container.innerHTML = "";
    var allTypes = Survey.ElementFactory.Instance.getAllTypes().filter(name => SurveyCreatorCore.QuestionToolbox.hiddenTypes.indexOf(name) < 0);
    for(var i = 0; i < allTypes.length; i ++) {
        addToolBoxItemIntoList(container, createDefaultItem(allTypes[i]));
    }
    container = document.getElementById("customItems");
    container.innerHTML = "";
    var customItems = getCustomItems();
    for(var name in customItems) {
        var item = customItems[name];
        item.isUsed = isItemUsed(name);
        addToolBoxItemIntoList(container, item);
    }
    if(container.children.length == 0) {
        container.innerHTML = "Select the question, click on '...' and then click on the first item to add the question here.";
    }
}

window.applyToolboxItems = function () {
    allToolboxItems.forEach(item => {
        var toolboxItem = creator.toolbox.getItemByName(item.name);
        if(!!toolboxItem) {
          toolboxItem.visible = item.isUsed;
        } else if(item.isUsed) {
          item.category = "Custom questions";
          creator.toolbox.addItem(item);
        }
      });
}

function showToolboxCustomization() {
    loadAllToolboxItems();
    modal.open();
}
window.modal = new RModal(document.querySelector("#toolboxCustomization"),{
    closeTimeout: 100,
    dialogClass: "modal__dialog",
    dialogOpenClass: "modal__dialog--animated modal__dialog--fade-in-down",
    focus: false
});
                    
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Customize the Toolbox at Runtime | Reactjs Example</title>
    
<meta name="viewport" content="width=device-width" />
    <script src="https://unpkg.com/react@17.0.1/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@17.0.1/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone@7.2.5/babel.min.js"></script>
    <script src="/DevBuilds/survey-core/survey.core.min.js"></script>
    <script src="/DevBuilds/survey-core/survey.i18n.min.js"></script>
    <script src="/DevBuilds/survey-react-ui/survey-react-ui.min.js"></script>
    <link href="/DevBuilds/survey-core/defaultV2.min.css" type="text/css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.10/ace.min.js" type="text/javascript" charset="utf-8"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.10/ext-language_tools.js" type="text/javascript" charset="utf-8"></script>
        <script src="/DevBuilds/survey-creator-core/survey-creator-core.min.js"></script>
        <link href="/DevBuilds/survey-creator-core/survey-creator-core.min.css" type="text/css" rel="stylesheet" />
        <script src="/DevBuilds/survey-creator-core/survey-creator-core.i18n.min.js"></script>
        <script src="/DevBuilds/survey-creator-react/survey-creator-react.min.js"></script>
        <style>
            :root {
                --tab-min-height: 600px;
            }
        </style>
    <link rel="stylesheet" href="./index.css">
<script type="text/javascript" src="https://unpkg.com/rmodal/dist/rmodal.js"></script>
</head>
<body style="margin: 0">
    
<svg style="display: none;">
    <symbol viewBox="0 0 16 16" id="icon-actionaddtosharedrepo"><path d="M7.3 8H1v2h5.2c.2-.7.6-1.4 1.1-2zM10 6.2V5H1v2h7.3c.5-.3 1.1-.6 1.7-.8zM1 2h9v2H1zM11.5 7C9 7 7 9 7 11.5S9 16 11.5 16s4.5-2 4.5-4.5S14 7 11.5 7zm2.5 5h-2v2h-1v-2H9v-1h2V9h1v2h2v1z"></path></symbol>
</svg>
<div id="toolboxCustomization" class="modal builder-page__modal" role="dialog">
    <div class="modal__dialog">
        <div class="modal__content">
            <div class="modal__header">
                <h4 class="modal__title">Toolbox Customization</h4>
            </div>
            <div class="modal__body">
                <div class="row">
                    <div class="row__column">
                        <div class="panel panel--default builder-page__panel">
                            <div class="panel__header">Standard Elements</div>
                            <div class="panel__body">
                                <div id="standardItems"></div>
                            </div>
                        </div>
                    </div>
                    <div class="row__column">
                        <div class="panel panel--default builder-page__panel">
                            <div class="panel__header">Custom Elements</div>
                            <div class="panel__body">
                                <div id="customItems"></div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="modal__footer">
                <input type="button" class="modal__button modal__button--default" data-dismiss="modal" value="OK" onclick="applyToolboxItems(); modal.close();" style="width:100px" />
                <input type="button" class="modal__button modal__button--danger" data-dismiss="modal" value="Cancel" onclick="modal.close();" style="width:100px" />
            </div>
        </div>
    </div>
</div>
<div id="surveyContainer">
            <div id="creatorElement" style="height: 100vh;"></div>
</div>

<script type="text/babel" src="./index.js"></script>

</body>
</html>

.builder-page__modal {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 999;
    display: none;
    overflow: hidden;
    -webkit-overflow-scrolling: touch;
    outline: 0;
}
.modal {
    font-family: "Segoe UI", Frutiger, "Frutiger Linotype", "Dejavu Sans", "Helvetica Neue", Arial, sans-serif;
    background: rgba(0, 0, 0, 0.3);
}
.modal__dialog {
      position: relative;
      max-width: 600px;
      margin: 30px auto;
}
.modal__content {
    position: relative;
    background-color: #fff;
    -webkit-background-clip: padding-box;
    background-clip: padding-box;
    border: 1px solid #999;
    border: 1px solid rgba(0, 0, 0, 0.2);
    border-radius: 6px;
    outline: 0;
    -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
    box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);
}
.modal__header {
    font-size: 18px;
    padding: 15px;
    border-bottom: 1px solid #e5e5e5;
}
.modal__button{
    display: inline-block;
    padding: 6px 12px;
    margin-bottom: 0;
    font-size: 14px;
    font-weight: 400;
    line-height: 1.42857143;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    -ms-touch-action: manipulation;
    touch-action: manipulation;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    background-image: none;
    border: 1px solid transparent;
    border-radius: 4px;
}
.modal__button--default {
    color: #333;
    background-color: #fff;
    border-color: #ccc;
    margin-right: 10px;
}
.modal__button--danger {
    color: #fff;
    background-color: #d9534f;
    border-color: #d43f3a;          
}
.modal__body {
    font-size: 14px;
    padding: 15px;
    max-height: 70vh;
}
.modal__footer {
    padding: 15px;
    text-align: right;
    border-top: 1px solid #e5e5e5;
}
.modal__dialog--animated {
    -webkit-animation-duration: 0.2s;
    animation-duration: 0.2s;
}
@keyframes fadeInDown {
    from {
      opacity: 0;
      -webkit-transform: translate3d(0, -100%, 0);
      transform: translate3d(0, -100%, 0);
    }
    to {
      opacity: 1;
      -webkit-transform: none;
      transform: none;
    }
  }
.modal__dialog--fade-in-down {
    -webkit-animation-name: fadeInDown;
    animation-name: fadeInDown;
}
.builder-page__panel {
    margin-bottom: 20px;
    border: 1px solid transparent;
    border-radius: 4px;
    -webkit-box-shadow: 0 1px 1px rgba(0,0,0,.05);
    box-shadow: 0 1px 1px rgba(0,0,0,.05);
}
.panel {
   background-color: #fff;
}
.panel--default {
    border-color: #ddd;
}  
.panel__header {
    color: #333;
    background-color: #f5f5f5;
    border-color: #ddd;
    padding-left: 5px;
}
.panel__body {
    padding: 15px;
    max-height: 62vh;
    overflow: auto;
}
.panel label {
    margin-bottom: 5px;
    display: inline-block;
    font-weight:normal;
}
.row {
    padding: 0;
}
.row::after{
    display: table;
    content: " ";
    clear: both;
}
.row__column {
    width: 48%;
    float: left;
    padding-right: 0;
    padding-left: 0;
}
.row__column:first-child {
    padding-right: 20px;
}
Loading...
Sorry, we can't retrieve the data from server. Please comeback later.

Why we use cookies.

This site uses cookies to make your browsing experience more convenient and personal. Cookies store useful information on your computer to help us improve the efficiency and relevance of our site for you. In some cases, they are essential to making the site work properly. By accessing this site, you consent to the use of cookies.

For more information, refer to DevSoft Baltic’ privacy policy and cookie policy.