Saturday, September 17, 2011

Client side custom validator in repeator control


Hi All,
Today I used custom validator inside a repeator and since this was first time I used this I thought to share it here.
 Scenario: I was having a repeator with two textboxes per row (one for installment amount and other for installment duration) and I was supposed to implement a client side validation that will force user to insert value in duration textbox, if he inserts value in amount textbox.
The code that I came up with was some-what like below:

Repeator was like this:

                  Payment
                    <%#(((RepeaterItem)Container).ItemIndex+1).ToString() %>:
                    <asp:TextBox ID="txtPaymentPlanAmount" runat="server" />    Due In
                   
                    <asp:TextBox ID="txtPaymentPlanDuration" runat="server" />
                    <asp:CustomValidator ID="cvPaymentPlanDuration" runat="server" ValidationGroup="PricingPlanValidator"
                        Display="Dynamic" CssClass="errMsg" EnableClientScript="true" Text="*" ErrorMessage="You have set the amount but not duration." ClientValidationFunction="PaymentPlanDurationValidator":CustomValidator>
                    <asp:DropDownList ID="ddlPaymentPlanDuration" runat="server">
                   
<asp:DropDownList>
                div>
 ValidationGroup="PricingPlanValidator" />
  
And validator method was like this:

<script type="text/javascript">
function PaymentPlanDurationValidator(sender, args) {
            var id = sender.id;
            var amountTextBoxName = id.replace("cvPaymentPlanDuration", "txtPaymentPlanAmount");
            var durationTextBoxName = id.replace("cvPaymentPlanDuration", "txtPaymentPlanDuration");

            var amountTextBox = document.getElementById(amountTextBoxName);
            var durationTextBox = document.getElementById(durationTextBoxName);

            if (amountTextBox.value) {
                  if (durationTextBox.value) {
                        args.IsValid = true;
} else {
                        args.IsValid = false;
}
                  else {
args.IsValid = true;
                  }
            }

script>

This method is called automatically by custom validator for each row. Here I replaced textbox ids with custom validator id to get runtime clientside name of textboxes (as in highlighted code lines) and the rest is simple javascript logic.

args.IsValid, this lets validator know that wether or not current row satisfies the desired condition.

Thursday, July 7, 2011

The world is built on C++

Hi All,

"The world is built on C++", Herb Sutter

I am not a C++ developer but found below news to be interesting. This also created a question in my mind, how much these changes can accelerate growth of C++ usage, keeping in mind the current status of its rivals (Java, C#, etc). Please spare a few minutes to share your views on my question here.

Apple's Mac OS X, Adobe Illustrator, Facebook, Google's Chrome browser, the Apache MapReduce clustered data-processing architecture, Microsoft Windows 7 and Internet Explorer, Firefox, and MySQL – to name just a handful – are written in part or in their entirety with C++.

According to Sutter, C++ is on the verge of its biggest change in the 13 years since it became an official ISO standard, a change that will make it relevant for the next two decades.

The recently finished C++ ISO standard, with the working name of C++0x, is due to be published this summer, following the finishing touches to the ISO spec language and standards wonks agreed upon in March.

If you have read so far you might also like to have a look at this article from where I got this information and words ;)


Saturday, July 2, 2011

Row level client side operation on asp.net gridview

Hi All,

Last weekend while helping one of my friends on his project, I needed to perform row level client side operation on asp.net gridview. Firstly I googled for finding something similar to “formulae in excel” for asp gridview. When I failed to find something good I decided to go with javascript to perform client side operation on individual gridview rows.

My scenario was of invoice sheet generation, where need was of addition of rows(one for each product selected) dynamically and then perform some calculation like displaying row wise total. On click of Add button new record for item selected in drop down is added(this is done from server side code). Here user can enter values in any of the textboxes. And system has to update values in Total Excessible Value column text box(see image below) accordingly.

For this I wrote two plain javascript functions and called them on onchange event of textbox. Below are grid view and jquery code that I used.

(Click to enlarge)

GridView that I used was below:

<asp:GridView ID="gdvInvoiceItems" runat="server" AutoGenerateColumns="False" ShowHeader="true"
        OnRowCommand="gdvInvoiceItems_RowCommand">
        <EmptyDataTemplate>
            No items added yet.
        EmptyDataTemplate>
        <Columns>
            <asp:TemplateField HeaderText="S No.">
                <ItemTemplate>
                    <%# Container.DataItemIndex + 1 %>
                    <asp:HiddenField ID="hdnItemId" runat="server" Value='<%# Eval("Id") %>' />
                ItemTemplate>
            asp:TemplateField>
            <asp:TemplateField HeaderText="Description of Goods" ItemStyle-CssClass="description">
                <ItemTemplate>
                    <asp:TextBox ID="txtDescription" runat="server" Text='<%# Eval("Description") %>'
                        CssClass="txtDescStyle">asp:TextBox>
                ItemTemplate>
            asp:TemplateField>
            <asp:TemplateField HeaderText="Quantity(Net)" ItemStyle-CssClass="quantity">
                <ItemTemplate>
                    <asp:TextBox ID="txtQuantity" runat="server" Text='<%# Eval("Quantity") %>' onchange="javascript:Multiply(this, this.value)">asp:TextBox>
                ItemTemplate>
            asp:TemplateField>
            <asp:TemplateField HeaderText="Value Per Unit" ItemStyle-CssClass="value">
                <ItemTemplate>
                    <asp:TextBox ID="txtValue" runat="server" Text='<%# Eval("PerUnitValue") %>' onchange="javascript:Multiply(this, this.value)">asp:TextBox>
                ItemTemplate>
            asp:TemplateField>
            <asp:TemplateField HeaderText="Total Exesible Value" ItemStyle-CssClass="exesiblevalue">
                <ItemTemplate>
                    <asp:TextBox ID="txtTotalExeValue" runat="server" Text='<%# Eval("Total") %>' CssClass="TotalExeValue">asp:TextBox>
                ItemTemplate>
            asp:TemplateField>
            <asp:TemplateField>
                <ItemTemplate>
                    <asp:LinkButton ID="lnkBtnRemove" runat="server" Text="Remove" ItemStyle-CssClass="remove">
                    asp:LinkButton>
                ItemTemplate>
            asp:TemplateField>
        Columns>
    asp:GridView>

JavaScript code used:

<script type="text/javascript">
      //This method is called when quantity/cost textbox looses focus with some change in content
      function Multiply(element, val)
      {
          var otherElementName = '';
          var finalElementName = '';
         
          //id of calling element i.e, quantity/cost textbox
          var elementName = element.id;
         
        //get second element, i.e., get quantity if change is in cost and vice-versa
          if(endsWith(elementName, "txtQuantity"))
          {
              otherElementName = elementName.replace("txtQuantity", "txtValue");
          }
          else if(endsWith(elementName, "txtValue"))
          {
              otherElementName = elementName.replace("txtValue", "txtQuantity");
          }    
          var otherElement = document.getElementById(otherElementName);
         
          //get textbox where final value is to be displayed
        finalElementName = elementName.replace("txtValue", "txtTotalExeValue")         
          var finalElement = document.getElementById(finalElementName);
          finalElement.value = otherElement.value * val;
      }
     
      //checks if given string ends with given suffix
      function endsWith(str, suffix) {
        return str.indexOf(suffix, str.length - suffix.length) !== -1;
    }

    script>

Highlighted lines onchange="javascript:Multiply(this, this.value)" are the one that are doing the magic. This onchange event doesn't comes in intellisense but it works.

Saturday, June 25, 2011

Page_Load getting called twice

Hi All,

While working on one of my assignments past week I faced a strange problem. The problem was that my Page_Load event handler was getting called twice for apparently no reason. I was absolutely stumped. Then after a bit of trouble shooting and hit & trial, I found that the problem was a image tag.

My page gets post backed twice only in scenarios when source attribute's value of image control was rendering empty. So I just arranged a no image url in cases when there was no actual image url and got rid of my problem.

Similar problem I also faced a few months back, at that time I was working with link button. Then I was using link button for redirect user to some other page on link click. At that time I solved my problem by using hyperlink control in place of link button control.

Both these cases were, more or less magical for me ;)

I shared with you how I got my problem solved but if you know why was this problem occurring then kindly spare a few minutes to share it here. One more thing in both of these cases I was working on DNN.

Monday, June 20, 2011

Creating a DNN skin object

Hi All,

Below is a demonstration of how to create a DNN skin object. I’ll demonstrate this by creating a skin object that will display total number of users in your dnn site. Here we go:
Ø      Create a new project with template type “DotNetNuke Compiled Module”. Some other project type like class library project might also do but this one is easiest to start with.
Ø      I created a new project with name “CurrentUsersInfoSkinObject” and then cleaned it up by deleting all of the files from it, except below:
o       ViewCurrentUsersInfoSkinObject.ascx
o       ViewCurrentUsersInfoSkinObject.ascx.cs
o       App_LocalResources/ ViewCurrentUsersInfoSkinObject.ascx.resx
o       CurrentUsersInfoSkinObject.dnn
Ø      SkinObjects inherit from SkinObjectBase so change line
o       partial class ViewCurrentUsersInfoSkinObject : PortalModulebase
o       to
o       partial class ViewCurrentUsersInfoSkinObject : SkinObjectBase
Ø      Now add a literal control to ascx page, like below:
o       <asp:Literal ID="litUsersCount" runat="server" Mode="PassThrough" EnableViewState="false">asp:Literal>
o       pay attention on Mode and EnableViewState property.
Ø      Add one line to the resource file as below. This will serve as the base string to be shown in skin object.


Ø      Now place three lines of code in code behind file of view control.
o       string templateText = Localization.GetString("UsersCountDisplayTemplate", Localization.GetResourceFile(this, _myFileName));
o       templateText = templateText.Replace("[USERSCOUNT]", UserController.GetUsers(PortalSettings.PortalId).Count.ToString());
o       litUsersCount.Text = templateText;
o       In above three lines, first line reads resource file to get source string. Second line replaces placeholder [USERCOUNT] with number of users and set literal control to show this value.
Ø      Now just build this project, place dll in bin folder of your DNN installation.
Ø      Now place ascx and resource file in desktop modules folder, I placed these as shown in below image.

Ø      Now go to your dnn skin file. For me it was at,
Portals\_default\Skins\MinimalExtropy\ index leftmenu 1024.ascx
Ø      Add a line to register your newly added control. Like

<%@ Register TagPrefix="dnn" TagName="ViewCurrentUsersCount" src="~/DesktopModules/SkinObjects/ViewCurrentUsersInfoSkinObject.ascx" %>
Ø       Now add a line to place it at your desired place in skin. I placed it along with login control, like below:
<dnn:ViewCurrentUsersCount runat="server" id="UserCount" />
Ø      That’s all that you need to do to see your first skin object working.

Monday, May 23, 2011

Display DNN user profile properties in column format

Hi All,

A few days back in one of the DNN portals that I manage I was required to provide functionality to download user info including user profile properties in column format. Initially what I did was using DNNs built in API for getting users and then iterate through their profile properties by using UserInfo.Profile.ProfileProperties

This worked fine initially but once the number of users started growing, this started tooking great deal of time and ultimately started timing out. So I thought that I should design my own procedure for doing this and hence I came up with below solution. Probably this may save a few hours of your time.


            SELECT u.UserID, u.Username,
            upo2.PropertyValue as [ContactType],
upo3.PropertyValue AS [Title],
upo4.PropertyValue AS [FirstName],
            upo5.PropertyValue AS [LastName],
upo6.PropertyValue  AS [Position],
UPO7.PropertyValue  AS [Company],
UPO8.PropertyValue  AS [MembershipPeriod], UPO9.PropertyValue  AS [MembershipJoinDate],
UPO10.PropertyValue  AS [MembershipExpiryDate], UPO11.PropertyValue  AS [Address1],
            UPO12.PropertyValue  AS [Address2],
UPO13.PropertyValue  AS [Address3],
UPO14.PropertyValue  AS [Town],
            UPO15.PropertyValue  AS [County],
UPO16.PropertyValue  AS [Post Code],
UPO17.PropertyValue  AS [Country],
            UPO18.PropertyValue  AS [MainPhone],
UPO19.PropertyValue  AS [AlternativePhone],
            UPO20.PropertyValue  AS [Email],
UPO21.PropertyValue  AS [MembershipNumber]

            FROM Users u

            LEFT OUTER JOIN UserProfile UPO1
            ON upo1.UserID = u.UserID AND upo1.PropertyDefinitionID = 394

            LEFT OUTER JOIN UserProfile UPO2
            ON upo2.UserID = u.UserID AND upo2.PropertyDefinitionID = 398

            LEFT OUTER JOIN UserProfile UPO3
            ON upo3.UserID = u.UserID AND upo3.PropertyDefinitionID = 393

            LEFT OUTER JOIN UserProfile UPO4
            ON upo4.UserID = u.UserID AND upo4.PropertyDefinitionID = 362

            LEFT OUTER JOIN UserProfile UPO5
            ON upo5.UserID = u.UserID AND upo5.PropertyDefinitionID = 364

            LEFT OUTER JOIN UserProfile UPO6
            ON upo6.UserID = u.UserID AND upo6.PropertyDefinitionID = 382

            LEFT OUTER JOIN UserProfile UPO7
            ON upo7.UserID = u.UserID AND upo7.PropertyDefinitionID = 381

            LEFT OUTER JOIN UserProfile UPO8
            ON upo8.UserID = u.UserID AND upo8.PropertyDefinitionID = 395

            LEFT OUTER JOIN UserProfile UPO9
            ON upo9.UserID = u.UserID AND upo9.PropertyDefinitionID = 396

            LEFT OUTER JOIN UserProfile UPO10
            ON UPO10.UserID = u.UserID AND UPO10.PropertyDefinitionID = 397

            LEFT OUTER JOIN UserProfile UPO11
            ON upo11.UserID = u.UserID AND UPO11.PropertyDefinitionID = 383

            LEFT OUTER JOIN UserProfile UPO12
            ON UPO12.UserID = u.UserID AND UPO12.PropertyDefinitionID = 384

            LEFT OUTER JOIN UserProfile UPO13
            ON UPO13.UserID = u.UserID AND UPO13.PropertyDefinitionID = 385

            LEFT OUTER JOIN UserProfile UPO14
            ON UPO14.UserID = u.UserID AND UPO14.PropertyDefinitionID = 386

            LEFT OUTER JOIN UserProfile UPO15
            ON UPO15.UserID = u.UserID AND UPO15.PropertyDefinitionID = 502

            LEFT OUTER JOIN UserProfile UPO16
            ON UPO16.UserID = u.UserID AND UPO16.PropertyDefinitionID = 391

            LEFT OUTER JOIN UserProfile UPO17
            ON UPO17.UserID = u.UserID AND UPO17.PropertyDefinitionID = 370

            LEFT OUTER JOIN UserProfile UPO18
            ON UPO18.UserID = u.UserID AND UPO18.PropertyDefinitionID = 392

            LEFT OUTER JOIN UserProfile UPO19
            ON UPO19.UserID = u.UserID AND UPO19.PropertyDefinitionID = 388

            LEFT OUTER JOIN UserProfile UPO20
            ON UPO20.UserID = u.UserID AND UPO20.PropertyDefinitionID = 389

            LEFT OUTER JOIN UserProfile UPO21
            ON UPO21.UserID = u.UserID AND UPO21.PropertyDefinitionID = 399

In above query, numbers in red are PropertyDefinitionIds for respective profile properties. You will need to change these numbers as per your database. To get PropertyDefinitionID, you can use below query in your dnn database.

select * from profilepropertydefinition where portalid= order by propertyName

Take special care of PortalId while retrieving propertiesDefinitionIds as their can be several versions of profile property, i.e., one for each portal.

About Me

My photo
Delhi, India
Fun, music, travel and nature loving, always smiling, computer addict!!