Changing text color in a DataGrid using itemRenderers

People constantly ask us how to change cell attributes like text color of individual DataGrid cells depending on data. I just answered a similar question on flexcoders today. If you are making any changes to individual cells, you will almost always use a custom itemRenderers. And… if you are changing the cell attributes depending on data, you will often need to override the set data function in your itemRenderer. Here is a sample of overriding set data to change the text color of a cell’s text if the data in the cell is greater than 10:

override public function set data(value:Object):void
{
if(value != null)
{
super.data = value;
if(value[DataGridListData(listData).dataField] < 10) {
setStyle(“color”, 0xFF0000);
}
else {
setStyle(“color”, 0x000000);
}
}
}

Demo: itemSample.swf

Sample Code:itemSample.mxml, CustomComp.as

If you want to make appearance of the cell to depend on a particular column’s data, then, you can change the code: value[DataGridListData(listData).dataField] to just use something like value.quantity (assuming “quantity” is the column dataField you are interested in.

About these ads

34 responses

  1. Phil Torgersen | Reply

    I have done this and it works fine. But – another question. How do I change the text color if the text row has merely been selected in the datagrid and the data has not changed? And how would I change the color back when the item is unselected?

  2. Actually, I have another entry about how to know when your itemRenderer is selected and there is some demo code about changing the color and other font styles when you are selected. Here is the link:

    http://butterfliesandbugs.wordpress.com/2007/06/25/how-to-know-when-my-itemrenderer-is-selected/

  3. Worked really fine! Thanks for the help!

  4. How do you make the text color or back ground color flash?

  5. How would one go about changing a cell’s text color when that cell’s row has been moused over (not selected, as covered in “How to know when my itemRenderer is selected?”)? Using event listeners, I’m able to determine when this should happen and to which cell, but I can’t figure out how to tell the cell renderer to make the change when the time comes.

  6. I want to have my cell as a gradient color one.Now i am using a custom itemrenderer. In my grid based upon some logical grouping I made colouring of cells using setStyle attribute.Kindly let me know is there any chances of using a gradient color using setstyle property.

    Thanks,
    Veeru

  7. Hello nice example. Your example gave me a head start at my project, but got a problem.

    [btw: I am new to flex, so sorry is its a silly question]

    Suppose there are two columns, “age” and “name”. If age is grater than 20 of any “age” cell, I want to color the respective “name” cell. How can I do that?
    Please help me.

    1. @Bahar: To change the behavior of an itemRenderer depending on its data, you always need to override the set data function in your itemRenderer. In that overridden function, you will check if the data.age > 20 and then write the code to turn the cell red. There is an example that will help you in one of my other blog postings. In the example, the itemRenderer checks if the data displayed in the cell is over the value 15, if so, it turns the background RED.

      http://butterfliesandbugs.wordpress.com/2007/07/11/using-an-itemrenderer-to-change-the-background-of-a-datagrid-cell/

  8. Hello,

    Thank you for your reply. May be I am going to ask you the dumbest question.

    I couldn’t solve my problem.

    My dataGrid code:

  9. Hello,

    Thank you for your reply. May be I am going to ask you the dumbest question.

    I couldn’t solve my problem.

    My dataGrid code:

    My custom renderer code: I created a AS class file in src folder where my mxml resides.

    its code:

    package {

    import mx.controls.Label;
    import mx.controls.dataGridClasses.*;

    public class ChangeColor extends Label {

    override public function set data(value:Object):void
    {
    if(value != null)
    {
    super.data = value;
    if(value.7 == 10) {
    setStyle(“color”, 0xFF0000);
    }
    else {
    setStyle(“color”, 0x000000);
    }
    }
    }
    }

    }
    ////

    But in mxml file, I am getting error as itemRenderer=”ChangeColor” as error, unknown property ChangeColor.

    Please help me. Tell what I am doing wrong.

  10. Hello-

    This implementation is great. I have a question about an application which is slightly different. Say I am populating my datagrid from an array like this:
    public var DP:Array = [{item: 'Ice Cream', qty: 4, rating: 7}, {item: 'Cones', qty: 21, rating: 3}, {item: 'Sandwich', qty: 14, rating: 9}, {item: 'Malt', qty: 1, rating: 4}];

    Now I display my data the exact same way as you are in the mxml (excluding rating), however in this case I would like to change the color of the font of the quantity cell not when quantity is 6. So for the above example, you would see that only Ice Cream and Sandwich would be red.

    Basically I’m asking if the information for an entire row is available (in this case ‘rating’) when rendering the cell quantity.

    I’ve tried something like this in CustomComp but it fails:
    package
    {
    import mx.controls.Label;
    import mx.controls.dataGridClasses.*;

    public class CustomComp extends Label {

    override public function set data(value:Object):void {
    if(value != null) {
    super.data = value;
    //if(value[DataGridListData(listData).dataField] = 6) {
    setStyle(“color”, 0xFF0000);
    }
    else {
    setStyle(“color”, 0x000000);
    }
    }
    }
    }
    }

  11. Sorry, I mistyped above, I’m looking to change font when rating \> 6 not when it is equal to 6.

    I’ve tried something like this in CustomComp but it fails:
    package
    {
    import mx.controls.Label;
    import mx.controls.dataGridClasses.*;

    public class CustomComp extends Label {

    override public function set data(value:Object):void {
    if(value != null) {
    super.data = value;
    if(value.rating \>= 6) {
    setStyle(”color”, 0xFF0000);
    }
    else {
    setStyle(”color”, 0×000000);
    }
    }
    }
    }
    }

  12. Hi,

    Is there any way to change the text color of the entire row of a datagrid based on data with out creating a itemrenderer for each column. I have around 10 columns, and want to change the color of text to red or green based on some data.

    Thanks,
    Shreyas

    1. @Shreyas – No, you need to use a custom itemRenderer in each column. However, you should be able to use the exact same itemRenderer for each column, so, this shouldn’t be too difficult. The only way to change the entire row is if that row is the “selected” one. Then, you can change one of the styles.

  13. Hi Sean,
    I suppose you have found a solution by now, but just in case you or someone is looking for an answer, I have adapted your code to make it work.
    I put some comment in it to explain.
    Note also that I have changed the name of the class to “Rating” and the name of the package to “com.renderers”, you can change those at your needs :

    package com.renderers {
    import mx.controls.Label;
    import mx.controls.dataGridClasses.*;

    public class Rating extends Label {
    private var _data:Object;

    override public function set data(value:Object):void {

    // — Save the data (for use in the get function)
    _data = value;

    // — at this point your Label is empty, so you
    // have to fill it with something,
    // in this example we simply show
    // the value of the item “rating”
    //
    text=value.rating;

    // but – as you intended – we can change the color
    if(value != null) {
    // rating is a textstring, so we have to
    // convert it into a integer
    var rating:uint = uint(value.rating);
    // now we can use it in the numeric comparison
    if(rating >= 6) {
    setStyle(“color”, 0xFF0000);
    }
    else {
    setStyle(“color”, 0x000000);
    }

    }
    }

    override public function get data():Object {
    return _data;
    }
    }
    }

  14. Thanks so much. This is just what I need.

  15. thanks a lot, I’ve been trying to get this to work on a project I’m working on. It just suits perfectly although I used a switch instead of the if ..else which is just fine. Thanks again. You just saved a butt.

  16. thanks a lot! your post helped me a lot!

  17. implementing this results in the datatipfunction is not working anymore =(

  18. anyone know why I would get the equivalent of “Definition CustomComp could not be found” ???

    it’s on the line where I set the itemRenderer in my MXML and I do import the CustomComp renderer file.

    I’m going in circles

  19. This example will work buy only when the datagrid is small. If you try this on a datagrid with 40 columns and say 1500 rows your application will become very slow. Try it. Is there a way this can be avoided

  20. hi.. thanks ur blog helpe me to solve a problem. Is it possible to do the same, if I am using inline itemrenderers?

  21. Perhaps a painfully dumb question, but….
    Where do I put the CustomComp.as file? I don’t see it being imported into the MXML example. I suppose this is because it’s overriding built in flex functionality. How does flex know to use this override?
    Thank you in advance for help.

  22. Doh, that was painful.
    To save you from writing a response just approve both comments :-)

    Where to put CustomComp.as file: Anywhere you want.
    Just be sure to specify the path in the MXML line that says:

    In my case the path was: itemRender=”extras.CustomComp”

    Cheers and thanks for leading me in the right direction!

  23. Great article. I was following a different way of doing it (coloring it at creation complete) but it was very inconsistent and actually didnt work. Also i come to know that in datagrid, items only visible rows are created so every time i scroll, instead of creating new elements it will repopulate the data.

    Thanks a lot.

  24. hey i have implement your code for changing color of cell data
    thanks
    but now i want to set a image in cell depend on the condition

    lyk if value.status==’Yellow’ && value.trend=’UP’
    so—–set a image
    lyk that

  25. hi, this is very intresting, but i wanna see how you use in the Mxml script….
    because i tried this:

    and i have an error message saying “the prefix componetnts is not bound”

  26. Thanks for the component, it was exacting what I was looking for but had to use it to render all the other columns so that the color changes on the row and not in just that cell. Thanks again. You saved me.

  27. Hi..I am facing a problem over here. I was able to change the color of the single column data but not the whole row text color.

    When i tried with value.rating of datafield, its throwing the following error.

    Property rating is not been identified in mx.controls.datagridclasses.* and is not assigned with any default value.

  28. Simply desire to say your article is as astonishing. The clearness in
    your post is simply cool and i could think you are a professional in this subject.
    Fine with your permission let me to seize your
    RSS feed to keep updated with imminent post.

    Thank you 1,000,000 and please carry on the enjoyable work.

  29. Hello would you mind stating which blog platform you’re using?
    I’m looking to start my own blog in the near future but I’m having a difficult time selecting between BlogEngine/Wordpress/B2evolution and Drupal.
    The reason I ask is because your layout seems different then most blogs and I’m looking for something unique.

    P.S Apologies for being off-topic but I had to ask!

    1. This is all wordpress. :)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: