Question T2587
Visible to All Users

Customize ImagePicker Template

created 6 years ago

Hey,

i want to customize the "\src\knockout\templates\question-imagepicker.html" template - but don't want to do that in
the survery library because I want to be able to update the sources again later.

Is there any best practice to do that?

I want to change from this

HTML
<script type="text/html" id="survey-question-imagepicker"> <fieldset data-bind="css: question.koCss().root"> <legend data-bind="attr: { 'aria-label': question.locTitle.renderedHtml }"></legend> <!-- ko foreach: { data: question.visibleChoices, as: 'item', afterRender: question.koAfterRender} --> <div data-bind="css: question.getItemClass(item)"> <label data-bind="css: question.koCss().label"> <input style="display: none;" data-bind="attr: {type: question.multiSelect ? 'checkbox' : 'radio', name: question.name + '_' + question.id, value: item.value, id: ($index() == 0) ? question.inputId : '', 'aria-required': question.isRequired, 'aria-label': question.locTitle.renderedHtml}, checked: question.koValue, enable: !question.isReadOnly && item.isEnabled, css: question.koCss().itemControl" /> <div> <!-- ko if: question.contentMode === "image" --> <img data-bind="css: question.koCss().image, attr: { src: $data.imageLink, width: question.imageWidth ? question.imageWidth + 'px' : undefined, height: question.imageHeight ? question.imageHeight + 'px' : undefined }, style: { objectFit: question.imageFit }"/> <!-- /ko --> <!-- ko if: question.contentMode === "video" --> <embed data-bind="css: question.koCss().image, attr: { src: $data.imageLink, width: question.imageWidth ? question.imageWidth + 'px' : undefined, height: question.imageHeight ? question.imageHeight + 'px' : undefined }, style: { objectFit: question.imageFit }"/> <!-- /ko --> <!-- ko if: question.showLabel --> <span data-bind="text: text || value, attr: { title: text || value }, css: question.koCss().itemText"></span> <!-- /ko --> </div> </label> </div> <!-- /ko --> </fieldset> </script>

to this:

HTML
<script type="text/html" id="survey-question-imagepicker"> <fieldset data-bind="css: question.koCss().root"> <legend data-bind="attr: { 'aria-label': question.locTitle.renderedHtml }"></legend> <!-- ko foreach: { data: question.visibleChoices, as: 'item', afterRender: question.koAfterRender} --> <div data-bind="css: question.getItemClass(item)"> <label data-bind="css: question.koCss().label"> <input style="display: none;" data-bind="attr: {type: question.multiSelect ? 'checkbox' : 'radio', name: question.name + '_' + question.id, value: item.value, id: ($index() == 0) ? question.inputId : '', 'aria-required': question.isRequired, 'aria-label': question.locTitle.renderedHtml}, checked: question.koValue, enable: !question.isReadOnly && item.isEnabled, css: question.koCss().itemControl" /> <div> <!-- ko if: question.contentMode === "image" --> <img data-bind="css: question.koCss().image, attr: { src: $data.imageLink, width: question.imageWidth ? question.imageWidth + 'px' : undefined, height: question.imageHeight ? question.imageHeight + 'px' : undefined }, style: { objectFit: question.imageFit }"/> <!-- /ko --> <!-- ko if: question.contentMode === "video" --> <embed data-bind="css: question.koCss().image, attr: { src: $data.imageLink, width: question.imageWidth ? question.imageWidth + 'px' : undefined, height: question.imageHeight ? question.imageHeight + 'px' : undefined }, style: { objectFit: question.imageFit }"/> <!-- /ko --> <!-- ko if: question.showLabel --> <span data-bind="text: text || value, attr: { title: text || value }, css: question.koCss().itemText"></span> <!-- /ko --> <!-- ko if: question.showPrice --> <span data-bind="text: getPriceFormatted(), attr: { title: price}, css: question.koCss().price"></span> <!-- /ko --> </div> </label> </div> <!-- /ko --> </fieldset> </script>

Maybe you can tell me how can I do that without changing the source files.
Thank you very much!

Patrick

Answers approved by surveyjs Support

created 6 years ago

Hello,

Yes. You can do it. here is the working sample - https://plnkr.co/edit/DP6fprclFNnnFr5DWKQ2?p=preview

JavaScript
new Survey .SurveyTemplateText() .replaceText(template, "question", "imagepicker"); Survey .Serializer .addProperty("imagepicker", "showPrice:boolean"); Survey .Serializer .addProperty("imageitemvalue", "price");

Thanks, Serge
SurveyJS Team

    Other Answers

    created 6 years ago

    Hi Serge,

    thank you - this is exactly what I am looking for.
    Now I have still two more questions :)

    1. When I want to use a custom function in the template for displaying the price value, how can I achieve this? I need the itemvalue and question objects as argument. So, when I register a global function with
    JavaScript
    Survey .FunctionFactory .Instance .register("getMyCustomPriceString", getCustomPrice);

    its not the scope i need.

    Currently I extend the sources again at \src\itemvalue.ts with a own function ItemValue.getPriceFormatted() But this is not what I want to do. Is there another way?
    Here the extended example: https://next.plnkr.co/edit/EFWJfKqDvLbluZhx
    I think I will need some more own functions on the source elements like ItemValue, so it would be very nice, if there is any possibility to do that without changing the source code of the library.

    1. Creator: I need a custom function on the ImageItemInplaceEditor class and change some logic here for adding new image items. (We use our own shop system media library for adding images here) - Again: currently I am doing that directly in the sources.
      Can override it in any way?
      Also I changed the imageItemsAdorner and addImageItemAdorner with my own logic.
      Maybe I can achieve this when I first unregister the base adorner with unregisterAdorner("image-items") / unregisterAdorner("add-image-item") and after that I register my own?

    I hope you can follow me and have some help for me ;-) Thanks!

      Show previous comments (4)

        Hello Patric,
        It is better do not customize templates, since we may change them with any minor version.
        What are you trying to implement?
        You may create your own custom property editor. Here is the example.

        Thank you,
        Andrew
        SurveyJS Team

        P P
        PatrickSchneider 6 years ago

          Okay, good to know.

          We are implementing a product configurator for our shop system and connect the choices to elements from our database.
          So users can insert "products" into survey creator (opens our own selector on "new item" click and insert the itemvalues to editor on callbacks) - this is why I have to change the functionality.
          The property values of the itemvalue-objects are filled automatically from our products.

          The base functionality of the item editor is what we need - Is there a way to inherit from that maybe?
          I just have to change some button click listeners…

          Example of * \src\templates\propertyEditors\propertyeditor-nesteditems.html *
          survey.jpg

          The listener for the click on "new item" / "Neu hinzufügen" is registered by javascript with "instance.onItemValueAdded(…)" - then i open a custom window and insert values on callback again and trigger the itemValue.propertyValueChanged(); function for the client update.

          survey2.jpg

          Patrick :)

            Hello,

            I've created a separate ticket on your behalf (T2602: Is there a possibility for changing creator templates?). It has been placed in our processing queue and will be answered shortly.

            Thanks, Serge
            SurveyJS Team