Link to home
Start Free TrialLog in
Avatar of tjgrindsted
tjgrindsted

asked on

Got problems adding events to asp Calendar, and week numbers.

Hi
First of all, im not a pro. so there are some things that im havent tryed/know aboud.

I have a code that adds week numbers to it.
User generated image
Look nice, but when i then add styling, i see the problem, the week numbers are added to the same cell as Monday, so if i want to style the week numbers, then i style monday to and if i god some dates from the prev. month, then it style the dates and the week number.
User generated image
Can someone help me adding an ekstra Row, where i can add the weeknumbers, so i can fix this problem or show me a guide for it in VB.

Code_Behind
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Globalization

Partial Class calendar_week_no
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs)

    End Sub

    Protected Sub Calendar2_DayRender(sender As Object, e As DayRenderEventArgs) Handles Calendar2.DayRender
        If e.Day.[Date].DayOfWeek = DayOfWeek.Monday Then
            Dim WeekNumber As New Label()
            'Note the enum that can be used to calculate the first week in different ways:
            'See http://msdn.microsoft.com/en-us/library/system.globalization.calendarweekrule(v=vs.100).aspx
            Dim weekNum As Integer = CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(e.Day.Date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday)
            WeekNumber.Text = weekNum.ToString()
            ' move the label to the left, outside the sunday cell, into the selector cell
            WeekNumber.Style.Add("left", "10px")
            WeekNumber.Style.Add("position", "absolute")
            e.Cell.Controls.Add(WeekNumber)
        End If
        hideExtraWeek(sender, e, DirectCast(Calendar2.FirstDayOfWeek, DayOfWeek))
    End Sub

    Protected Sub hideExtraWeek(sender As Object, e As DayRenderEventArgs, dw As DayOfWeek)
        If dw = DirectCast(7, DayOfWeek) Then
            dw = DirectCast(0, DayOfWeek)
        End If
        ' FirstDayOfweek returns 7 when set to default, But it's zero based so valid values are 0 to 6
        Dim blnBrowserDoesntSupportsEmptyRow As [Boolean] = Request.Browser.Browser = "Chrome" OrElse Request.Browser.Browser = "Safari"

        Dim dayOfWeek As Integer = Convert.ToInt16(e.Day.[Date].DayOfWeek)
        Dim compensate As Integer = dayOfWeek - Convert.ToInt16(dw)
        Dim WeekStart As DateTime = e.Day.[Date].AddDays(-1 * compensate)
        Dim WeekEnd As DateTime = WeekStart.AddDays(6)

        ' If the start and end of the week does not have relevance to the current month
        If WeekStart.Month = WeekEnd.Month AndAlso e.Day.IsOtherMonth Then
            e.Cell.Text = ""
            e.Cell.Height = 1
            ' fix for chrome. Visible=false leaves a blank row even when there are no <td>s in the <tr>
            e.Cell.Visible = blnBrowserDoesntSupportsEmptyRow
        End If
    End Sub

End Class

Open in new window


Main_Page
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="calendar_week_no.aspx.vb" Inherits="calendar_week_no" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>  
 </head>
 <body>
     <form id="form1" runat="server">
     <div>
         <asp:Calendar ID="Calendar2" runat="server" OnDayRender="Calendar2_DayRender" 
            NextPrevFormat="FullMonth"  
            SelectionMode="Day"  
            ForeColor="WhiteSmoke"  
            DayNameFormat="Full"  
            Font-Names="Brush Script Std"  
            Width="650">  
            <DayHeaderStyle  
                 BackColor="SeaGreen"  
                 Font-Bold="false"  
                 />  
            <DayStyle  
                 BackColor="DarkOrange"  
                 BorderColor="Orange"  
                 BorderWidth="1"  
                 Font-Italic="true"  
                 Font-Size="Large"  
                 />  
            <NextPrevStyle  
                 Font-Italic="true"  
                 />  
            <OtherMonthDayStyle  
                 BackColor="Tomato"  
                 BorderColor="Orange"  
                 />  
            <SelectedDayStyle  
                 BackColor="DarkOliveGreen"  
                 BorderColor="SpringGreen"  
                 />  
            <TodayDayStyle  
                 BackColor="DarkViolet"  
                 />  
            <TitleStyle  
                 BackColor="DarkGreen"  
                 Height="35"  
                 Font-Size="Large"  
                 />  
        </asp:Calendar> 
     </div>
     </form>
 </body>
 </html>

Open in new window


And then im trying to add some events to a calendar with another dayrender, but i get the error: System.NullReferenceException and something use NEW
For this line: For Each Row As DataRow In _DayEventsTable.Rows

Code_Behind
Imports System.Collections.Generic
Imports System.Data
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Partial Class calendar_daytext
    Inherits System.Web.UI.Page
    Private _DayEventsTable As DataTable

    Protected Sub Page_Load(sender As Object, e As EventArgs)
        _DayEventsTable = New DataTable()
        _DayEventsTable.Columns.Add("Date")
        _DayEventsTable.Columns.Add("Title")

        _DayEventsTable.Rows.Add(DateTime.Now.AddDays(-2).[Date].ToString(), "Meeting with Boss")
        _DayEventsTable.Rows.Add(DateTime.Now.[Date].ToString(), "Lunch with Suzan")
        _DayEventsTable.Rows.Add(DateTime.Now.AddDays(2).[Date].ToString(), "Trip to Paris!")
    End Sub

    Protected Sub DayRender(sender As Object, e As DayRenderEventArgs)
        For Each Row As DataRow In _DayEventsTable.Rows
            Dim [Date] As String = Row("Date").ToString()
            Dim Title As String = Row("Title").ToString()

            If [Date] = e.Day.[Date].ToString() Then
                e.Cell.Controls.Add(New LiteralControl("<p>" & Title & "</p>"))
            End If
        Next
    End Sub
End Class

Open in new window

Avatar of Bob Learned
Bob Learned
Flag of United States of America image

If you are talking about a null in this code:

 
Protected Sub DayRender(sender As Object, e As DayRenderEventArgs)
        For Each Row As DataRow In _DayEventsTable.Rows
            Dim [Date] As String = Row("Date").ToString()
            Dim Title As String = Row("Title").ToString()

            If [Date] = e.Day.[Date].ToString() Then
                e.Cell.Controls.Add(New LiteralControl("<p>" & Title & "</p>"))
            End If
        Next
    End Sub

Open in new window


my guess is that you don't have a reference to _DayEventsTable.  Are you persisting that somewhere, like a Session variable, between post backs?
Avatar of tjgrindsted
tjgrindsted

ASKER

The 2 codes are 2 diffrent calendars
What does that mean?  What line is causing the problem?
The first Code_Behind and the Main_Code are 1 code, that make the error with the styling.

The 2. Code_Behind are another calendar that are making the error.
Error: System.NullReferenceException and something about use NEW.
For this line: For Each Row As DataRow In _DayEventsTable.Rows
And for this code i only call the DayRender in the Calendar with OnDayRender.
In this line:

For Each Row As DataRow In _DayEventsTable.Rows

what is Nothing?  My guess was _DayEventsTable.
I dont know, i get this error
User generated image
If you hover over _DayEventsTable, the debugger should show you a value or Nothing.  You need to instantiate _DaysEventsTable on every post-back.  If you are not storing in a Session variable, and restoring on post-back, then that error will happen.
When exactly is DayRender() getting called?  Please show me the code from which it is called.
@ TheLearnedOne
Its Nothing...


@ cpkilekofp
Isent it using the _DayEventsTable from the Page_Load !?
Yes, but is this code getting executed before Page_Load?  There is code normally hidden from you in an initialization event for the page but from which some functions can be called.  If DayRender() is somehow getting called in the page initialization event, before Page_Load(), then _DayEventsTable would be null.
I only have the code i showed, i found it on the net, and im new to this, and on the main page i only got the asp:calendar, so if u cant see nothing else then NO its not getting executed before Page_Load
Since you're new to this, you should understand that you don't know what's being executed when, because you have no idea what's going on behind the scenes.  I do understand that you yourself have not modified the initialize event.

Try this, as it will force the DataTable to be initialized before you attempt to iterate through it:

Imports System.Collections.Generic
Imports System.Data
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Partial Class calendar_daytext
    Inherits System.Web.UI.Page
    Private _DayEventsTable As DataTable

    Protected Sub Page_Load(sender As Object, e As EventArgs)
	InitDayEventsTable
        _DayEventsTable = New DataTable()
        _DayEventsTable.Columns.Add("Date")
        _DayEventsTable.Columns.Add("Title")

        _DayEventsTable.Rows.Add(DateTime.Now.AddDays(-2).[Date].ToString(), "Meeting with Boss")
        _DayEventsTable.Rows.Add(DateTime.Now.[Date].ToString(), "Lunch with Suzan")
        _DayEventsTable.Rows.Add(DateTime.Now.AddDays(2).[Date].ToString(), "Trip to Paris!")
    End Sub

    Protected Sub InitDayEventsTable()

        _DayEventsTable = New DataTable()
        _DayEventsTable.Columns.Add("Date")
        _DayEventsTable.Columns.Add("Title")

        _DayEventsTable.Rows.Add(DateTime.Now.AddDays(-2).[Date].ToString(), "Meeting with Boss")
        _DayEventsTable.Rows.Add(DateTime.Now.[Date].ToString(), "Lunch with Suzan")
        _DayEventsTable.Rows.Add(DateTime.Now.AddDays(2).[Date].ToString(), "Trip to Paris!")

    End Sub

    Protected Sub DayRender(sender As Object, e As DayRenderEventArgs)

	If _DayEventsTable Is Nothing Then InitDayEventsTable

        For Each Row As DataRow In _DayEventsTable.Rows
            Dim [Date] As String = Row("Date").ToString()
            Dim Title As String = Row("Title").ToString()

            If [Date] = e.Day.[Date].ToString() Then
                e.Cell.Controls.Add(New LiteralControl("<p>" & Title & "</p>"))
            End If
        Next
    End Sub
End Class 

Open in new window

Ahh ok, so its notworking when its in Page_Load, i need to make a "Event Handler" sub, and then call the sub in the Page_Load.

Thx..

Can u help with the week number/styling error !?

I ended up with this and its works about the event.
Imports System.Collections.Generic
Imports System.Data
Imports System.Web
Imports System.Web.UI
Imports System.Web.UI.WebControls

Partial Class calendar_daytext
    Inherits System.Web.UI.Page
    Private _DayEventsTable As DataTable

    Protected Sub Page_Load(sender As Object, e As EventArgs)
	InitDayEventsTable
    End Sub

    Protected Sub InitDayEventsTable()

        _DayEventsTable = New DataTable()
        _DayEventsTable.Columns.Add("Date")
        _DayEventsTable.Columns.Add("Title")

        _DayEventsTable.Rows.Add(DateTime.Now.AddDays(-2).[Date].ToString(), "Meeting with Boss")
        _DayEventsTable.Rows.Add(DateTime.Now.[Date].ToString(), "Lunch with Suzan")
        _DayEventsTable.Rows.Add(DateTime.Now.AddDays(2).[Date].ToString(), "Trip to Paris!")

    End Sub

    Protected Sub DayRender(sender As Object, e As DayRenderEventArgs)

	If _DayEventsTable Is Nothing Then InitDayEventsTable

        For Each Row As DataRow In _DayEventsTable.Rows
            Dim [Date] As String = Row("Date").ToString()
            Dim Title As String = Row("Title").ToString()

            If [Date] = e.Day.[Date].ToString() Then
                e.Cell.Controls.Add(New LiteralControl("<p>" & Title & "</p>"))
            End If
        Next
    End Sub
End Class 
                                            

Open in new window

The problem is, it's not an error.  What is happening is that you are simply adding text to the column containing the first day of that week, so any styling that day gets, your week number will get.  You need to look at the code that asp:Calendar uses on the client to see what exactly the resultant table looks like.  Once you know its name, you can use Javascript to change its layout once it's arrived at the client (such as adding a new column at the front of the table).  How are your Javascript skills?
hmm on a scale from 1-10.....4-5

but is it something like this
Add colum to table

if yes, how do i then do, so it add the colums to the left and not to the right.
You don't.  You move the contents of all cells one column right, then populate the leftmost column as you will.

var i;
var j;

for (i = 0; i < tbl.rows.length; i++)
{
    for (j = 1; j < tbl.rows[i].cells.length; j++)
    {
        tbl.rows[i].cells[j].innerHTML = tbl.rows[i].cells[j - 1].innerHTML;
    }
}

Open in new window


Then set the .innerHTML of the first column to the values you want for you week numbers.  Embed them in <span></span> and set the style on the <span> (you can do this in simple text).
have tryed this, no fix.
"no fix" doesn't tell me much except you don't like the results.  What did you do, exactly, and what happened as a result?
i think i just close this thread, as i pointed out im new to this and need help, not with a complet solution, but an ex. that shows how it work can be helping alot bc. u pro. are using words/slang that i dont know what means, bc im not a pro, im trying to learn this, in my sparetime.
I understand that you're not a pro.  I'm not using slang; I'm using the correct names of the items I'm talking about.  I am a pro, and I don't use slang when talking to a newbie.

That said, the only way I can help you get to where you need to go is to understand what happened when you say "no fix".  If this is pure amusement for you, that's fine, delete the question and I will quit donating you my time.  If you actually want to learn how to do programming, the most important thing you'll need to learn is how to fix your programs, and I'm trying to help you do that;  if learning this is worth your while, then please just tell me exactly what code changes you made (by showing them to me) and what results you got (by showing them to me).
okay i have this that i found in C# and have converted and added some things to, but i cant get it to add the columns and the week to the columns, In C# its works fine, but i can only get the calendar showed in VB code, without the columns and the week numbers.

Main_page
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default_vb.aspx.vb" Inherits="Default_vb" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Calendar with week numbers</title>
    
    <script type="text/javascript">
        function addWkColumn(tblId, wkStart) {
            var tbl = document.getElementById(tblId);

            var tblBodyObj = tbl.tBodies[0];
            for (var i = 0; i < tblBodyObj.rows.length; i++) {
                // Month Header
                if (i == 0) {
                    // Add extra colspan column
                    tblBodyObj.rows[i].cells[0].colSpan = 8;
                }
                // Week Header
                if (i == 1) {
                    // Add week column headline
                    var newCell = tblBodyObj.rows[i].insertCell(0);
                    newCell.innerHTML = 'uge';
                    newCell.style.fontSize = '8px';
                    newCell.style.fontWeight = 'bold';
                    newCell.style.verticalAlign = 'bottom';
                    newCell.style.backgroundColor = '#ffffee';
                }

                // Normal row
                if (i >= 2) {
                    // Add the weeknumbers
                    var newCell = tblBodyObj.rows[i].insertCell(0);
                    if (tblBodyObj.rows[i].cells[1].style.color != 'white' || tblBodyObj.rows[i].cells[2].style.color != 'white' || tblBodyObj.rows[i].cells[3].style.color != 'white' || tblBodyObj.rows[i].cells[4].style.color != 'white' || tblBodyObj.rows[i].cells[5].style.color != 'white' || tblBodyObj.rows[i].cells[6].style.color != 'white' || tblBodyObj.rows[i].cells[7].style.color != 'white') {
                        newCell.innerHTML = wkStart;
                        wkStart += 1;
                    }
                    newCell.style.fontSize = '8px';
                    newCell.style.backgroundColor = '#ffffee';
                }
            }
        }

        </script>
    
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Calendar ID="Calendar1" runat="server" OnDayRender="Calendar1_DayRender" ShowNextPrevMonth="false" NextPrevFormat="FullMonth" Width="200px" SelectionMode="none">
        </asp:Calendar>
    </div>
    </form>
</body>
</html>

Open in new window


Code_Behind
Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Globalization

Partial Public Class Default_vb
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(sender As Object, e As EventArgs)
        ' Add weeknumbers
        addWeekNumberColumn()
    End Sub

    Private Sub addWeekNumberColumn()
        ' Get the date shown in the calendar control
        Dim curMonth As DateTime = Calendar1.VisibleDate

        ' Find first day of the current month
        curMonth = Convert.ToDateTime(curMonth.Year.ToString() + "-" + curMonth.Month.ToString() + "-01")

        ' Build javascript
        Dim jscript As String = "<script type='text/javascript'> " & vbCr & vbLf & "addWkColumn('" + Calendar1.ClientID + "', " + getISOWeek(curMonth).ToString() + ");" & vbCr & vbLf & "</script>"

        ' Add script to page for execution of addWkColumn javascript function
        Page.ClientScript.RegisterStartupScript(Me.[GetType](), "AddWeeknumbers", jscript)
    End Sub

    Private Function getISOWeek(day As DateTime) As Integer
        Return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(day, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday)
    End Function

    Protected Sub Calendar1_DayRender(sender As Object, e As DayRenderEventArgs) Handles Calendar1.DayRender
        hideExtraWeek(sender, e, DirectCast(Calendar1.FirstDayOfWeek, DayOfWeek))
    End Sub

    Protected Sub hideExtraWeek(sender As Object, e As DayRenderEventArgs, dw As DayOfWeek)
        If dw = DirectCast(7, DayOfWeek) Then
            dw = DirectCast(0, DayOfWeek)
        End If
        ' FirstDayOfweek returns 7 when set to default, But it's zero based so valid values are 0 to 6
        Dim blnBrowserDoesntSupportsEmptyRow As [Boolean] = Request.Browser.Browser = "Chrome" OrElse Request.Browser.Browser = "Safari"

        Dim dayOfWeek As Integer = Convert.ToInt16(e.Day.[Date].DayOfWeek)
        Dim compensate As Integer = dayOfWeek - Convert.ToInt16(dw)
        Dim WeekStart As DateTime = e.Day.[Date].AddDays(-1 * compensate)
        Dim WeekEnd As DateTime = WeekStart.AddDays(6)

        ' If the start and end of the week does not have relevance to the current month
        If WeekStart.Month = WeekEnd.Month AndAlso e.Day.IsOtherMonth Then
            e.Cell.Text = ""
            e.Cell.Height = 1
            ' fix for chrome. Visible=false leaves a blank row even when there are no <td>s in the <tr>
            e.Cell.Visible = blnBrowserDoesntSupportsEmptyRow
        End If
    End Sub

End Class

Open in new window

You were so very close.  The Javascript needs two changes:

1.  You have to actually call the function to add the week numbers; you never did.
    <form id="form1" runat="server">
    <div>
        <asp:Calendar ID="Calendar1" runat="server" OnDayRender="Calendar1_DayRender" ShowNextPrevMonth="false" NextPrevFormat="FullMonth" Width="200px" SelectionMode="none">
        </asp:Calendar>
    </div>
    <script type="text/javascript" language="javascript">
        // <!--
        addWkColumn("Calendar1", 0);
        // -->
    </script>
    </form>

Open in new window


2.  This small change to the normal rows avoids a runtime error:
                // Normal row
                if (i >= 2) {
                    // Add the weeknumbers
                    var newCell = tblBodyObj.rows[i].insertCell(0);
                    if (tblBodyObj.rows[i].cells[1]) {
                        if (tblBodyObj.rows[i].cells[1].style.color != 'white' || tblBodyObj.rows[i].cells[2].style.color != 'white' || tblBodyObj.rows[i].cells[3].style.color != 'white' || tblBodyObj.rows[i].cells[4].style.color != 'white' || tblBodyObj.rows[i].cells[5].style.color != 'white' || tblBodyObj.rows[i].cells[6].style.color != 'white' || tblBodyObj.rows[i].cells[7].style.color != 'white') {
                            tblBodyObj.rows[i].cells[0].innerHTML = "<span>" + String(wkStart) + "</span>";
                            wkStart += 1;
                        }
                    }
                    tblBodyObj.rows[i].cells[0].style.fontSize = '8px';
                    tblBodyObj.rows[i].cells[0].style.backgroundColor = '#ffffee';
                }

Open in new window

Hi Cpkilekofp

I have played with it, and i cant get it to write the right weeknumbers for the weeks
User generated image
I hope u can guide me.
Right now i have this code
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default_vb.aspx.vb" Inherits="Default_vb" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Calendar with week numbers</title>
    
    <script type="text/javascript">
        function addWkColumn(tblId, wkStart) {
            var tbl = document.getElementById(tblId);

            var tblBodyObj = tbl.tBodies[0];
            for (var i = 0; i < tblBodyObj.rows.length; i++) {
                // Month Header
                if (i == 0) {
                    // Add extra colspan column
                    tblBodyObj.rows[i].cells[0].colSpan = 8;
                }
                // Week Header
                if (i == 1) {
                    // Add week column headline
                    var newCell = tblBodyObj.rows[i].insertCell(0);
                    newCell.innerHTML = 'uge';
                    newCell.style.fontSize = '8px';
                    newCell.style.fontWeight = 'bold';
                    newCell.style.verticalAlign = 'bottom';
                    newCell.style.backgroundColor = '#ffffee';
                }

                // Normal row
                if (i >= 2) {
                    // Add the weeknumbers
                    var newCell = tblBodyObj.rows[i].insertCell(0);
                    if (tblBodyObj.rows[i].cells[1]) {
                        if (tblBodyObj.rows[i].cells[1].style.color != 'white' || tblBodyObj.rows[i].cells[2].style.color != 'white' || tblBodyObj.rows[i].cells[3].style.color != 'white' || tblBodyObj.rows[i].cells[4].style.color != 'white' || tblBodyObj.rows[i].cells[5].style.color != 'white' || tblBodyObj.rows[i].cells[6].style.color != 'white' || tblBodyObj.rows[i].cells[7].style.color != 'white') {
                            tblBodyObj.rows[i].cells[0].innerHTML = "<span>" + String(wkStart) + "</span>";
                            {
                                newCell.innerHTML = wkStart;
                                wkStart += 1;
                                if (wkStart == 53) {
                                    wkStart = 1;
                                }
                            }
                        }
                    }
                    tblBodyObj.rows[i].cells[0].style.fontSize = '8px';
                    tblBodyObj.rows[i].cells[0].style.backgroundColor = '#ffffee';
                }
            }
        }

        </script>
    
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Calendar ID="Calendar1" runat="server" OnDayRender="Calendar1_DayRender" ShowNextPrevMonth="false" NextPrevFormat="FullMonth" Width="200px" SelectionMode="none">
        </asp:Calendar>
        <script type="text/javascript" language="javascript">
            // <!--
            addWkColumn("Calendar1", 0);
            // -->
    </script>
    </div>
    </form>
</body>
</html>

Open in new window


Imports System
Imports System.Data
Imports System.Configuration
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Globalization

Partial Public Class Default_vb
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(sender As Object, e As EventArgs)
        ' Add weeknumbers
        addWeekNumberColumn()
    End Sub

    Private Sub addWeekNumberColumn()
        ' Get the date shown in the calendar control
        Dim curMonth As DateTime = Calendar1.VisibleDate

        ' Find first day of the current month
        curMonth = Convert.ToDateTime(curMonth.Year.ToString() + "-" + curMonth.Month.ToString() + "-01")

        ' Build javascript
        Dim jscript As String = "<script type='text/javascript'> " & vbCr & vbLf & "addWkColumn('" + Calendar1.ClientID + "', " + getISOWeek(curMonth).ToString() + ");" & vbCr & vbLf & "</script>"

        ' Add script to page for execution of addWkColumn javascript function
        Page.ClientScript.RegisterStartupScript(Me.[GetType](), "AddWeeknumbers", jscript)
    End Sub

    Private Function getISOWeek(day As DateTime) As Integer
        Return CultureInfo.CurrentCulture.Calendar.GetWeekOfYear(day, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday)
    End Function

    Protected Sub Calendar1_DayRender(sender As Object, e As DayRenderEventArgs) Handles Calendar1.DayRender
        hideExtraWeek(sender, e, DirectCast(Calendar1.FirstDayOfWeek, DayOfWeek))
    End Sub

    Protected Sub hideExtraWeek(sender As Object, e As DayRenderEventArgs, dw As DayOfWeek)
        If dw = DirectCast(7, DayOfWeek) Then
            dw = DirectCast(0, DayOfWeek)
        End If
        ' FirstDayOfweek returns 7 when set to default, But it's zero based so valid values are 0 to 6
        Dim blnBrowserDoesntSupportsEmptyRow As [Boolean] = Request.Browser.Browser = "Chrome" OrElse Request.Browser.Browser = "Safari"

        Dim dayOfWeek As Integer = Convert.ToInt16(e.Day.[Date].DayOfWeek)
        Dim compensate As Integer = dayOfWeek - Convert.ToInt16(dw)
        Dim WeekStart As DateTime = e.Day.[Date].AddDays(-1 * compensate)
        Dim WeekEnd As DateTime = WeekStart.AddDays(6)

        ' If the start and end of the week does not have relevance to the current month
        If WeekStart.Month = WeekEnd.Month AndAlso e.Day.IsOtherMonth Then
            e.Cell.Text = ""
            e.Cell.Height = 1
            ' fix for chrome. Visible=false leaves a blank row even when there are no <td>s in the <tr>
            e.Cell.Visible = blnBrowserDoesntSupportsEmptyRow
        End If
    End Sub

End Class

Open in new window

I see the correction you made for year-wrap.  Unfortunately, you botched the placement of the code where you display the week number in HTML - the following block is now ALWAYS executed instead of just when the conditions for display are correct.  Here is your corrected HTML/Javascript:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default_vb.aspx.vb" Inherits="Default_vb" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
    <title>Calendar with week numbers</title>
    
    <script type="text/javascript">
        function addWkColumn(tblId, wkStart) {
            var tbl = document.getElementById(tblId);

            var tblBodyObj = tbl.tBodies[0];
            for (var i = 0; i < tblBodyObj.rows.length; i++) {
                // Month Header
                if (i == 0) {
                    // Add extra colspan column
                    tblBodyObj.rows[i].cells[0].colSpan = 8;
                }
                // Week Header
                if (i == 1) {
                    // Add week column headline
                    var newCell = tblBodyObj.rows[i].insertCell(0);
                    newCell.innerHTML = 'uge';
                    newCell.style.fontSize = '8px';
                    newCell.style.fontWeight = 'bold';
                    newCell.style.verticalAlign = 'bottom';
                    newCell.style.backgroundColor = '#ffffee';
                }

                // Normal row
                if (i >= 2) {
                    // Add the weeknumbers
                    var newCell = tblBodyObj.rows[i].insertCell(0);
                    if (tblBodyObj.rows[i].cells[1]) {
                        if (tblBodyObj.rows[i].cells[1].style.color != 'white' 
				|| tblBodyObj.rows[i].cells[2].style.color != 'white' 
				|| tblBodyObj.rows[i].cells[3].style.color != 'white' 
				|| tblBodyObj.rows[i].cells[4].style.color != 'white' 
				|| tblBodyObj.rows[i].cells[5].style.color != 'white' 
				|| tblBodyObj.rows[i].cells[6].style.color != 'white' 
				|| tblBodyObj.rows[i].cells[7].style.color != 'white') {
                            newCell.innerHTML = wkStart;
                            wkStart = (wkStart % 52) + 1;	// 0 % 52 + 1 = 1, 1 % 52 + 1 = 2...51 % 52 + 1 = 52, 52 % 52 + 1 = 1; 
								// thus, this formula always loops through 1..52 when wkStart is initialized 
								// to the last week number before the current month - this example, of course,
								// is for January, where the previous week is either 52 or 0.  If you are 
								// planning to display a list of these in sequence, or any arbitrary month,
								// you'll need to precalculate the value of the starting week.
                            tblBodyObj.rows[i].cells[0].innerHTML = "<span>" + String(wkStart) + "</span>";
                        }
                    }
                    tblBodyObj.rows[i].cells[0].style.fontSize = '8px';
                    tblBodyObj.rows[i].cells[0].style.backgroundColor = '#ffffee';
                }
            }
        }

        </script>
    
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:Calendar ID="Calendar1" runat="server" OnDayRender="Calendar1_DayRender" ShowNextPrevMonth="false" NextPrevFormat="FullMonth" Width="200px" SelectionMode="none">
        </asp:Calendar>
        <script type="text/javascript" language="javascript">
            // <!--
            addWkColumn("Calendar1", 0);
            // -->
    </script>
    </div>
    </form>
</body>
</html>

Open in new window


However, I have another concern:  How are you handling midweek year start/year end?  For instance, when Jan 1 is on a Wednesday, does this count as week 1? And if so, does Dec 31 fall in week 53 of this year, or week 1 of next year?  You need to settle this question for proper display of December.
Hi again thx for reply, after the changes i still dont get the right weeknumbers.
User generated image
I'm about to go on vacation for a week and I will be unable to access the internet for most of that time.  Did you change the argument for AddWkColumn() to the week number just before the first week in June?
Hi

Np...

I just use the code i have showed and u have changes, i havent done anythings else, so No about AddWkColumn()
How do i do that !?
Each time you display a month in the Calendar control, you will have to calculate the initial week number minus 1 and pass it to AddWkColumn() instead of zero (which only works for the first week in the year).  Subtract the date of the first day of the first week of the year from the current date giving a TimeSpan, divide the .Days field by 7 (NOT the .TotalDays field) and pass that result to AddWkColumn().
BTW, if you do this in the C# code-behind, you can pass it using a Page property:

C#:

    protected readonly int WkNumber
    {
        get
        {
            TimeSpan ts = DateTime.Now - DateTime.Parse(DateTime.Now.Year.ToString() + "/1/1");
            return ts.Days / 7;
        }
    }


Javascript:

AddWkColumn(<%=WkNumber()%>);    // replace previous call with this
hmm this is in VB not C#
ASKER CERTIFIED SOLUTION
Avatar of Christopher Kile
Christopher Kile
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This question has been classified as abandoned and is closed as part of the Cleanup Program. See the recommendation for more details.