Inherited listbox won't validate.

M

Mark Bauer

I have a question, maybe someone can help.

I have some code for a Linked ListBox that won't validated clientside
with the .NET Validators. Are there any special things that need to
be done when you inherit a listbox in a web custom control to get it
validate??? Could the controls adding to the pages onload and onchange
events be causing the problem of the control not getting added to the
list of validators before it's changed by the onload event and then
fires the validatorchange even before the vals array is initialized???

Ok, so it starts out that I need a linked list box, so I do some
looking on the google and find a truely excellent article & control &
source at http://www.atgconsulting.com/dotnetlinkedlistbox.aspx

One of the things I love about .NET, lots of people are talking about
it.

So I go thru the tutor and implement the control (which is wonderful
for linked list boxes, and well explained), but when I try to use a
RequiredFieldValidator, it bombs in WebUIValidation.js

function ValidatorOnChange() {
var vals = event.srcElement.Validators;<<<== Link Breaks with here
Microsoft JScript runtime error: Object required error message
var i;
for (i = 0; i < vals.length; i++) {
ValidatorValidate(vals);
}
ValidatorUpdateIsValid();
}

Damn.. I do some fishing around, and figure it's something with the
control, I wrote the author and he wrote back in about 10 minutes
which was neat because it was about midnight his time and says..

"Yes, you're right, some other people have pointed that out as well
(including the person who did the vb.net implementation)."

"I'm not sure how to make the element automatically participate in a
validation, so for now I've been telling people to avoid adding these
elements to a dotnet validation scheme, and to just do some custom
scripting if you need it. If you figure something out, feel free to
share."

Damn.. I don't know much about .NET validation except how to use them.
So I head off and search up and down the net.

I find some stuff about an IVaildator, but that's for Validation
controls, not controls that need to be validated.

I find some stuff about ValidationPropertyAttribute, but the error I
get is not the error that people describe, plus the control inherits
from the ListBox control, so it should have that, and I can pick it
from the RequiredFieldValidator's ControlToValidate list.. so.. you
know.. that doesn't seem like it.

Anyway, I've spent about 4-5 hours or more learning and search
about validation, which is more time that it would have taken me to
write my own javascript validation for the page.

Can anyone help???

You can get the code at the link about, get it, goto step 9, add a
requiredfieldvalidator to either listbox or linkedlistbox.

Thanks!

Here's the code for the control.

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.Text;
using System.Data.SqlClient;
using System.Xml;
using System.Xml.Xsl;
using System.Xml.XPath;
using System.IO;
using System.Configuration;

namespace oodynlistbox
{
/// <summary>
/// Summary description for linkedListBox_ctl.
/// </summary>
[ToolboxData("<{0}:linkedListBox_ctl
runat=server></{0}:linkedListBox_ctl>")]
[ValidationProperty("SelectedValue")]
public class linkedListBox_ctl :
System.Web.UI.WebControls.ListBox
{
private string m_SourceName;
private string m_Table; //
this property names the table that is used to populate this cell.
private string m_ValueField; // this
property defines the field name that is used to populate the "value"
property of this cell.
private string m_TextField; //
this property defines the field name that is used to populate the
displayable "text" property of this cell.
private string m_SourceValue; // this
property defines the field name for the search value in the source
table.
private string m_SourceLink; // this
property defines the field name for the linking field into source
table.
private string m_DestLink; //
this property defines the field name for the destination table.
private string m_SourceTable; //if the
tablename for the linking table is different from the "Table"
property,
//this property names that table.
//private string m_ListStyle; //
setting the style for our contained listbox...
private string sSourceClientID;
private string m_InitialValue; // initial
value of this listbox
private string m_ConnectString; // the connect
string...
private string sThisClientID = "";

protected override void OnLoad(EventArgs e)
{
string sOutput = "";
sThisClientID = this.ClientID;
try
{
System.Web.UI.Control genericControl =
Page.FindControl(m_SourceName);
if (genericControl == null)
{
// no source control found?
sOutput += "<br><b>Error:</b>
No source control specified.<br>\n";
}
else if (genericControl is ListBox)
{
// the presumption is that any
HtmlSelect is a "top of chain"
// so we need to trigger its
onchange when the page loads

System.Web.UI.WebControls.ListBox lstSource = (ListBox)genericControl;
sSourceClientID =
lstSource.ClientID;

lstSource.Attributes["onchange"] +=
@"listboxItemSelected(this,null,this.form['" + sThisClientID + "']);";
if
(!Page.IsClientScriptBlockRegistered(sSourceClientID + "onload"))
{

Page.RegisterStartupScript(sSourceClientID + "onload", "<script
language='javascript'>\nwindow.onload=addCommandTo(window.onload,'document.forms[0][\""
+ sSourceClientID +

"\"].onchange();');\n</script>\n");
}
}
else if (genericControl is
DropDownList)
{
// the presumption is that any
HtmlSelect is a "top of chain"
// so we need to trigger its
onchange when the page loads

System.Web.UI.WebControls.DropDownList lstSource =
(DropDownList)genericControl;
sSourceClientID =
lstSource.ClientID;

lstSource.Attributes["onchange"] +=
@"comboItemSelected(this,null,this.form['" + sThisClientID + "']);";
if
(!Page.IsClientScriptBlockRegistered(sSourceClientID + "onload"))
{

Page.RegisterStartupScript(sSourceClientID + "onload", "<script
language='javascript'>\nwindow.onload=addCommandTo(window.onload,'document.forms[0][\""
+ sSourceClientID +

"\"].onchange();');\n</script>\n");
}
}
else if (genericControl is HtmlSelect)
{
// the presumption is that any
HtmlSelect is a "top of chain"
// so we need to trigger its
onchange when the page loads

System.Web.UI.HtmlControls.HtmlSelect lstSource =
(HtmlSelect)genericControl;
sSourceClientID =
lstSource.ClientID;
if (lstSource.Size == 1)
{

lstSource.Attributes["onchange"] +=
@"comboItemSelected(this,null,this.form['" + sThisClientID + "']);";
}
else
{

lstSource.Attributes["onchange"] +=
@"listboxItemSelected(this,null,this.form['" + sThisClientID + "']);";
}
if
(!Page.IsClientScriptBlockRegistered(sSourceClientID + "onload"))
{

Page.RegisterStartupScript(sSourceClientID + "onload", "<script
language='javascript'>\nwindow.onload=addCommandTo(window.onload,'document.forms[0][\""
+ sSourceClientID +

"\"].onchange();');\n</script>\n");
}
}
else if (genericControl is
linkedListBox_ctl)
{
oodynlistbox.linkedListBox_ctl
lstSource = (linkedListBox_ctl)genericControl;
sSourceClientID =
lstSource.ClientID;

lstSource.Attributes["onchange"] +=
@"listboxItemSelected(this,this.form['hdn" + lstSource.ClientID +
"'],this.form['" + sThisClientID + "']);";
}
else if (genericControl is
linkedDropDownList_ctl)
{

oodynlistbox.linkedDropDownList_ctl lstSource =
(linkedDropDownList_ctl)genericControl;
sSourceClientID =
lstSource.ClientID;

lstSource.Attributes["onchange"] +=
@"comboItemSelected(this,this.form['hdn" + lstSource.ClientID +
"'],this.form['" + sThisClientID + "']);";
}
else
{
sOutput += "<br><b>Error</b>:
Unable to find source control, unexpected control type.<br>";
}
addGenericClientScripts();
Page.RegisterHiddenField("hdn" +
sThisClientID, m_InitialValue);
this.Attributes["onchange"] +=
@"listboxItemSelected(this,this.form['hdn" + sThisClientID +
"'],null);";

Page.RegisterStartupScript(sThisClientID + "onload", "<script
language='javascript'>\nwindow.onload=addCommandTo(window.onload,'initListFromHidden(document.forms[0][\""
+
sThisClientID +
"\"],document.forms[0][\"hdn" + sThisClientID +
"\"]);');\n</script>\n");
if
(!Page.IsClientScriptBlockRegistered("complete"))
{

Page.RegisterStartupScript("complete", "<script
language='javascript'>\nwindow.onload=addCommandTo(window.onload,'vComplete
= true;');\n</script>\n");
}
}
catch (Exception er)
{
sOutput += "<br>Error opening
connection: " + er.ToString().Replace("\n", "<br>") + "<br>";
}
finally
{
if (sOutput.Length > 0)
{
Page.Response.Write(sOutput);
}
}
}
/// <summary>
/// Render this control to the output parameter
specified.
/// </summary>
/// <param name="output"> The HTML writer to write out
to </param>
protected override void Render(HtmlTextWriter output)
{
string sOutput = "";
try
{
SqlConnection mySqlConnection = new
SqlConnection(m_ConnectString);
try
{
mySqlConnection.Open();
// Put user code to initialize
the page here
DataSet myDataSet2 = new
DataSet();

string sQuery = @"SELECT
table1." + m_SourceValue + @" as search, table2." + m_ValueField + @"
as val, table2." + m_TextField + @" as display
FROM " + m_SourceTable + @" as table1, " + m_Table + @" as table2
WHERE table1." + m_SourceLink + "=table2." + m_DestLink + @"
ORDER BY search, display
FOR XML AUTO, XMLDATA";
// sOutput += "<pre>" + sQuery
+ "</pre>";
SqlCommand mySqlCommand2 = new
SqlCommand(sQuery, mySqlConnection);

mySqlCommand2.CommandTimeout =
15;

myDataSet2.ReadXml((XmlTextReader)mySqlCommand2.ExecuteXmlReader(),
XmlReadMode.Fragment);

myDataSet2.DataSetName =
"root";

XmlDocument doc = new
XmlDocument();

doc.LoadXml(myDataSet2.GetXml());

XslTransform trans = new
XslTransform();

trans.Load(Page.Server.MapPath("oodynlistbox.xslt"));
// the transform takes an
argument: the listbox name

System.Xml.Xsl.XsltArgumentList argList = new XsltArgumentList();

argList.AddParam("listboxname", "", sThisClientID + sSourceClientID);
StringWriter sWriter = new
StringWriter(new StringBuilder(null));
trans.Transform(doc, argList,
sWriter, new XmlUrlResolver());
string sScriptOutput =
sWriter.GetStringBuilder().ToString();
// oddly enough, the results
of the xsl transform include a
// line at the top that says
<?xml version="1.0" ?>
// -- which is a pita, imo: we
don't want it in our script output
// so let's strip it out
(huh... isn't there an easier way?):
sScriptOutput =
sScriptOutput.Remove(0, sScriptOutput.IndexOf("?>") + 2);
// write a display version of
the script on the page
//sOutput += "<pre>" +
sScriptOutput + "</pre>";
// write the script between
<script language='javascript'> tags...
if
(!Page.IsClientScriptBlockRegistered(sThisClientID + "array"))
{

Page.RegisterClientScriptBlock(sThisClientID + "array", "");
output.Write("<script
language='javascript'>\n" + sScriptOutput + "\n</script>");
}
}
catch (Exception er)
{
sOutput += "<br>Error: " +
er.ToString().Replace("\n", "<br>") + "<br>";
}
finally
{
mySqlConnection.Close();
}
}
catch (Exception er)
{
sOutput += "<br>Error opening
connection: " + er.ToString().Replace("\n", "<br>") + "<br>";
}
finally
{
if (sOutput.Length > 0)
{
output.Write(sOutput);
}
base.Render(output);
}
}
/// <summary>
/// this property names the table that is used to
populate this cell.
/// </summary>
public string Table
{
get
{
return m_Table;
}
set
{
m_Table = value;
}
}
/// <summary>
/// the name of the database field name in the
destination table used as the value of this listbox
/// </summary>
public string ValueField
{
get
{
return m_ValueField;
}
set
{
m_ValueField = value;
}
}
/// <summary>
/// the name of the database field name in the
destination table used as the displayable text
/// </summary>
public string TextField
{
get
{
return m_TextField;
}
set
{
m_TextField = value;
}
}
/// <summary>
/// the name of the database field name in the source
table used in the database link
/// </summary>
public string SourceLink
{
get
{
return m_SourceLink;
}
set
{
// if "SourceValue" hasn't been set
yet, default it to this value
if (m_SourceValue == null)
m_SourceValue = value;
m_SourceLink = value;
}
}
/// <summary>
/// this property defines the field name for the
search value in the source table.
/// (that is, the field that identifies the value parm
in the upstream listbox)
/// </summary>
public string SourceValue
{
get
{
return m_SourceValue;
}
set
{
m_SourceValue = value;
}
}
/// <summary>
/// the name of the linking field in the destination
table
/// </summary>
public string DestLink
{
get
{
return m_DestLink;
}
set
{
m_DestLink = value;
}
}
/// <summary>
/// the name of the database table where the
sourcelink and sourcevalue fields are found
/// </summary>
public string SourceTable
{
get
{
return m_SourceTable;
}
set
{
m_SourceTable = value;
}
}
public string InitialValue
{
get
{
return m_InitialValue;
}
set
{
m_InitialValue = value;
}
}
/// <summary>
/// the id of the upstream listbox control we're
linked to
/// </summary>
public String source
{
get
{
return m_SourceName;
}
set
{
m_SourceName = value;
}
}
/// <summary>
/// a database connect string to be used by this
control
/// </summary>
public string ConnectString
{
get
{
return m_ConnectString;
}
set
{
m_ConnectString = value;
}
}
/// <summary>
/// write out the required generic client-side scripts
if they haven't already been written
/// </summary>
private void addGenericClientScripts()
{
// this sub writes out the generic client
scripts
// but only if they haven't been written yet
if
(!Page.IsClientScriptBlockRegistered("linkedListBox_generic"))
{

Page.RegisterClientScriptBlock("linkedListBox_generic", @"
<script language='javascript'><!--
var vComplete = false;
function comboItemSelected(oList1,oHidden,oList2){
if (vComplete && oHidden){
if (oList1.selectedIndex <= 0){
oHidden.value='';
} else {

oHidden.value=oList1.options[oList1.selectedIndex].value;
}
}
if (oList1 && oList2!=null){
clearComboOrList(oList2);
if (oList1.selectedIndex <= 0){
oList2.options[oList2.options.length] = new
Option('Please make a selection from the list', '');
} else {
fillCombobox(oList2, oList2.id + oList1.id +
'=' + oList1.options[oList1.selectedIndex].value);
}
}
}
function listboxItemSelected(oList1, oHidden, oList2){
if (vComplete && oHidden && oList1){
if (oList1.selectedIndex == -1){
oHidden.value = '';
} else {
oHidden.value =
oList1.options[oList1.selectedIndex].value;
}
}
if (oList1 && oList2){
clearComboOrList(oList2);
if (oList1.selectedIndex == -1){
oList2.options[oList2.options.length] = new
Option('Please make a selection from the list', '');
} else {
fillListbox(oList2, oList2.id + oList1.id +
'=' + oList1.options[oList1.selectedIndex].value);
}
}
}
function clearComboOrList(oList){
if (oList) {
oList.selectedIndex = -1;
for (var i = oList.options.length - 1; i >= 0; i--){
oList.options = null;
}
oList.selectedIndex = -1;
if (oList.onchange) oList.onchange();
}
}
function fillCombobox(oList, vValue){
if (oList) {
if (vValue != '') {
if (assocArray[vValue]){
oList.options[0] = new Option('Please make a
selection', '');
var arrX = assocArray[vValue];
for (var i = 0; i < arrX.length; i = i + 2){
if (arrX != 'EOF') {

oList.options[oList.options.length] = new Option(arrX[i + 1],
arrX);
}
}
if (oList.options.length == 1){
oList.options[0] = new Option('None
found', '');
} else if (oList.options.length == 2){
oList.selectedIndex=1;
}
} else {
oList.options[0] = new Option('None found',
'');
}
}
if (oList.onchange){
oList.onchange();
}
}
}
function fillListbox(oList, vValue){
if (oList) {
if (vValue != '') {
if (assocArray[vValue]){
var arrX = assocArray[vValue];
for (var i = 0; i < arrX.length; i = i + 2){
if (arrX != 'EOF')
oList.options[oList.options.length] = new Option(arrX[i + 1],
arrX);
}
if (oList.options.length == 1){
oList.selectedIndex = 0;
}
} else {
oList.options[0] = new Option('None found',
'');
}
}
if (oList.onchange) {
oList.onchange();
}
}
}
function setListToValue(oList, vValue){
if (oList) {
if (vValue && vValue != '') {
for (var i = 0; i < oList.options.length; i++){
if (oList.options.value == vValue){
oList.selectedIndex = i;
return;
}
}
}
oList.selectedIndex = -1;
}
}

function initListFromHidden(oList, oHidden){
if (oList && oHidden) {
setListToValue(oList,oHidden.value);
if (oList.onchange){
oList.onchange();
}
}
}
function addCommandTo(fAnon, sNewCommand){
var sScript;
if (fAnon){
sScript = new String(fAnon);
if (sScript.indexOf('{') > 0){
sScript =
sScript.substring(sScript.indexOf('{') + 1, sScript.lastIndexOf('}') -
1);
sScript += sNewCommand;
}
} else {
sScript = new String(sNewCommand);
}
return new Function(sScript);
}
//--></script>");
}
}
}
}
 
M

Mark Bauer

I think I might have found the answer.. it seems to be the
oList.onchange function being called in the javascript..
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,990
Messages
2,570,211
Members
46,796
Latest member
SteveBreed

Latest Threads

Top