Bind CSS class of a UI5 control programatically to a model value

Viewed 639

Is there a way to bind the class attribute of a ui5-input-template inside a sap.ui.table.Table to a model value?

What I tried so far is:

[
  {
    label: 'arow',
    disabled: true,
    class: 'myClass1',
    data: [
      {
        value: 'rowVal1'
      }
    ]
  },
  // ...
]

and

myTable.bindColumns("/columns", function (index: string, context: any) {
  let indParts: string[] = index.split("-");
  let ind = +indParts[indParts.length - 1];
  var colLabel = context.getProperty().label;
  let template = new sap.m.Input({
    value: `{data/${ind}/value}`,
    class: '{= ${class} }',
    enabled: '{= !${disabled} && !${data/' + ind + '/disabled} }',
  });
  // template.addStyleClass('{class}');
  // template.setClass('{class}');
  let column =  new sap.ui.table.Column({
    label: colLabel,
    width: `{width}`,
    template: template,
  });
  return column;
});
myTable.bindRows("/rows");

It seems as if I cannot use the model binding here, only add static class values when I create the template. Is this right?

1 Answers

As suggested in the comment, one of the solutions is to enhance the control's set of properties with your own property to allow binding the style class.

Here is a working sample: https://embed.plnkr.co/ik9PIdHKvK8udpQt

And here a snippet from the control extension:

sap.ui.define([
  "sap/m/Input",
  "sap/m/InputRenderer",
], function(Input, InputRenderer) {
  "use strict";

  return Input.extend("demo.control.Input", {
    metadata: {
      properties: {
        "styleClass": {
          type: "string",
          defaultValue: null,
          bindable: true,
        }
      }
    },

    renderer: { // will be merged with the parent renderer (InputRenderer)
      apiVersion: 2, // enabling semantic rendering (aka. DOM-patching)
      // Implement the hook method from the parent renderer
      addOuterClasses: function (oRenderManager, oInput) {
        InputRenderer.addOuterClasses.apply(this, arguments);
        oRenderManager
          .class("demoControlInput") // Standard CSS class of demo.control.Input
          .class(oInput.getStyleClass()); // Custom CSS class defined by application
      },
    },

  });
});

As documented in the topic Extending Input Rendering, some base controls allow overwriting existing methods from the renderer. If you look at the sap.m.InputRenderer, for example, you can see that the renderer provides multiple hooks to be overwritten by subclasses such as the addOuterClasses.

And since styleClass in our customer control is a valid ManagedObject property, binding in JavaScript ("programmatically") also works:

new Input({ // required from "demo/control/Input"
  // ...,
  styleClass: "{= ${class}}"
});
Related