﻿function openPopup(url)
{
	window.open(url,'_blank','width=600,height=600,left=50,top=50');
}

/* Tabs from one field to another. Send field id as string */
function tabIt(fromStr,toStr)
{
    var from = document.getElementById(fromStr);
    var to = document.getElementById(toStr);
    
    if (from.getAttribute && from.value.length == from.getAttribute("maxlength"))
        to.focus();
}

/* shows/hides the div with the given name */
function HideDiv(divName)
{
    // get the div object
    var objDiv = $(divName);
    
    // set visibility
    if (objDiv.style.visibility == 'visible')
    {
        objDiv.style.visibility = 'hidden';
        objDiv.style.display = 'none';
    }
    else
    {
        objDiv.style.visibility = 'visible';
        objDiv.style.display = 'block';
    }
}

/* shows the div with the given name */
function ShowDiv(divName)
{
    // get the div object
    var objDiv = $(divName);
    
    // set visibility
    objDiv.style.visibility = 'visible';
    objDiv.style.display = 'block';
}

/* hides the div with the given name */
function HideDivEx(divName)
{
    // get the div object
    var objDiv = $(divName);
    
    // set visibility
    objDiv.style.visibility = 'hidden';
    objDiv.style.display = 'none';
}

// ------------------------------------------------------------------------------------


// http://www.codeproject.com/useritems/JavaScript_Tips.asp
// http://www.codeproject.com/useritems/JavaScript_Tips_-_Part_2.asp

/* 
    Get DOM elements with one simple method 
    
    instead of: var elem = document.getElementById('TextBox1');
    
    use: var elem = $('TextBox1');
    or: var elemArr = $('TextBox1', 'TextBox2');
*/
function $() 
{
   var elements = new Array();
   for (var i = 0; i < arguments.length; i++) 
   {
      var element = arguments[i];
      if (typeof element == 'string')
         element = document.getElementById(element);
      if (arguments.length == 1)
         return element;
      elements.push(element);
   }
   return elements;
}


/*
    Add event handler
    
    You can easily bind/unbind a function to an event so that it gets called whenever the
    event fires on the object.


    Internet Explorer DOM (Document Object Model) provides attachEvent and
    detachEvent methods, while Mozilla DOM provides addEventListener and
    removeEventListener methods to add/remove event handlers.
    
    Example: AddEventHandler(obj, 'keydown', KeyDownEventHandler);
*/
function AddEventHandler(obj, eventName, functionNotify) 
{
   if (obj.attachEvent) 
   {
      obj.attachEvent('on' + eventName, functionNotify);
   }
   else if (obj.addEventListener) 
   {
      obj.addEventListener(eventName, functionNotify, true);
   }
   else 
   {
      obj['on' + eventName] = functionNotify;
   }
}


/*
    Remove event handler
    
    You can easily bind/unbind a function to an event so that it gets called whenever the
    event fires on the object.


    Internet Explorer DOM (Document Object Model) provides attachEvent and
    detachEvent methods, while Mozilla DOM provides addEventListener and
    removeEventListener methods to add/remove event handlers.
    
    Example: RemoveEventHandler(obj, 'keydown', KeyDownEventHandler);
*/
function RemoveEventHandler(obj, eventName, functionNotify) 
{
   if (obj.detachEvent) 
   {
      obj.detachEvent('on' + eventName, functionNotify);
   }
   else if (obj.removeEventListener) 
   {
      obj.removeEventListener(eventName, functionNotify, true);
   }
   else 
   {
      obj['on' + eventName] = null;
   }
}

/*
    Disable a button after click to prevent subsequent postbacks to server
    
    To prevent subsequent postbacks to server, as soon as the user clicks the submit button
    you can disable it and change its text in the onclick event handler.
    
    Example:
    
    ASPX
        <asp:button id="btnSubmit" runat="server" Text="Submit" />

    C#
        protected void Page_Load(object sender, EventArgs e)
        {
           btnSubmit.Attributes.Add("onclick", "DisableButton(this);" +
           Page.ClientScript.GetPostBackEventReference(this,
           btnSubmit.ID.ToString()));
        }
*/
function DisableButton(buttonElem) 
{
   buttonElem.value = 'Please Wait...';
   buttonElem.disabled = true;
}


/*
    Create your own watermark textbox
    
    The main purpose of a watermark is to provide information to the user about the textbox 
    without cluttering up the page. You have probably seen many examples of this in search 
    textboxes in websites. When a watermarked textbox is empty, it displays a message to 
    the user. Once the user types some text into the textbox, the watermarked text disappears. 
    When the user leaves the textbox the watermarked text appears again if the content of the 
    textbox is empty.

    You can easily change your textbox to provide watermark behavior by adding onfocus and 
    onblur event handlers. In the focus event, clear the textbox if its text matches the 
    watermark text. In the blur event, set the text back to watermark text if the textbox empty.
    
    Example:
    
    ASPX
        <asp:TextBox ID="txtWatermark" runat="server" />

    C#
        protected void Page_Load(object sender, EventArgs e)
        {
           string strWatermark = "Search Karamasoft.com";
           txtWatermark.Text = strWatermark;
           txtWatermark.Attributes.Add("onfocus", "WatermarkFocus(this, '" + strWatermark + "');");
           txtWatermark.Attributes.Add("onblur", "WatermarkBlur(this, '" + strWatermark + "');");
        }
*/
function WatermarkFocus(txtElem, strWatermark) 
{
   if (txtElem.value == strWatermark) txtElem.value = '';
}

function WatermarkBlur(txtElem, strWatermark) 
{
   if (txtElem.value == '') txtElem.value = strWatermark;
}


/*
    Validate max character length in a text area
    
    HTML input type of text element provides a built-in MaxLength property to set the maximum 
    number of characters that the user can enter. However, the TextArea element does not have 
    such property to limit the number of characters that can be entered. When you have an 
    ASP.NET TextBox control with TextMode="MultiLine" in your web page, it is rendered as an 
    HTML TextArea element and you cannot use MaxLength property to set the maximum number characters.

    What you can do is to define a keypress event handler for the TextBox control to check the 
    length of the text inside the text area and cancel the event if the MaxLength is reached.
    
    Example:
    
    ASPX
        <asp:TextBox ID="txtValidateMaxLength" runat="server" TextMode="MultiLine" />

    C#
        protected void Page_Load(object sender, EventArgs e)
        {
           txtValidateMaxLength.Attributes.Add("onkeypress", "return
                ValidateMaxLength((window.event) ? window.event : arguments[0],
                this.value, 5)");
        }
*/
function ValidateMaxLength(evnt, str, maxLength) 
{
   var evntKeyCode = GetEventKeyCode(evnt);
   // Ignore keys such as Delete, Backspace, Shift, Ctrl,
   // Alt, Insert, Delete, Home, End,
   // Page Up, Page Down and arrow keys
   var escChars = ",8,17,18,19,33,34,35,36,37,38,39,40,45,46,";
   if (escChars.indexOf(',' + evntKeyCode + ',') == -1) 
   {
      if (str.length >= maxLength) {
         alert("You cannot enter more than " + maxLength + "characters.");
         return false;
      }
   }
   return true;
}


/*
    Format number
    
    You can use the following method to format your numbers or currency values. It takes four 
    arguments: the number to format, the number of decimal places, a Boolean to indicate whether 
    zeros should be appended, and a Boolean to indicate whether commas should be inserted to separate 
    thousands.
*/
function FormatNumber(num, decimalPlaces, appendZeros, insertCommas) 
{
   var powerOfTen = Math.pow(10, decimalPlaces);
   var num = Math.round(num * powerOfTen) / powerOfTen;
   if (!appendZeros && !insertCommas)
   { 
      return num;
   }
   else 
   {
      var strNum = num.toString();
      var posDecimal = strNum.indexOf(".");
      if (appendZeros) 
      {
         var zeroToAppendCnt = 0;
         if (posDecimal < 0) 
         {
            strNum += ".";
            zeroToAppendCnt = decimalPlaces;
         }
         else 
         {
            zeroToAppendCnt = decimalPlaces - (strNum.length - posDecimal - 1);
         }
         for (var i = 0; i < zeroToAppendCnt; i++) 
         {
            strNum += "0";
         }
      }
      if (insertCommas && (Math.abs(num) >= 1000)) 
      {
         var i = posDecimal;
         if (i < 0) 
         {
            i = strNum.length;
         }
         i -= 3;
         while (i >= 1) 
         {
            strNum = strNum.substring(0, i) + ',' + strNum.substring(i, strNum.length);
            i -= 3;
         }
      }
      return strNum;
   }
}


/*
    Get inner text
    
    Internet Explorer provides an innerText property to get or set the text between the start 
    and end tags of the object. Firefox does not provide an innerText property but a textContent 
    property to get or set the inner text. For the browsers that do not provide a property to get 
    or set the inner text, you can clear the HTML tags inside the innerHTML property.
*/
function GetInnerText(elem) 
{
 return (typeof(elem.innerText) != 'undefined') ? elem.innerText : (typeof(elem.textContent) != 'undefined') ? elem.textContent : elem.innerHTML.replace(/<[^>]+>/g, '');
}


/*
    Toggle display
    
    You can toggle the display of an HTML element easily by toggling its style display value 
    between 'none' and ''.
    
    Example:
    ASPX
        <asp:LinkButton ID="lbToggleDisplay" runat="server" OnClientClick="ToggleDisplay('pnlToggleDisplay'); return false;">Toggle Display</asp:LinkButton>
        <asp:Panel ID="pnlToggleDisplay" runat="server">
            Panel content here!
        </asp:Panel>
*/
function ToggleDisplay(elemId) 
{
 var elem = document.getElementById(elemId);
 elem.style.display = (elem.style.display != 'none') ? 'none' : '';
}


/*
    Check whether an item exists in the array
    
    JavaScript Array object does not provide a built-in method to return whether a given value 
    exists in the array. However, we can add a prototype method to extend Array functionality 
    by adding a method to return whether the array has the given value.
    
    Example:
        var arr = new Array();
        arr[0] = 'test';
        alert(arr.has('test')); // Should display true
        alert(arr.has('test2')); // Should display false
*/
Array.prototype.has = function(value) 
{
 var i;
 for (var i = 0, loopCnt = this.length; i < loopCnt; i++) 
 {
  if (this[i] === value) 
  {
   return true;
  }
 }
 return false;
};


/*
    Retrieve query string values
    
    ASP.NET provides Request.QueryString collection that retrieves the values of the 
    variables in the HTTP query string, but there is no built-in mechanism to retrieve 
    query string collection on the client-side. However, you can parse the window location 
    search property to get the query string values by using the GetAttributeValue method 
    that we provided in one of our previous tips to center your window. Note that 
    window.location.search property gets or sets the substring of the href property 
    that follows the question mark.
    
    This method takes three arguments: a name/value pair list, the attribute name to 
    retrieve its value, the first delimiter and the second delimiter. The first delimiter 
    will be ampersand and the second delimiter would be equal sign to parse query string 
    variables. 
    
    Example:
        return GetAttributeValue(window.location.search, varName, '&', '=');
*/
function GetAttributeValue(attribList, attribName, firstDelim, secondDelim) 
{
 var attribNameLowerCase = attribName.toLowerCase();
 if (attribList) 
 {
  var attribArr = attribList.split(firstDelim);
  for (var i = 0, loopCnt = attribArr.length; i < loopCnt; i++) 
  {
   var nameValueArr = attribArr[i].split(secondDelim);
   for (var j = 0, loopCnt2 = nameValueArr.length; j < loopCnt2; j++) 
   {
    if (nameValueArr[0].toLowerCase().replace(/\s/g, '') == attribNameLowerCase && loopCnt2 > 1) 
    {
     return nameValueArr[1];
    }
   }
  }
 }
} 


/*
    Move the focus away from your dropdown after change event
    
    When the user changes the selection in a DropDownList, the focus remains inside the dropdown. 
    If the user presses up/down arrow key or moves the mouse wheel, that action triggers the 
    onchange event on the dropdown. You can prevent this by making the dropdown lose focus in 
    the onchange event. 
    
    Example:
    
    ASPX
        <asp:DropDownList id="ddlLoseFocus" runat="server" AutoPostBack="true" />

    C#
        protected void Page_Load(object sender, EventArgs e)
        {
            ddlLoseFocus.Attributes.Add("onchange", "LoseFocus(this)");
        }
    
*/
function LoseFocus(ddlElem) 
{
 ddlElem.blur();
}


// ****************************************************************************
// Pass data from one page to another using post
// ****************************************************************************

/*
    Pass data from one page to another using post
    
    If you need to pass small amounts of data from one page to another, you can pass it in the 
    query string and the target page can retrieve it through Request.QueryString collection 
    (GET operation). However, if you need to pass large amount of data you cannot pass it in 
    the query string since Internet Explorer has maximum 2048 character limit on the address 
    of the page. In these cases, you can pass data from one page to another using POST operation. 
    In your source page, define a hidden variable to hold the data to pass and pass only its ID 
    to the target page in the query string.

    The target page should first get that ID through Request.QueryString collection. Then it should 
    set its own hidden variable value with the one in the source frame on the client-side during 
    BODY onload event handler. You can use opener object on the client-side to retrieve the DOM 
    elements in the opener page. Then it should do a postback to itself and retrieve the value 
    of its hidden variable through Request.Form collection. 
*/

/*
    Source Page JavaScript
    
    Source Page ASPX
        <asp:TextBox ID="txtPassData" runat="server" Text="Data to pass" CssClass="TextBox"></asp:TextBox>
        <asp:Button ID="btnPassData" runat="server" Text="Pass Data" CssClass="Button" OnClientClick="PassData('txtPassData'); return false;" /> 
*/
function PassData(ctlID) 
{
 window.open('TargetPage.aspx?ctlID=' + ctlID, 'NewWindow', 'width=400,height=300,location=no,menubar=no,resizable=no,scrollbars=no,status=yes,toolbars=no');
}


/*
    Target Page JavaScript
    
    Target Page ASPX
        <body onload="Body_Onload()">
            <form id="form1" runat="server">
            <div>
            Text passed: <asp:Label ID="lblTextPassed" runat="server" Text="Label"></asp:Label>
            </div>
            <asp:HiddenField ID="hfTextPassed" runat="server" Value="" />
            <asp:HiddenField ID="hfPageStatus" runat="server" Value="" />
            </form>
        </body>

    Target Page C#
        public const string SET_TEXT = "SetText";
        public const string TEXT_IS_SET = "TextIsSet"; 

        protected void Page_Load(object sender, EventArgs e)
        {
         // Initial entry
         if (hfPageStatus.Value == SET_TEXT)
         {
          // Set page status not to enter again
          hfPageStatus.Value = TEXT_IS_SET;
         }
         lblTextPassed.Text = hfTextPassed.Value;
        } 
*/
function Body_Onload() 
{
    var pageStatusElem = document.getElementById('hfPageStatus');
    
    // Page status hidden field value is initially empty string
    if (pageStatusElem.value == '') 
    {
        // Set text to spell check hidden field value to the text in the opener window
        document.getElementById('hfTextPassed').value = opener.window.document.getElementById('<%=Request.QueryString["ctlID"]%>').value; 

        // Set page status hidden field value so that when the page is posted back it can process text to spell check retrieved from the opener window
        pageStatusElem.value = '<%=SET_TEXT%>'; 

        // Post back the page
        document.form1.submit();
    }
} 

// ****************************************************************************
// END - Pass data from one page to another using post
// ****************************************************************************

// ****************************************************************************
// Concatenate your strings efficiently
// ****************************************************************************

/*
    Concatenate your strings efficiently
    
    Even though it is easy to concatenate strings using the + operator, string operations become 
    very costly in terms of CPU cycle when the strings get bigger and there are a lot of strings 
    to concatenate.

    The better alternative is to create your own StringBuilder JavaScript object that is similar 
    to the StringBuilder object in the .NET Framework. You can define your StringBuilder object 
    with a buffer array property to store the strings to concatenate. Then add an Append method 
    to add a string to the buffer array. The JavaScript Array object provides a join method that 
    puts all the elements of an array into a string separated by a specified delimiter. 
    ConvertToString method will join all elements of the buffer array into a string.
    
    Instead of the following:
        var str = 'This ' + 'is ' + 'a ' + 'test';

    You can now use the following:
        var sb = new StringBuilder;
        sb.Append('This ');
        sb.Append('is ');
        sb.Append('a ');
        sb.Append('test');
        var str = sb.ConvertToString(); 
*/
function StringBuilder() 
{
 this.buffer = [];
}

StringBuilder.prototype.Append = function(str) 
{
 this.buffer[this.buffer.length] = str;
};

StringBuilder.prototype.ConvertToString = function() 
{
 return this.buffer.join('');
};

// ****************************************************************************
// END - Concatenate your strings efficiently
// ****************************************************************************


// ****************************************************************************
// Use hash tables for efficient lookups
// ****************************************************************************

/*
    Use hash tables for efficient lookups
    
    Hash tables provide a way of efficient addition of new entries and the time spent searching 
    for a specified key is independent of the number of items stored, which is O(1). 
    
    We can now create our HashTable object using the associative array functionality. Our 
    HashTable object will have two properties: hashArr property that stores key/value pairs 
    and length property that keeps track of the number of items in the hash table. It will 
    provide four methods: get method to retrieve the value for a given key, put method to add 
    a key/value pair to the hash table, remove method to remove a key/value pair from the hash 
    table and has method to return whether given key value exists in the hash table.
    
    Example:
        var phoneLookup = new HashTable();
        phoneLookup.put('Jane', '111-222-3333');
        phoneLookup.put('John', '444-555-6666');
        alert(phoneLookup.get('Jane'));
*/
function HashTable()
{
    this.hashArr = new Array();
    this.length = 0;
}

HashTable.prototype.get = function(key) 
{
    return this.hashArr[key];
};

HashTable.prototype.put = function(key, value) 
{
 if (typeof(this.hashArr[key]) == 'undefined') 
 {
  this.length++;
 }
    this.hashArr[key] = value;
};

HashTable.prototype.remove = function(key) 
{
 if (typeof(this.hashArr[key]) != 'undefined') 
 {
  this.length--;
  var value = this.hashArr[key];
  delete this.hashArr[key];
  return value;
 }
};

HashTable.prototype.has = function(key) 
{
 return (typeof(this.hashArr[key]) != 'undefined');
};

// ****************************************************************************
// END - Use hash tables for efficient lookups
// ****************************************************************************


// ****************************************************************************
// Center your window on the screen
// ****************************************************************************

/*
    Center your window on the screen
    
    You can center your windows opened with the window.open method on the screen. Both Internet 
    Explorer and Mozilla DOM provide window screen object that has availWidth and availHeight 
    properties to retrieves the width and height of the working area of the system's screen. 
    All you need to do is to get the difference between the screen width (or height) value and 
    the window width (or height) value and divide it by 2.
    
    The features argument usually looks like the following:
        'width=400,height=300,location=no,menubar=no,resizable=no,scrollbars=no,status=yes,toolbars=no'
    
    Example:

    JavaScipt:    
        function OpenWindowCentered(windowWidth, windowHeight) 
        {
            WindowOpenHelper('http://www.karamasoft.com', 'WindowCentered', 
                'width=400,height=300,location=no,menubar=no,
                resizable=no,scrollbars=no,status=yes,toolbars=no', true);
        }

    ASPX
        <asp:LinkButton ID="lbOpenWindowCentered" runat="server"
            OnClientClick="OpenWindowCentered(); return false;">Open window
            centered
        </asp:LinkButton>
*/

/*
    First, we need to create a method to parse the width and height values in the features 
    string. Since we might want to use this method for other purposes to split name/value pairs 
    such as parsing query strings to find query string values, let's make it a generic method.
    
    This method takes three arguments: a name/value pair list, the attribute name to retrieve 
    its value, the first delimiter and the second delimiter. The first delimiter will be comma 
    and the second delimiter will be equal sign in this case. The first delimiter would be 
    ampersand and the second delimiter would be equal sign to parse query string variables.
*/
function GetAttributeValue(attribList, attribName, firstDelim, secondDelim) 
{
   var attribNameLowerCase = attribName.toLowerCase();
   if (attribList) 
   {
      var attribArr = attribList.split(firstDelim);
      for (var i = 0, loopCnt = attribArr.length; i < loopCnt; i++) 
      {
         var nameValueArr = attribArr[i].split(secondDelim);
         for (var j = 0, loopCnt2 = nameValueArr.length; j < loopCnt2; j++) 
         {
            if (nameValueArr[0].toLowerCase().replace(/\s/g, '') == attribNameLowerCase && loopCnt2 > 1) 
                return nameValueArr[1];
         }
      }
   }
}

/*
    methods to retrieve available screen width and height values.
*/
function GetScreenWidth() 
{
   return window.screen.availWidth;
}

function GetScreenHeight() 
{
   return window.screen.availHeight;
}

/*
    create our window.open wrapper method to center the window by using these methods
*/
function WindowOpenHelper(sURL, sName, sFeatures, centerWindow) 
{
   var windowLeft = '';
   var windowTop = '';
   if (centerWindow) 
   {
      var windowWidth = GetAttributeValue(sFeatures, 'width', ',', '=');
      windowLeft = (typeof(windowWidth) != 'undefined') ? ',left=' + ((GetScreenWidth() - windowWidth) / 2) : '';
      var windowHeight = GetAttributeValue(sFeatures, 'height', ',', '=');
      windowTop = (typeof(windowHeight) != 'undefined') ? ',top=' + ((GetScreenHeight() - windowHeight) / 2) : '';
   }
   window.open(sURL, sName, sFeatures + windowLeft + windowTop);
}

// ****************************************************************************
// END - Center your window on the screen
// ****************************************************************************


