Thursday, July 26, 2012

Changing color in Repeater with an HTML Table

<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1" OnItemDataBound="Repeater1_ItemDataBound"  >

      <HeaderTemplate>
        <table>
          <tr><th>Title</th><th>Title ID</th><th>Type</th><th>Publisher ID</th><th>Price</th></tr>
      </HeaderTemplate>

      <ItemTemplate>

        <tr id="Tr1" runat="server">
          <td>
            <asp:Label ID="lblTitle" runat="server" Text='<%# Eval("title") %>' />
          </td>
          <td>
           <asp:Label ID="lbltitle_id" runat="server" Text='<%# Eval("title_id") %>' />
            <%# Eval("title_id") %>
          </td>
          <td>
         <asp:Label ID="lbltype" runat="server" Text='<%# Eval("type") %>' />

          </td>
          <td>
           <asp:Label ID="lblpub_id" runat="server" Text='<%# Eval("pub_id") %>' />
       
          </td>
          <td>
          <asp:Label ID="lblprice" runat="server" Text='<%# Eval("price")%>' />       

          </td>
        </tr>

      </ItemTemplate>
        <SeparatorTemplate>
                        <tr> <td colspan="5" ><hr size="10" style="background-color:Azure;" /></td></tr>
       </SeparatorTemplate>

      <FooterTemplate> </table> </FooterTemplate>
      </asp:Repeater>


codebehind :

protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
    {    

        if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
        {
            foreach (Control c in e.Item.Controls)
            {
                if (c is System.Web.UI.HtmlControls.HtmlTableRow)
                {                                    
                   
                    HtmlTableRow tr = (HtmlTableRow)c;
                    foreach (Control c1 in tr.Controls)
                    {
                     
                        Label mylabel = (Label)c1.FindControl("lblprice");

                        if (mylabel != null)
                        {
                            if (Convert.ToDecimal(mylabel.Text) >20)
                            {
                                tr.BgColor = "Red";

                            }
                        }      
                    }
                }
            }
        }
    }

FancyBox not work in UpdatePanel

ปัญหาที่พบ
เวลาเรานำ FancyBox เข้ามาใช้ใน Web Page ของเรา เราจะต้องทำการเรียกคำสั่ง $("a").fancybox(); ที่ $(document).ready(function() { .. } เพื่อ initialize FancyBox ซึ่ง Web เราก็จะสวยงามตามประสา

แต่นรกมาเยือนเมื่อเราเขียน web app บน asp.net โดยใช้ "ASP.NET AJAX Control Toolkit" และใช้ Component "UpdatePanel" มาครอบไว้ที่ GridView มันจะทำให้ web page ของเราสามารถ send request แบบ asynchronous ได้ (พูดง่าย ๆ คือ page จะไม่แว๊บ เวลา server control ทำงาน) เช่น กดปุ่ม delete บน GridView แล้วเขียน Code ให้ Refresh GridView ผลที่ได้คือ page จะไม่แว๊บเลย แต่ถ้าใน GridView มี link ไปยังรูปภาพที่เป็น FancyBox มันจะไม่ทำงาน (คือ FancyBox ไม่ขึ้น จะเป็นการ Link โดยเปิดรูปภาพเฉย ๆ)

สาเหตุ
ทุกครั้งที่มีการเรียก asynchronous ผ่าน AJAX Control Toolkit มันจะ refresh ใหม่ทุกครั้งเพียงแต่เราไม่เห็น และการ Refresh Page แบบพิเศษนี้แหละที่ทำให้ jQuery ไม่สามารถจับ event $(document).ready(...) ได้

การแก้ปัญหา
เราก็แค่สั่ง initialize FancyBox ใหม่อีกครั้ง เมื่อมีการทำ Asynchronous Operation โดยเพิ่ม java script function ดังต่อไปนี้ (โดยของเดิมก็ยังคงไว้) ..
  1. function pageLoad(sender, args) {  
  2.    if (args.get_isPartialLoad()) {  
  3.       $("a").fancybox();
  4.    }  
  5. }  

Friday, July 20, 2012

CustomValidator - returns false but form submits anyway

I think this has bitten me a couple of times now.  If you implement a CustomValidator with server side validation in ASP.Net, then you set args.IsValid to true if the validation passes or to false if the validation fails.  But even if you return false, the form continues the submit process anyway!

The trick is that when you set args.IsValid, that sets a flag in the Page class called Page.IsValid, and you still need to check that Page.IsValid flag somewhere in your form processing.  For example, I check it in my button click handler and just return from the method if Page.IsValid is false.  The error message that you set for your CustomValidator will then be displayed.

I should mention that the post that got me part of the way to figuring this out was on Egghead Cafe, but it lacked example code and the actual property name.  Here is some example code of using this process to limit the file size on an asp:FileUpload control using a CustomValidator with server side validation.

.aspx file
...

<asp:FileUpload runat="server" ID="uplResume" />
<asp:CustomValidator ID="FileSizeValidator" runat="server" ControlToValidate="uplResume"
ErrorMessage="File size should not be greater than 2 MB." OnServerValidate="FileSizeValidator_ServerValidate"></asp:CustomValidator>
...

.aspx.cs file
...

    protected void FileSizeValidator_ServerValidate(object source, ServerValidateEventArgs args)
    {
        int fileSize = uplResume.FileBytes.Length;
        if (uplResume.FileBytes.Length > 2 * MEGABYTES)
        {
            args.IsValid = false;
        }
        else
        {
            args.IsValid = true;
        }
    }


    protected void btnSubmit_Click(object sender, EventArgs e)
    {
        if (!Page.IsValid)
        {
            return;
        }
        // do processing for valid form here
    }



ref : http://kcwebprogrammers.blogspot.com/2011/02/customvalidator-returns-false-but-form.html

Using the CustomValidator’s ClientValidationFunction

You can use the CustomValidator by just implementing the OnServerValidate event, but any other validation controls that are validated client side will need to be valid before the CustomValidator will be used.  Doing this causes a postback to validate the CustomValidator and as it’s not client side the validation message will not be shown in a ValidationSummary.
Here is a CustomValidator to validate that a checkbox is checked:
<asp:customvalidator errormessage="You must agree." id="cvTerms" onservervalidate="cvTerms_ServerValidate" runat="server">
</asp:customvalidator>

Usually with validators you would set the ControlToValidate property to the ID of the control you want to validate, but this doesn’t work for a checkbox, so I will explicitly reference the checkbox in the event handler:
protected void cvTerms_ServerValidate(object source, ServerValidateEventArgs args)
{
    args.IsValid = cbTerms.Checked;
}


ServerValidateEventArgs has two properties; IsValid and Value.  IsValid is set in the handler depending on if the checkbox is checked.  Value is not used here due to not setting the ControlToValidate property.  If the ControlToValidate property was set to a TextBox, then args.Value would be the text value from the TextBox.
This all works nicely, but it would be good to do this validation client side, also allowing the error to show in a ValidationSummary.  To do this I have created a JavaScript function to do the client side validation:
function cvTerms_ClientValidate(source, args)
{
    args.IsValid = document.getElementById('<%= cbTerms.ClientID %>').checked;
}


I also need to set the ClientValidationFunction property of the CustomValidator to the name of my JavaScript function.
In JavaScript args works very much in the same way as it does in C#.  I am setting args.IsValid based on whether the checkbox is checked.
Now validation will work at client side, and if JavaScript is disabled, the server side event handler will be used.  Below is another simple example that ensures a TextBox contains no more than 1000 words.
ASP
<asp:CustomValidator ID="cvText"
                     ControlToValidate="txtText"
                     runat="server"
                     ErrorMessage="Your text is over 1000 words."
                     OnServerValidate="cvtext_ServerValidate"
                     ClientValidationFunction="cvText_ClientValidate" />


C#
protected void cvText_ServerValidate(object source, ServerValidateEventArgs args)
{
    string[] numOfWords = args.Value.Split(new char[] { ' ' });
    args.IsValid = numOfWords.Length <= 1000;
}

JavaScript
function custStory_ServerValidate(source, args)
{
    var numOfWords = args.Value.split(" ");
    args.IsValid = numOfWords.length <= 1000;
}
ref : http://www.joe-stevens.com/2009/08/12/using-the-customvalidators-clientvalidationfunction/

Wednesday, July 18, 2012

XmlTextWriter Formating UTF8 , Newline and Indent

private void ReadConfig()
        {
            string xFile = @"C:\PIH\PIHPharmacy\";
            string strFilename = "PIHPharmacy.cfg";
            XmlDocument xmlStartupFile = new XmlDocument();

            if (!File.Exists(Path.Combine(xFile, strFilename)))
            {
                //initialize the Xml Text Writer
                XmlTextWriter xmlWriter = new XmlTextWriter(Path.Combine(xFile, strFilename), Encoding.UTF8);
                xmlWriter.Formatting = Formatting.Indented;
                xmlWriter.Indentation = 4;

                xmlWriter.WriteStartDocument(true);
                xmlWriter.WriteComment("Developed by : Siriroj IT Team ");
                xmlWriter.WriteStartElement("PIHMedicineLable"); //Root Element    

                xmlWriter.WriteStartElement("mServerName");
                xmlWriter.WriteString("PIH-INTRANET\\SQLEXPRESS"); //Attribute Value          
                xmlWriter.WriteEndElement(); //End of dbName Element          

                xmlWriter.WriteStartElement("mDatabase");
                xmlWriter.WriteString("PIHPharmacyDBTest"); //Attribute Value          
                xmlWriter.WriteEndElement(); //End of dbName Element  

                xmlWriter.WriteStartElement("mUser");
                xmlWriter.WriteString("sa");
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("mPassword");
                xmlWriter.WriteString("siriroJ");
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("extServerName");
                xmlWriter.WriteString("192.168.0.121"); //Attribute Value          
                xmlWriter.WriteEndElement(); //End of dbName Element          

                xmlWriter.WriteStartElement("extDatabase");
                xmlWriter.WriteString("MAIN"); //Attribute Value          
                xmlWriter.WriteEndElement(); //End of dbName Element  

                xmlWriter.WriteStartElement("extUser");
                xmlWriter.WriteString("sa");
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("extPassword");
                xmlWriter.WriteString("ub!fighting#123");
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("reportPath");
                xmlWriter.WriteString(@"S:\Report\Pharmacy\");
                xmlWriter.WriteEndElement();

                xmlWriter.WriteStartElement("printerChecmoLabel");
                xmlWriter.WriteString(@"\\IPAddress\PrinterName");

                xmlWriter.WriteEndElement();

                xmlWriter.WriteEndDocument();
                xmlWriter.Flush();
                xmlWriter.Close();
            }
            XmlTextReader reader = new XmlTextReader("PIHPharmacy.cfg");
            while (reader.Read())
            {
                if (reader.NodeType == XmlNodeType.Element)
                {
                    if (reader.Name == "mServerName")
                    {
                        generalClass.xMainServer = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "mDatabase")
                    {
                        generalClass.xMainDBName = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "mUser")
                    {
                        generalClass.xMainUserId = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "mPassword")
                    {
                        generalClass.xMainPassword = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "extServerName")
                    {
                        generalClass.xExtServer = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "extDatabase")
                    {
                        generalClass.xExtDBName = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "extUser")
                    {
                        generalClass.xExtUserId = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "extPassword")
                    {
                        generalClass.xExtPassword = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "reportPath")
                    {
                        generalClass.xReportLocation = reader.ReadElementContentAsString();
                    }
                    if (reader.Name == "printerChecmoLabel")
                    {
                        generalClass.xPrinterChemoLabel = reader.ReadElementContentAsString();
                    }
                }
            }
            reader.Close();
        }

Monday, July 9, 2012

Right click to select a row in a Datagridview

        private void dgContDrugs_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                var hti = dgContDrugs.HitTest(e.X, e.Y);
                dgContDrugs.ClearSelection();
                dgContDrugs.Rows[hti.RowIndex].Selected = true;
                dgContDrugs.CurrentCell = dgContDrugs[hti.ColumnIndex, hti.RowIndex];
            }
        }
 or

  private void dgContDrugs_CellMouseDown_1(object sender, DataGridViewCellMouseEventArgs e)
        {
            if (e.RowIndex >= 0 && e.ColumnIndex >= 0 && e.Button == MouseButtons.Right)
            {
                dgContDrugs.CurrentCell = dgContDrugs[e.ColumnIndex, e.RowIndex];
            }
        }