2014 - Development Simply Put

A blog simplifies main concepts in IT development and provides tips, hints, advices and some re-usable code. "If you can't explain it simply, you don't understand it well enough" -Albert Einstein

  • Development Simply Put

    If you can't explain it simply, you don't understand it well enough.

    Read More
  • Integrant

    Based in the U.S. with offshore development centers in Jordan and Egypt, Integrant builds quality custom software since 1992. Our staff becomes an extension of your team to eliminate the risks of software development outsourcing and our processes...

    Read More
  • ITWorx

    ITWorx is a global software professional services organization. Headquartered in Egypt, the company offers Portals, Business Intelligence, Enterprise Application Integration and Application Development Outsourcing services to Global 2000 companies.

    Read More
  • Information Technology Institute

    ITI is a leading national institute established in 1993 by the Information and Decision Support Centre.

    Read More

2014-09-17

How To Develop/Adjust ASP.NET User Controls For Multiple Instances Support




When developing ASP.NET user controls you should keep in mind whether they need to support multiple instances feature or not. In other words, you should decide if more than one instance of your user control could be added on the same page. Why do you need to make up your mind on this? ...... wait and see.


Code Sample
You can download the code sample from here


Assume that you need to develop a user control which is simply a text box and a clear button. Once the clear button is clicked the text inside the text box should be cleared. Also, our user control should support multiple instances feature.

We will create the solution as in the image below.


Here we have two approaches to implement our user control; a BAD approach which will cause some issues as we will see and another GOOD approach which will work perfectly. So we will start with the bad approach to fully understand why we need the good one.


Bad Approach

TextWithClear.ascx:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TextWithClear.ascx.cs" Inherits="DevelopmentSimplyPut.MultiInstanceUserControl.Controls.TextWithClear" %>

<script type="text/javascript" src="../Scripts/jquery-1.11.0.min.js"></script>

<div style="border-color:red;border-width:thin;border-style:solid;width:20%;">
    <input id="txt_MyTextBox" name="txt_MyTextBox" type="text" value="" />
    <br />
    <input id="btn_Clear" type="button" value="Clear" onclick = "Clear();" />
</div>

<script type="text/javascript">
    function Clear() {
        $("#txt_MyTextBox").val("");
    }
</script>

Home.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Home.aspx.cs" Inherits="DevelopmentSimplyPut.MultiInstanceUserControl.Home" %>

<%@ Register Src="~/Controls/TextWithClear.ascx" TagPrefix="uc1" TagName="TextWithClear" %>


<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <uc1:TextWithClear runat="server" id="TextWithClear1" />
        <br />
        <uc1:TextWithClear runat="server" id="TextWithClear2" />
    </div>
    </form>
</body>
</html>


After running the application, we will get the image below.


As we can see both text boxes have the same id. Clicking the "Clear" button of the first instance will cause the first text box to be cleared as in the image below.


Unfortunately clicking the "Clear" button of the second instance also causes the first text box (not the second text box) to be cleared as in the image below.


This happened as both text boxes have the same id, so the javascript code selecting the text boxes by id will always return the first one only and then apply the clear action. That is why clicking the "Clear" button of both user control instances will always clear the first text box.

This is the time to try the good approach.


Good Approach

TextWithClear.ascx:
<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="TextWithClear.ascx.cs" Inherits="DevelopmentSimplyPut.MultiInstanceUserControl.Controls.TextWithClear" %>

<script type="text/javascript" src="../Scripts/jquery-1.11.0.min.js"></script>

<div id="MainContainer" runat="server" style="border-color:red;border-width:thin;border-style:solid;width:20%;">
    <input id="txt_MyTextBox" name="txt_MyTextBox" type="text" value="" />
    <br />
    <input id="btn_Clear" type="button" value="Clear" onclick = "GetCurrentTextWithClearControlManager<%= this.ClientID %>().Clear();" />
</div>

<script type="text/javascript">
    function TextWithClearControlManager(_controlClientId) {
        this.ControlClientId = _controlClientId;
        this.GetMainContainerDomElement = function GetMainContainerDomElement() {
            return $("div[id^=" + this.ControlClientId + "][id$=MainContainer]").eq(0);
        };
        this.Clear = function Clear() {
            this.GetMainContainerDomElement().find("#txt_MyTextBox").val("");
        };
    }

    function GetCurrentTextWithClearControlManager<%= this.ClientID %>() {
        return new TextWithClearControlManager('<%= this.ClientID %>');
    }
</script>

Home.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Home.aspx.cs" Inherits="DevelopmentSimplyPut.MultiInstanceUserControl.Home" %>

<%@ Register Src="~/Controls/TextWithClear.ascx" TagPrefix="uc1" TagName="TextWithClear" %>


<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <uc1:TextWithClear runat="server" id="TextWithClear1" />
        <br />
        <uc1:TextWithClear runat="server" id="TextWithClear2" />
    </div>
    </form>
</body>
</html>


After running the application, we will get the image below.


As we can see both text boxes have the same id but each outer container div of each user control has its own unique id which is composed from the id of the user control and the static id which was given to the div. Clicking the "Clear" button of the first instance will cause the first text box to be cleared as in the image below.


Now clicking the "Clear" button of the second instance causes the second text box to be cleared as in the image below.


This is good news but what really happened here?

Steps
  1. Wrapped our user control into a main container DOM element or used an already existing one as in our case here
  2. Gave it an id which is "MainContainer" in our case
  3. Marked it as a server control by adding "runat="server""
  4. Added a javascript function which acts as a constructor for a manager object. This manager object is user control instance related. It controls and serves only the user control instance whose client id is passed to its constructor
  5. Inside this manager object we defined a function called "GetMainContainerDomElement" which is responsible for returning the main container DOM element of its corresponding user control. In our case here it returns the outer "MainContainer" div of corresponding user control
  6. Also inside this manager object we defined the clear function but this time we make use of the "GetMainContainerDomElement" function to focus on the current outer div of the user control corresponding to the current manager object. Then, we select the proper text box which is a child of this main div, not another div. This way we make sure that all actions will be applied on the corresponding user control instance without affecting any other instances
  7. Created the function whose name is composed of "GetCurrentTextWithClearControlManager" followed by the client id of the user control. This is to make sure that the function "GetCurrentTextWithClearControlManager" of all user control instances will not replace and overwrite each other as they are finally on the same page. This function is used to return the manager object of each user control instance to be used inside DOM elements tags. In our case we used it as follows "onclick = "GetCurrentTextWithClearControlManager<%= this.ClientID %>().Clear();""
Now each "Clear" button accesses its corresponding manager object and fires the right "Clear" function.


That's it. Hope this will help you someday.
Good luck.



2014-06-21

How To Access ASP.NET Web.config AppSettings On Client-Side Javascript



You can download the code presented into this post from here


There are many ways by which you can access your ASP.NET web application web.config application settings through your client-side javascript code. The common thing between all of these ways is that to do so you for sure need to access the server-side.

The most proper way I prefer is to load all your application settings in a batch the first time your page is loaded and I think the best practice here is to use a handler to achieve this task. The handler will be responsible for accessing the web.config and retrieving all the application settings keys and their corresponding values and finally returning the response as a javascript file to be loaded once the handler is requested.

This way all what you have to do is to include the handler as a javascript resource on your page or master page then once the page is loaded you will have all your application settings as javascript variables.

Let's have a look on the code below to see what I am talking about.



Web.config
<?xml version="1.0"?>

<!--
  For more information on how to configure your ASP.NET application, please visit
  http://go.microsoft.com/fwlink/?LinkId=169433
  -->

<configuration>
    <system.web>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>

  <appSettings>
    <add key="SampleSetting" value="This is the setting value"/>
  </appSettings>
  
</configuration>

ClientGlobalVars.ashx.cs
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Web;
using System.Web.SessionState;
using System.Collections.Specialized;

namespace DevelopmentSimplyPut.Handlers
{
    public class ClientGlobalVars : IHttpHandler, IRequiresSessionState 
    {
        public void ProcessRequest(HttpContext context)
        {
   context.Response.ClearHeaders();
   context.Response.ContentType = "application/x-javascript";
   context.Response.Cache.SetCacheability(HttpCacheability.Public);
   context.Response.CacheControl = Convert.ToString(HttpCacheability.Public);
            context.Response.Write("var AppSettings = new Object();\n");

            NameValueCollection appSettings = ConfigurationManager.AppSettings;

            for (int i = 0; i < appSettings.Count; i++)
            {
                string key = appSettings.GetKey(i);
                string value = appSettings.Get(i);
                context.Response.Write(string.Format(CultureInfo.InvariantCulture, "AppSettings.{0} = '{1}';\n", key, value));
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

ClientGlobalVars.ashx
<%@ WebHandler Language="C#" CodeBehind="ClientGlobalVars.ashx.cs" Class="DevelopmentSimplyPut.Handlers.ClientGlobalVars" %>

Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="AccessAppSettingsFromJs.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script type="text/javascript" src="/Handlers/ClientGlobalVars.ashx"></script>

    <script>
        alert(AppSettings.SampleSetting);
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    </div>
    </form>
</body>
</html>

So now once you open Default.aspx in a web browser you get the result in the image below.



That's it. You can now access your application settings from client-side javascript.


2014-06-16

Paging Concept - The Main Equations To Make It Easy




The paging concept is used in many fields that it is even used in our daily lives. When you have a set of items and you want to divide them equally between some sort of containers or groups, you are thinking of paging but may be you don't recognize it.

The aim of this post is to explain some mathematical equations which can make it easy for you to implement the paging concept. If you are expecting to find explanations for the paging concept on specific applications like operating systems memory management or file system or whatever, then you are reading the wrong article.

The best way to explain paging is to apply on an example. Let's assume that we have a collection of 10 items and we want to divide these 10 items into groups where each group contains 3 items.

If we apply the calculations manually, we will have the items distributed as in the image below.


This was easy as the items count is not that big but this is not always the case. Also, we need to come up with the mathematical operation or equation which can be used to carry out the paging task automatically or through code.

After some analysis you will find that the mathematical relation will end up as in the image below.


The equation states that when we divide the "Item Index" on "Page Size", we get the "Page Index" and the remainder will be the "Item Index Per Page". Let's apply this mathematical equation on the example we have on hand right now.


When we divided "Item Index = 2" (Third item) on "Page Size = 3" we got "Page Index = 0" and "Item Index Per Page = 2". This means that the third item is the third item on the first page.

Also, when we divided "Item Index = 3" (Fourth item) on "Page Size = 3" we got "Page Index = 1" and "Item Index Per Page = 0".  This means that the fourth item is the first item on the second page.

Also, when we divided "Item Index = 7" (Eighth item) on "Page Size = 3" we got "Page Index = 2" and "Item Index Per Page = 1".  This means that the eighth item is the second item on the third page.

Also, when we divided "Item Index = 9" (Tenth item) on "Page Size = 3" we got "Page Index = 3" and "Item Index Per Page = 0".  This means that the tenth item is the first item on the fourth page.


So, we can transform the equation into the shape below:

Item Index = (Page Index * Page Size) + Item Index Per Page


This means that if we have a value for "Page Index" and a value for "Page Size" and we need to know the index of the first item and the last item on this page we can use the equation above as follows.

First Item Index = (Page Index * Page Size) + Min Item Index Per Page
                             = (Page Index * Page Size) + 0
                             = (Page Index * Page Size)

Last Item Index = (Page Index * Page Size) + Max Item Index Per Page
                            = (Page Index * Page Size) + (Page Size - 1)

But note that if the calculated "Last Item Index" is greater than the index of the last item in the whole collection, then take the smaller number which is the index of the last item in the whole collection.


To verify the equations above let's apply on the example we have on hand.

On the first page, (first item index = 0 * 3 = 0) and (last item index = (0 * 3) + (3 - 1) = 2)
On the second page, (first item index = 1 * 3 = 3) and (last item index = (1 * 3) + (3 - 1) = 5)
On the third page, (first item index = 2 * 3 = 6) and (last item index = (2 * 3) + (3 - 1) = 8)
On the fourth page, (first item index = 3 * 3 = 9) and (last item index = (3 * 3) + (3 - 1) = 11 which is greater than the max available item index (9), therefore, last item index = 9)


That's it, as you can see these equations can make your life much easier.
Goodbye.


2014-01-13

For SQL Hierarchical Data, How To Show Only Tree Branches Including Certain Type Of Entities And Discard Others



SQL Hierarchical Data

If you have a tree of entities represented into a SQL database into parent-child relation as in the image above, you may need to be able to view only the tree branches which include a certain type of entities
and discard the branches which don't include this type.

For example, let's have a look on the tree above and assume that we need to show only the branches which include the "J" type of entities. For this to happen, then we need to transfer the above tree into the one below.

SQL Hierarchical Data

How to do this in SQL?
To be able to answer this question, we first need to know how our mind does it. Our mind does a lot of processing and computing in an efficient way which makes us think that it is so easy, but is it that easy?

Assume that we have these types of entities in our tree.


And the real entities instances in our database are as in the image below.


Which means that our entities are in the tree form as in the image below.


Now, let's assume that we need to view only the tree branches including the "J" type. To do this manually just by a piece of paper and a pen, we look at the leaf entities in the tree. By leaf I mean the entities which have no children. Then, up from there we trace each branch and if a branch doesn't include a "J", we erase this branch till we finally get the final tree.

To do this in a more systematic approach, we can first locate our leaf entities. Then, we go up one level for each one of the leaf entities, then another one level up and so on till we reach the top of the tree. This could be illustrated as in the table below.


As you can see, we first started with the leaf entities and it took us five iterations to reach the top most of the tree. But why do we need to do that?

We did that because we already know the sequence of the system entities types, for example we know that if the leaf entity of a branch is "T", then this branch will not have a "J" as "J" comes after "T". So, we needed to trace back each branch to decide which branch to keep and which to discard.

Does that mean that every branch doesn't end with "J" should be completely deleted up to the top of the tree? No, as you can see in our tree above, there is a branch which ends with "T4", we are sure that this branch will not include a "J" but if we delete this branch up to the "C" entity, we will lose "P2" which has valid "J" children.

So, to get it right you can think of it as a voting system. Each entity in the tree should vote on whether its parent should be kept or no. Finally, we sum the voting on each parent and know if at least one child needs this parent, if not, we can discard this parent without any problems or loosing any valid branches.

So, each entity of the leaf entities should already know if its parent should be kept or not, so in our example, if the leaf entity is a "J", then its parent should be voted a "1". But if the leaf entity is a "S" or "T" or "P" or "C" then the parent should be voted a "0".

So, this leads us to the result in the image below.


Now, we need to sum the votes of each entity to know which entities to keep and which to discard. After doing the summation, we will get the result as in the image below.


So, to make sure the logic we applied here is valid, let's return to the tree diagram and highlight the entities which got a sum of "0" votes. These entities are decided by all child entities to be useless and disposable.

SQL Hierarchical Data

Are these the entities we can delete from the tree to make sure every branch includes a "J" entity? Yes, those are the ones and by deleting them we get the final tree as in the image below.


So, now we are sure that the logic we applied is valid but can we apply this complex logic in SQL?

Applying the same logic in SQL

--Creating the Entities table.
--This table contains the main entities in the system with
--their internal parent-child relations.
DECLARE @Entities AS Table
(
 Id INT
 , Name NVARCHAR(100)
 , ParentId INT
)

--Inserting entites into the @Entities table
INSERT INTO @Entities
(
 Id
 , Name
 , ParentId
)
VALUES
(1, 'Company', NULL)
, (2, 'Project Leader', 1)
, (3, 'Team Leader', 2)
, (4, 'Senior', 3)
, (5, 'Junior', 4)



--Creating the AggregatedEntities table.
--This table contains each main entity and its children
--recursively down to the end of the tree.
DECLARE @AggregatedEntities AS Table
(
 EntityId INT
 , EntityName NVARCHAR(100)
 , ChildId INT
)

;WITH AggregatedEntitiesTVP(EntityId, EntityName, ChildId) AS
(
 SELECT Parent.Id AS EntityId
 , Parent.Name AS EntityName
 , Child.Id AS ChildId
 FROM @Entities AS Parent
 
 INNER JOIN @Entities AS Child
 ON Child.ParentId = Parent.Id

 UNION 

 SELECT Parent.Id AS EntityId
 , Parent.Name AS EntityName
 , Parent.Id AS ChildId
 FROM @Entities AS Parent

 UNION ALL

 SELECT AggregatedEntitiesTVP.EntityId AS EntityId
 , AggregatedEntitiesTVP.EntityName AS EntityName
 , Entities.Id AS ChildId
 FROM AggregatedEntitiesTVP
 
 INNER JOIN @Entities AS Entities
 ON (Entities.ParentId = AggregatedEntitiesTVP.ChildId)
)

INSERT INTO @AggregatedEntities
(
 EntityId
 , EntityName
 , ChildId
)
SELECT DISTINCT EntityId
, EntityName
, ChildId
FROM AggregatedEntitiesTVP
ORDER BY EntityId, ChildId



--Creating AllEntities table.
--This table includes the created instances of the
--main entities.
DECLARE @AllEntities AS Table
(
 Id INT
 , Name NVARCHAR(100)
 , ParentId INT
 , TypeId INT
)

INSERT INTO @AllEntities
(
 Id
 , Name
 , ParentId
 , TypeId
)
VALUES
(1, 'C', NULL, 1)
, (2, 'P1', 1, 2)
, (3, 'P2', 1, 2)
, (4, 'T1', 2, 3)
, (5, 'T2', 2, 3)
, (6, 'T3', 2, 3)
, (7, 'T4', 3, 3)
, (8, 'T5', 3, 3)
, (9, 'S1', 4, 4)
, (10, 'S2', 4, 4)
, (11, 'S3', 5, 4)
, (12, 'S4', 6, 4)
, (13, 'S5', 6, 4)
, (14, 'S6', 8, 4)
, (15, 'S7', 8, 4)
, (16, 'J1', 10, 5)
, (17, 'J2', 10, 5)
, (18, 'J3', 11, 5)
, (19, 'J4', 11, 5)
, (20, 'J5', 14, 5)
, (21, 'J6', 14, 5)



--Declaring a variable to hold the required ensured entity type
--Each branch in the tree should include this entity type, otherwise,
--the whole branch will be excluded from the final result
DECLARE @EnsuredEntityType AS NVARCHAR(10)
SET @EnsuredEntityType = 'Junior'



;WITH EnsuredEntityTree(Id, Name, ParentId, Voting) AS
(
 --Strating with the leaf entities on the tree as the seed
 SELECT parent.Id
 , parent.Name
 , parent.ParentId
 , CASE
 WHEN 
 (
 parent.TypeId IN (SELECT ChildId FROM @AggregatedEntities WHERE EntityName = @EnsuredEntityType)
 ) THEN 1
 ELSE 0 END AS Voting
 FROM @AllEntities AS parent
 
 LEFT OUTER JOIN @AllEntities AS children
 ON children.ParentId = parent.Id
 
 WHERE children.Id IS NULL

 UNION ALL

 SELECT parent.Id
 , parent.Name
 , parent.ParentId
 , et.Voting --the same voting from the original seed object
 FROM @AllEntities AS parent
 INNER JOIN EnsuredEntityTree AS et
 ON et.ParentId = parent.Id
)



SELECT DISTINCT Id, Name, ParentId
FROM EnsuredEntityTree
GROUP BY Id, ParentId, Name
HAVING SUM(Voting) > 0


Finally, I hope you find this useful someday.
Good luck.