New to Kendo UI for jQuery? Download free 30-day trial

Use AngularJS ng-click in ListBox Template

Environment

Product Progress® Kendo UI® ListBox for jQuery
Created with version 2017.3.1026

Starting with R2 2022, the Kendo UI team officially drops the support for AngularJS 1.x through Kendo UI for jQuery. The AngularJS related files and functionality are removed from the bundles and distribution in R3 SP1 2023. The last version that contains the files is R3 2023.

Description

Is it possible to use angularjs + ng-click inside of a listbox template if I construct the listbox using angular syntax? I'd like to be able to click one of the items in the listbox and have it call the same ng-click function that the button can (really I want any angular stuff in there to work, not just ng-click)

Solution

Indeed the AngularJS templates do not include one which works out of the box for the Kendo UI ListBox.

It is possible to use AngularJS directive in the jQuery template if we compile it programmatically.

Here are the important steps:

  1. Add an event handler to the dataBound event of the first ListBox(the one which has a dataSource).
  2. Add an event handler to both of the ListBoxes add events.
  3. Pass the function to the handlers above using a $timeout because the add event is triggered before the item is actually added in which the compilation occurs:
    $scope.compileTemplate = function(e){     
        var listbox = this;
        $timeout(function(){
            var rows = listbox.items();
            rows.each(function(index,row){
                if(!$(row).hasClass("ng-scope")){
                    $compile(row)($.extend($scope.$new(), listbox.dataItem(row)));
                }               
            });
        });           
    }

The example loads Kendo UI 2023.3.1010 version.

      <script src="https://kendo.cdn.telerik.com/2023.3.1010/js/angular.min.js"></script>
      <script src="https://kendo.cdn.telerik.com/2023.3.1010/js/kendo.all.min.js"></script>

    <div id="example" ng-app="KendoDemos">
      <h2>Compile AngularJS directives in jQuery template</h2>
      <p style="color: #fff;background-color: #ff4350;width:460px;font-size:20px;">Click the Image in the template to trigger "ng-Click"</p>
      <div class="demo-section k-content wide" ng-controller="MyCtrl">
        <select name="optional" id="optional" kendo-list-box k-options="selectOptions1"></select>
        <select name="selected" id="selected" kendo-list-box k-options="selectOptions2"></select>
      </div>
    </div>

    <script>
      angular.module("KendoDemos", [ "kendo.directives" ])
        .controller("MyCtrl", function($scope, $compile, $timeout){

        var customerTemplate = '<span ng-click="clicked()" class="k-state-default" style="background-image: url(\'https://demos.telerik.com/kendo-ui/content/web/Customers/#:data.CustomerID#.jpg\')"></span>' +
            '<span class="k-state-default"><h3>#: data.ContactName #</h3><p>#: data.CompanyName #</p></span>';

        $scope.clicked = function(){
          alert("ng-clicked");  
        }

        $scope.compileTemplate = function(e){      
            var listbox = this;
            $timeout(function(){
              var rows = listbox.items();
              rows.each(function(index,row){
                if(!$(row).hasClass("ng-scope")){
                  $compile(row)($.extend($scope.$new(), listbox.dataItem(row)));
                }                
              });
            });            
          }

        $scope.customPlaceholder = function(draggedItem) {
          return draggedItem
            .clone()
            .addClass("custom-placeholder")
            .removeClass("k-ghost");
        }


        $scope.selectOptions1 = {
          dataBound: $scope.compileTemplate,
          add: $scope.compileTemplate,
          dataTextField: "ContactName",
          dataValueField: "CustomerID",
          template: customerTemplate,
          dataSource: {
            transport: {
              read: {
                dataType: "jsonp",
                url: "https://demos.telerik.com/kendo-ui/service/Customers",
              }
            }
          },
          draggable: { placeholder: $scope.customPlaceholder },
          dropSources: ["selected"],
          connectWith: "selected",
          toolbar: {
            position: "right",
            tools: ["moveUp", "moveDown", "transferTo", "transferFrom", "transferAllTo", "transferAllFrom", "remove"]
          }
        };

        $scope.selectOptions2 = {
          dataTextField: "ContactName",
          dataValueField: "CustomerID",
          template: customerTemplate,
          dataSource:[],
          draggable: { placeholder: $scope.customPlaceholder },
          dropSources: ["optional"],
          connectWith: "optional",
          add: $scope.compileTemplate,
        };
      })
    </script>

    <style>
      #example .demo-section {
        max-width: none;
        width: 695px;
      }

      #example .k-listbox {
        width: 326px;
        height: 310px;
      }

      #example .k-listbox:first-child {
        width: 360px;
        margin-right: 1px;
      }

      .k-ghost {
        display:none!important;
      }

      .custom-placeholder {
        opacity: 0.4;
      }

      #example .k-item {
        line-height: 1em;
      }

      /* Material Theme padding adjustment*/

      .k-material #example .k-item,
      .k-material #example .k-item.k-hover,
      .k-materialblack #example .k-item,
      .k-materialblack #examplel .k-item.k-hover {
        padding-left: 5px;
        border-left: 0;
      }

      .k-item > span {
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
        display: inline-block;
        vertical-align: top;
        margin: 20px 10px 10px 5px;
      }

      #example .k-item > span:first-child,
      .k-item.k-drag-clue > span:first-child {
        -moz-box-shadow: inset 0 0 30px rgba(0,0,0,.3);
        -webkit-box-shadow: inset 0 0 30px rgba(0,0,0,.3);
        box-shadow: inset 0 0 30px rgba(0,0,0,.3);
        margin: 10px;
        width: 50px;
        height: 50px;
        border-radius: 50%;
        background-size: 100%;
        background-repeat: no-repeat;
      }

      #example h3,
      .k-item.k-drag-clue h3 {
        font-size: 1.2em;
        font-weight: normal;
        margin: 0 0 1px 0;
        padding: 0;
      }

      #example p {
        margin: 0;
        padding: 0;
        font-size: .8em;
      }
    </style>
In this article