Ext Grid Renderer Danger

This is an archived post from the ExtJS era — the code may be obsolete, but the principles often still apply.

Well, not a real danger. You won't get hurt if you use a renderer even if you use it wrongly. Nevertheless, renderers can introduce unexpected behavior that is not easy to fix what can cause frustrations and upsets or increased development time, at least. Let's see what we need to know to avoid that.

What is a renderer?

renderer is a function called by Ext for each cell in a grid column to generate the HTML markup for that cell.

Renderer function is call with arguments that are described in detail in the documentation. We take just first three for the demonstration. They are:

  • value - raw value from the underlying record
  • meta - the object used for adding a css or attributes to the grid cell
  • record - the record being processed

The default renderer only returns value and grids can work happily without a configured renderer in many cases.

However, we can use the value and data from other fields of the record to change how the value is displayed or we can even derive a new value from the existing data in the record. Renderers can also be used for conditional highlighting of cells, make some font bold or other color or even to define cell tooltips.

Example

In this example I will first demonstrate problems introduced by incorrect use of renderers and then the solution of these problems. The grids use actors database from http://themoviedb.org. Grids pull ~1000 records with the following structure:

We want to display the following columns:

  • First Name
  • Last Name
  • Full Name
  • Birthday
  • Age
  • Photo

Obviously, we do not have all data in the received JSON; full name is missing but we have first and last name so we can concatenate, age is missing but we have birthday so we can calculate the difference between today and the birthday and we can calculate the full img src from the profile path. So we configure our renderers as follows:

Go back and read the comments in the above code...

The problematic grid

Open grids in new window

The problems:

  1. Try to sort by (full) Name. The grid does not sort by full name but by last name.
  2. Try to sort by Age ascending (using the column menu). You can see that the sort is descending in fact.
  3. Try to search for "Tom". Tom Hanks and Tom Cruise are not found.

Why all this? The single origin of the above problems is that we use renderers to derive new data from the existing data. Grid is just a view, all sorting and filtering is done in the store but store does not have full name and age.

The working grid

Every problem has a solution so has this. Try the same actions in the following grid that works as expected. Finds Hanks and Cruise and sorts the correct direction.Open grids in new window

The solution

    The general rule is:

Never ever use renderers to derive new data from the existing data. Use them only for user interface embellishment.

  Thus, we need to create the missing data elsewhere. Where? In the model.

Now we only need to point dataIndex of Name and Age to the new model fields and we are done. Of course, the tooltip and name link renderers stay, but they are UI renderers, not data creation renderers.     The general rule is:

Never ever use renderers to derive new data from the existing data. Use them only for user interface embellishment.

  Thus, we need to create the missing data elsewhere. Where? In the model.

Now we only need to point dataIndex of Name and Age to the new model fields and we are done. Of course, the tooltip and name link renderers stay, but they are UI renderers, not data creation renderers.

10 comments

  1. Srinivasa Rao SJanuary 13, 2015archive
    Hi Saki, I am working on a project where i need to display a combobox inside a grid. i am successful by using widgetcolumn in ExtJS 5.0.1. i have another column checkboxcolumn, where based on this checkbox value i need to enable/disable combobox in respective row. But i am unable to get refernce of combobox reference on checkbox change event. I am stuck since week's time, your help is really appreciable. --Srinivasa Rao S
    1. SakiJanuary 14, 2015archive
      You can have combo as a column editor same way as <a href="https://learnfromsaki.com/ext-examples/#writable-grid" target="_blank" rel="nofollow">here</a> (double click on a row in Industry column). Other solution would be to configure the combo as above but for single click and, if you want, you can style the cell that it would <i>look</i> like combo for all rows while it would be a real combo only after click.
      1. Amy VredevoogdFebruary 9, 2015archive
        This is a great post. I logged in and cannot find the code example. Can you direct me?
        1. SakiFebruary 10, 2015archive
          It can be that the browser is still caching before-login version. Reload the browsers and the code should be there.
        2. Rus ManMay 7, 2015archive
          Use cache buster, add ?_dc=12345 to the url
  2. Алекс ЯApril 29, 2016archive
    I'm stuck with the 'sort by rendered value' issue mentioned in the article. But the pros of render-way are that you can use a controller function for it, and can access any other associated viewmodel stores to calculate the result value. I didn't succeed to achieve this within the convert function, which scope is limited by only the particular data record, not the view's viewmodel or controller.
    1. michael darrettaOctober 27, 2016archive
      how can you have renderer on more then one column in a grid?
      1. SakiApril 30, 2017archive
        You can have renderer for each column in the grid. They are defined on per-column basis, so as many columns that many possible renderers.
  3. wang qiangMarch 27, 2017archive
    The search of "The problematic grid" is right
    1. SakiApril 30, 2017archive
      Well, if I search for Tom, Tom Hanks is not found so I cannot fully search in the column with renderer.

Comments are closed on archived posts.