@openui5/sap.m
Version:
OpenUI5 UI Library sap.m
146 lines (125 loc) • 5.31 kB
JavaScript
/*!
* OpenUI5
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
/**
* Defines support rules of the Select control of sap.m library.
*/
sap.ui.define(["sap/ui/support/library", "sap/ui/model/BindingMode"],
function(SupportLib, BindingMode) {
"use strict";
// shortcuts
var Categories = SupportLib.Categories, // Accessibility, Performance, Memory, ...
Severity = SupportLib.Severity, // Low, Medium, High
Audiences = SupportLib.Audiences; // Control, Internal, Application
// const
var DEFAULT_MODEL_SIZE_LIMIT = 100;
//**********************************************************
// Rule Definitions
//**********************************************************
/**
*Checks if the 'items' aggregation binding of sap.m.Select is limited to 100 items
*/
var oSelectRule = {
id : "selectItemsSizeLimit",
audiences: [Audiences.Control],
categories: [Categories.Usability],
enabled: true,
minversion: "1.28",
title: "Select: Items have size limit of 100",
description: "The 'items' model imposes a default size limit of 100",
resolution: "Use the sap.ui.model.Model.prototype.setSizeLimit to adjust the size limit of the 'items' model if you expect more than 100 items",
resolutionurls: [{
text: "API Reference for sap.ui.model.Model",
href: "https://sdk.openui5.org/api/sap.ui.model.Model"
}],
check: function (oIssueManager, oCoreFacade, oScope) {
oScope.getElementsByClassName("sap.m.Select")
.forEach(function(oElement) {
var oBinding = oElement.getBinding("items"),
oModel = oBinding && oBinding.oModel;
if (oModel && (oModel.iSizeLimit === DEFAULT_MODEL_SIZE_LIMIT)) {
var sElementId = oElement.getId(),
sElementName = oElement.getMetadata().getElementName();
oIssueManager.addIssue({
severity: Severity.Low,
details: "Select '" + sElementName + "' (" + sElementId + ") model has a default limit of 100 items",
context: {
id: sElementId
}
});
}
});
}
};
var oSelectedKeyBindingRule = {
id: "selectedKeyBindingRule",
audiences: [Audiences.Control],
categories: [Categories.Bindings],
enabled: true,
minversion: "1.64",
title: "Select: 'selectedKey' property incorrectly bound to item which is bound to the 'items' aggregation",
description: "Binding the 'selectedKey' property to the 'items' aggregation results in a non-working Select " +
"control in TwoWay binding mode. When the user changes the selected item, the key of the bound item " +
"(under the list bound to the 'items' aggregation) also changes, resulting in an incorrect change of the " +
"selected item.",
resolution: "If binding of 'selectedKey' is necessary, bind it to a model entry which is not bound to the " +
"'items' aggregation of the Select control.",
check: function (oIssueManager, oCoreFacade, oScope) {
oScope.getElementsByClassName("sap.m.Select")
.forEach(function(oElement) {
var sElementId,
sElementName,
oSelectedKeyModel,
oItemsModel,
sSelectedKeyBindingPath,
sItemsBindingPath,
sSelectedKeyMinusItemsBindingPath;
if (
oElement.isBound("selectedKey") &&
oElement.isBound("items")
) { // Both metadata entries are bound
oSelectedKeyModel = oElement.getBinding("selectedKey").getModel();
oItemsModel = oElement.getBinding("items").getModel();
if (
oSelectedKeyModel && // We have a model for the selectedKey
oItemsModel && // We have a model for the items
oSelectedKeyModel.getId() === oItemsModel.getId() && // Both entries are bound to the same model
oSelectedKeyModel.getDefaultBindingMode() === BindingMode.TwoWay // Model is in TwoWay binding mode
) {
sSelectedKeyBindingPath = oElement.getBindingPath("selectedKey");
sItemsBindingPath = oElement.getBindingPath("items");
sSelectedKeyMinusItemsBindingPath = sSelectedKeyBindingPath.replace(sItemsBindingPath, "");
// We will check that the binding path of the "selectedKey" is not a child of the "items"
// binding path
//
// For example:
// * "selectedKey" bindingPath equals "/ProductCollection/1/ProductId"
// * "items" bindingPath equals "/ProductCollection"
// * Subtracting "items" from "selectedKey" binding path should remain "/1/ProductId"
if (
sSelectedKeyBindingPath.indexOf(sItemsBindingPath) === 0 && // "selectedKey" starts with "items" binding path
sSelectedKeyMinusItemsBindingPath.length > 0 && // "selectedKey" is longer than "items" binding path
sSelectedKeyMinusItemsBindingPath[0] === "/" // remaining binding path starts with slash
) {
sElementId = oElement.getId();
sElementName = oElement.getMetadata().getElementName();
oIssueManager.addIssue({
severity: Severity.High,
details: "Select '" + sElementName + "' (" + sElementId + ") 'selectedKey' property incorrectly bound to item which is bound to the 'items' aggregation",
context: {
id: sElementId
}
});
}
}
}
});
}
};
return [
oSelectRule,
oSelectedKeyBindingRule
];
}, true);