0
votes

I'm trying to create a sap.m.Table with fixed header. I tried several aproaches, and in one of them something is weird is happening.

I tried to create a new custom control based in sap.m.Table, and redefine the renderer (based in sap.m.TableRenderer which is based in sap.m.ListBaseRerender) to put a div around tbody and tfoot (I know this would be an invalid HTML) and the make the div scrollable via CSS. This code can't get the scroll as it is now, it requires extra work.

This is the new control:

(function() {
    var table = sap.m.Table.extend("sap.m.FixedHeaderTable2", {
        metadata: {
            properties: {},
            aggregations: {},
            events: {}
        },
        init : function(){
            if (sap.m.Table.prototype.init) {
                sap.m.Table.prototype.init.apply(this, arguments);
            }
        },
        renderer: function (oRM, oControl) {
            sap.ui.require("sap.ui.core.Renderer");
            sap.ui.require("sap.m.TableRenderer");
            var renderer = sap.ui.core.Renderer.extend(sap.m.TableRenderer);

            renderer.renderListHeadAttributes = function(r, c) {
                this.renderColumns(r, c, 'Head');
                r.write("<div style=\"border:10px solid green\">");// ADDED
                r.write('<tbody');
                r.writeAttribute('id', c.addNavSection(c.getId('tblBody')));
                r.write('>');
            };

            renderer.renderListEndAttributes = function(r, c) {
                r.write('</tbody>');
                c._hasFooter && this.renderColumns(r, c, 'Foot');
                r.write("</div>");// ADDED
                r.write('</table>');
            }

            renderer.render(oRM, oControl);
        }
    });
    return table;
})();

renderListheadAttributes and renderListEndAttributes are functions of the base renderers and the only changes to it are the lines marked with "added" comment.

The html I get is this, and you can see empty div and table whith thead, tbody and tfoot: HTML image

So I tried to change tbody tags in my renderer (lines marked with "modified") to see what happens:

renderer.renderListHeadAttributes = function(r, c) {
    this.renderColumns(r, c, 'Head');
    r.write("<div style=\"border:10px solid green\">");// ADDED
    r.write('<div');// MODIFIED
    r.writeAttribute('id', c.addNavSection(c.getId('tblBody')));
    r.write('>');
};

renderer.renderListEndAttributes = function(r, c) {
    r.write('</div>');// MODIFIED
    c._hasFooter && this.renderColumns(r, c, 'Foot');
    r.write("</div>");// ADDED
    r.write('</table>');
};

Now my div has an empty div inside, but the table still has thead, tbody and tfoot as children. HTML image

I also notice that border-image: none; is appearing from nowhere. This and the fact that render is not working as intended make me think that some sort of post-render is happening that modify DOM. As far as I know, only place where this can be happening is in onAfterRendering, but it doesn't seems to be there (I remove onAfterRendering via addEventDelegate and empty function).

Where/why is this "postrender" happening?


I'm aware that there are better ways to do this, and I know a scroll inside another scrool is bad (and worse in mobile devides). I have already a working solution.

This question is not about how to achieve scroll with fixed header, it is about why is this weird behaviour is happening.

1

1 Answers

0
votes

This behaviour is caused by browsers due to invalid HTML (div inside table), so it has nothing to do with SAPUI5 rendering process... That is specified here: http://w3c.github.io/html/syntax.html#foster-parenting (Alohci answer).

You can get more details in the following question: Browser changing incorrect HTML by itself. Where is stated that behaviour? Is there a way to avoid it?