Formatting Select2 Options in Angular

One of the great features of Select2 is that you can format the choices beyond just a list of text values. In this post, I’ll show how you can format the display of values in a Select2 in Angular.

Before we dig in…

These examples were adapted from an XPages application that uses Angular, but there’s nothing related to XPages in the code shown here. (In reality, you’d likely call an XPages REST service to dynamically populate the list of choices, but it’s not necessary in these examples.)

If you’ve used a Select2 in any other context, then the solution here may not be surprising. If you haven’t, then you’ll see how Select2 choices can be formatted.

The examples in this post use the ui-select2 for Angular. (There’s a note at the top of the page that says this control has been deprecated in favor of a newer version.) The code needs to be added to the application, but that is outside of the scope of this post.

Getting up to Speed on Angular

If you don’t have any background in Angular, the angularjs.org tutorial is a great place to start.

Also check out Marky Roden’s great series on using Angular in XPages.

Basic Select2

These examples will all create a Select2 control in Angular that will display a list of fruit and allow the user to choose one.

Here is the basic Select2:

Angular Select2 1a

Once a value is selected, it is shown in the field and separately below the Select2.

Angular Select2 1b

The basic HTML for the template is as follows:

<select ui-select2="select2Config" ng-model="fruit"
        data-placeholder="Select a fruit..." style="min-width:150px">
    <option value=""></option>
    <option ng-repeat="option in options" value="{{option}}">{{option}}</option>
</select>

<br><br>
Selected Value: {{fruit}}

Lines 1-2 start the select tag.

  • The ui-select2 attribute references the configuration object in the Angular controller that sets properties for the control.
  • The ng-model attribute defines that the selected value will be bound to a “field” (if you will) named fruit in the model.
  • The data-placeholder attribute sets the placeholder text when no value has been selected.
  • The style attribute sets a minimum width for the control. (This is not necessary)

Line 3 includes an empty value at the start of the list.

Line 4 uses an ng-repeat directive to build the list of options to choose from. The options list is set in the controller (code shown below).

Line 8 is simply displays the selected value. It is not necessary, but it shows off the two-way binding feature of Angular.

The controller used with the template on this page is as follows:

//Select2 controller - basic
MyAppControllers.controller('select2Ctrl_basic', ['$scope', '$http', '$routeParams',
  function ($scope, $http, $routeParams) {
    $scope.options = ['apple', 'banana', 'grape', 'lime', 'orange'];
  }
]);

That’s it! All I did was define the controller and define an options property in the scope and set it to an array. The template reads the array and generates an option for each value in the array.

Text Formatting

In this example, I’ll show how to change the color of each option based on the value. We’ll use the same HTML template for the Select2.

Angular Select2 2

Here’s the controller for this example:

MyAppControllers.controller('select2Ctrl_formatted', ['$scope', '$http', '$routeParams',
  function ($scope, $http, $routeParams) {
    $scope.options = ['apple', 'banana', 'grape', 'lime', 'orange'];
    
    // Format the control to display a span with the text changed to the color of the fruit
    $scope.format = function (data) {
      var fontColor = 'black';
        	
      switch (data.id) {
        case 'apple':
          fontColor = 'DarkRed';
          break;
        case 'banana':
          fontColor = 'Gold';
          break;
        case 'grape':
          fontColor = 'Purple';
          break;
        case 'lime':
          fontColor = 'LimeGreen';
          break;
        case 'orange':
          fontColor = 'Orange';
          break;
      }
        	
      return  "<span style='color:" + fontColor + "'>" + data.text + "</span>";
    };

    $scope.select2Config = {
      formatResult: $scope.format,
      formatSelection: $scope.format
    };

}]);

In this controller, lines 6-28 create a function that is used to format the options in the list. The function accepts a data object that is the current option in the select2. (The function will be called once for each option as the list is built.) The data object contains a text property that is the actual display value for that option.

Lines 9-25 define a switch statement that sets the fontColor variable based on the fruit.

Line 27 is the key — it returns a span that includes a style attribute to set the font color and display the option.

Lines 30-33 define the configuration object used for the Select2. (This is specified in the ui-select2 attribute of the HTML template.) It tells the control to format each selection and the result using the format() function defined in the controller.

The difference between formatSelection and formatResult

The formatSelection function formats the values in the drop-down list. The formatResult function formats the selected value, shown at the top of the list when the rest of the list is dropped-down. (The example below shows ‘orange’ selected.)

Angular Select2 3

You can use different formatting functions, but it seems common to use the same formatting function for both.

Adding an Image

In this example, I’ll show how to display an image next to each option, based on the value. We’ll use the same HTML template for the Select2.

Angular Select2 4

Here’s the controller for this example:

MyAppControllers.controller('select2Ctrl_image', ['$scope', '$http', '$routeParams',
  function ($scope, $http, $routeParams) {

    $scope.options = ['apple', 'banana', 'grape', 'lime', 'orange'];

    // Format the control to display an image corresponding with the name of the fruit
    $scope.format = function (data) {
      	
      var url = '';
        	
      switch (data.text) {
        case 'apple':
          url = 'apple.png';
          break;
        case 'banana':
          url = 'banana.png';
          break;
        case 'grape':
          url = 'grapes.gif';
          break;
        case 'lime':
          url = 'lime.png';
          break;
        case 'orange':
          url = 'orange.png';
          break;
      }
        	
      return  "<img src='" + url +"' />&nbsp;&nbsp;" + data.text;
    };           
        
    $scope.select2Config = {
      formatResult: $scope.format,
      formatSelection: $scope.format
    };

}]);

This is very similar to the last example, with the exception that it determines the url and returns an img tag to display next to the text value. This adds a very nice touch to the UI of the control. (Note: The images referenced in this example are all icons that I added to the NSF as image resources.)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: