Abhishek
Abhishek

Reputation: 43

valueStateText not defined for SAPUI5 custom control

I have below custom control created by extending sap.m.Input that lets the user enter only numbers. However, when there is actually an error the state of control changes to Error with red borders but the valueStateText is not displayed when it has focus. How can I get the valueStateText for my custom control? Shouldn't it inherit from sap.m.Input?

Custom Control code:

sap.ui.define([
    "sap/m/Input"
], function (Control) {
    "use strict";
    return Control.extend("sample.control.NumericInput", {
        metadata: {
            properties: {},
            aggregations: {},
            events: {}
        },
        init: function () {
            if (sap.ui.core.Control.prototype.onInit) {
                sap.ui.core.Control.prototype.onInit.apply(this, arguments);
            }
            this.attachLiveChange(this.onLiveChange);
        },
        renderer: function (oRM, oControl) {
            sap.m.InputRenderer.render(oRM, oControl);
        },
        onLiveChange: function (e) {
            var _oInput = e.getSource();
            var val = _oInput.getValue();
            val = val.replace(/[^\d]/g, "");
            _oInput.setValue(val);
        }
    });
});

XML code:

<hd:NumericInput value="{path:'payload>/MyNumber',type:'sap.ui.model.type.String',constraints:{minLength:1,maxLength:10}}" valueStateText="My Number must not be empty. Maximum 10 characters."/>

enter image description here

Upvotes: 0

Views: 1011

Answers (2)

D. Seah
D. Seah

Reputation: 4592

you can greatly reduce your code to

  Input.extend('NumericInput', {
    renderer: {
    },
    onAfterRendering: function () {
      if (Input.prototype.onAfterRendering) {
        Input.prototype.onAfterRendering.apply(this, arguments);
      }
      this.$().find("INPUT").each(function(i, input) {
        $(input).on("keypress keyup blur", function(event) {
            $(this).val($(this).val().replace(/[^\d].+/, ""));
            if ((event.which < 48 || event.which > 57)) {
                event.preventDefault();
            }
         });
      });
    },
  });

https://jsbin.com/muberid/1/edit?js,output

Upvotes: 0

orogers
orogers

Reputation: 577

In your init override you need to call the init of the parent control (not onInit of sap.ui.core.Control). The init of the sap.m.InputBase (sap.m.Input's parent class) sets up the valuestate initial values and rendering so it's missing all that code out and not working correctly as you've found.

Check out this example based on your code:

sap.ui.define([
    "sap/m/Input"
], function (Control) {
    "use strict";
  
    return Control.extend("sample.control.NumericInput", {
        metadata: {
            properties: {},
            aggregations: {},
            events: {}
        },
        init: function () {
            Control.prototype.init.apply(this, arguments);
            this.attachLiveChange(this.onLiveChange);
        },
        renderer: function (oRM, oControl) {
            sap.m.InputRenderer.render(oRM, oControl);
        },
        onLiveChange: function (e) {
            var _oInput = e.getSource();
            var val = _oInput.getValue();
            val = val.replace(/[^\d]/g, "");
            _oInput.setValue(val);
        }
    });
});


// Small model
const model = new sap.ui.model.json.JSONModel({
  MyNumber: "10000000000000000000",
});

// Create an example of the control (JS not XML but idea is the same)
const input = new sample.control.NumericInput({
  valueState: "Error",
  valueStateText:"My Number must not be empty. Maximum 10 characters.",
  value: {
    path:'/MyNumber',
    type:'sap.ui.model.type.String',
    constraints:{minLength:1,maxLength:10}
  }
});

input.setModel(model);
input.placeAt('content');
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>JS Bin</title>
    <script 
            src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" 
            id="sap-ui-bootstrap" 
            data-sap-ui-theme="sap_fiori_3" 
            data-sap-ui-xx-bindingSyntax="complex" 
            data-sap-ui-libs="sap.m"></script>
  </head>
  <body class="sapUiBody sapUiSizeCompact">
    <div id='content'></div>
  </body>
</html>

Upvotes: 1

Related Questions