Saturday 17 March 2012

DYNAMICALLY CLONING HTML CONTROLS USING JQUERY



Here is a complete example and walkthrough for dynamically cloning a container that has a set of HTML controls.
I used jquery for scripting, so included the library reference in the head section.
<head> 
   <script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>

</head>
As for the body, let's add a button to open up our modal dialog.
<body>
...  
<div id="calc-se-buttons">
    <input type="button" value="Print" id="print" name="print" class="button" />
</div>
Let's now create a container that has the contents that we intend to clone. In this example, we will clone the container with the id print-input, . Assigning a style (print-input-style) to the container which we want to clone is important here, because later we will depend on style name while calculating the number of cloned elements that we currently have.
<div id="print">
    <br/>
    <div id="print-input-1" class="print-input-style" >
        <label for="modal-print-title-1">Title</label>&nbsp;
        <select name="modal-print-title-1" id="modal-print-title-1">
                <option value='Mr'>Mr</option>
                <option value='Miss'>Miss</option>
                <option value='Ms'>Ms</option>
                <option value='Mrs'>Mrs</option>
                <option value='Dr'>Dr</option>
                <option value='Fr'>Fr</option>
            </select>&nbsp;&nbsp;
        <label for="modal-print-name-1">First Name</label>&nbsp;
        <input name="modal-print-name-1" id="modal-print-name-1" type="text" size="6" />&nbsp;&nbsp;
        <label for="modal-print-surname-1">Last Name</label>&nbsp;
        <input name="modal-print-surname-1" id="modal-print-surname-1" type="text" size="6" />
        <br/>
    </div>
    <br/><br/>
    <div id="div-add-customer">
        <img id="add-customer" src="../images/add-more.gif" alt="Add New Customer" width="20" height="20" />
    </div>
</div>

Next, let's implement the jquery function that clones the print-input container and bind it to the add-customer button.
This function simply counts the current number of clonable elements, clones one of them and assigns an incremented number for each of the element ids. So, as new elements are added, main container ids go one after the other like print-input-1, print-input-2,.... The ids of the contained controls are also incremented accordingly.
There is a business rule to limit the number of added elements to 4. This is quite useful if you want to keep the size of your container consistent or limit the number of elements for some reason.



$(document).ready(function () {
  $('#add-customer').click(function () {
    // how many "duplicatable" input fields we currently have
    var num = $('.print-input-style').length;
    // the numeric ID of the new input field being added 
    var newNum = new Number(num + 1);      
        
    var currentContainerId = '#print-input-' + num;
 
    // create the new element via clone(), and manipulate it's ID using newNum
    var newElem = $(currentContainerId).clone().attr('id''print-input-' + newNum);
 
    // manipulate the name/id values of the input inside the new element
    $(currentContainerId).children('label').each(function (i) {
      var attrFor = $(this).attr('for');
      $(this).attr('for', attrFor.substring(0, attrFor.lastIndexOf("-") + 1) + newNum);
    });
    $(currentContainerId).children('select').each(function (i) {
      var attrId = $(this).attr('id');
      var attrName = $(this).attr('name');
      $(this).attr('id', attrId.substring(0, attrId.lastIndexOf("-") + 1) + newNum)
        .attr('name', attrName.substring(0, attrName.lastIndexOf("-") + 1) + newNum);
    });
    $(currentContainerId).children('input').each(function (i) {
      var attrId = $(this).attr('id');
      var attrName = $(this).attr('name');
      $(this).attr('id', attrId.substring(0, attrId.lastIndexOf("-") + 1) + newNum)
        .attr('name', attrName.substring(0, attrName.lastIndexOf("-") + 1) + newNum);
    });
 
    // insert the new element after the last "duplicatable" input field
    $(currentContainerId).after(newElem);
 
    // business rule: you can only add 4 names
    if (newNum == 4)
      $('#add-customer').attr('disabled''disabled');
    });
});

There, each time you hit the plus button (add-customer), the entire row is duplicated.
 

CREATING A SIMPLE & NICE MODAL POPUP USING JQUERY UI

Here is an example on how to implement a modal popup within HTML using the dialog feature of jQuery ui plugin giving hints about auto open option and a simple customization to achieve a nice dialog.
In the header, including jQuery library and jquery-ui library will be sufficient as preliminary. jQuery UI library can be downloaded from the following link, where there other good examples.


http://jqueryui.com/demos/dialog/

There is also the custom header class to be used in the dialog definition.


<head>
<script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.17.custom.min.js"></script>
<style type="text/css">
.ui-widget-header-custom 
{
    background-color#3D9700;
    color:White;
    font-weight:bold;
}
</style>


Next, let's place a button in the body to open the modal dialog.

<body>
...
<input type="button" value="Email" id="email" name="email" class="button" />
...

The following div in the body contains the content of the dialog box. It consists of a title, name, surname and email of a person.



<div id="modalEmail">
    <br/>
    <div id="modal-email-container">
        <label for="modal-email-address">Email</label>&nbsp;
        <input name="modal-email-address" id="modal-email-address" type="text" size="26" />
    </div>
    <br/><br/>
    <div id="modal-email-name-container" class="mail-input-style" >
        <label for="modal-email-title-1">Title</label>&nbsp;&nbsp;
        <select name="modal-email-title-1" id="modal-email-title-1">
                <option value='Mr'>Mr</option>
                <option value='Miss'>Miss</option>
                <option value='Ms'>Ms</option>
                <option value='Mrs'>Mrs</option>
                <option value='Dr'>Dr</option>
                <option value='Fr'>Fr</option>
            </select>&nbsp;&nbsp;&nbsp;
        <label for="modal-email-name">First Name</label>&nbsp;
        <input name="modal-email-name" class="customer-details" id="modal-email-name" type="text" size="6" />&nbsp;&nbsp;&nbsp;
        <label for="modal-email-surname">Last Name</label>&nbsp;
        <input name="modal-email-surname" class="customer-details" id="modal-email-surname" type="text" size="6" />
    </div>
</div>
Now comes the actual implementation of ui-dialog in jQuery. If the dialog is intended to be reused, the best way is to disable auto-open option and bind a button or event to open the dialog.
There are currently two buttons in our dialog, but you can add as many buttons and regarding functionalities as you wish.
See the implementation of custom header class, first removing the default and adding the class we initially defined in the HTML header.

var $dialog2 = $('#modalEmail')
.dialog({
  autoOpen: false,
  title: 'Email Details',
  modal: true,
  resizable: false,
  width: 380,
  height: 300,
  show: 'drop',
  buttons: [
  {
     text: 'Email',
     click: function () {
       var parameters = getPrintParams('email');
       emailForm(parameters);
       alert("Quote information PDF emailed succesfully.");
       $(this).dialog("close");
     }
  },
  {
     text: 'Cancel',
     click: function () { $(this).dialog("close"); }
  }
  ],
  open: function (event, ui) {
    $(this).parents(".ui-dialog:first").find(".ui-widget-header")
      .removeClass("ui-widget-header").addClass("ui-widget-header-custom");
    $('#modalEmail').css('overflow''hidden');
  }
});

The resulting dialog looks like the following:




Happy coding!

Saturday 4 February 2012

ENRICH ENUMS WITH ATTRIBUTES AND RETRIEVE VALUES GENERICALLY



Working on repayment frequency enumeration and its annual occurence,  I came up with the idea of implementing field attributes. Then found a good way to obtain the value of annual occurences which is embedded to the attribute. I implemented an enumeration extension to achieve this.

This is a neat and tidy way to enrich enumerations with custom attributes and get the values of these attributes by an enumeration extension.

The enumeration class:

namespace MyApplication.Domain.Enumerations
{
  public enum RepaymentFrequency
  {
     [AnnualOccurence(12)] 
     [DaysImplied(30)]
     Monthly, 

     [AnnualOccurence(52)] 
     [DaysImplied(7)]
     Weekly,
        ....
        ....
}


The custom attribute class for AnnualOccurence (it will be pretty much the same for DaysImplied):

using System;
 
namespace MyApplication.Domain.Enumerations
{
    [AttributeUsage(AttributeTargets.Field)]
    public class AnnualOccurence : Attribute
    {
        public static readonly short Unassigned = -1;
 
        public AnnualOccurence()
        {
            _numberOfAnnualRepayments = Unassigned;
        }
 
        private short _numberOfAnnualRepayments;
        public short NumberOfAnnualRepayments
        {
            get { return _numberOfAnnualRepayments;}
        }
 
        public AnnualOccurence(short numberOfOccurences)
        {
            _numberOfAnnualRepayments = numberOfOccurences;
        }
 
        public override string ToString()
        {
            return "Annual Occurence = " + _numberOfAnnualRepayments.ToString();
        }
    }
}
Now, there is a good way to get the values of such attributes from an 'enumeration instance', by implementing the following extension:

using System;
using System.Linq;
 
namespace HomeStart.LoanCalculators.Domain.Enumerations
{
    public static class EnumExtensions
    {
        public static Expected GetAttributeValue<T, Expected>
                      (this Enum enumeration, Func<T, Expected> expression)
            where T : Attribute
        {
         T attribute = enumeration.GetType().GetMember(enumeration.ToString())[0]
                            .GetCustomAttributes(typeof(T), false)
                               .Cast<T>().SingleOrDefault();
 
            if (attribute == null)
                return default(Expected);
 
            return expression(attribute);
        }
    }
}
 
with the following usage:  
 
RepaymentFrequency repaymentFrequency = repaymentFrequency.Weekly;
... 
var numberOfAnnualRepayments = 
                 repaymentFrequency.GetAttributeValue<AnnualOccurence, short>
                                            (x => x.NumberOfAnnualRepayments);
var numberOfDaysImplied =  
                 repaymentFrequency.GetAttributeValue<DaysImplied, short> 
                                            (x => x.NumberOfDaysImplied);
...


where 52 will be assigned to numberOfAnnualRepayments
and 7 will be assigned to numberOfDaysImplied in this case.


Thursday 2 February 2012

JAVASCRIPT AND JQUERY CHART LIBRARIES


There are many javascript / jquery based client side web graphic tools that can be used for various purposes. So many that it is hard to decide which one to pick.

I have looked into the most popular and useful ones and assessed them in detail, based on their features and other factors like compatibility, learning curve.


Remember, the best tool changes depends on your purpose, type & size of chart you want to use and whether you are after more advanced features like dynamic rendering and interactivity.