Jan 11

Existing RequiredFieldValidator cannot validate CheckBoxList nor RadioButtonList control. Instead it raises exception: "Control 'checkBoxList' referenced by the ControlToValidate property of 'requiredFieldValidator' cannot be validated.". Writting custom validator is quite simple process. There is one important thing to be aware of. CustomValidator performs validation if controls Text property is set. Problem is that CheckBoxList and RadioButtonList Text property is always empty, Therefore we should first set validotars ValidateEmptyText property to true.

JavaScript to perform client side validation looks like:

function MyCode_ListControlRequiredValidation(source, args) {
	var listObj = document.getElementById(source.controltovalidate);
	var listObjInputs = listObj.getElementsByTagName('input');
	for(var i = 0; i < listObjInputs.length; i++) {
		if (listObjInputs[i].checked) {
			args.IsValid = true;
	args.IsValid = false;

For server side validation we should override ControlPropertiesValid and EvaluateIsValid methods. Detailed description can be found on MSDN site.

ListControlRequiredValidator.cs (1.61 kb)

Tags: |
Jan 09

Probably everybody have tried to use asp menu control. Control can be oriented in two ways:
- horizontal where dynamic content is expanded downwards
- vertical where dynamic content is expanded in right direction
Recently I've placed menu on a bottom of a page and wanted to expand upwards. None of the properties allows that kind of behaviour, I needed quick solution for the problem. Most of solutions found on net involves rewriting javascript method PopOut_Show. I don't want to mess with that code so I decided to write own expansion.

Let's look how menu control works. Static menu content is rendered with classic html table element. Dynamic content is placed in div element. When user moves mouse over table's cell then an iframe element is created and populated with dynamic content. To achieve upward expansion of menu we need to move up div and iframe elements. If we move up only one of those elements a region of white space shows up on a screen.

First thing we need to do is to find all static containers and change onmouseover event. These containers are html TD cells named {0}n{1} where {0} is menu ClientID and {1} is a sequential number starting with 0. We need to call existing method and then make correction of DIV (named {0}n{1}Items) and IFRAME (named {0}n{1}_MenuIFrame) element. Javascript which changes mouseover event looks like:

function MyCode_AspMenuUpwardExpandInit(menuId) {
	var i = -1;
	var menuTdObj = null; 
	do {
		menuTdId = menuId + 'n' + i;
		menuTdObj = WebForm_GetElementById(menuTdId);
		if (menuTdObj != null) {
			var mouseOverScript = menuTdObj.onmouseover + '';
			if (mouseOverScript.indexOf('Dynamic') < 0) {
				mouseOverScript = mouseOverScript.substring(mouseOverScript.indexOf('{') + 1, mouseOverScript.lastIndexOf('}'));
				var panelId = menuTdId + 'Items';
				var script = mouseOverScript + '; MyCode_AspMenuUpwardExpandCorrection(\'' + menuTdId + '\', \'' + panelId + '\');';
				menuTdObj.onmouseover = new Function(script);
	while(menuTdObj != null)

Javascript which moves up div panel and iframe:

function MyCode_AspMenuUpwardExpandCorrection(menuTdId, panelId) {
	var panel = WebForm_GetElementById(panelId);
	if (panel == null) return;
	var panelPos = WebForm_GetElementPosition(panel);

	var menuTdObj = WebForm_GetElementById(menuTdId);
	var menuTdObjPos = WebForm_GetElementPosition(menuTdObj);

	var childFrameId = panelId + '_MenuIFrame';
	var childFrame = WebForm_GetElementById(childFrameId);

	var newY = menuTdObjPos.y - panelPos.height;

	WebForm_SetElementY(panel, newY);
	WebForm_SetElementY(childFrame, newY);

To use this we need to call MyCode_AspMenuUpwardExpandInit function and pass it menu's ClientID property

<script type="text/javascript" language="javascript">
MyCode_AspMenuUpwardExpandInit(<%= cmsMenu.ClientID %>);

or you can use webcontrol (AspMenuUpwardExpand.cs (2.58 kb)):

<asp:Menu runat="server" ID="cmsMenu" Orientation="Horizontal" DataSourceID="xmlDataSource">
MyCode:AspMenuUpwardExpand ID="menuUpward" runat="server" MenuControl="cmsMenu" />

This solution works in IE8, FF3, Chrome. Didn't have time to check other browsers.

Tags: |