cancel
Showing results for 
Search instead for 
Did you mean: 

sap.ui.table TreeTable Binding Problem (Scrolling)

0 Kudos

Hello,

i am currently writing a little Fiori App for intern managers to give employees a rating of their qualification. This gives HR the opportunity, to find the right training opportunities.

I am therefore using a sap.ui.table.TreeTable to visualize the hierachy of our qualification catalog, each column represents a single employee:

the number in the brackets is the must-have-value of the specific qualification.

Red = Underrated, Green: Accurate, Blue: Overrated.

Data binding:

Extended RatingIndicator to append the custom style class onAfterRendering, these style classes control the colors of the stars:

jQuery.sap.declare("ZRatingIndicator");
sap.m.RatingIndicator.extend('ZRatingIndicator', {
	metadata: {
		properties: {
			clazz: 'string'
		}
	},
	renderer: function(oRm, oControl) {
		sap.m.RatingIndicatorRenderer.render(oRm, oControl);
	},
	onAfterRendering: function() {
		if (sap.m.RatingIndicator.prototype.onAfterRendering) {
			sap.m.RatingIndicator.prototype.onAfterRendering.apply(this);
		}


		s.onValueBasedStyleClass(this);


	}
});

In function onValueBasedStyleClass i fetch the styleClass:

var styleClass;
oRatingIndicator.removeStyleClass("OVERRATED");
oRatingIndicator.removeStyleClass("UNDERRATED");
oRatingIndicator.removeStyleClass("ACCURATE");


try {
	if (soll > ist) {
		styleClass = "UNDERRATED";
	} else if (ist > soll) {
		styleClass = "OVERRATED";
	} else if (ist == soll) {
		styleClass = "ACCURATE";
	} else {
		//Nothing.
	}
	if (styleClass != undefined) {
		oRatingIndicator.addStyleClass(styleClass);
	}
} catch (e) {
	console.error(e.message);
}

Binding:

oNewCol = new sap.ui.table.Column({
	//[...]
	template: new sap.m.FlexBox({
		direction: "Row",
		alignItems: "Center",
		justifyContent: "Start",
		alignContent: "Center",
		items: [
			new ZRatingIndicator({
				visible: "{" + uKey + "_VISIBLE}",
				maxValue: "{" + uKey + "_MAX}",
				value: "{" + uKey + "_VALUE}",
				tooltip: "{" + uKey + "_TOOLTIP}",
				editable: "{" + uKey + "_EDITABLE}",


				customData: [
					new sap.ui.core.CustomData({
						key: "SOLL",
						value: "{" + uKey + "_MIN}"
					})
				],


				liveChange: function(oEvt) {
					//[...]
				}


			}),
			new sap.m.Label({
				text: "(" + "{" + uKey + "_MIN}" + ")",
				visible: "{" + uKey + "_VISIBLE}",
				tooltip: "Minimum",
				design: "Bold"
			}).addStyleClass("MAX_LABEL")
		]
	})
});
oTreeTable.addColumn(oNewCol);

CSS (e.g.):

.UNDERRATED > .sapMRISel {
    float: left;
    display: block;
    overflow: hidden;
    padding: 0;
    margin: 0;
    color: #b00;
    word-wrap: normal;
    white-space: nowrap;
}


.UNDERRATED > .sapMRIHov {
    float: left;
    display: none;
    overflow: hidden;
    word-wrap: normal;
    white-space: nowrap;
    color: #b00;
}

This works fine on first sight.

When i scroll down, still good.

When i scroll up by one mouse wheel step, the binding has some pain.

First rendering after scroll down:

1 out of 5 stars, must-have 4, --> Underrated --> Red. Binding works.

One step upstairs:

1 out of 5 stars, must-have 4 --> Accurate --> Green, WRONG!

The whole binding paramers to the properties of RatingIndicator are fine, but the styleClass is not rendered properly.

Scrolling down again leads back to the right rendering.

Hint: problem does NOT depend on the rendering engine, but on the binding. The wrong style class is binded to the dom element:

Of course i've done some data bindings through out my days as a ui5 dev, but i cant see the error this time...

If anybody has an idea, please advise!

Cheers,

Stephan

Accepted Solutions (1)

Accepted Solutions (1)

Fabrice
Active Participant

Hi,

i think it is because the TreeTable is a sap.ui.table.Table. This Control "simulate" the rows. In the dom you only have the visible rows and when you scroll, just the bindings are changed, not the control itself. That's why when you scroll down the style class stay but the value (binding) change. Your control is no more rendered.

A solution could be to fetch the classes after the binding change and not in the onAfterRendering function.

You can, for exemple, overwrite the setValue function in your ZRatingIndicator :

setValue : function(sValue){
   sap.m.RatingIndicator.prototype.setValue.call(this,sValue);
   s.onValueBasedStyleClass(this);   
}

Regards

Fabrice

0 Kudos

Hi Fabrice,

thank you for your answer.

This does not work for me, still the same problem.

I tried both, overwriting the setValue() function and add a listener on the binding's onChange event.

any other suggestions?

best regards,

Stephan

Fabrice
Active Participant
0 Kudos

Hi,

do you have an error in the debugger console?

in debug mode, do you go in the setValue function?

Thanks in advance

Regards

Fabrice

Fabrice
Active Participant

Hi,

maybe you could wait for the customdata binding :

customData:[
  newsap.ui.core.CustomData({
    key:"SOLL",
    value:"{path:" + uKey + "_MIN, events : {dataReceived : '.onDataReceivedForSOLL'} }"})
],

and call onValueBasedStyleClass in onDataReceivedForSOLL

or

you could try a special property for your custom control and redefine the set function:

sap.m.RatingIndicator.extend('ZRatingIndicator', {
	metadata: {
		properties: {
			clazz: 'string',
                        istAndSoll: {type : "string[]"},
		}
	},
        ...
        setIstAndSoll : function(aIstAndSoll){
            var sIst = aIstAndSoll[0];
            var sSoll = aIstAndSoll[1];
            ...
        },

and you can bind your values without the custom data:

new ZRatingIndicator({
				visible: "{" + uKey + "_VISIBLE}",
				maxValue: "{" + uKey + "_MAX}",
				value: "{" + uKey + "_VALUE}",
				tooltip: "{" + uKey + "_TOOLTIP}",
				editable: "{" + uKey + "_EDITABLE}",
                                istAndSoll : "{" + uKey + "_VALUE},{" + uKey + "_MIN}",
                                ... 

It is ideas, i did not test them

I hope it will help

Regards

Fabrice

0 Kudos

Hi Fabrice,

that's the key.

After switching from customData to a local property entry, the redefined onAfterRendering call always gehts the current value.

code:

sap.m.RatingIndicator.extend('ZRatingIndicator', {
	metadata: {
		properties: {
			clazz: 'string',
			soll: 'string'
		}
	},
	renderer: function(oRm, oControl) {
		sap.m.RatingIndicatorRenderer.render(oRm, oControl);
		
	},
	onAfterRendering: function() {
		if (sap.m.RatingIndicator.prototype.onAfterRendering) {
			sap.m.RatingIndicator.prototype.onAfterRendering.apply(this);
		}


		s.onValueBasedStyleClass(this);


	}
});

new ZRatingIndicator({
	visible: "{" + uKey + "_VISIBLE}",
	maxValue: "{" + uKey + "_MAX}",
	value: "{" + uKey + "_VALUE}",
	tooltip: "{" + uKey + "_TOOLTIP}",
	editable: "{" + uKey + "_EDITABLE}",
	soll: "{" + uKey + "_MIN}",


	liveChange: function(oEvt) {
		s.onValueBasedStyleClass(oEvt.getSource(), oEvt.mParameters.value);
	}


}),

At onValueBaseStyleClass i dont access customData.value anymore, but custom property oRatingIndicator.mProperties.soll.

This property has at every point of time the right value, even after not beeing rerendered while table scrolling.

thank you for your help 🙂

Fabrice
Active Participant

Hi,

Glad that works 😄

For info, the getter and setter for properties are automaticaly created. You can access your property with

oRatingIndicator.getSoll()

instead of

oRatingIndicator.mProperties.soll

Regards

Fabrice

Answers (1)

Answers (1)

0 Kudos

Hi,

theres no error in console.

yep, it jumps in the setValue function, at this point of time, its too early for the customData to get binded.

sValue (actual value of rating) is binded, but customData.value is always null.

Left: setValue()

Right: onAfterRendering()

regards,

Stephan