Change text color based on field value (Details View)

I would like to change the text color from black to red if a field value in the details view page is “N/A”. I don’t want to change the label color, just the value.

Example: Field 1 = 1234 (text color black) / Field 1 = N/A (text color red)

I know that is a simple thing to do in on a table using display rules, but need some help with code for details page.

Thank you… JON

Hi Jon,

I’d be happy to help with your code.

So firstly, this will be handled with Javascript instead of only CSS, as the CSS depends on the current field value.

Knack uses a Javascript library called jQuery. Your jQuery needs to do the following steps:

  1. When the view is rendered, get the field value from the data parameter. Relevant article: View Render.
  2. Select the HTML element that holds the field value. Relevant article: jQuery Selectors
  3. If the field value is “N/A”, use the css() method to add a CSS style of color:red to the HTML element you selected in step 2. Relevant article: jQuery css() method

If you need the code to be more dynamic and apply to multiple views or multiple field values then there are additional steps, but your question only mentioned “N/A” on a Details view.

Hope this helps.

Thank you. Will give it a try.

Do you by chance have an example code you can share?

Here’s my “failed” attempt on this code. Any working revisions is greatly appreciated…

$(document).on(‘knack-view-render.view_187’, function(event, view, data) {
var fieldValue = $(“field_267.kn-detail-body”).text().trim();
if (fieldValue === “N/A”) {
$(“p”).css(“color”, “red”);
}
});

You’re close. It will work with the following adjustments:

  • Set the CSS on .kn-detail-body instead of p. Selecting p means “select all the paragraph elements on the page” which we don’t want to do.
  • There’s a small typo in field_267.kn-detail-body. It should be like this: .field_267 .kn-detail-body with a period before the field and a space after. Relevant article: CSS Selectors

This should work:

$(document).on('knack-view-render.view_187', function (event, view, data) {
  var $field = $('#view_187 .field_267 .kn-detail-body')
  var fieldValue = $field.text().trim()

  if (fieldValue === 'N/A') {
    $field.css('color', 'red')
  }
})

Dang it, I almost had it… Thank you, works as expected.

I know this is from over a year ago, but wondering if I can get some follow up.

I am creating a learning management system and I have 40+ modules with 1-5 Lessons in each module.

I used this post to put together code for one module that has 8 lessons within it. I have 8 detail views on one scene. Each detail view links to the relevant lesson and displays the status of that lesson (not stated, in process, complete, etc) - see attached image.

Now I can copy and paste this code snippet for each view that needs to reference it, but you mention be able to make it more dynamic so I can apply it to multiple views and field values…can you help me with this? for reference, here is the code for lesson 1, lesson 2, and lesson 3 and here is a snapshot of what it looks like on the scene. Note that in the code, the view ID changes AND the field ID.

/Change text color based on field value (Details View) - this is used in the modules lessons summary page
//normal pregnancy and prenatal care
//lesson one
$(document).on(‘knack-view-render.view_2344’, function (event, view, data) {
var $field = $(‘#view_2344 #kn-input-field_1377’)
var fieldValue = $field.text().trim()

if (fieldValue === ‘NOT STARTED’) {
$field.css(‘color’, ‘RED’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘IN PROGRESS’) {
$field.css(‘color’, ‘ORANGE’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘COMPLETE’) {
$field.css(‘color’, ‘GREEN’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘SUBMITTED’) {
$field.css(‘color’, ‘BLUE’)
$field.css(‘font-weight’,‘bold’)
}
})
//lesson two
$(document).on(‘knack-view-render.view_2357’, function (event, view, data) {
var $field = $(‘#view_2357 #kn-input-field_1378’)
var fieldValue = $field.text().trim()

if (fieldValue === ‘NOT STARTED’) {
$field.css(‘color’, ‘RED’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘IN PROGRESS’) {
$field.css(‘color’, ‘ORANGE’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘COMPLETE’) {
$field.css(‘color’, ‘GREEN’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘SUBMITTED’) {
$field.css(‘color’, ‘BLUE’)
$field.css(‘font-weight’,‘bold’)
}
})

//lesson 3
$(document).on(‘knack-view-render.view_2387’, function (event, view, data) {
var $field = $(‘#view_2387 #kn-input-field_1379’)
var fieldValue = $field.text().trim()

if (fieldValue === ‘NOT STARTED’) {
$field.css(‘color’, ‘RED’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘IN PROGRESS’) {
$field.css(‘color’, ‘ORANGE’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘COMPLETE’) {
$field.css(‘color’, ‘GREEN’)
$field.css(‘font-weight’,‘bold’)
}
if (fieldValue === ‘SUBMITTED’) {
$field.css(‘color’, ‘BLUE’)
$field.css(‘font-weight’,‘bold’)
}
})

Hi Leah,

To make it more dynamic and reduce the need to copy-and-paste code into multiple views, you can create a function. Here’s an example of creating a function and using it.

// This function changes text color based on view number and field number.
function changeTextColor(viewKey, fieldKey) {
  var $field = $(`#${viewKey} #kn-input-${fieldKey}`)
  var fieldValue = $field.text().trim()

  if (fieldValue === 'NOT STARTED') {
    $field.css('color', 'RED')
    $field.css('font-weight', 'bold')
  } else if (fieldValue === 'IN PROGRESS') {
    $field.css('color', 'ORANGE')
    $field.css('font-weight', 'bold')
  }
}

// Invoke your function on any views you want the code to run.
$(document).on('knack-view-render.view_1', function(event, view, data) {
	changeTextColor(view.key, 'field_1')
})

$(document).on('knack-view-render.view_2', function(event, view, data) {
  changeTextColor(view.key, 'field_2')
})

That’s the general idea.

P.S. Question for you:
It’s unusual that your database has different field numbers for the same field i.e. Lesson Status. Do you have many “Lessons” tables and/or many “Lessons Status” fields? Maybe you have special requirements that I’m unaware of.

How do I do this for multiple fields in a view?

Example: if any field value is 'No" in a view, make it red

Hi @Angie,

Here’s how to do what you asked.

// If any field value is 'No' in view 24, make it red.
$(document).on('knack-view-render.view_24', function (event, view, data) {
  var $fields = $(`#${view.key} .kn-detail-body`)

  $fields.each(function(index, field) {
    var $fieldValue = $(field).text().trim()
    if ($fieldValue === 'No') {
      $(field).css('color', 'red')
    }
  })
})

Note: There might be a better way to achieve what you want depending on your needs. For example, you could create a flexible function that changes the text color to red when it’s any “negative” value such as No, False, Off, or a negative number, as well. That might be more flexible than checking for “No.”

Hope this helps. Feel free to reach out if you need additional custom coding.

-Knack Pros

Hi guys,

You can use the KTL’s feature called Colorize Field by Value. Keyword: _cfv

You can have complex conditional rules using the powerful ktlCond and ktlRefVal keyword options.
It’s even possible to compare a given record’s field value against another value in a field from another view in the page.

See examples in my video here.

See Documentation here.

All open-source and free.
Very easy to setup.

See Carl Holmes videos too to get started.

Have fun!
Normand D.

Thank you! Very helpful and worked great!

Yes we have 64 Modules with 3-7 lessons within each module. There is a table set up for each module and a field for each lesson. I’d really like to simplify the code as its going to be so much repetitive code.

I really wanted this to work, in fact it works beautifully on a details view. My app is setup that the pages I need this on are form views. The field is a multi-choice field with a read-only value. Is there any way to apply the _cfv keyword to a form view?

I ended up changing my forms to be details views rather than forms. This allowed me to be able to use the KTL solution for my app. It will be such a time saver and was worth the work of having to redo a portion of my app to make it work. Thanks!

I made it work! changed all my forms to details views and was able to get the _cfv to change based on the value of the field. What a great time saver! I will be using this throughout my app now.

1 Like

Really happy to read that!

I’m impressed that you found that elegant workaround.

On my side, I tried to add support for Forms, but it’s a bit complicated, and didn’t have the time to complete the feature before you! But I will get back at it later because I think it will be useful.

Good job!

Norm

1 Like