Modify text by adjusting text color based on the contrast with the background color using knockout databinding

I am working with a table that contains data from my database:

Here is the ViewModel structure:

function alertViewModel(i) {
    var self = this;
    self.Id = ko.observable(i.Id);

self.AlertType = ko.observable(i.AlertType);
self.Category = ko.observable(i.Category);
self.Color = ko.observable(i.Color);
self.AlertText = ko.observable(i.AlertText);
self.update = function (data) {
    if (typeof (data.AlertType) != 'undefined') self.AlertType(data.AlertType);
    if (typeof (data.Category) != 'undefined') self.Category(data.Category);
    if (typeof (data.Color) != 'undefined') self.Color(data.Color);
}
};

In the cshtml file, I present the data in this way:

<table class="table" id="alertstable">
                                <tbody data-bind="foreach: alerts">
                                    <tr data-bind="style: { backgroundColor: Color }">
                                        <td>
                                            <b data-bind="text: AlertText">Message</b>
                                        </td>

                                    </tr>
                                </tbody>
                            </table>

Each row of the table can have a different background color, and depending on that color, the text color should change to black or white. Here is a code snippet demonstrating the contrast calculation:

function getContrastYIQ(hexcolor){
    var r = parseInt(hexcolor.substr(0,2),16);
    var g = parseInt(hexcolor.substr(2,2),16);
    var b = parseInt(hexcolor.substr(4,2),16);
    var yiq = ((r*299)+(g*587)+(b*114))/1000;
    return (yiq >= 128) ? 'black' : 'white';
}

I am looking for a way to dynamically change the text color based on the background color. Any help with implementing this functionality would be greatly appreciated. Thank you!

Answer №1

To enhance the viewmodel, consider implementing a Knockout Computed Observable for controlling text color, such as "TextColor". This computed property would rely on the existing Color observable and utilize a specific function like the following example:

self.TextColor = ko.computed(function() {
    return getContrastYIQ(self.Color());
});

Lastly, include a color binding within the current style binding on tr element:

databind="style: { backgroundColor: Color, color: TextColor }"

Answer №2

After conducting some thorough research, I managed to uncover the solution:

  1. To begin with, I included this line in the viewmodel:

    self.TextColor = ko.observable(i.TextColor);

  2. When loading the viewmodel with data from the database, I added:

    element['TextColor'] = getContrastYIQ(element.Color);

  3. Further modifications were made in the cshtml file by adding:

    databind="style: { backgroundColor: Color, color: TextColor }"

  4. The getContrastYIQ() function underwent the following changes:

    function cutHex(h) { return (h.charAt(0) == "#") ? h.substring(1, 7) : h }

    function HexToR(h) { return parseInt((cutHex(h)).substring(0,2),16) }

    function HexToG(h) { return parseInt((cutHex(h)).substring(2, 4), 16) }

    function HexToB(h) { return parseInt((cutHex(h)).substring(4, 6), 16) }

    function getContrastYIQ(hexcolor) { var r = HexToR(hexcolor); var g = HexToG(hexcolor); var b = HexToB(hexcolor); var yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000; return (yiq >= 128) ? 'black' : 'white'; }

This implementation worked flawlessly for me. Hopefully, it can be of assistance to others as well!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How to retrieve the image source from a block using jQuery

Currently, I am working on developing a slider for my webpage using jquery's "Cycle" plugin. However, I have encountered an issue with accessing the image sources used in the slider. To provide more context, here is a snippet of code from the 'he ...

Issue with the JQuery FadeIn effect on my website when a div is repositioned for visibility

I have been working on revamping an existing website at www.gjelavoie.com. To enhance the user experience, I decided to use jquery fadein() and fadeout() functions for displaying my Contact form without visitors having to temporarily access the main page. ...

Uncertainties surrounding the complexity of this multi-stage form

Exploring this multi-step form I have a couple of questions: 1) Is there a way to transfer the value from the first step to the second step of the form? 2) How can I ensure that the datepicker value is not empty (to prevent user progress in the firs ...

Attempting to create a slider utilizing jQuery

I'm currently working on creating a slider using jquery. I have downloaded the cycle plugin for the slider and included it in my file. The slider consists of 7 pictures. Below is the code I am using, can someone please help me identify any issues? &l ...

Adjust Sidebar Height to Match Document Height (using React Pro Sidebar)

Having an issue with the height of a sidebar component in Next.js using React Pro Sidebar. It seems to be a JavaScript, HTML, and CSS related problem. I've tried several suggested solutions from Stack Overflow, but none of them seem to work. Surprisin ...

Inline CSS alignment

While experimenting with layout inline elements, I came across some unusual behavior. Can someone please explain why there is a difference? I have applied the following CSS to both HTML structures: .time { position: relative; top:100px; heigh ...

Using Flexbox to align content in a column with space between items

Is there a way to move the read more button to the bottom of the card using flexbox in a column layout? The top section, middle paragraph, and see more button are each contained within their own div inside the parent card div. https://i.stack.imgur.com/NG ...

Various hues blending and intertwining with one another

https://i.stack.imgur.com/zLrNK.png Could someone please clarify what is happening here? I'm attempting to change the background color to dodgerblue, but for some reason, the white background color is still showing through. Below is the code snippet ...

Accordion-style elements arranged in a grid format, smoothly displacing surrounding content

I am facing an issue with a grid of accordions, as demonstrated in the codesandbox linked below. The problem arises when I open one accordion, causing all the accordions in the row below to shift down. Ideally, only the accordion directly below should be p ...

Bidirectional binding of attributes in an Angular directive

I have developed a custom Angular Directive known as evoEventMirror. Its main purpose is to attach a jQuery event to an inserted element and apply a specified CSS style to the "root" element. Refer to the example below: <div id="#mydiv" evo-event-mirro ...

Is the item positioned above another item instead of being positioned to the left of it?

Looking for help with my mobile navigation setup. I want to add text that says ' ...

Is there a way to showcase an epub format book using only HTML5, CSS, and jQuery?

Can ePub format books be displayed in a web browser using only HTML5, CSS, and jQuery? I would appreciate any suggestions on how to accomplish this. Additionally, it needs to be responsive so that it can work on iPad. While I am aware of this requirement, ...

Tips on customizing the CSS responsiveness of your Bootstrap carousel

I have recently installed a Bootstrap theme on my Wordpress site and I am trying to make some CSS adjustments. One issue I am facing is with the carousel. Currently, when I resize the website or view it on a mobile device... The carousel maintains a lar ...

Arranging Content with Bootstrap Columns

I am trying to organize my content into three sections as follows: A - main content of page B - very important content (must be visible without scrolling) C - less important content. The current layout I have is like this: ----- |A|B| |A|C| ----- Howe ...

Interactive canvas artwork featuring particles

Just came across this interesting demo at . Any ideas on how to draw PNG images on a canvas along with other objects? I know it's not a pressing issue, but I'm curious to learn more. ...

Addressing see-through box styling in CSS

When working on a website using HTML and CSS, I encountered an issue with a transparent box. All elements within this box are also transparent, but I want them to be solid without any opacity. How can I resolve this? .parent { display: inline-block; ...

Is there a way to resolve the issue of this div sticking to the top of the

I am currently working on building a portfolio website. One issue I'm facing is that my first div (for the "About Me" section) appears below my second div on the webpage. My goal is to have the first div displayed in full screen on both mobile and des ...

Guide to pinpointing a location with Google Maps

I am currently working on setting up a contact page that includes Google Maps to show the location of a meeting place. Here is the code I am using: JavaScript (function(){ document.getElementById('map_canvas').style.display="block"; var ...

Prevent ui-select from being highlighted when clicked

here's a dilemma : (all in angular 1) I'm using a ui-select like this : https://i.stack.imgur.com/RzH2u.png Here's the code snippet : <div class="formZone-group"> <div class="mandatory-fl"> <div class="man ...

Spinning html/css content using JavaScript

Greetings! I am currently working on a demo site using just HTML, CSS, and JavaScript. Typically, I would use Ruby and render partials to handle this issue, but I wanted to challenge myself with JavaScript practice. So far, I have created a code block that ...