Welcome Guest Search | Active Topics | Sign In | Register

Calendar - Client Template Options
shkup
Posted: Sunday, May 11, 2008 1:41:20 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
I'm evaluating your product.
I try to use the title template in order to display simple drop downs for years and months selections.
The problem is that you don't render server side controls there so I'm obligated to client side controls only.
It means that there are no unique id's for these controls, so when I have more than one calendar in the page I can't locate the control in the relevant calendar instance and operate it.
I succeed to accomplish the task but the code contains many workarounds that I don't like. Please try to help me finding more elegant solution.

Notice some code lines I had to use:
g_curCalendar = control.c;
in order to save the current calendar client id. <%= %> is not an option since I want one script to work for all calendars instances.

also:
the js function getCalendarControl that locates the client control in the template at the right calendar. It goes to parent elements and looks for the cliend id of the calendar there which is quite a primitive code that I would like to avoid.

I use the ClientSideOnEvalVar event to initialize the years and months selectors but it called many times for every calendar and not only once per calendar (affects performance).

If you have suggestions how to accomplish it I will highly appreciate it.

//JS Script

var g_curCalendar = null;

var months = ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"];

function getCalendar()
{
if(g_curCalendar == null)
{
return null;
}

return eo_GetObject(g_curCalendar);
}

function getCalendarAttribute(objID)
{
if(g_curCalendar == null)
{
return null;
}

var calElelment = document.getElementById(g_curCalendar);
if(calElelment == null)
{
return null;
}

var objFullID = calElelment.attributes[objID];
if(objFullID == null)
{
return null;
}

return objFullID.value;
}

function setToday()
{
var today = new Date();

var calendar = getCalendar();
if(calendar == null)
{
return;
}

//Select today!
calendar.setSelectedDate(today);

eo_HideAllPopups();
}

function goToPrevMonth()
{
var calendar = getCalendar();
if(calendar == null)
{
return;
}

calendar.goPrevMonth();
}

function yearChange(ddlYear)
{
if(ddlYear == null)
{
return;
}

var calendar = getCalendar();
if(calendar == null)
{
return;
}

//Get the selected year
var yearIndex = ddlYear.selectedIndex;
var selectedYear = ddlYear.options[yearIndex].value;

//render years
buildYears(ddlYear, selectedYear);

//Get the current year
var curYear = calendar.getVisibleDate();

//Set the new year
curYear.setFullYear( selectedYear);

//Set the new current year in the calendar
calendar.goTo(curYear);
}

function buildYears(calendar, ddlYear, selectedYear)
{
var yearsBefore = getCalendarAttribute('YearsBefore');
var yearsAfter = getCalendarAttribute('YearsAfter');
if(yearsBefore == null || yearsAfter == null)
{
return;
}

var year, item;
var startYear = selectedYear - parseInt(yearsBefore, 10);
var endYear = selectedYear + parseInt(yearsAfter, 10);

for (year = startYear; year <= endYear ; year++)
{
item = new Option(year, year);
ddlYear.options.add(item);

item.selected = year == selectedYear;
}
}

function yearInit(calendar)
{
if(calendar == null)
{
return;
}

var ddlYear = getCalendarControl('ddlYear');
if(ddlYear == null)
{
return;
}

//Get the current year
var curYear = calendar.getVisibleDate();
var selectedYear = curYear.getFullYear();

//build the years
buildYears(calendar, ddlYear, selectedYear);
}

function getCalendarControl(ctrlName)
{
var ctrls = document.getElementsByName(ctrlName);
if(ctrls == null)
{
return null;
}

var i;

for(i=0; i<ctrls.length; i++)
{
var curElement = ctrls[i].parentElement;

while(curElement != null)
{
if(curElement.id != 'undefined' && curElement.id.indexOf(g_curCalendar) > -1)
{
return ctrls[i];
}

curElement = curElement.parentElement;
}
}

return null;
}

function monthInit(calendar)
{
if(calendar == null)
{
return;
}

var ddlMonth = getCalendarControl('ddlMonth');
if(ddlMonth == null)
{
return;
}

//Get the current month
var curMonth = calendar.getVisibleDate();
var selectedMonthIndex = curMonth.getMonth();

//Create the months
var monthItem, i;
for(i=0;i<12; i++)
{
monthItem = new Option(months[i]);
monthItem.selected = i == selectedMonthIndex;
ddlMonth.options.add(monthItem);
}

ddlMonth.selectedIndex = selectedMonthIndex;
}

function monthChange(ddlMonth)
{
var calendar = getCalendar();
if(calendar == null)
{
return;
}

//Get the selected month
var month = ddlMonth.selectedIndex;

//Get the current month
var curMonth = calendar.getVisibleDate();

//Change the month
curMonth.setMonth(month);

//Set the new current month
calendar.goTo(curMonth);
}

function goToNextMonth()
{
var calendar = getCalendar();
if(calendar == null)
{
return;
}

calendar.goNextMonth();
}

function initSelectors(control, varName, varFormat)
{
//No control
if(control == null)
{
return;
}

g_curCalendar = control.c;

monthInit(control);
yearInit(control);
}

//User Control HTML
<%@ Control Language="C#" AutoEventWireup="true" Codebehind="Calendar.ascx.cs" Inherits="EOCalTest.Calendar" %>

<%@ Register TagPrefix="eo" Namespace="EO.Web" Assembly="EO.Web" %>

<link href="css/Calendar.css" rel="stylesheet" type="text/css" />
<div dir="rtl">
<eo:DatePicker ID="DatePicker1" runat="server" SwapStyle="None" ClientSideOnEvalVar="initSelectors"
PickerFormat="dd/MM/yyyy" AllowMultiSelect="False" DayHeaderFormat="Short" FirstDayOfWeek="Sunday"
SelectedDates="" ControlSkinID="None" DayCellHeight="16" DayCellWidth="21" GridLineColor="207, 217, 227"
GridLineFrameVisible="False" GridLineVisible="True" TitleTemplateScope="Title"
TitleFormat="MMM yyyy" DisabledDates="">
<SelectedDayStyle CssClass="SelectedDayStyle" />
<DayStyle CssClass="DayStyle" />
<CalendarStyle CssClass="CalendarStyle" />
<DayHeaderStyle CssClass="DayHeaderStyle" />
<DayHoverStyle CssClass="DayHoverStyle" />
<TitleStyle CssClass="TitleStyle" />
<TitleTemplate Visible="true">
<table class="TitleStyle" width="100%">
<tr>
<td valign="middle">
<a id="A1" href="javascript:goToNextMonth();">
<img src="Images/TitleLeft.gif" border="0" />
</a>
</td>
<td align="center">
<select id="ddlYear" name="ddlYear" style="text-align: center; direction: rtl;" onchange="javascript:yearChange(this);">
</select>
</td>
<td align="center">
<select id="ddlMonth" name="ddlMonth" style="text-align: center; direction: rtl;" onchange="javascript:monthChange(this);">
</select>
</td>
<td valign="middle">
<a id="prevNextPicker" href="javascript:goToPrevMonth();">
<img src="Images/TitleRight.gif" border="0" />
</a>
</td>
</tr>
</table>
</TitleTemplate>
<FooterTemplate>
<table dir="rtl" style="font-size: 11px; font-family: Verdana" border="0" cellspacing="5"
cellpadding="0" width="100%" align="center">
<tr title="בחר את היום הנוכחי" onclick="javascript:setToday('year_picker1', 'month_picker1');">
<td valign="middle">
<img src="{img:00040401}" /></td>
<td style="cursor: pointer;" valign="middle">
<nobr>
היום: {var:today:dd/MM/yyyy}</nobr>
</td>
</tr>
</table>
</FooterTemplate>
</eo:DatePicker>
</div>
<%@ Control Language="C#" AutoEventWireup="true" Codebehind="Calendar.ascx.cs" Inherits="EOCalTest.Calendar" %>

<%@ Register TagPrefix="eo" Namespace="EO.Web" Assembly="EO.Web" %>

<link href="css/Calendar.css" rel="stylesheet" type="text/css" />
<div dir="rtl">
<eo:DatePicker ID="DatePicker1" runat="server" SwapStyle="None" ClientSideOnEvalVar="initSelectors"
PickerFormat="dd/MM/yyyy" AllowMultiSelect="False" DayHeaderFormat="Short" FirstDayOfWeek="Sunday"
SelectedDates="" ControlSkinID="None" DayCellHeight="16" DayCellWidth="21" GridLineColor="207, 217, 227"
GridLineFrameVisible="False" GridLineVisible="True" TitleTemplateScope="Title"
TitleFormat="MMM yyyy" DisabledDates="">
<SelectedDayStyle CssClass="SelectedDayStyle" />
<DayStyle CssClass="DayStyle" />
<CalendarStyle CssClass="CalendarStyle" />
<DayHeaderStyle CssClass="DayHeaderStyle" />
<DayHoverStyle CssClass="DayHoverStyle" />
<TitleStyle CssClass="TitleStyle" />
<TitleTemplate Visible="true">
<table class="TitleStyle" width="100%">
<tr>
<td valign="middle">
<a id="A1" href="javascript:goToNextMonth();">
<img src="Images/TitleLeft.gif" border="0" />
</a>
</td>
<td align="center">
<select id="ddlYear" name="ddlYear" style="text-align: center; direction: rtl;" onchange="javascript:yearChange(this);">
</select>
</td>
<td align="center">
<select id="ddlMonth" name="ddlMonth" style="text-align: center; direction: rtl;" onchange="javascript:monthChange(this);">
</select>
</td>
<td valign="middle">
<a id="prevNextPicker" href="javascript:goToPrevMonth();">
<img src="Images/TitleRight.gif" border="0" />
</a>
</td>
</tr>
</table>
</TitleTemplate>
<FooterTemplate>
<table dir="rtl" style="font-size: 11px; font-family: Verdana" border="0" cellspacing="5"
cellpadding="0" width="100%" align="center">
<tr title="בחר את היום הנוכחי" onclick="javascript:setToday('year_picker1', 'month_picker1');">
<td valign="middle">
<img src="{img:00040401}" /></td>
<td style="cursor: pointer;" valign="middle">
<nobr>
היום: {var:today:dd/MM/yyyy}</nobr>
</td>
</tr>
</table>
</FooterTemplate>
</eo:DatePicker>
</div>


//User Control Code Behind
public partial class Calendar : System.Web.UI.UserControl
{
#region Members

private const int DEFAULT_YEARS_BEOFRE = 10;
private const int DEFAULT_YEARS_AFTER = 10;

private enum eAttrEntries
{
YearsBefore,
YearsAfter,
}

#endregion

protected void Page_Load(object sender, EventArgs e)
{
}

protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);

if(!Page.ClientScript.IsClientScriptIncludeRegistered("PreloanCalendar"))
{
Page.ClientScript.RegisterClientScriptInclude(typeof(Page), "/PreloanCalendar", "PreloanCalendar.js");
}
}

protected override void Render(HtmlTextWriter writer)
{
this.EnsureID();

RegisterAttrsInCalendar(eAttrEntries.YearsBefore.ToString(), DEFAULT_YEARS_BEOFRE.ToString(), true);
RegisterAttrsInCalendar(eAttrEntries.YearsAfter.ToString(), DEFAULT_YEARS_AFTER.ToString(), true);

base.Render(writer);
}

#region Properties

[Description("The selected date")]
public DateTime SelectedDate
{
get
{
return DatePicker1.SelectedDate;
}
set
{
DatePicker1.SelectedDate = value;
}
}

[Description("The count of years that should be rendered before the selected year")]
public int YearsBefore
{
get
{
string key = eAttrEntries.YearsBefore.ToString();
if (DatePicker1.Attributes[key] == null)
{
return DEFAULT_YEARS_BEOFRE;
}

return int.Parse(DatePicker1.Attributes[key]);
}
set
{
if (value < 0)
{
throw new ArithmeticException("The years before count should be posotive number");
}

RegisterAttrsInCalendar(eAttrEntries.YearsBefore.ToString(), value.ToString(), false);
}
}

[Description("The count of years that should be rendered after the selected year")]
public int YearsAfter
{
get
{
string key = eAttrEntries.YearsAfter.ToString();
if (DatePicker1.Attributes[key] == null)
{
return DEFAULT_YEARS_AFTER;
}

return int.Parse(DatePicker1.Attributes[key]);
}
set
{
if (value < 0)
{
throw new ArithmeticException("The years after count should be posotive number");
}

RegisterAttrsInCalendar(eAttrEntries.YearsAfter.ToString(), value.ToString(), false);
}
}

private void RegisterAttrsInCalendar(string attrName, string val, bool dontOverrideIfExist)
{
if (DatePicker1.Attributes[attrName] == null)
{
DatePicker1.Attributes.Add(attrName, string.Empty);
}
else if (dontOverrideIfExist)
{
return;
}

DatePicker1.Attributes[attrName] = val;
}

#endregion
}

//css
body
{
}

.CalendarStyle
{
text-align:center;
border-right: #cfd9e3 1px solid;
border-top: #cfd9e3 1px solid;
font-size: 11px;
border-left: #cfd9e3 1px solid;
cursor: hand; border-bottom: #cfd9e3 1px solid;
font-family: verdana;
background-color: #eaeaea;
}

.SelectedDayStyle
{
font-size: 11px;
font-family: verdana;
border-right: black 1px solid;
border-top: black 1px solid;
border-left: black 1px solid;
border-bottom: black 1px solid;
background-color: white;
}

.DayStyle
{
font-size: 11px;
font-family: verdana;
border-right: #eaeaea 1px solid;
border-top: #eaeaea 1px solid;
border-left: #eaeaea 1px solid;
border-bottom: #eaeaea 1px solid;
background-color: #eaeaea;
}

.DayHeaderStyle
{
font-size: 11px;
font-family: verdana;
height: 17px;
}

.DayHoverStyle
{
font-size: 11px;
font-family: verdana;
border-right: black 1px solid;
border-top: black 1px solid;
border-left: black 1px solid;
border-bottom: black 1px solid;
background-color: white;
}

.TitleStyle
{
padding-right: 3px;
padding-left: 3px;
font-weight: bold;
padding-bottom: 3px;
color: white;
padding-top: 3px;
border-bottom: #cfd9e3 1px solid;
background-color: #006699;
font-size: 11px;
font-family: verdana;
background-color: #4a73bd;
}
eo_support
Posted: Sunday, May 11, 2008 7:24:49 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,090
Hi,

Thanks for posting in the forum. We have reviewed your code and believe you can use "this" variable to simply the code quite a bit.

We support several built-in "variables" in client template. For example, you can use:

Code: HTML/ASPX
<img src="{img:00040401}" /></td>


Here "{img:00040401}" is a built-in variable that will be evalulated and replaced with an Url to an built-in image at runtime. Another very useful variable is "{var:this}". For example, you can also do:

Code: HTML/ASPX
<a href="void javascript:window.alert({var:this}.getId());">
show client ID</a>


This anchor would display the ClientID of the hosting control when clicked. For example, if this link is inside a Calendar with ClientID "main_usercontrol1_Calendar1", then "{var:this}" is translated into "eo_GetObject('main_usercontrol1_Calendar1')" first. Thus calling getId() on the return value of that statement would return "main_usercontrol1_Calendar1". In another word, {var:this}.getId() pretty much has the same effect as <%=xxxx.ClientID%>.

This also means you do not have to keep a global variable g_curCalendar and use ClientSideOnEvalVar to initialize it. Just use {var:this} whenever you need the JavaScript object for the hosting Calendar control.

Hope this helps. Please feel free to let us know if you have any more questions.

Thanks


shkup
Posted: Sunday, May 11, 2008 8:10:58 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
This is not very helpful since:

1. I can't pass the ClientSideOnEvalVar any arguments. so var:this is not an option there.

2. ClientSideOnEvalVar is called 3 times at initiazliation time and one time every calendar popup.
I need it to run only at the popup operation. Can I somehow know if this is initialization or popup?
shkup
Posted: Sunday, May 11, 2008 8:42:51 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
{var:this} can help me here and there but I still have the problem of locating controls in the client templates in that specific calendar.

How can I get a control from a calendar client template?
eo_support
Posted: Sunday, May 11, 2008 9:19:06 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,090
shkup wrote:
How can I get a control from a calendar client template?


That's exactly what {var:this} is for. It returns the client side Calendar object, in another word, it returns the same client side object eo_GetObject("your_calendar_client_id") returns. That's also why you can use {var:this}.getId() to return the ClientID of your control.

You should not rely on ClientSideOnEvalVar to initialize things. There are two scenarios where you might want to initialize certain DHTML elements:

1. When the Calendar loads;
2. When the drop down pops up;

For the first scenario, you should use ClientSideOnLoad, for the second one, you can use the other workaround that we previous provided to you.

I do not exactly know what you mean by "I can't pass the ClientSideOnEvalVar any arguments. so var:this is not an option there". Can you explain?

Thanks
shkup
Posted: Sunday, May 11, 2008 9:31:56 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
Oh, by the way - using {var:this} cause additional calls to ClientSideOnEvalVar (Called once per var) so my code runs again and again while all I want is to initialize the drop downs on popup time...
eo_support
Posted: Sunday, May 11, 2008 9:45:16 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,090
It does. That's exactly the reason why you should not rely on ClientSideOnEvalVar to initialize. ClientSideOnEvalVar is designed for one purpose and you should not use it for another purpose. As we have already explained in our previous post, you should move the initialization code elsewhere.
shkup
Posted: Sunday, May 11, 2008 9:45:44 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
You got me real wrong.

I need to fill the drop downs when the user clicks on the date picker.
OnClientLoad is not called there, only the ClientSideOnEvalVar.

If you have another method I can use to achieve this task I'll be glad to hear...

This fact obligates me to reduce the use of {var:this} since every usage causes one more call to the ClientSideOnEvalVar function.

The {var:this} DOES NOT helps me to locate a control in the client template it just passes the calendar.

Example:

<TitleTemplate Visible="true">
<table class="TitleStyle" width="100%">
<tr>
<td valign="middle">
<a id="A1" href="javascript:goToNextMonth();">
<img src="Images/TitleLeft.gif" border="0" />
</a>
</td>
<td align="center">
<select id="ddlYear" name="ddlYear" style="text-align: center; direction: rtl;" onchange="javascript:yearChange(this);">
</select>
</td>

If I want to locate ddlYear in the ClientSideOnEvalVar function I currently don't have any way to do it.
eo_support
Posted: Sunday, May 11, 2008 10:15:25 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,090
Hi,

I understand that you had two questions:

1. How to trigger initialization code when user clicks the calendar button (which you currently rely on ClientSideOnEvalVar but is having performance issue);

2. How to locate a control in the client template (which you need in your initialization code);

For the first question, I believe before you post in the forum, you emailed us with exactly the same question. We have already offered completely JavaScript code for that question. So please check that email for the solution and let us know if you still have any questions on that.

For the second question, the easiest way is to again using "variables", but instead of using built-in ones such as var:this, you will need to use custom variable. For example, you can define a custom variable as "my_client_id", you can then use it this way in your client template:

Code: HTML/ASPX
<select id="{var:my_client_id}_ddlYear" ....>
....
</select>


Since "my_client_id" is not a built-in variable, you must handle ClientSideOnEvalVar to "evaluate" this variable. That's when you would use ClientsideOnEvalVar:

Code: HTML/ASPX
<eo:DatePicker ID="DatePicker1" ClientSideOnEvalVar="on_eval_var" ...>
...
</eo:DatePicker>


Code: JavaScript
function on_eval_var(control, varName, varFormat)
{
    if (varName == "my_client_id")
       return control.getId();
}


This two pieces together would translate the ID of your select element to "Calendar1_ddlYear". That should give controls inside the client template an unique ID based on the ClientID of the Calendar. Once you have unique IDs based on the Calendar's ClientID, the rest should be easy.

Please let us know if this solves the problem for you.

Thanks
shkup
Posted: Sunday, May 11, 2008 10:37:05 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
In your mail you suggested the usage of ClientSideOnLoad. Well, It doesn't work since ClientSideOnLoad is not called when the user clicks the date picker button so the drop downs are empty. (The template html can't contain the items since they are dynamically loaded).

About creating the unique id using a variable this is a great idea and I'll use it.

So the only remaining problem for me is to dynamically fill the drop downs when the user clicks on the date picker button without executing the code so many times.

I would like to apologize if I'm sound a bit bitter, your control is awesome, but too much JavaScript cause me allergies. :-)
eo_support
Posted: Sunday, May 11, 2008 10:48:16 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,090
Hi,

The solution we provided in the email will work even if it uses ClientSideOnLoad, which I will explain below:

1. You would provide two functions: one "load handler", which would handle ClientSideOnLoad, and one "click handler", which would handle the picker button click event;

2. When user clicks the picker button, your "click handler" is called. Your "load handler" is NOT called here;

3. Obviously, you would initialize whatever you need to initialize in your "click handler". Not your "load handler".

So the purpose for you to handle ClientSideOnLoad is not to perform the initialization when calendar load, the purpose is to hook up your click handler with the calendar so that your click handler will be called every time user clicks the button so you can perform the initialization there.

Hope this clears up.

Thanks
shkup
Posted: Sunday, May 11, 2008 11:00:30 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
OK, The only problem is:

From your mail:

Note you will need to change "DatePicker1" to the ID of your date picker for
getElementById call.

I don't know there the id of the image nor the calendar....
eo_support
Posted: Sunday, May 11, 2008 11:25:54 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,090
That's very easy. Just use:

document.getElementById("_eo_<%=DatePicker1.ClientID%>_picker");

Thanks
shkup
Posted: Sunday, May 11, 2008 11:28:35 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
I do it this way:

function hookupCalendarEvents(control)
{debugger;
if(control == null)
{
return;
}

var imgId = "_eo_" + control.getId() + "_popupimg";
var img = document.getElementById(imgId);
if(img == null)
{
return;
}

img.attachEvent('onclick', onCalendarPopup);
}

this is cool BUT - The calendar is unknown when the onclick is called!!! I must have there in order to initialize the controls....
eo_support
Posted: Sunday, May 11, 2008 11:39:39 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,090
Hi,

Your way is also good. As for Calendar control, you can do this:

Code: JavaScript
function hookupCalendarEvents(control)
{
    //get the image
    var imgId = "_eo_" + control.getId() + "_popupimg";
    var img = document.getElementById(imgId);

    //store the control as a member of the img object
    img.calendar = control;

    ......

}

function onCalendarPopup()
{
    //get the calendar control
    var calendar = this.calendar;

   .....now you have the calendar control.....
}


The key is, "this" is the img element when you are inside your onCalendarPopup handler. So you an use it to store whatever you'd like.

Thanks
shkup
Posted: Sunday, May 11, 2008 11:47:18 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
Thanks.

I used the following:

function onCalendarPopup(e)
{
if(e == null || e.srcElement == null)
{
return;
}

var calendar = eo_GetObject(e.srcElement.calendarId);
if(calendar == null)
{
return;
}

monthInit(calendar);
yearInit(calendar);
}

function hookEvent(element, eventName, callback)
{
if(element == null)
{
return;
}

if(element.addEventListener)
{
element.addEventListener(eventName, callback, false);
}
else if(element.attachEvent)
{
element.attachEvent("on" + eventName, callback);
}
}

function hookupCalendarEvents(control)
{
if(control == null)
{
return;
}

var imgId = "_eo_" + control.getId() + "_popupimg";
var img = document.getElementById(imgId);
if(img == null)
{
return;
}

img.setAttribute('calendarId', control.getId());

hookEvent(img, 'click', onCalendarPopup);
}

The code does look a lot better. The only problem is that after a value has been selected in the drop downs they are empty (looks like the calendar re creates itself after I call it's goTo() function and since it's not click operation nothing is filled in the drop downs).
I'll look into it tomorrow. If you can leave me your notes about this I'll appreciate it a lot.

THANKS!!!!
eo_support
Posted: Sunday, May 11, 2008 12:02:48 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,090
Quote:
looks like the calendar re creates itself after I call it's goTo() function and since it's not click operation nothing is filled in the drop downs


That is correct. You will need to handle ClientSideOnScroll to catch that scenario and re-initialize your select element.

This should solve your last question and all together you should have a much more elegant solution now. You might still feel a little bit "too much" JavaScript, but please keep in mind that you are trying to implement a quite sophisicated solution, and this is only possible with all the flexibilities that our controls support. What you are trying to implment is simply not possible with many other product on the market.

Our goal is such that, for most users, they should never need to touch any JavaScript in order to use our controls; For advanced users, they should have enough options to customize our control as far as their skill allows. Unfortunately you seems to fall into the advanced user group. :)
shkup
Posted: Sunday, May 11, 2008 12:21:24 PM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
I have checked most of the calendars out there and none is even close to your capabilities.
It is a bit "heavy" on the page but all calendars I've seen make an impact on page size so I guess it's justified.
Your support is the best I have seen and I work with most of the big third party controls companies out there.
You are definitely on the right track.

Best Regards, Yaron.
shkup
Posted: Monday, May 12, 2008 2:34:24 AM
Rank: Member
Groups: Member

Joined: 5/11/2008
Posts: 16
It seems that all the chanes caused side effects in popup position and z-order. I have published a post about it but I want to mention that the problem doesn't appear with the old lame js script.

the new source looks as follows:

//Test aspx

<%@ Page Language="C#" AutoEventWireup="true" Codebehind="Default.aspx.cs" Inherits="EOCalTest._Default" %>

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

<%@ Register TagPrefix="preloan" TagName="Calendar" Src="Calendar.ascx" %>

<%@ Register Assembly="System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
Namespace="System.Web.UI" TagPrefix="asp" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="cc2" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>בחינת תאריכון</title>
<link href="css/Calendar.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="scriptManager" runat="server"></asp:ScriptManager>
<asp:UpdatePanel UpdateMode="Always" id="panel1" runat="server">
<ContentTemplate>
<table align="right" dir="rtl">
<tr>
<td>
<table>
<tr>
<td>
<preloan:Calendar ID="calendar1" YearsBefore="70" YearsAfter="10" runat="server"></preloan:Calendar>
</td>
<td>
<preloan:Calendar ID="calendar2" YearsBefore="70" YearsAfter="10" runat="server"></preloan:Calendar>
</td>
</tr>
<tr>
<td>
<asp:DropDownList ID="ddl1" Width="200px" runat="server">
</asp:DropDownList>
</td>
<td>
<asp:TextBox ID="txt1" runat="server"></asp:TextBox>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<asp:GridView ID="gvTry" runat="server" AutoGenerateColumns="false" OnRowCommand="gvTry_RowCommand" OnRowDataBound="gvTry_RowDataBound" OnRowEditing="gvTry_RowEditing" OnRowCancelingEdit="gvTry_RowCancelingEdit" OnRowUpdating="gvTry_RowUpdating">
<Columns>
<asp:BoundField ReadOnly="true" HeaderText="שם" DataField="Name" />
<asp:BoundField ReadOnly="true" HeaderText="ת.ז" DataField="ID" />
<asp:TemplateField HeaderText="תאריך לידה">
<ItemTemplate>
<asp:Label ID="lblBirthDate" Text='<%# DataBinder.Eval(Container,"DataItem.BirthDate","{0:dd/MM/yyyy}")%>' runat="server"></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<preloan:Calendar ID="calBirthDate" YearsBefore="70" YearsAfter="10" runat="server"></preloan:Calendar> </EditItemTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Link" ShowCancelButton="true" ShowEditButton="true" EditText="ערוך" CancelText="בטל" UpdateText="עדכן" />
</Columns>
</asp:GridView>
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>
</html>


//Control code

<%@ Control Language="C#" AutoEventWireup="true" Codebehind="Calendar.ascx.cs" Inherits="EOCalTest.Calendar" %>

<%@ Register TagPrefix="eo" Namespace="EO.Web" Assembly="EO.Web" %>

<link href="css/Calendar.css" rel="stylesheet" type="text/css" />
<div dir="rtl">
<eo:DatePicker ID="DatePicker1" runat="server" SwapStyle="None" ClientSideOnScroll="initCalendar" ClientSideOnLoad="hookupCalendarEvents" ClientSideOnEvalVar="evaluateCalendarsVariables"
PickerFormat="dd/MM/yyyy" AllowMultiSelect="False" DayHeaderFormat="Short" FirstDayOfWeek="Sunday"
SelectedDates="" ControlSkinID="None" DayCellHeight="16" DayCellWidth="21" GridLineColor="207, 217, 227"
GridLineFrameVisible="False" GridLineVisible="True" TitleTemplateScope="Title"
TitleFormat="MMM yyyy" DisabledDates="">
<PickerStyle CssClass="PickerStyle" />
<SelectedDayStyle CssClass="SelectedDayStyle" />
<DayStyle CssClass="DayStyle" />
<CalendarStyle CssClass="CalendarStyle" />
<DayHeaderStyle CssClass="DayHeaderStyle" />
<DayHoverStyle CssClass="DayHoverStyle" />
<TitleStyle CssClass="TitleStyle" />
<TitleTemplate Visible="true">
<table class="TitleStyle" width="100%" style="overflow:visible">
<tr>
<td valign="middle">
<a id="A1" href="javascript:goToNextMonth({var:this});">
<img src="Images/TitleLeft.gif" border="0" />
</a>
</td>
<td align="center">
<select id="{var:my_client_id}_ddlYear" style="text-align: center; direction: rtl;" onchange="javascript:yearChange({var:this}, this);">
</select>
</td>
<td align="center">
<select id="{var:my_client_id}_ddlMonth" style="text-align: center; direction: rtl;" onchange="javascript:monthChange({var:this}, this);">
</select>
</td>
<td valign="middle">
<a id="prevNextPicker" href="javascript:goToPrevMonth({var:this});">
<img src="Images/TitleRight.gif" border="0" />
</a>
</td>
</tr>
</table>
</TitleTemplate>
<FooterTemplate>
<table dir="rtl" style="font-size: 11px; font-family: Verdana" border="0" cellspacing="5"
cellpadding="0" width="100%" align="center">
<tr title="בחר את היום הנוכחי" onclick="javascript:setToday({var:this});">
<td valign="middle">
<img src="{img:00040401}" /></td>
<td style="cursor: pointer;" valign="middle">
<nobr>
היום: {var:today:dd/MM/yyyy}</nobr>
</td>
</tr>
</table>
</FooterTemplate>
</eo:DatePicker>
</div>


//JS Code


var months = ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"];

function getCalendarAttribute(calendarID, objID)
{
var calElelment = getCalendarElement(calendarID);
if(calElelment == null)
{
return null;
}

var objFullID = calElelment.attributes[objID];
if(objFullID == null)
{
return null;
}

return objFullID.value;
}

function getCalendarElement(calendarID)
{
if(calendarID == null)
{
return;
}

return document.getElementById(calendarID);
}

function setToday(calendar)
{
if(calendar == null)
{
return;
}

var today = new Date();

//Select today!
calendar.setSelectedDate(today);

eo_HideAllPopups();
}

function goToPrevMonth(calendar)
{
if(calendar == null)
{
return;
}

calendar.goPrevMonth();
}

function goToNextMonth(calendar)
{
if(calendar == null)
{
return;
}

calendar.goNextMonth();
}

function yearChange(calendar, ddlYear)
{
if(calendar == null || ddlYear == null)
{
return;
}

//Get the selected year
var yearIndex = ddlYear.selectedIndex;
var selectedYear = ddlYear.options[yearIndex].value;

//Get the current year
var curYear = calendar.getVisibleDate();

//Set the new year
curYear.setFullYear(selectedYear);

//Set the new current year in the calendar
calendar.goTo(curYear);
}

function buildYears(calendarID, ddlYear, selectedYear)
{
ddlYear.options.length = 0;

var yearsBefore = getCalendarAttribute(calendarID, 'YearsBefore');
var yearsAfter = getCalendarAttribute(calendarID, 'YearsAfter');
if(yearsBefore == null || yearsAfter == null)
{
return;
}

var year, item;
var startYear = parseInt(selectedYear, 10) - parseInt(yearsBefore, 10);
var endYear = parseInt(selectedYear, 10) + parseInt(yearsAfter, 10);

for (year = startYear; year <= endYear ; year++)
{
item = new Option(year, year);
ddlYear.options.add(item);

item.selected = year == selectedYear;
}
}

function getCalendarControl(calendarID, ctrlID)
{
if(calendarID == null || ctrlID == null)
{
return null;
}

var fullCtrlId = calendarID + "_" + ctrlID;

return document.getElementById(fullCtrlId);
}

function yearInit(calendar)
{
if(calendar == null)
{
return;
}

var ddlYear = getCalendarControl(calendar.getId(), 'ddlYear');
if(ddlYear == null || ddlYear.options.length > 0)
{
return;
}

//Get the current year
var curYear = calendar.getVisibleDate();
var selectedYear = curYear.getFullYear();

//build the years
buildYears(calendar.getId(), ddlYear, selectedYear);
}

function monthInit(calendar)
{
if(calendar == null)
{
return;
}

var ddlMonth = getCalendarControl(calendar.getId(), 'ddlMonth');
if(ddlMonth == null || ddlMonth.options.length > 0)
{
return;
}

//Get the current month
var curMonth = calendar.getVisibleDate();
var selectedMonthIndex = curMonth.getMonth();

//Create the months
var monthItem, i;
for(i=0;i<12; i++)
{
monthItem = new Option(months[i]);
monthItem.selected = i == selectedMonthIndex;
ddlMonth.options.add(monthItem);
}

ddlMonth.selectedIndex = selectedMonthIndex;
}

function monthChange(calendar, ddlMonth)
{
if(calendar == null || ddlMonth == null)
{
return;
}

//Get the selected month
var month = ddlMonth.selectedIndex;

//Get the current month
var curMonth = calendar.getVisibleDate();

//Change the month
curMonth.setMonth(month);

//Set the new current month
calendar.goTo(curMonth);
}

function onCalendarPopup(e)
{
if(e == null || e.srcElement == null)
{
return;
}

var calendar = eo_GetObject(e.srcElement.calendarId);
if(calendar == null)
{
return;
}

initCalendar(calendar, 'onCalendarPopup');
}

function initCalendar(calendar, eventName)
{
monthInit(calendar);
yearInit(calendar);
}

function hookEvent(element, eventName, callback)
{
if(element == null)
{
return;
}

if(element.addEventListener)
{
element.addEventListener(eventName, callback, false);
}
else if(element.attachEvent)
{
element.attachEvent("on" + eventName, callback);
}
}

function hookupCalendarEvents(control)
{
if(control == null)
{
return;
}

var imgId = "_eo_" + control.getId() + "_popupimg";
var img = document.getElementById(imgId);
if(img == null)
{
return;
}

img.setAttribute('calendarId', control.getId());

hookEvent(img, 'click', onCalendarPopup);
}

function evaluateCalendarsVariables(control, varName, varFormat)
{
//No control
if(control == null)
{
return;
}

if (varName == "my_client_id")
{
return control.getId();
}
}


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.