0

I have created an angularjs directive called image-multiselect which can be used as follows.

   <image-multiselect items="landTransportTypes" image="illustrationURL" itemname="name" append="<div class='detail'>...some html here...</div>"></image-multiselect>

Notice the append attribute which is assigned an html as string. This html string i expect to use for modifying the template attribute in the DDO as follows

function(){

    var imageMultiselect = function(){

        return {

            scope : {
                        items: "=",
                        image: "@",
                        itemname: "@",
                        append: "@" 

                    },

            template : "<div style='background:#f2f2f2;padding:20px;margin:20px;border-radius:5px;min-height:100px;'>" +
                        "<div ng-repeat='item in items' class='card text-center'>" +
                            "<img class='card-img' src='{{item[image]}}' alt='Avatar'>" +
                            "<div class='detail'>" +

                                "<b>{{item[itemname]}}</b>" +

                                 /*append used to customize template as per requirement*/
                                 "{{append}}"+

                            "</div>" +
                         "</div>" +
                       "</div>"

        }


    }

    angular.module("myApp").directive("imageMultiselect",imageMultiselect); 

}());

Problem : The html string passed in the append is not rendered as html rather entire markup is displayed as it is on the page ?

RaghaveShukla
  • 289
  • 6
  • 17

2 Answers2

2

Angular doesnt render HTML, because of the potential dangeros bahaviour of unknown HTML. If you want your HTML to be rendered use the ngSanitize
Then use

<div ng-bind-html="variableWithHTMLString"> </div>

When using the $sanitize service. Data in ng-bind-html will by default be rendered.

I've made a plunker to your exsample: https://plnkr.co/edit/Vi46BsuAsnuk3N3R4Yz9?p=preview

The changes are that the append varibale is binded with ng-bind-html, sanitaize is downloaded in sciript tag and injected in module.

Anders Vestergaard
  • 1,139
  • 1
  • 14
  • 21
  • Thanks that is pretty much what i was looking for but the only question that remains now is that can i use `ng-model` inside the html markup given to `ng-bind-html` – RaghaveShukla Jan 22 '17 at 09:24
  • Dont know what you are trying to do, but if it's something like Stackoverflow input and preview, you can use: ideas from this post: http://stackoverflow.com/questions/20796102/angularjs-data-bind-in-ng-bind-html I made a simple plunker to illustrate: https://plnkr.co/edit/SXIIdIVbDlmAqMnjKITJ?p=preview – Anders Vestergaard Jan 22 '17 at 09:49
  • Well what i am trying to do is create a multi-select gallery of images, which would take list of urls to display image and name of the item, but it would also have a detail section which will remain empty, but when the developer provides some html the detail section will be replaced by that html. In our application the detail section in some cases need to be replaced by an input field used for storing item count. But i am planning to make it generic so that anyone can use it. What i am experiencing is that with your example ng-bind-html just takes simple html but it removes the input field. – RaghaveShukla Jan 22 '17 at 10:00
  • Yes ng-bind-html evaluates html in a "secure" way. They removed the privious ng-bind-html-unsafe but I've seen people implementing this directives them self. Like http://stackoverflow.com/questions/22808062/ng-bind-html-doesnt-work-for-input-tags . – Anders Vestergaard Jan 22 '17 at 10:04
  • You are correct i have found one such implementation that allows me to implement the exactly the way i wanted. https://github.com/francisbouvier/ng_html_compile – RaghaveShukla Jan 22 '17 at 11:04
0

@Anders thanks for your response, it gave me the right direction. I used @Ander's approach but instead of using ng-bind-html i used ng-html-compile directive by Francis Bouvier ( https://github.com/francisbouvier/ng_html_compile )

Use Directive

<image-multiselect items="landTransportTypes" 
                                   image="illustrationURL" 
                                   itemname="name"
                                   append="<input type='text' name='count' placeholder='Count' ng-model="transport.count" class='form-control input-sm'/></div>">
                                   </image-multiselect>

Directive Definition

(function(){

    var imageMultiselect = function(){

        return {

            scope : {
                        items: "=",
                        image: "@",
                        itemname: "@",
                        append: "@" 

                    },

            template : "<div style='background:#f2f2f2;padding:20px;margin:20px;border-radius:5px;min-height:100px;'>" +
                        "<div ng-repeat='item in items' class='card text-center'>" +
                            "<img class='card-img' src='{{item[image]}}' alt='Avatar'>" +
                            "<div class='detail'>" +
                                "<b>{{item[itemname]}}</b>" + 
                                /* This is where i use ng-html-compile directive, which works wonders for me, refer : https://github.com/francisbouvier/ng_html_compile  */
                                     "<span ng-html-compile='append'></span>" +

                            "</div>" +
                         "</div>" +
                       "</div>"

        }


    }

    angular.module("myApp").directive("imageMultiselect",imageMultiselect);


}());
RaghaveShukla
  • 289
  • 6
  • 17