После этой статьи: https://cpratt.co/bootstrap-4-responsive-calendar-asp-net-core-taghelper/ Мне удалось реализовать пользовательский помощник по тегам Календаря, который принимает в качестве параметров месяц и год и отображает календарь на этот месяц.
Он отображает стандартный календарь с несколькими днями из предыдущих месяцев и днями в будущем. Я хочу скрыть все строки, у которых нет дней в текущем месяце, поэтому в некоторых месяцах может быть только 5 строк вместо 6, как в стандартном календаре.
Я пытался скрыть некоторые ячейки, используя css, но это все равно дает мне 6 строк с пустыми ячейками.
см. Пример кода, как описано в статье:
https://codepen.io/chrisdpratt/pen/OOybam Как видите, есть строка с датами не в этом месяце. Я хочу отображать только те строки, в которых есть несколько включительных дней в текущем месяце.
А вот код в помощнике по тегам c#, который отображает html.
[HtmlTargetElement("calendar", TagStructure = TagStructure.NormalOrSelfClosing)]
public class CalendarTagHelper : TagHelper
{
public int Month { get; set; }
public int Year { get; set; }
public List<CalendarEvent> Events { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "section";
output.Attributes.Add("class", "calendar");
output.Content.SetHtmlContent(GetHtml());
output.TagMode = TagMode.StartTagAndEndTag;
}
private string GetHtml()
{
var monthStart = new DateTime(Year, Month, 1);
var events = Events?.GroupBy(e => e.Date);
var html = new XDocument(
new XElement("div",
new XAttribute("class", "container-fluid"),
new XElement("header",
new XElement("h4",
new XAttribute("class", "display-4 mb-2 text-center"),
monthStart.ToString("MMMM yyyy")
),
new XElement("div",
new XAttribute("class", "row d-none d-lg-flex p-1 bg-dark text-white"),
Enum.GetValues(typeof(DayOfWeek)).Cast<DayOfWeek>().Select(d =>
new XElement("h5",
new XAttribute("class", "col-lg p-1 text-center"),
d.ToString()
)
)
)
),
new XElement("div",
new XAttribute("class", "row border border-right-0 border-bottom-0"),
GetDatesHtml()
)
)
);
return html.ToString();
IEnumerable<XElement> GetDatesHtml()
{
var startDate = monthStart.AddDays(-(int)monthStart.DayOfWeek);
var dates = Enumerable.Range(0, 42).Select(i => startDate.AddDays(i));
foreach (var d in dates)
{
if (d.DayOfWeek == DayOfWeek.Sunday && d != startDate)
{
yield return new XElement("div",
new XAttribute("class", "w-100"),
String.Empty
);
}
var mutedClasses = "d-none d-lg-inline-block bg-light text-muted";
yield return new XElement("div",
new XAttribute("class", $"day col-lg p-2 border border-left-0 border-top-0 text-truncate {(d.Month != monthStart.Month ? mutedClasses : null)}"),
new XElement("h5",
new XAttribute("class", "row align-items-center"),
new XElement("span",
new XAttribute("class", "date col-1"),
d.Day
),
new XElement("small",
new XAttribute("class", "col d-lg-none text-center text-muted"),
d.DayOfWeek.ToString()
),
new XElement("span",
new XAttribute("class", "col-1"),
String.Empty
)
),
GetEventHtml(d)
);
}
}
IEnumerable<XElement> GetEventHtml(DateTime d)
{
return events?.SingleOrDefault(e => e.Key == d)?.Select(e =>
new XElement("a",
new XAttribute("class", $"event d-block p-1 pl-2 pr-2 mb-1 rounded text-truncate small bg-{e.Type} text-white"),
new XAttribute("title", e.Title),
e.Title
)
) ?? new[] {
new XElement("p",
new XAttribute("class", "d-lg-none"),
"No events"
)
};
}
}
}
Я знаю, что мне нужно настроить эту строку var dates = Enumerable.Range(0, 42).Select(i => startDate.AddDays(i));
, чтобы получить правильный диапазон, чтобы строки без дней в текущем месяце вообще не отображались, но, похоже, я не могу обернуть его вокруг.