AjaxControlToolkit is undefined - Error when bringing an extender up to date - asp.net

I am looking for some way to warn the user if a form is 'dirty' and they try and navigate away from it.
This project seemed to do exactly what I needed.
However, it was written back in 2007, and when I tried to use it "as-is" in my .NET 4.0 app with the latest version of the Ajax Control Toolkit it didn't work.
So, I downloaded the source (available from the CodeProject article) and tried to bring it up-to-date. But this is the first time I've attempted such a task and I'm a bit lost.
The error I'm now getting is as follows:
Microsoft JScript runtime error: 'AjaxControlToolkit' is undefined
The line in the DirtyPanelExtenderBehaviour.js which gives the error is:
DirtyPanelExtender.DirtyPanelExtenderBehavior.registerClass('DirtyPanelExtender.DirtyPanelExtenderBehavior', AjaxControlToolkit.BehaviorBase);
Here's what I've done so far:
1. Downloaded the source from the Codeproject article
2. Opened in Visual Studio 2010 and completed the upgrade wizard
3. Deleted references to AjaxControlToolkit.dll and replaced with a new reference to the latest version of the toolkit
4. Amended references to ScriptManager with ToolkitScriptManager (Not sure if this was needed)
5. Amended the sample website to use a ToolkitScriptManager on the page in place of a ScriptManager
Sooo, any ideas what I've done wrong? Or what I'm missing? So that I can recompile the DirtyPanelExtender.dll and use it in my .NET 4.0 project?
The full code is below that I am using. The original author wrote this with exception of my amendments as detailed above - I'm not taking credit!
DirtyPanelExtender.cs:
using System;
using System.Web.UI.WebControls;
using System.Web.UI;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Collections.Generic;
using System.Text;
using AjaxControlToolkit;
[assembly: System.Web.UI.WebResource("DirtyPanelExtender.DirtyPanelExtenderBehavior.js", "text/javascript")]
namespace DirtyPanelExtender
{
[Designer(typeof(DirtyPanelExtenderDesigner))]
[ClientScriptResource("DirtyPanelExtender.DirtyPanelExtenderBehavior", "DirtyPanelExtender.DirtyPanelExtenderBehavior.js")]
[TargetControlType(typeof(Panel))]
[TargetControlType(typeof(UpdatePanel))]
public class DirtyPanelExtender : ExtenderControlBase
{
[ExtenderControlProperty]
[DefaultValue("Data has not been saved.")]
public string OnLeaveMessage
{
get
{
return GetPropertyValue("OnLeaveMessage", "");
}
set
{
SetPropertyValue("OnLeaveMessage", value);
}
}
protected override void OnPreRender(EventArgs e)
{
string values_id = string.Format("{0}_Values", TargetControl.ClientID);
string values = (Page.IsPostBack ? Page.Request.Form[values_id] : String.Join(",", GetValuesArray()));
ToolkitScriptManager.RegisterHiddenField(this, values_id, values);
base.OnPreRender(e);
}
private string[] GetValuesArray()
{
return GetValuesArray(TargetControl.Controls);
}
private string[] GetValuesArray(ControlCollection coll)
{
List<string> values = new List<string>();
foreach (Control control in coll)
{
if (control is RadioButtonList)
{
for (int i = 0; i < ((RadioButtonList)control).Items.Count; i++)
{
values.Add(string.Format("{0}_{1}:{2}", control.ClientID, i, ((RadioButtonList)control).Items[i].Selected.ToString().ToLower()));
}
}
else if (control is ListControl)
{
StringBuilder data = new StringBuilder();
StringBuilder selection = new StringBuilder();
foreach (ListItem item in ((ListControl) control).Items)
{
data.AppendLine(item.Text);
selection.AppendLine(item.Selected.ToString().ToLower());
}
values.Add(string.Format("{0}:data:{1}", control.ClientID, Uri.EscapeDataString(data.ToString())));
values.Add(string.Format("{0}:selection:{1}", control.ClientID, Uri.EscapeDataString(selection.ToString())));
}
else if (control is IEditableTextControl)
{
values.Add(string.Format("{0}:{1}", control.ClientID, Uri.EscapeDataString(((IEditableTextControl)control).Text)));
}
else if (control is ICheckBoxControl)
{
values.Add(string.Format("{0}:{1}", control.ClientID, ((ICheckBoxControl)control).Checked.ToString().ToLower()));
}
values.AddRange(GetValuesArray(control.Controls));
}
return values.ToArray();
}
public void ResetDirtyFlag()
{
ToolkitScriptManager.RegisterClientScriptBlock(TargetControl, TargetControl.GetType(),
string.Format("{0}_Values_Update", TargetControl.ClientID), string.Format("document.getElementById('{0}').value = '{1}';",
string.Format("{0}_Values", TargetControl.ClientID), String.Join(",", GetValuesArray())), true);
}
}
}
DirtyPanelExtenderBehaviour.js:
Type.registerNamespace('DirtyPanelExtender');
DirtyPanelExtender.DirtyPanelExtenderBehavior = function(element) {
DirtyPanelExtender.DirtyPanelExtenderBehavior.initializeBase(this, [element]);
this._OnLeaveMessageValue = null;
}
DirtyPanelExtender.DirtyPanelExtenderBehavior.prototype = {
isDirty : function() {
var values_control = document.getElementById(this.get_element().id + "_Values");
var values = values_control["value"].split(",");
for (i in values) {
var namevalue = values[i];
var namevaluepair = namevalue.split(":");
var name = namevaluepair[0];
var value = (namevaluepair.length > 1 ? namevaluepair[1] : "");
var control = document.getElementById(name);
if (control == null) continue;
// alert(control.id + " -> " + control.type);
if (control.type == 'checkbox' || control.type == 'radio') {
var boolvalue = (value == "true" ? true : false);
if(control.checked != boolvalue) {
// alert("checkbox changed: " + control.checked + " vs. " + boolvalue);
return true;
}
} else if (control.type == 'select-one' || control.type == 'select-multiple') {
if (namevaluepair.length > 2) {
if ( control.options.length > 0) {
// control is listbox
// there's data:value and selection:value
var code = value;
value = (namevaluepair.length > 2 ? namevaluepair[2] : "");
var optionValues = "";
// concat all listbox items
for( var cnt = 0; cnt < control.options.length; cnt++) {
if (code == 'data') {
optionValues += control.options[cnt].text;
} else if (code == 'selection') {
optionValues += control.options[cnt].selected;
}
optionValues += "\r\n";
}
if( encodeURIComponent(optionValues) != value ) {
// items in the listbox have changed
// alert("listbox " + code + " changed: " + encodeURIComponent(optionValues) + " vs. " + value);
return true;
}
}
} else if(control.selectedIndex != value) {
// alert("dropdown selection changed: " + control.selectedIndex + " vs. " + value);
return true;
}
} else {
if(encodeURIComponent(control.value) != value) {
// alert("control " + control.type + " changed: " + control.value + " vs. " + value);
return true;
}
}
}
return false;
},
initialize : function() {
DirtyPanelExtender.DirtyPanelExtenderBehavior.callBaseMethod(this, 'initialize');
DirtyPanelExtender_dirtypanels[DirtyPanelExtender_dirtypanels.length] = this;
},
dispose : function() {
DirtyPanelExtender.DirtyPanelExtenderBehavior.callBaseMethod(this, 'dispose');
},
get_OnLeaveMessage : function() {
return this._OnLeaveMessageValue;
},
set_OnLeaveMessage : function(value) {
this._OnLeaveMessageValue = value;
}
}
DirtyPanelExtender.DirtyPanelExtenderBehavior.registerClass('DirtyPanelExtender.DirtyPanelExtenderBehavior', AjaxControlToolkit.BehaviorBase);
var DirtyPanelExtender_dirtypanels = new Array()
function DirtyPanelExtender_SuppressDirtyCheck()
{
window.onbeforeunload = null;
}
function __newDoPostBack(eventTarget, eventArgument)
{
// supress prompting on postback
DirtyPanelExtender_SuppressDirtyCheck();
return __savedDoPostBack (eventTarget, eventArgument);
}
var __savedDoPostBack = __doPostBack;
__doPostBack = __newDoPostBack;
window.onbeforeunload = function (eventargs)
{
for (i in DirtyPanelExtender_dirtypanels)
{
var panel = DirtyPanelExtender_dirtypanels[i];
if (panel.isDirty())
{
if(! eventargs) eventargs = window.event;
eventargs.returnValue = panel.get_OnLeaveMessage();
break;
}
}
}

The BehaviorBase class now resides in a different namespace. You need to replace the line...
DirtyPanelExtender.DirtyPanelExtenderBehavior.registerClass('DirtyPanelExtender.DirtyPanelExtenderBehavior', AjaxControlToolkit.BehaviorBase);
with...
DirtyPanelExtender.DirtyPanelExtenderBehavior.registerClass('DirtyPanelExtender.DirtyPanelExtenderBehavior', Sys.Extended.UI.BehaviorBase);

Related

How display a json error message?

I cannot display the Json message, Im trying prevente that user upload files with same name this is my controller code:
//POST: /Quote/Create Save the Uploaded file
public ActionResult SaveUploadedFile(int? chunk, string name)
{
bool exists;
var fileUpload = Request.Files[0];
var uploadPath = "C:\\Files";
chunk = chunk ?? 0;
if (System.IO.File.Exists(Path.Combine(uploadPath, name)))
{
exists = true;
}
else {
exists = false;
}
if (!exists)
{
using (var fs = new FileStream(Path.Combine(uploadPath, name), chunk == 0 ? FileMode.Create : FileMode.Append))
{
var buffer = new byte[fileUpload.InputStream.Length];
fileUpload.InputStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, buffer.Length);
}
return Json(new { success = true }, JsonRequestBehavior.AllowGet);
}
else {
return Json(new { success = false, Message = "The file" + name +"already exists" }, JsonRequestBehavior.AllowGet);
}
}
This is my view code, if files success is false, then display the Json message:
UploadComplete: function (up, files) {
if (!files.success) {
alert(files.Message);
console.log(up);
} else {
var j = 0;
if (count > 0) {
j = count;
} else {
j = #i + '';
}
$.each(files, function (i, file) {
var extension = file.name.split(".");
$('.files').append('<input type=\"hidden\" name=\"Files[' + j + '].Name\" value=\"' + file.name + '\" />');
$('.files').append('<input type=\"hidden\" name=\"Files[' + j + '].Date\" value=\"' + "#DateTime.Now" + '\" />');
j++;
});
}
}
Thanks in advance !!
It seems that you need to be returning a string result rather than an ActionResult, since all you really want is if it passed or not. Also shortened your code a little to reflect the changes.
If you did want to return an object (meaning you wanted more than one property), I would create a model (class and then object), then return JsonResult rather than ActionResult.
Good documentation on how to return JsonResult object
C#
public string SaveUploadedFile(int? chunk, string name)
{
bool exists = false;
var fileUpload = Request.Files[0];
var uploadPath = "C:\\Files";
chunk = chunk ?? 0;
exists = System.IO.File.Exists(Path.Combine(uploadPath, name));
if (!exists)
{
using (var fs = new FileStream(Path.Combine(uploadPath, name), chunk == 0 ? FileMode.Create : FileMode.Append))
{
var buffer = new byte[fileUpload.InputStream.Length];
fileUpload.InputStream.Read(buffer, 0, buffer.Length);
fs.Write(buffer, 0, buffer.Length);
}
}
return message = !exists ? string.Empty
: "The file" + name + " already exists";
}
Javascript
if (files.message != '') { // meaning "exists" is true
console.log(up);
} else {
......
......
}

Write custom plugins/extensions like kendoui and telerik for asp.net mvc razor

Telerik and kendoUI offers a number of html controls like grids, charts etc. to enhance the ui in asp.net mvc. More interesting thing is they are used as html extensions and hence we can bind some model to the controls which also makes it somewhat strongly typed. It also uses javascript libs to handle client side interactions. I need to get some gist over how can we write custom plugins like kendo and telerik like building my own grid component. What is the proper pattern that i should follow?
This is not good example but i think it is good start.
This method generates dataTable
public static string GenerateTableHtml<TValue>(IEnumerable<TValue> model, string DeleteUrl, string EditUrl)
{
StringBuilder Table = new StringBuilder();
Table.AppendLine("<script type='text/javascript'> $(document).ready(function () {"
+ "$('.btnDelete').click(function () {"
+ "var url = $(this).attr('dropzone');"
+ "$('#dialog-form').attr('action', url);})"
+ "})</script>");
Table.AppendLine(" <div class=\"dataTables_wrapper\"><div class=\"\">");
string TableButtonsTemplate = "<td><div class=\"table_buttons\">"
+ "<img src=\"../Images/icons/dark/pencil.png\")\" title=\"რედაქტირება\" />"
+ "<a href=\"#\" id=\"opener\" class=\"btnDelete\" dropzone=\"{1}\">"
+"<img class=\"\" src=\"../Images/icons/dark/close.png\")\" title=\"წაშლა\" /></a>"
+ "</div></td>";
string TableButtons = String.Empty;
bool HaveActionButtons = false;
string rowID = string.Empty;
if (String.IsNullOrEmpty(DeleteUrl) == false || string.IsNullOrEmpty(EditUrl) == false)
{
HaveActionButtons = true;
}
Table.AppendLine("<table class=\"display dTable\" cellspacing=\"0\" cellpadding=\"0\" border=\"0\">");
Table.AppendLine("<thead>");
Table.AppendLine("<tr>");
int ColumnIndex = 0;
int rowIndexer = 0;
var fType = model.GetType().FullName;
var startIndex = fType.IndexOf("[[") + 2;
var type = fType.Substring(startIndex, fType.Length - startIndex - 2);
foreach (var item in model)
{
if (ColumnIndex == 0)
{
var properties = item.GetType().GetProperties();
foreach (var prop in properties)
{
var metaData = ModelMetadataProviders.Current.GetMetadataForProperty(null,
Type.GetType(type), prop.Name);
if (metaData.DisplayName != null)
{
Table.AppendLine("<th class=\"ui-state-default\" rowspan=\"1\" colspan=\"1\">" + metaData.DisplayName + "</th>");
}
else
{
Table.AppendLine("<th class=\"ui-state-default\" rowspan=\"1\" colspan=\"1\">" + prop.Name + "</th>");
}
}
Table.AppendLine("<th></th>");
Table.AppendLine("</tr>");
Table.AppendLine("</thead>");
Table.AppendLine("<tbody>");
}
foreach (var value in item.GetType().GetProperties().Select(x => x.GetValue(item, null)))
{
int rowCount = item.GetType().GetProperties().Select(x => x.GetValue(item, null)).Count();
rowIndexer++;
if (rowIndexer != rowCount)
{
if (rowIndexer == 1)
{
Table.AppendLine("<tr class=\"gradeA odd\">");
}
if (value != null)
{
string val = value.ToString();
Table.AppendLine("<td>" + val + "</td>");
rowID = item.GetType().GetProperty("ID").GetValue(item, null).ToString();
}
else
{
Table.AppendLine("<td></td>");
}
}
else
{
if (value != null)
{
Table.AppendLine("<td>" + value.ToString() + "</td>");
}
else
{
Table.AppendLine("<td></td>");
}
if (HaveActionButtons == true)
{
Table.AppendLine(String.Format(TableButtonsTemplate, EditUrl + rowID, DeleteUrl + rowID));
}
Table.AppendLine("</tr>");
if (rowIndexer != item.GetType().GetProperties().Count())
{
Table.AppendLine("<tr class=\"gradeA odd\">");
}
}
}
rowIndexer = 0;
ColumnIndex++;
}
Table.AppendLine("</tbody></table></div></div>");
Table.AppendLine(String.Format(Resources.MainResources.ModalDialogConfirm, "Confirmation",
"<strong>Warning!</strong><br /> Are you sure you want to delete user?", ""));
return Table.ToString();
}

regular expression asp.net

I trying to improve a textbox that filters a gridview, by implementing an enhanced textbox that can identify AND, OR, NOT operators by searching for this keywords in the string the user inputs in the textbox.
I am trying to do a regular expression to group the results but I'm not very good at this and I am failing to get what I want.
An example of what I want is as follows:
string = "build1 and build2 and build3 or build4 or not build5 and not build6"
results in a split mode:
build1 and
build2 and
build3 or
build4 or not
build5 and not
build6
This is because then I will take the first for example and replace with
SomeTable.Name_Of_Build = 'build1' AND
SomeTable.Name_Of_Build = 'build2' AND .... so on
This works for me
\w+(\sand\snot|\sor\snot|\sand|\sor|$)
I might recommend that instead of using a regular expression to group the results you do something like this. I think it would be more robust than trying to guess at the right regex.
string filter = "build1 and buil2 and build3 or build4 or not build5"
list<string> filterTokens = filter.Split(new char[] {' '})
string gridViewFilter = "";
bool notEqual = false;
foreach(string token in filterTokens)
{
if(token == "and")
{
gridViewFilter += "and"
}
else if(token == "or")
{
gridViewFilter += "or"
}
else if(token == "not")
{
notEqual = true;
}
else if(notEqual)
{
gridViewFilter += "SomeTable.Name_Of_Build <> '" + token + "'";
notEqual = false;
}
else
{
gridViewFilter += "SomeTable.Name_Of_Build <> '" + token + "'";
}
}
Also, if you really want to implement a robust and full featured sort you need to look into using Reverse Polish Notation (RPN). It would allow you to handle parentheses and order of operations. An RPN implementation would look something like this.
private bool CheckForFilterMatch(string filter, List<string> values, bool exactMatch)
{
for (int i = 0; i < values.Count; i++)
{
values[i] = values[i].ToLower();
}
if (filter.Trim() == "")
{
return true;
}
List<string> rpn = GetPostFixNotation(filter);
Stack<bool> output = new Stack<bool>();
foreach (string token in rpn)
{
if (IsValue(token))
{
bool isMatch;
if (exactMatch)
{
isMatch = values.Contains(token.ToLower());
}
else
{
isMatch = false;
foreach (string value in values)
{
isMatch = (value.IndexOf(token.ToLower()) != -1);
if (isMatch) break;
}
}
output.Push(isMatch);
}
else if (IsOperator(token))
{
bool operand1 = output.Pop();
bool operand2 = output.Pop();
if (token == "&")
{
output.Push(operand1 && operand2);
}
if (token == "|")
{
output.Push(operand1 || operand2);
}
}
}
return output.Pop();
}
public List<string> GetPostFixNotation(string filter)
{
if (filter == "")
{
return new List<string>();
}
List<string> postFixNotation = new List<string>();
Queue<string> output = new Queue<string>();
Stack<string> operators = new Stack<string>();
List<string> parsedFilter = ParseFilterTokens(filter);
foreach (string token in parsedFilter)
{
if (IsValue(token))
{
output.Enqueue(token);
}
else if (IsOperatorNoParenth(token))
{
while (operators.Count > 0 && IsOperatorNoParenth(operators.Peek()))
{
if ((operators.Count > 0 && (Precedence(token) <= Precedence(operators.Peek()))))
{
string operatorToReturn = operators.Pop();
output.Enqueue(operatorToReturn);
}
else break;
}
operators.Push(token);
}
else if (token == "(")
{
operators.Push(token);
}
else if (token == ")")
{
while (operators.Count > 0 && operators.Peek() != "(")
{
output.Enqueue(operators.Pop());
}
operators.Pop();
}
}
while (operators.Count > 0)
{
output.Enqueue(operators.Pop());
}
while (output.Count > 0)
{
postFixNotation.Add(output.Dequeue());
}
return postFixNotation;
}
Try this regex out:
(build[^b]+)

runtime generated Checkbox validation

I have panel in the asp.net webpage, and i m generating the checkbox at runtime..
i want to validate checkbox, required field validator when form submit.
here is my code:
cv = new CustomValidator();
cv.ID = "cv" + "_" + dt.Rows[0]["RefQueID"].ToString();
cv.ValidationGroup = "grp";
cv.Display = ValidatorDisplay.None;
cv.ErrorMessage = "- Question " + intQuestionNo.ToString();
cv.ClientValidationFunction = "chkCount";
cv.Attributes.Add("rfvid", cv.ID.ToString());
//this portion of code is for custom validation javascript function
StringBuilder sb = new StringBuilder();
sb.Append("<script type='text/javascript'> function chkCount(sender,args) { ");
sb.Append(" args.IsValid = GetChk(document.getElementById('ctl00_ContentPlaceHolder1_" + cbl.ID.ToString() + "'))");
sb.Append(" } </script>");
Page page = HttpContext.Current.Handler as Page;
page.RegisterStartupScript("_Check", sb.ToString());
and in my javascript function i return this:
function GetChk(chkbox, args) {
if (!isConfirmed) {
alert('hi');
var chkBoxList = document.getElementById(chkbox.ClientID);
var chkBoxCount = chkBoxList.getElementsByTagName("input");
for (var i = 0; i < chkBoxCount.length; i++) {
if (chkBoxCount[i].checked == true) {
return true;
}
}
return false;
}
return true;
}
but i m not getting the value of the checkbox...
required value:=
ctl00_ContentPlaceHolder1_tc_hospital_improvement_features_tp_Reflection_cbl_116_0
Actual Value:=
ctl00_ContentPlaceHolder1_tc_hospital_improvement_features_tp_complete_stage_chk_confirm
pls help...
first get the runtime generated control into the codebehind file from class file.
and then secondly after getting the control property, we can validate the checbox list.
Get the control into codebehind file from class file.
CheckBoxList cbl = (CheckBoxList)pnlref.FindControl("cbl_116");
provide the javascript validation to the runtime generated checkbox list.
function GetChk(chkbox, args) {
if (!isConfirmed) {
var chkBoxList = document.getElementById('ctl00_ContentPlaceHolder1_tc_hospital_improvement_features_tp_Reflection_cbl_116');
var chkBoxCount = chkBoxList.getElementsByTagName("input");
for (var i = 0; i < chkBoxCount.length; i++) {
if (chkBoxCount[i].checked == true) {
return true;
}
}
return false;
}
return true;
}

composite control accessing javascript functions

I am creating a composite control, that implements IScriptControl.
in CreateChildControls() function i have this:
HtmlGenericControl ul = new HtmlGenericControl("ul");
HtmlGenericControl b2 = new HtmlGenericControl("li");
b2.Style["background-image"] = string.Format("url({0})", imageSrc);
b2.Style["list-style"] = "none";
b2.Style["background-repeat"] = "no-repeat";
b2.Style["background-position"] = "center center";
b2.Style["border-style"] = "none";
b2.Style["width"] = "20px";
b2.Style["height"] = "20px";
b2.Style["float"] = "left";
b2.InnerHtml = " ";
b2.Attributes["onmouseover"] =
b2.Attributes["onmouseout"] =
ul.Controls.Add(b2);
barContainer.Controls.Add(ul);
What I need is to set
b2.Attributes["onmouseover"]
and
b2.Attributes["onmouseout"]
attributes for Javascript functions that are defined in Prototype Model.
ProjectW.Edition.prototype = {
.
.
.
MouseOver: function(ctrl)
{
DoWork...
},
MouseOut: function(ctrl)
{
DoWork...
},
If this is needed:
#region IScriptControl Implementation
protected virtual IEnumerable<ScriptReference> GetScriptReferences()
{
ScriptReference reference = new ScriptReference();
reference.Assembly = "ProjectW";
reference.Name = "ProjectW.EditonScripts.js";
return new ScriptReference[] { reference };
}
protected virtual IEnumerable<ScriptDescriptor> GetScriptDescriptors()
{
ScriptControlDescriptor descriptor = new ScriptControlDescriptor("ProjectW.Edition", this.ClientID);
descriptor.AddProperty(....);
);
return new ScriptDescriptor[] { descriptor };
}
IEnumerable<ScriptReference> IScriptControl.GetScriptReferences()
{
return GetScriptReferences();
}
IEnumerable<ScriptDescriptor> IScriptControl.GetScriptDescriptors()
{
return GetScriptDescriptors();
}
#endregion
UPDATE:
The html elements that generated inside CreateChildControls dynamically - on runtime.
Why you are using simple HTMLControls in combination with CompositeControl? If the control makes from these simple tags. Thus, use WebControl instead. Somthing like this.
public override void RenderContents(HtmlTextWriter writer)
{
writer.RenderBeginTag(HtmlTextWriterTag.Ul);
writer.AddStyleAttribute(HtmlTextWriterStyle.BackgroundImage, "...");
.
.
.
writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID + "_Foo");
writer.RenderBeginTag(HtmlTextWriterTag.Li);
writer.Write(" ");
writer.RenderEndTag();
writer.RenderEndTag();
base.RenderControl(writer);
}
Adding event handler in ASP.NET Ajax Enabled controls has some simple differences. You should add a unique id to the target tag. And add the event to that like bellow.
ProjectW.Edition.prototype = {
initialize: function()
{
base.callBaseMethod(this, "initialize");
$addHandlers($get(this.get_id() + "_Foo"), "mouseover", Function.createDelegate(this, MouseOver));
}
dispose: function()
{
base.callBaseMethod(this,"dispose");
$removeHandler($get(this.get_id() + "_Foo"), "mouseover", Function.createDelegate(this, MouseOver));
}
MouseOver: function(ctrl)
{
DoWork...
},
MouseOut: function(ctrl)
{
DoWork...
}
}

Resources