Page 1 of 1

How to use PageHelper.SetMaxLengthCountDown on OPC Ship Msg

Posted: Tue Mar 23, 2010 5:41 pm
by ZLA
We're using the OPC ShipMessage field as our gift message with AC 7.0.2. I copied the count and label field (255 characters remaining) from the ShipMethodPage conlib and created the following.

Markup:

Code: Select all

<table cellpadding="0" cellspacing="4" >
 <tr>
   <th class="rowHeader">
     <asp:Label ID="ShipMessageLabel" runat="server" Text="Gift Message:" SkinID="FieldHeader"></asp:Label>&nbsp;&nbsp;
     <p style="font-weight: normal;">
        <asp:Label ID="ShipMessageCount"  runat="server" Text="255" ></asp:Label>
        <asp:Label ID="ShipMessageHelp"  runat="server" Text=" characters remaining" ></asp:Label>
     <p>
   </th>
   <td>
     <asp:TextBox ID="ShipMessage" runat="server" Text="" MaxLength="255" 
       TextMode="MultiLine" Columns="20" Rows="3"></asp:TextBox>
   </td>
 </tr>
</table>
Added to Page_PreRender:

Code: Select all

        SetGiftMessageLength();
where SetGiftMessageLength is as follows:

Code: Select all

   private void SetGiftMessageLength()
   {
      foreach (RepeaterItem item in ShipmentList.Items)
      {
         if (item.ItemType == ListItemType.AlternatingItem || item.ItemType == ListItemType.Item)
         {
            Control msgBox = item.FindControl("ShipMessage");
            Control msgBoxLbl = item.FindControl("ShipMessageCount");
            if (msgBox != null && msgBoxLbl != null)
            {
               PageHelper.SetMaxLengthCountDown(msgBox as TextBox, msgBoxLbl as Label);
               ((Label)msgBoxLbl).Text = Convert.ToString(Convert.ToInt16(((Label)msgBoxLbl).Text) - Convert.ToInt16(((TextBox)msgBox).Text.Length));
            }
         }
      }
   }
(I also tried calling this routine immediately after each ShipmentList.ItemDataBound call with the same effect.)

The message textbox does have onkeyup="return checkLength(this, 255, document.getElementById('ctl00_wpm_CheckoutPage_ctl01_ShipmentList_ctl00_ShipMessageCount'))" added to it. But nowhere on the page is the javascript function checkLength defined.

Since this worked on the multiple destination page, I haven't figured out why the checkLength script isn't being registered on the page. Can anyone spot my error? Thank you.

Re: How to use PageHelper.SetMaxLengthCountDown on OPC Ship Msg

Posted: Wed Mar 24, 2010 4:47 am
by jmestep
It's in the PageHelper.cs in the App_Code folder.

Code: Select all

public static void SetMaxLengthCountDown(TextBox inputControl, WebControl counter)
    {
        StringBuilder script = new StringBuilder();
        script.Append(("<script language=\"javascript\">\r\n"));
        script.Append(("<!--\r\n"));
        script.Append("function checkLength(tb, maxChars, counter) {\r\n");
        script.Append("if ((isNaN(maxChars) == true) || (maxChars <= 0)) return;\r\n");
        script.Append("var charCount = tb.value.length;\r\n");
        script.Append("if (charCount > maxChars) tb.value = tb.value.substr(0, maxChars);\r\n");
        script.Append("var charsLeft = (maxChars - charCount);\r\n");
        script.Append("if (charsLeft < 0) charsLeft = 0;\r\n");
        script.Append("if (counter) {\r\n");
        script.Append("if (document.all) counter.innerText = charsLeft;\r\n");
        script.Append("else counter.textContent = charsLeft;\r\n");
        script.Append("}}\r\n");
        script.Append(("// -->\r\n"));
        script.Append(("</script>\r\n"));
        inputControl.Attributes.Add("onkeyup", "return checkLength(this, " + inputControl.MaxLength.ToString() + ", document.getElementById('" + counter.ClientID + "'))");
        inputControl.Page.ClientScript.RegisterClientScriptBlock(string.Empty.GetType(), "checkLength", script.ToString());
    }

Re: How to use PageHelper.SetMaxLengthCountDown on OPC Ship Msg

Posted: Wed Mar 24, 2010 7:55 am
by ZLA
Hi Judy. I had seen that code and it's definitely being called since the onkeyup attribute is added to the control. But for some reason, the client script block with the function definition doesn't appear in the rendered html.

One thing I noticed is there is a javascript warning that "Empty string passed to getElementById()." without any source line number. This doesn't happen during multiple destination checkout. I've verified that the counter.ClientID is correct for the counter control. One difference is that the counter and textbox are in separate table cells but that wouldn't cause the script registration to fail.

There's only a single shipment so it can't be the register script block being called twice (which is safe anyway).

Please let me know if you have other suggestions.

Re: How to use PageHelper.SetMaxLengthCountDown on OPC Ship Msg

Posted: Wed Mar 24, 2010 8:11 am
by ZLA
I found a link (http://forums.asp.net/t/1295255.aspx) that says it may be an UpdatePanel issue. Since SetMaxLengthCountDown uses ClientScript.RegisterClientScriptBlock, it won't work. But using ScriptManager.RegisterClientScriptBlock may handle both update and non-update cases. I'll post what I find out.

Re: How to use PageHelper.SetMaxLengthCountDown on OPC Ship Msg

Posted: Wed Mar 24, 2010 8:20 am
by ZLA
:D

That was it! In PageHelper.cs, change

Code: Select all

inputControl.Page.ClientScript.RegisterClientScriptBlock(string.Empty.GetType(), "checkLength", script.ToString());
to

Code: Select all

ScriptManager.RegisterClientScriptBlock(inputControl.Page,string.Empty.GetType(), "checkLength", script.ToString(),false);
and then SetMaxLengthCountDown will work on pages with or without an UpdatePanel. This would probably apply anywhere in AC where ClientScript.RegisterClientScriptBlock is used.