Product Templates - Regular Expression Validation & Required

For general questions and discussions specific to the AbleCommerce 7.0 Asp.Net product.
Post Reply
ZLA
Commodore (COMO)
Commodore (COMO)
Posts: 496
Joined: Fri Mar 13, 2009 2:55 pm

Product Templates - Regular Expression Validation & Required

Post by ZLA » Wed May 27, 2009 10:02 pm

I've expanded upon existing forum code (viewtopic.php?f=42&t=7154&hilit=+required) to make customer fields required. I can now define regular expression validation for customer fields. I also added a small enhancement to the required fields validation.

Usage is documented within the code. Please note the following:
  • I changed the name of the required fields list variable (from requiredFieldsList to requiredFields) from that in the original link above so it would be consistent with the regexFields variable.
  • I made all text fields required by default since that matches my customer's products best.
  • You can use html in the validation message. For my customer, they can't enter two words in a text field unless they order a different product. So the validation message says "To enter two words, please order the <a href="Double-Word-Puzzle-P383.aspx">Double Word Puzzle</a>" and provides a link to the correct product.
Here are the changes to make for both enhancements:

In ProductHelper.cs BuildProductChoices,

Code: Select all

using System.Collections;

    // SG Customization - ZLA 2009-05-20 - Validate custom fields using Regular Expressions
    // 
    // Product Template Usage:
    //      Customer Field   : Text Box named 'Middle Name'
    //      Merchant Field 1 : Text Box named 'Regex2 Field', value of 'Middle Name'
    //      Merchant Field 2 : Text Box named 'Regex2 Expression', value of '^\w+$'
    //      Merchant Field 3 : Text Box named 'Regex2 Message', value of 'Middle name can not include spaces.'
    // - Note that Regex2 above can be anything that begins with Regex. 
    // - For example, 'Regex', 'Regex1', 'RegexA', 'RegexCat', 'RegexDog', etc.

    struct RegexFieldValidator
    {
        public string RegexField; 
        public string RegularExpression;
        public string ErrorMessage;

        public RegexFieldValidator(string regexField, string regularExpression, string errorMessage)
        {
            this.RegexField = regexField;
            this.RegularExpression = regularExpression;
            this.ErrorMessage = errorMessage;
        }
    }

    // SG Customization - ZLA 2009-05-20 - Validate all Text Boxes / Text Areas unless individual custom fields selected.
    // 
    // Product Template Usage:
    //      -- Scenario 1 --
    //      Merchant Field   : none
    //      Customer Field 1 : Text Box named 'First Name' - Required By default
    //      Customer Field 2 : Text Box named 'Last Name' - Required By default
    // 
    //      -- Scenario 2 --
    //      Merchant Field 1 : Text Box named 'Required Fields List', value of 'First Name,LastName'
    //      Customer Field 1 : Text Box named 'First Name' - Required
    //      Customer Field 2 : Text Box named 'Middle Initial' - Optional
    //      Customer Field 3 : Text Box named 'Last Name' - Required
    //
    //      -- Scenario 3 --
    //      Merchant Field 1 : Text Box named 'Required Fields List', value of '' (empty string)
    //      Customer Field 1 : Text Box named 'First Name' - Optional
    //      Customer Field 2 : Text Box named 'Middle Initial' - Optional
    //      Customer Field 3 : Text Box named 'Last Name' - Optional
    // - Note that 'Required Fields List' or 'RequiredFieldsList' will work. Match based on Name.replace(' ','')

    public static void BuildProductChoices(Product product, PlaceHolder phChoices)
    {
        // ADD IN THE PRODUCT TEMPLATE CHOICES
        ProductTemplate template = product.ProductTemplate;
        if (template != null)
        {
            // DETERMINE VALIDATOR FIELDS - PRE-PROCESSING
            bool RequireAllFields = true;
            ArrayList requiredFields = new ArrayList();
            Hashtable regexFields = new Hashtable();

            if (product != null)
            {
                foreach (ProductTemplateField tf in product.TemplateFields)
                {
                    if (tf.InputField.IsMerchantField)
                    {
                        // DETERMINE REQURIED FIELDS - empty value allowed
                        if (tf.InputField.Name.Replace(" ", "") == "RequiredFieldsList")
                        {
                            RequireAllFields = false;
                            if (!string.IsNullOrEmpty(tf.InputValue))
                            {
                                foreach (string fn in tf.InputValue.Split(",".ToCharArray()))
                                {
                                    requiredFields.Add(fn);
                                }
                            }
                        }
                        
                        // DETERMINE REGEX FIELDS - empty value ignored 
                        if (!string.IsNullOrEmpty(tf.InputValue) && 
                            tf.InputField.Name.StartsWith("Regex") && tf.InputField.Name.EndsWith(" Field"))
                        {
                            //Find all matching regex merchant fields
                            string regexField = tf.InputField.Name.Split(' ')[0];   // Extract RegexN from "RegexN Field"
                            string regexExpression = string.Empty;
                            string regexMessage = string.Empty;
                            foreach (ProductTemplateField rtf in product.TemplateFields)
                            {
                                if (rtf.InputField.Name.StartsWith("Regex") && rtf.InputField.Name.EndsWith(" Expression"))
                                {
                                    regexExpression = rtf.InputValue;
                                }
                                if (rtf.InputField.Name.StartsWith("Regex") && rtf.InputField.Name.EndsWith(" Message"))
                                {
                                    regexMessage = rtf.InputValue;
                                }
                                if (!string.IsNullOrEmpty(regexExpression) && !string.IsNullOrEmpty(regexMessage))
                                {
                                    RegexFieldValidator rgxfv = new RegexFieldValidator(regexField, regexExpression, regexMessage);
                                    regexFields.Add(tf.InputValue, rgxfv);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            
            foreach (InputField input in template.InputFields)
            {
                if (!input.IsMerchantField)
                {
                    // ADD THE CONTROL TO THE PLACEHOLDER
                    phChoices.Controls.Add(new LiteralControl("<tr><td colspan=\"2\">"));
                    phChoices.Controls.Add(new LiteralControl((input.UserPrompt + "<br />")));
                    WebControl o = input.GetControl();

                    if (o != null)
                    {
                        phChoices.Controls.Add(o);
                        if (input.InputType == InputType.TextBox || input.InputType == InputType.TextArea)
                        {
                            // REGEX FIELD VALIDATORS
                            if (regexFields.Contains(input.Name))
                            {
                                RegexFieldValidator rgx = (RegexFieldValidator)regexFields[input.Name];
                                RegularExpressionValidator rgxfv = new RegularExpressionValidator();
                                rgxfv.ID = "rgxfv" + input.InputFieldId.ToString();
                                rgxfv.ControlToValidate = o.ID;
                                rgxfv.Text = "*";
                                rgxfv.ErrorMessage = rgx.ErrorMessage;
                                rgxfv.ValidationGroup = "AddToBasket";
                                rgxfv.ValidationExpression = rgx.RegularExpression;
                                phChoices.Controls.Add(rgxfv);
                            }

                            // REQUIRED FIELD VALIDATORS
                            if (RequireAllFields || requiredFields.Contains(input.Name))
                            {
                              RequiredFieldValidator rfv = new RequiredFieldValidator();
                              rfv.ID = "rfv" + input.InputFieldId.ToString();
                              rfv.ControlToValidate = o.ID;
                              rfv.Text = "*";
                              rfv.ErrorMessage = "Please enter " + input.Name;
                              rfv.ValidationGroup = "AddToBasket";
                              phChoices.Controls.Add(rfv);
                            }
                        }
                    }

                    phChoices.Controls.Add(new LiteralControl("</td></tr>"));                
                }
            }
        }
    }
    // SG End Customization - ZLA 2009-05-20
In ProductCustomFieldsDialog.ascx.cs Page_PreRender, change

Code: Select all

                    if (!string.IsNullOrEmpty(tf.InputValue) && tf.InputField.IsMerchantField)
to

Code: Select all

                    if (!string.IsNullOrEmpty(tf.InputValue) && tf.InputField.IsMerchantField && 
                        !tf.InputField.Name.StartsWith("Regex") &&
                        tf.InputField.Name.Replace(" ", "") != "RequiredFieldsList")
In Conlib/Utility/OrderItemDetail.ascx.cs, add

Code: Select all

    // SG Customization - ZLA 2009-05-20 - prevent regular expression merchant fields from displaying
    OrderItemInputCollection _OrderItemInputCollection = new OrderItemInputCollection();
    //public OrderItemInputCollection OrderItemInputCollection
    //{
    //    get { return _OrderItemInputCollection; }
    //    set { _OrderItemInputCollection = value; }
    //}
    // SG End Customization - ZLA 2009-05-20
in the class properties section, say below the OrderItem _OrderItem; section. In Page_PreRender, change

Code: Select all

                //SHOW INPUTS
                if (_OrderItem.Inputs.Count > 0)
                {
                    InputList.DataSource = _OrderItem.Inputs;
                    InputList.DataBind();
                }
                else
to

Code: Select all

                //SHOW INPUTS
                if (_OrderItem.Inputs.Count > 0)
                {
                    // SG Customization - ZLA 2009-05-20 - prevent regular expression merchant fields from displaying
                    // SG Customization - ZLA 2009-05-20 - prevent required fields merchant field from displaying
                    foreach (OrderItemInput oii in _OrderItem.Inputs)
                    {
                        if (!oii.Name.StartsWith("Regex") && oii.Name.Replace(" ", "") != "RequiredFieldsList")
                        {
                            _OrderItemInputCollection.Add(oii);
                        }
                    }
                    InputList.DataSource = _OrderItemInputCollection;
                    InputList.DataBind();
                    // SG End Customization - ZLA 2009-05-20
                }
                else
If you're using custom conlibs, don't forget to update your user control sources to reflect this customizations: ProductDescription.ascx uses ProductCustomFieldsDialog.ascx.

Please let me know if you find this useful or have other comments. -- ZLA

ZLA
Commodore (COMO)
Commodore (COMO)
Posts: 496
Joined: Fri Mar 13, 2009 2:55 pm

Re: Product Templates - Regular Expression Validation & Required

Post by ZLA » Mon Jun 01, 2009 5:02 pm

I also had to modify the following:

Admin_UserControls_OrderItemDetail as follows:

Code: Select all

    // SG Customization - ZLA 2009-06-01 - prevent regular expression merchant fields from displaying
    OrderItemInputCollection _OrderItemInputCollection = new OrderItemInputCollection();

                //SHOW INPUTS
                if (_OrderItem.Inputs.Count > 0)                
                {
                    // SG Customization - ZLA 2009-05-20 - prevent regular expression merchant fields from displaying
                    // SG Customization - ZLA 2009-05-20 - prevent required fields merchant field from displaying
                    foreach (OrderItemInput oii in _OrderItem.Inputs)
                    {
                        if (!oii.Name.StartsWith("Regex") && oii.Name.Replace(" ", "") != "RequiredFieldsList")
                        {
                            _OrderItemInputCollection.Add(oii);
                        }
                    }
                    InputList.DataSource = _OrderItemInputCollection;
                    InputList.DataBind();
                    // SG End Customization - ZLA 2009-05-20
                }
Vendor Notification Email:

Code: Select all

#if ($orderItem.Inputs.Count > 0)
  #foreach( $input in $orderItem.Inputs )
    #if(!$input.Name.StartsWith("Regex") && $input.Name.Replace(" ", "") != "RequiredFieldsList")
      <strong>$input.Name</strong><strong>:</strong> 
      $input.InputValue
    #end
  #end
#end
-- ZLA

Post Reply