0

In my Razor page, I have this property that is a list containing some dates:

public List<Dates> MyDates { get; set; }

The problem is how to take the date values and send them to the js (since the calendar is build in the js file I can't add an id in the html to use it).

This is how I take them from my Razor Page in the html:

@foreach(var date in Model.MyDates)
{
    @date.Date;
}
gameloverr2
  • 85
  • 2
  • 17
  • Set the `Model.MyDates` into a `JSON string` then in the script you can do something like this: `var dateString = @Model.MyDates; var dateObj = JSON.parse(dateString)`; See this for converting to `JSON string` https://stackoverflow.com/questions/6201529/how-do-i-turn-a-c-sharp-object-into-a-json-string-in-net – Alvin Stefanus Aug 02 '20 at 10:32

2 Answers2

1

Create a CSS rule base on the List<Date> Model.MyDates. In your cshtml file you can do things like:

<style>
@Html.Raw(string.Join(", ", Model.MyDates.Select(x => string.Format("[data-date='{0}']", x.ToString("yyyyMMdd")))))
{
    /* your CSS styles */
}
</style>

Use Html.Raw() to render a non-escaped html and use , as the separator.

The resultant CSS style rule will be something like:

<style>
[data-date='20200821'], [data-date='20200822'], [data-date='20200823']
{
  color: red
}
</style>

After that, render your calendar using js. For the cell of each day, you render a data-date attribute:

<td data-date='20200823'>23</td>

In this way, if the data in data-data matched with your CSS class generated, it will be styled.


In my opinion, using data attribute selector to style the calendar is simple (e.g. does not requires parsing the object into json and decode it in js side) and it may also fits your future needs.

For example, if you want to style all the dates in Aug, 2020, you can create another CSS rule like:

[data-date=^='202008']
{
  /* your styles */
}

In this way you don't need to change your js code (i.e. your logic). See the snippet below for more details.

var y = "2020"
var m = "08"
var i = "24"

document.getElementById("calendar").innerHTML = "<div data-date='" + y + m + i + "'>" + i + "</div>"

// example of same month
document.getElementById("calendar").innerHTML += "<div data-date='20200825'>(202008)25</div>"

// example of same day
document.getElementById("calendar").innerHTML += "<div data-date='20200724'>(202007)24</div>"
#calendar,
div {
  font-size: 2rem;
  display: inline-block;
  margin: 5px;
}

[data-date='20200824'] {
  color: red;
}


/* all day 24 */

[data-date$='24'] {
  border: 4px solid blue;
}


/* all 2020 Aug */

[data-date^='202008'] {
  background: orange;
}
<div id="calendar"></div>

P.S. I did not check if all the code above can be run by copy-n-paste but if you get the idea illustrated then you should know how to implement that.

Bemn
  • 1,291
  • 1
  • 7
  • 22
  • Your solution seems a very good one, but the problem is that when I render the calendar in js, I need to actually use variables and not directly the date, something like: `i`And this syntax is obviously not working. How could that be done? – gameloverr2 Aug 03 '20 at 08:49
  • @gameloverr2 assuming that `year`, `month` and `i` are **string**, then your js code should be something like: `"" + i + ""`. See this example on Jsfiddle: https://jsfiddle.net/qdur6xog/ – Bemn Aug 03 '20 at 09:04
  • You are right is working like that. Just another question, do you possibly know the syntax for the Razor page to @string.Join? I used your code but It gives me syntax error and I am not sure why – gameloverr2 Aug 03 '20 at 09:12
  • @gameloverr2 looks like some syntax errors in my example. I've updated the code above, and wrapped it by `@Html.Raw()` to make sure that a non-escaped html string will be rendered. – Bemn Aug 03 '20 at 10:33
  • The problem is that the @Html.Raw syntax says : "Myssing a selector in the style rule" and when I run the app it says that my list is null, even though is not null – gameloverr2 Aug 03 '20 at 11:14
  • Looks like you don't have a selector in the style, see [this link](https://forums.asp.net/t/2045138.aspx?Missing+selector). Does the app failed to compile and run in this case? – Bemn Aug 03 '20 at 11:27
  • I checked with the debug in the console and the list has items. Maybe the @Html.Raw is not available for Asp.Net-Core? – gameloverr2 Aug 03 '20 at 11:31
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/219122/discussion-between-bemn-and-gameloverr2). – Bemn Aug 03 '20 at 11:32
0

I think you can use a ViewDate like below:

Model:

public class Dates
{
    public string Date { get; set; }
}

Handler:

public class IndexModel : PageModel
{
    public List<Dates> MyDates { get; set; }
    public void OnGet()
    {
        MyDates = new List<Dates>
        {
            new Dates{ Date = DateTime.Now.ToShortDateString()},
            new Dates{ Date = DateTime.Now.ToShortDateString()},
            new Dates{ Date = DateTime.Now.ToShortDateString()}
        };
        ViewData["Date"] = Newtonsoft.Json.JsonConvert.SerializeObject(MyDates);
    }
}

View:

@section scripts{
    <script>
    
        $(document).ready(function () {
            var x = [];
            var dates = @Html.Raw(ViewData["Date"]);
            dates.forEach(element => x.push(element.Date));
            console.log(x);
        })
    </script>
}

Result:

enter image description here

mj1313
  • 7,930
  • 2
  • 12
  • 32
  • This solution seems a good one but even If I did the exact same thing as you, on the console there will be no result – gameloverr2 Aug 03 '20 at 07:44
  • Please check the ViewData in your page if it has the data. The ViewData can be used on the current page, for example, I define it in IndexModel and then it is just vaild on index page. Maybe you can show us more codes to fix the problem. – mj1313 Aug 03 '20 at 08:10
  • My ViewData looks like this: `@{ ViewData["Title"] = "Home Page";}` I am not sure what is the syntax to include the date – gameloverr2 Aug 03 '20 at 08:14
  • You need to define a new ViewData["Date"]:`ViewData["Date"] = Newtonsoft.Json.JsonConvert.SerializeObject(Model.MyDates);` – mj1313 Aug 03 '20 at 08:23