Uli Hartman
Uli Hartman

Reputation: 11

changing inidividual row-heights in a qooxdoo qx.ui.progressive table

I'm trying to change the individual row height of a qx.ui.progressive table to accommodate for more text and have multiple text-lines in a cell. I tried to do that on a qx.ui.table but individual row heights can't be changed on that one.

So I'm looking qx.ui.progressive table to do that, there is an example in the qooxdoo demo browser (qxl.demobrowser.demo.progressive.ProgressiveTable_VarRowHeight) but it uses image heights for setting the height of the cell, how would I set the row height with .string or .html content?

Thanks

Uli

Here is what I tried to resize individual table rows to accommodate for longer text/ html content

      var createRow = function (html, new_height) {
        var ret = {
          renderer: "row",
          location: "end",
          data: [html, html],
          // data: [{html, height: h}, {html, height: h}],
          height: new_height // Custom height
        };

        return ret;
      };


      var columnWidths = new qx.ui.progressive.renderer.table.Widths(2);
      columnWidths.setWidth(0, "2*");
      columnWidths.setWidth(1, "1*");

      var columnNames = ["Literal", "Html"];

      // Instantiate a Progressive with a default structure with header
      var header = new qx.ui.progressive.headfoot.TableHeading(
        columnWidths,
        columnNames
      );

      var footer = new qx.ui.progressive.headfoot.Progress(
        columnWidths,
        columnNames
      );

      var structure = new qx.ui.progressive.structure.Default(header, footer);
      var progressive = new qx.ui.progressive.Progressive(structure);

      // Instantiate a data model and populate it.
      var dataModel = new qx.ui.progressive.model.Default();
      var rowData = [];

      var html =
        "<div style='background-color: cyan; text-align: center;'>" +
        "  Hello world!" +
        "</div>";
      rowData.push(createRow(html, 40));

      var html =
        "<div style='background-color: cyan; text-align: center;'>" +
        "  Hi there." +
        "  <span style='color: red;'>" +
        "    &nbsp;&nbsp;&nbsp;" +
        "    I'm very red!" +
        "  </span>" +
        "</div>";

      rowData.push(createRow(html, 80));


      dataModel.addElements(rowData);

      // Tell Progressive about its data model
      progressive.setDataModel(dataModel);

      // Instantiate a table row renderer
      var rowRenderer = new qx.ui.progressive.renderer.table.Row(columnWidths);

      // Give Progressive the renderer, and assign a name
      progressive.addRenderer("row", rowRenderer);

      // Tell the row renderer to use a String renderer for column 0
      var r = new qx.ui.progressive.renderer.table.cell.String();
      rowRenderer.addRenderer(0, r);

      // Tell the row renderer to use an HTML renderer for column 1
      var r = new qx.ui.progressive.renderer.table.cell.Html();
      rowRenderer.addRenderer(1, r);

Upvotes: 1

Views: 69

Answers (1)

Derrell Lipman
Derrell Lipman

Reputation: 616

The key to variable row height is understanding the cellInfo map which is passed to each cell renderer. The cellInfo map is documented in the class qx.ui.progressive.renderer.table.cell.Abstract, available in the API viewer.

Of particular importance is the cellInfo.height member. The cell renderer's render method may update cellInfo.height to indicate the minimum amount of vertical space required for the cell. The entire row's height will be the maximum of the row's cells' required cellInfo.height upon return from all cells' render method.

The image cell renderer uses the loaded image's height to set cellInfo.height. The Html and String renderers do not update cellInfo.height. To solve your problem, therefore, you just need to create a new cell renderer similar to, or descended from, the Html or String renderer. Your renderer's render method will ascertain the required height of the cell, and set cellInfo.height to that value before returning. Note that ascertaining the height may be a trivial process, or not. If, for example, you want the cell to contain a number of bullet points of text, each bullet point known to consume no more than one line of space, then your height calculation would simply multiply the number of bullet points by a fixed number of pixels that fit a single line of text. On the other hand, if you need to fit arbitrary wrapping text into the cell, you'll have a less trivial exercise to make that calculation.

Here is example code that can be copied and pasted into the playground:

qx.Class.define("progressive.AlternatingHeightHtmlRenderer",
{
  extend : qx.ui.progressive.renderer.table.cell.Html,

  members :
  {
    /** Whether the next rendered row is to be tall (true) or short (false) */
    _isTall : false,

    // overridden
    render(cellInfo)
    {
      let html = this.base(arguments, cellInfo);

      // Alternate row heights. If _isTall is false, we'll use the
      // provided cellInfo.height (where 0 means use default height).
      // If true, we'll set it taller. The row's height will be the
      // maximum height of the rendered cells in the row.
      if (this._isTall)
      {
        // Use a taller-than-normal height for this cell
        cellInfo.height = 40;
      }

      // Toggle so that next row is the alternate height
      this._isTall = ! this._isTall;

      return html;
    }
  }
});



let createRow = function (rowNum, text) {
  let ret = {
    renderer: "row",
    location: "end",
    data: [rowNum + "", text],
  };

  return ret;
};

let columnWidths = new qx.ui.progressive.renderer.table.Widths(2);
columnWidths.setWidth(0, 60);
columnWidths.setWidth(1, "1*");

let columnNames = ["Row", "Text"];

// Instantiate a Progressive with a structure including header
let header = new qx.ui.progressive.headfoot.TableHeading(
  columnWidths,
  columnNames
);
let structure = new qx.ui.progressive.structure.Default(header);
let p = new qx.ui.progressive.Progressive(structure);

// Instantiate a data model and populate it.
let dataModel = new qx.ui.progressive.model.Default();
let rowData = [];

rowData.push(createRow(0, "I am small."));
rowData.push(createRow(1, "I am tall."));
rowData.push(createRow(2, "This, too, is small."));
rowData.push(createRow(3, "This, too, is tall."));

dataModel.addElements(rowData);

// Tell Progressive about its data model
p.setDataModel(dataModel);

// Instantiate a table row renderer
let rowRenderer = new qx.ui.progressive.renderer.table.Row(
  columnWidths
);

// Give Progressive the renderer, and assign a name
p.addRenderer("row", rowRenderer);

// Tell the row renderer to use our custom renderer for column 1
let r = new progressive.AlternatingHeightHtmlRenderer();
rowRenderer.addRenderer(1, r);

p.set({
  width: 400,
  maxWidth: 400,
});

this.getRoot().add(p, { left: 50, top: 50, bottom: 50 });

p.render();

Upvotes: 3

Related Questions