Inherited listbox won't validate.

Discussion in 'ASP .Net Web Controls' started by Mark Bauer, Sep 28, 2004.

  1. Mark Bauer

    Mark Bauer Guest

    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>");
    }
    }
    }
    }
    Mark Bauer, Sep 28, 2004
    #1
    1. Advertising

  2. Mark Bauer

    Mark Bauer Guest

    I think I might have found the answer.. it seems to be the
    oList.onchange function being called in the javascript..
    Mark Bauer, Sep 28, 2004
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. James Hancock

    Inherited Page Won't Fire Postback Events

    James Hancock, Apr 5, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    447
    =?Utf-8?B?QmlsbCBCb3Jn?=
    Apr 8, 2004
  2. Richard Barnet

    Re: <wbr /> won't validate

    Richard Barnet, Jul 24, 2003, in forum: HTML
    Replies:
    0
    Views:
    392
    Richard Barnet
    Jul 24, 2003
  3. Richard Barnet

    Re: <wbr /> won't validate

    Richard Barnet, Jul 24, 2003, in forum: HTML
    Replies:
    2
    Views:
    478
    Nick Theodorakis
    Jul 25, 2003
  4. Nikolay Kurtov
    Replies:
    6
    Views:
    542
  5. 7stud --
    Replies:
    11
    Views:
    394
    7stud --
    Nov 9, 2007
Loading...

Share This Page