Pass single model value (string) as parameter to reusable javascript function to set table cell class in MVC view

My view displays a table containing the state of some data, grouped in columns:

  • Ready
  • Done
  • Skipped
  • N/A

I've got about 6 columns and multiple rows each time (simplified sample to follow below) I need to set the cell background color which is easily done via css, however setting the style class each time via repeated code in the view is tediously time consuming for each column and prone to errors.

So I thought of using a javascript function using a parameter of the model value (the above listed state) to dynamically set the class css style.

I'm not 100% sure on how to go about it.

Sample code:

@using NS.Data
@model NS.Models.PublicationsModel


@{
    ViewBag.Title = "PublicationState";
    Layout = "~/Views/Shared/_Layout.cshtml";
    var PublicationState = Model.PublicationState.ToList();
}
@*Below the idea of the intended "reusable" javascript function*@
<script type="text/javascript" language="javascript">
    $(function ToggleCellColour(StepState) {

        switch (StepState) {
            case "Ready":
                return "cssReadyState";
                break;
            case "Done":
                return "cssDoneState";
                break;
            case "Skipped":
                return "cssSkippedState";
                break;
            default:
                return "";
                break;
        }
    });
</script>
<h2>Publication State</h2>

@Html.ActionLink("Back to previous page", "ActionName", "ControllerName", new { returnActive = true }, null)
<table class="table">
    <tr>
        <th>Client</th>
        <th>Availability Communicated to Team</th>
        <th>Schedule Test</th>
        <th>Tested</th>
        <th>Planned Prod Implementation</th>
        <th>Implemented to Prod</th>
    </tr>
    @*Returned Publication States: N/A, Ready, Skipped, Done*@
    @foreach (var PubSt in PublicationState)
    {
           <tr>
                <td>@PubSt.Client</td>
                <td align="center" class="ToggleCellColour(@PubSt.Availability_Communicated_to_Team)"> @*This is where I thought of calling the javascript method to determine the css formatting for the cell*@
                    @if (PubSt.Availability_Communicated_to_Team != "N/A")
                    {
                        if (PubSt.Availability_Communicated_to_Team == "Done" || PubSt.Availability_Communicated_to_Team == "Skipped")
                        {
                            <img src="~/Images/MailClosed.png" />
                        }
                        else @*The "Ready" State*@
                        {
                            <img src="~/Images/MailOpen.png" />
                        }
                    }
                    else
                    {
                        @PubSt.Availability_Communicated_to_Team
                    }
                </td>
                <td align="center" class="ToggleCellColour(@PubSt.Schedule_Test)">
                    @if (PubSt.Schedule_Test != "N/A")
                    {
                        if (PubSt.Schedule_Test == "Done" || PubSt.Schedule_Test == "Skipped")
                        {
                            <img src="~/Images/MailClosed.png" />
                        }
                        else
                        {
                            <img src="~/Images/MailOpen.png" />
                        }
                    }
                    else
                    {
                        @PubSt.Schedule_Test
                    }
                </td>
                <td align="center" class="ToggleCellColour(@PubSt.Tested)">
                    @if (PubSt.Tested != "N/A")
                    {
                        if (PubSt.Tested == "Done" || PubSt.Tested == "Skipped")
                        {
                            <img src="~/Images/MailClosed.png" />
                        }
                        else
                        {
                            <img src="~/Images/MailOpen.png" />
                        }
                    }
                    else
                    {
                        @PubSt.Tested
                    }
                </td>
                <td align="center" class="ToggleCellColour(@PubSt.Planned_Prod_Implementation)">
                    @if (PubSt.Planned_Prod_Implementation != "N/A")
                    {
                        if (PubSt.Planned_Prod_Implementation == "Done" || PubSt.Planned_Prod_Implementation == "Skipped")
                        {
                            <img src="~/Images/MailClosed.png" />
                        }
                        else
                        {
                            <img src="~/Images/MailOpen.png" />
                        }
                    }
                    else
                    {
                        @PubSt.Planned_Prod_Implementation
                    }
                </td>
                <td align="center" class="ToggleCellColour(@PubSt.Implemented_on_Prod)">
                    @if (PubSt.Implemented_on_Prod != "N/A")
                    {
                        if (PubSt.Implemented_on_Prod == "Done" || PubSt.Implemented_on_Prod == "Skipped")
                        {
                            <img src="~/Images/MailClosed.png" />
                        }
                        else
                        {
                            <img src="~/Images/MailOpen.png" />
                        }
                    }
                    else
                    {
                        @PubSt.Implemented_on_Prod
                    }
                </td>
            </tr>
        }
    }
</table>

It is possible to repeat the if else statement code as I have done to display the images, however I thought I could spare the trouble and introduce less errors by using the javascript function to simplify things.

Any help will be greatly appreciated.

1 answer

  • answered 2018-12-05 20:43 JuanR

    If you are using JQuery, you could add a data attribute to the cell as well as some identifier (e.g. class name) that allows you to target it, then have unobtrusive JS set the CSS class for you:

    <tr>
        <td class="coloredCell" data-availability="@PubSt.Planned_Prod_Implementation">stuff</td>
    </tr>
    

    Then use JS to set the color on document ready:

    $(function ()
    {
        $('.coloredCell').each(function (index, element)
        {
            var availability = $(element).attr("data-availability");
            var cssClass;
            switch (availability)
            {
                case "Ready":
                    cssClass = "cssReadyState";
                    break;
                case "Done":
                    cssClass = "cssDoneState";
                    break;
                case "Skipped":
                    cssClass = "cssSkippedState";
                    break;
                default:
                    cssClass = "";
                    break;
            }
            $(element).addClass(cssClass);
        });
    });