0

I have model function that returns a list of dates. In my view, I don't want to duplicate the similar code into jQuery to populate a dropdown list.

Can the jQuery execute the model function which it's in C# and store the list of dates?

public List<string> GetAvailableDateInStrings()
{
    List<string> dateList = new List<string>();
    foreach(Year year in this.m_years)
    {
        foreach(Month month in year.GetMonths())
        {
            string monthString = month.MonthInEnum.ToString() + " " + year.CalendarYear.ToString();
            if(year.CalendarYear == this.m_cutOffYear && month.MonthInYear <= this.m_cutOffMonth)
            {
                dateList.Add(monthString);
            }
            else if(year.CalendarYear < this.m_cutOffYear)
            {
                dateList.Add(monthString);
            }
        }
    }
    return dateList;
}

Below is what I do now. But I want to reduce the code duplication by not creating the similar code in jQuery. So the jQuery needs to execute the C# function and store the list of dates in variable, then populate into dropdown list.

<script src="/Bootstrap_Sufee/assets/js/vendor/jquery-2.1.4.min.js"></script>
<script type="text/javascript">$(document).ready(function() {
    $("#attendanceReportType").change(function() {
        if ($("#attendanceReportType").val() == "Class Monthly") {
            $("#attendanceReportYear").empty();
            $("#attendanceReportYear").append("<option>May 2018</option>");
            $("#attendanceReportYear").append("<option>April 2018</option>");
            $("#attendanceReportYear").append("<option>March 2018</option>");
    });
});</script>
Stephen Kennedy
  • 20,585
  • 22
  • 95
  • 108
KWCham
  • 11
  • 4
  • 6
  • 1
    How about just making an action that returns a JsonResult of the GetAvailableDateInStrings function. Then just have your jQuery call that action and iterate through the Json collection it returns to populate your select. – Mark Fitzpatrick May 15 '18 at 16:26
  • "Can the jQuery execute the model function which it's in C#"...if you expose it via an action method, then yes. This kind of thing is what AJAX is for. – ADyson May 15 '18 at 18:41

2 Answers2

0

The best approach to solve this use ajax. In this case your c# function look like this.

 public JsonResult GetAvailableDateInStrings()
    {
        List<string> dateList = new List<string>();
        foreach (Year year in this.m_years)
        {
            foreach (Month month in year.GetMonths())
            {
                string monthString = month.MonthInEnum.ToString() + " " + year.CalendarYear.ToString();
                if (year.CalendarYear == this.m_cutOffYear && month.MonthInYear <= this.m_cutOffMonth)
                {
                    dateList.Add(monthString);
                }
                else if (year.CalendarYear < this.m_cutOffYear)
                {
                    dateList.Add(monthString);
                }
            }
        }
        return Json(dateList);
    }

And jQuery code will look like this.

<script src="/Bootstrap_Sufee/assets/js/vendor/jquery-2.1.4.min.js"></script>

<script type="text/javascript">

        $(document).ready(function () {
        $("#attendanceReportType").change(function () {
            if ($("#attendanceReportType").val() === "Class Monthly") {
                $("#attendanceReportYear").empty();
                $.ajax({
                    type: 'POST',
                    url: '/YourController/GetAvailableDateInStrings',
                    success: function (response) {
                        var dateList = response.result;
                        $.each(dateList,
                            function (index, obj) {
                                $("#attendanceReportYear").append("<option>" + obj + "</option>");
                            });
                    }
                });
            }
        });
        });

</script>
Shahid Malik
  • 163
  • 13
  • The c# function must be a controller action? I am actually new to web development, I really appreciate your answer. :) – KWCham May 16 '18 at 20:50
  • @KWCham. Yes it should be. If you have this method in any other class than you should make any additional method in your controller which will be called through Ajax. – Shahid Malik May 17 '18 at 04:53
0

Ajax is possible, as the other answer told you. But there is an easier solution: generating the needed code in your view, using the ViewBag.

In your controller action

ViewBag.MyDateList = myListOfDates;

In your view

$("#attendanceReportType").change(function() {
    if ($("#attendanceReportType").val() == "Class Monthly") {
        $("#attendanceReportYear").empty();

        @foreach (var myDate in ViewBag.MyDateList)
        {
            $("#attendanceReportYear").append("<option>@myDate.ToString("MMMM yyyy")</option>");
        }
    }
});

This will generate the needed jQuery code without requiring you to copy/paste it yourself.

Flater
  • 12,908
  • 4
  • 39
  • 62
  • Oh, c# code can be directly executed in jQuery? I am new to web development, really appreciate your answer. :) – KWCham May 16 '18 at 20:51
  • @KWCham: Not directly in jQuery. Rather, the view is built using Razor, which generates the webpage for you. The generated page is sent to the browser, which executes the Javascript/jQuery on the page (which may include specific scripts you generated in Razor). You can influence that Razor generation process with things like the `@foreach`, which means you can iteratively generate part of the webpage content. This can be HTML, javascript, jQuery, ... it doesn't really matter. Think of Razor as an advanced webpage HTML String.Format variant, because that's essentially what it does. – Flater May 16 '18 at 20:56
  • @KWCham: Just to be clear: The controller executes the action. The controller then tells Razor to render a view. Razor renders that view, which is effectively just creating the HTML of the webpage (a string). MVC sends that string to the browser that sent the web request. The browser then renders the page accordingly, and executes any JavaScript on the page. Razor runs on the webservice; jQuery runs in the client browser. One does not run in the other in the literal sense. They don't even run on the same machine (server vs user's computer) – Flater May 16 '18 at 21:01
  • In that case, if I understand correctly, the jQuery code above executes in client side, when it reaches c# code, it make another request to server to execute the c# code, then the server sends the result back to where jQuery sent the request? – KWCham May 16 '18 at 21:39
  • @KWCham Every new request creates a new webpage, which is run by itself. So yes, jQuery can cause a web request, which returns a new page, on which jQuery is executed, but it won't be the same page as before. There are more complex ways around this but this is getting out of scope of the question here. I suggest looking at an MVC tutorial as this is the core of how MVC operates – Flater May 17 '18 at 04:04