C# & Razor: Dynamic Calendar Using HTML Table in ASP.NET - c#

Good day,
I'm trying to create a dynamic calendar using HTML table. I have a few problems that I'm facing right now.
I have no idea how to specify if the specific first day of the month is Sunday, Monday, Tuesday, Wednesday, Thursday or Saturday.
How to fix my table body to show the table properly layout like a calendar.
So far, these are my codes in my razor page.
#{ // responsible for getting the first and last days of the month
var getDate = DateTime.Now;
var firstDayOfTheMonth = new DateTime(getDate.Year, getDate.Month, 1);
var lastDayOfTheMonth = firstDayOfTheMonth.AddMonths(1).AddDays(-1);
var numberOfDays = Convert.ToInt16(lastDayOfTheMonth.ToString("dd"));
}
// My HTML table
<table border="1">
<thead>
<tr>
<th>Sunday</th>
<th>Monday</th>
<th>Tuesday</th>
<th>Wednesday</th>
<th>Thursday</th>
<th>Friday</th>
<th>Saturday</th>
</tr>
</thead>
<tbody>
<tr>
#for (var i = 0; i < numberOfDays + 1; i++)
{
<td>#i</td>
}
</tr>
</tbody>
Here's the current output:
Thank you in advance.

To generate a calendar as a table, you need to generate a 7 column x 6 row grid to allow for all possible months so your loop needs to iterate 42 times (not the number of days in the month), where the first cell is the last Sunday of the previous month (unless the current month starts on a Sunday)
To calculate the date in the first cell, use
DateTime startDate = firstDayOfTheMonth.AddDays(-(int)firstDayOfTheMonth.DayOfWeek);
Then to generate the table in your view
<table>
<thead>
.... // add day name headings
</thead>
<tbody>
<tr>
#for (int i = 0; i < 42; i++)
{
DateTime date = startDate.AddDays(i);
if (i % 7 == 0 && i > 0)
{
#:</tr><tr> // start a new row every 7 days
}
<td>#date.Day</td>
}
</tr>
</tbody>
</table>
You might also want to style any days not in the current month differently, in which case you could conditional add a class name, for example
if (startDate.Month == getDate.month)
{
<td class="current">#date.Day</td>
}
else
{
<td>#date.Day</td>
}

Asp.net MVC Example:
#{
int currentMonth = DateTime.Now.Month;
int currentYear = DateTime.Now.Year;
DateTime firstDay = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1);
int daysInCurrentMonth = DateTime.DaysInMonth(firstDay.Year, firstDay.Month);
DateTime lastDay = new DateTime(currentYear, currentMonth, daysInCurrentMonth);
// Sunday casted to int gives 0 but that will not work for us, we need 7 to be able to calculate number of empty cells correctly
int dayOfWeekFirst = ((int)firstDay.DayOfWeek > 0) ? (int)firstDay.DayOfWeek : 7;
int dayOfWeekLast = ((int)lastDay.DayOfWeek > 0) ? (int)lastDay.DayOfWeek : 7;
}
HTML:
<tr align="center">
<!-- filling up space of previous month -->
#for (int a = 1; a < dayOfWeekFirst; a++)
{
#:<td></td>
}
<!-- filling up space of current month -->
#for (int i = 1; i <= daysInCurrentMonth; i++)
{
DateTime renderedDay = new DateTime(firstDay.Year, firstDay.Month, i);
// if Sunday
if (renderedDay.DayOfWeek == DayOfWeek.Sunday)
{
#:<td class="calendar-holiday">#i</td></tr><tr align="center">
}
// if Saturday
else if (renderedDay.DayOfWeek == DayOfWeek.Saturday)
{
#:<td class="calendar-holiday">#i</td>
}
// if normal day
else
{
#:<td>#i</td>
}
}
<!-- filling up space of next month -->
#for (int a = 1; a <= 7-dayOfWeekLast; a++)
{
#:<td></td>
}
</tr>
Here is full example details
https://forums.asp.net/t/1695201.aspx?Making+a+Calendar+table+

Related

Dynamically bind dropdown with month names

I place a dropdownlist into my web page, then add following code to bind items to dropdown list within the page load event.
In this case is a dropdownlist with month names.
On this dropdownlist when the month changes, the previous months are no longer displayed and the previous month is no longer shown after the day 20th of the following month.
How can I also exclude from the list the months following the one on the list?
E.G.
At this time in the dropdownlist month list I have the months included from February to December
After the twentieth day of month February I will have in dropdownlist the months included from March to December
The question is to see only March in dropdownlist month and not see following months (from April to December...)
public partial class DD_Monthbind : Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Monthbind();
}
}
private void Monthbind()
{
DateTimeFormatInfo info = DateTimeFormatInfo.GetInstance(null);
int currentMonth = DateTime.Now.Month;
for (int i = 1; i < 13; i++)
{
bool isMonthInPast = ((i + 1) < currentMonth) || (i + 1 == currentMonth && DateTime.Now.Day > 20);
if (!isMonthInPast)
DropDownList1.Items.Add(new ListItem(info.GetMonthName(i), i.ToString()));
}
}
}
update
private void Monthbind()
{
DateTimeFormatInfo info = DateTimeFormatInfo.GetInstance(null);
int currentMonth = DateTime.Now.Month;
for (int i = 1; i < 13; i++)
{
bool isMonthInPast = (i < currentMonth) || (i == currentMonth && DateTime.Now.Day > 20);
if (!isMonthInPast)
{
DropDownList1.Items.Add(new ListItem(info.GetMonthName(i), i.ToString()));
}
}
foreach (ListItem item in DropDownList1.Items)
{
if (DropDownList1.Items.IndexOf(item) != 0)
{
item.Enabled = false;
}
}
}

how to display all days in any month in a datagridview in wpf

I am still new in wpf development. I have a datagrid with 7 columns, days of the week(sunday to saturday). I want to display the days of any month depending on the user's selection on the grid. May someone please help me with this? thank you. At the moment, I have a switch case for all the months in a year and I can get the days in the month, I just need to know how to add the result to the datagrid and for the days to fall on the right day.
this is what I have;
switch (cTvDaySelected)
{
case "January":
var dates = new List<string>();
for (var date = new DateTime(d1.Year, d1.Month, 1); date.Month == d1.Month; date = date.AddDays(1))
{
dates.Add(date.ToLongDateString().Substring(0,2));
//for (int i = 0; i < dates.Count; i++)
//{
// dm.sun = date.ToLongTimeString().Substring(0,2);
//}
}
dm.sun = dates.FirstOrDefault();
MonthModel.Add(dm);
month_record.ItemsSource = MonthModel;
break;
}
DateTime.DaysInMonth function will help you in your situation. Here is similar logic which can help you to get your desire output.
int Year = 2019;
int Month = 2;
int TotalDaysInMonth = DateTime.DaysInMonth(Year, Month);
for (int i = 1; i <= TotalDaysInMonth; i++)
{
DateTime dt = new DateTime(Year, Month, i);
// Insert it into your Model...
}

Filling specific cells in html table with razor pages

After trying to fill a html table with data from a MVC model, we ran into a problem. This code below generates a table, which is supposed to represent a schedule. The first row displays the days of the week, and the first column displays the number representation of the school hours.
<table class="table2">
<tr>
<th></th>
#{ string[] days = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };}
#for (int i = 0; i < days.Length; i++)
{
<th>#(days[i])</th>
}
</tr>
#{
TimeSpan timeSpan = new TimeSpan(8, 30, 0); //08:30:00
TimeSpan AddTime = new TimeSpan(0, 50, 0); //00:50:00
TimeSpan timeSpan2 = new TimeSpan();
}
#{ for (int i = 1; i < 16; i++)
{
<tr>
<td>
<h3>#(i)</h3>
<a>
#{timeSpan.ToString();}
#(string.Format("{0:00}:{1:00}", timeSpan.Hours, timeSpan.Minutes))
</a>
#{timeSpan2 = timeSpan.Add(AddTime);}
<div>
<a>
#(string.Format("{0:00}:{1:00}", timeSpan2.Hours, timeSpan2.Minutes))
#{timeSpan = timeSpan2;}
</a>
</div>
</td>
#foreach (var item in Model)
{
if (item.Hours.Contains(i))
{
for (int x = 0; x < days.Length; x++)
{
if (item.Day != days[x])
{
<td>
</td>
}
else
{
<td>
#(item.Class)
#(item.Classroom)
</td>
}
}
}
}
</tr>
}
}
</table>
Our model looks like this;
public class ScheduleModel
{
[Display(Name = "Lesson Code")]
public string LessonCode { get; set; }
[Display(Name = "Day")]
public string Day { get; set; }
[Display(Name = "Classroom")]
public string Classroom { get; set; }
[Display(Name = "Hours")]
public int[] Hours { get; set; }
[Display(Name = "Class")]
public string Class { get; set; }
}
Ill try to explain what we're trying to do. Our view gets a list of models, filled with the data specified above. We want to display this data in the html table we tried to create above. The "Day" variable corresponds to the days in the top row of the table, and the Hours int[] corresponds to the hours in the first column of the table. These values should be compared with eachother to find the correct spot in the table. We almost got it to work, with the code displayed above, but we ran into a problem with duplicate hours and empty cells.
Lets say we get 2 instances of the model, one looks like this;
Day : Monday
Hours : [1,2,3]
and the second looks like this :
Day : Tuesday
Hours: [1,2,3]
The problem with this is that the foreach loop goes through the first model completly, and fills all cells in the first row with empty cells, then when the foreach loops through the second model, it cannot fill the already created empty cells, so it just sticks them on at the end; screenshot to visualize the problem ;
So it all boils down to this; how do we generate the rows, but in such a way that we can still add new data into the empty fields.
This works perfectly!
#for (int x = 0; x < 7; x++)
{
<td>
#foreach(var item in Model)
{
if (item.Hours.Contains(i))
{
if(item.Day == days[x]){
#(item.Class)
#(item.Classroom)
}
else
{
#("")
}
}
}
</td>
}

How to load a csv file as Json data in a MVC web application. Header can be different

I'm trying to read a csv file so that I can load a jQuery DataTable. The csv file might have different headers. I was using the header to create the columns for the jQuery table. Then loading the file in and creating the rows. I was doing this directly from the csv file and all worked okay, but only if the file was small. I needed to move to using Json in order to implement a way using Linq to sort, filter, and query in the Model portion of the code. While trying to move to an MVC model, I got into a position where I can't extract the rows from the Json data.
Here is the ViewFile, which currently has the LoadDataAsJson (which should be in the Model class, I'll bet). The Json it creates is correct.
public IActionResult ViewFile()
{
string fileName = Request.Form["fileName"];
ViewData["name"] = fileName;
ViewData["data"] = LoadDataAsJson(dir + Path.DirectorySeparatorChar + fileName, 100);
return View();
}
private string LoadDataAsJson(string fileName, int limit)
{
string[] headers = new string[8];
StringBuilder bldr = new StringBuilder();
bldr.Append("[");
using (TextReader reader = new StreamReader(fileName))
{
String line = null;
int k = 0;
while ((line = reader.ReadLine()) != null)
{
if (k > limit)
break;
if (k++ != 0)
{
if (k != 2)
bldr.Append(","); // append a comma to the end of previous line
List<string> aRow = FormatAsJsonArray(line);
bldr.AppendLine();
bldr.Append("{");
for (int i = 0; i < headers.Length; i++)
{
bldr.Append(headers[i]);
bldr.Append(":\"");
bldr.Append(aRow[i]);
bldr.Append("\"");
if (i != headers.Length - 1)
bldr.Append(",");
}
bldr.Append("}");
}
else
{
headers = line.Split(',');
}
}
}
bldr.Append(Environment.NewLine + "]" + Environment.NewLine);
return bldr.ToString();
}
private List<string> FormatAsJsonArray(string aLine)
{
int k = 0;
string[] tokens = aLine.Split(',');
List<string> items = new List<string>();
string lastPart = "";
if (tokens.Length > 6)
{
for (int i = 7; i < tokens.Length; i++)
{
lastPart = String.Concat(lastPart, tokens[i]);
if (i != tokens.Length - 1)
lastPart += ",";
}
}
for (int i = 0; i < tokens.Length; i++)
{
if (i > 8)
break;
if (tokens[i].Contains("["))
{
List<string> msecs = MsecColumnAsJson(tokens[i]);
for (int kk = 0; kk < msecs.Count; kk++)
items.Add(msecs[kk]);
}
else if (k < 7)
items.Add(tokens[i]);
k++;
}
if (lastPart != null && lastPart.Length > 0)
items.Add(lastPart);
return items;
}
The ViewFile.cshtml contains in part.
<h2>#ViewData["name"]</h2>
<div class="container">
<br />
<table id="table_id" class="table table-condensed table-striped table-hover display">
<thead>
<tr>
<th>DateTime</th>
<th>Msecs</th>
<th>Thread</th>
<th>Level</th>
<th>Logger</th>
<th>Host</th>
<th>Msg Type</th>
<th>Message</th>
</tr>
</thead>
<tbody>
#{
string logFile = (string)#ViewData["data"];
var k = 0;
}
#foreach (string lf logFile)
{
if (k++ > 50)
{
break;
}
<tr>
#foreach (string item in lf)
{
<td>
#item
</td>
}
</tr>
}
</tbody>
</table>
</div>
I end up getting cannot convert type 'char' to 'string' in each of the foreach statements. I tried using var for the var logFile = #ViewData["data"] line, but then the rest isn't working.
My intention was to extract on Json array line at a time, then break each of those up into a single td. How can I use the LogFileModel to contain the handling of the data, and create a view and controller to do this?
I would suggest going a different approach.
Use TextFieldParser from Microsoft.VisualBasic.FileIO (Yes, you can use that in C#) to read CSV and place it as data model and then use Newtonsoft.Json to create json from that objects.
Here's more on TextFieldParser: https://coding.abel.nu/2012/06/built-in-net-csv-parser/

Populating a dropdown list using a for loop in razor

I know it is not the best practice to do this, but I am curious on how you would populate a dropdownlist using a for loop in razor.
I am trying to do it this way
#{
int year = DateTime.Now.Year;
#Html.DropDownListFor(model => model.ResolutionYear, new List<SelectListItem>
{
for (var i = 0; i < 10; i++)
{
if (year - i == year)
{
new SelectListItem() { Text = (year - i).ToString(), Value = (year - i).ToString(), Selected = true };
}
else
{
new SelectListItem() { Text = (year - i).ToString(), Value = (year - i).ToString() };
}
}
})
}
It doesn't seem to like the way I am doing it as it keeps shouting at me } expected I have all all the closing brackets for each open bracket. Perhaps I am populating my DropDownList wrong? Is it even possible to populate this way or should I just do it in the controller?
Don't do it. Keep your Views as benign as possible. Use your View Model and Controller, that's what they're for. But for curiosity's sake, here's one way:
#{ var year = DateTime.Now.Year; }
<select>
#for (var i = year; (i > year - 10); i--)
{
if (i == (year - 3))
{
<option value="#i" selected>#i</option>
}
else
{
<option value="#i">#i</option>
}
}
</select>

Categories

Resources