﻿//Displays the requested spawn control and its associated label.
function showSpawn(uidPrefix, group, name) {
    //combine with prefix
    var spawn = getElementByName(uidPrefix, uidPrefix + name);

    //show the spawn control and label    
    showElement(spawn);
    showElementsFor(uidPrefix, name);
}

function showSpawnGrid(uidPrefix, group, name, editable) {
    var spawn = getElementByName(uidPrefix, uidPrefix + name);

    //show the containing element
    showElement(spawn);
    showElementsFor(uidPrefix, name);

    //load the grid
    //alert('Loading grid: ' + uidPrefix + ', name: ' + name);
    loadGrid(uidPrefix, name, editable);
}

//Hides the specified spawn and its associated label for the given group.
function hideFieldInGroup(uidPrefix, group, name) {
    //combine with the prefix
    name = uidPrefix + name;

    var fieldgroup = getTrackedGroup(uidPrefix, group);

    if (fieldgroup != null) {
        for (j = 0; j < fieldgroup.length; j++) {
            if (fieldgroup[j] == name) {
                //close each spawn element and its label
                var field = getElementByName(uidPrefix, fieldgroup[j]);

                hideElement(field);

                //strip off the prefix before sending to function
                var fieldName = fieldgroup[j].substring(uidPrefix.length);

                hideElementsFor(uidPrefix, fieldName);
                clearSelections(uidPrefix, fieldName);

                return;
            }
        }
    }
}

//Hides all spawned controls and their associated labels for the given group.
function hideAllFieldsInGroup(uidPrefix, group) {
    //combine with the prefix
    //name = uidPrefix + name;

    var fieldgroup = getTrackedGroup(uidPrefix, group);

    if (fieldgroup != null) {
        for (j = 0; j < fieldgroup.length; j++) {
            //close each spawn element and its label
            var field = getElementByName(uidPrefix, fieldgroup[j]);

            hideElement(field);

            //strip off the prefix before sending to function
            var fieldName = fieldgroup[j].substring(uidPrefix.length);

            hideElementsFor(uidPrefix, fieldName);
            clearSelections(uidPrefix, fieldName);
        }
    }
}

//Determines if a checkbox spawn is tied to another checkbox with the same group.
//Prevents closing shared spawn fields when both checkboxes are slected.
function noGroupSpawnDuplicates(id, name, value) {
    var element = document.getElementById(id);
    var elements = document.getElementsByName(name);

    //default to true because we might not have found the element(s) were were looking for
    var result = true;

    if (element != null && elements != null) {
        //get the spawn group from the sender's attribute
        var senderAttr = _getAttribute(element, "alt");

        if (senderAttr != null) {
            //look at each element
            for (i = 0; i < elements.length; i++) {
                //if the element can be checked as is checked
                if (elements[i].checked) {
                    //get the attribute text of the current element
                    var elementAttr = _getAttribute(elements[i], "alt");

                    if (elementAttr != null) {
                        //get the spawn group from the current element and compare it to the sender,
                        //if they match and the element is checked then return false                    
                        if (senderAttr.nodeValue.indexOf(value) == elementAttr.nodeValue.indexOf(value)) {
                            result = false;
                            break;
                        }
                    }
                }
            }
        }
    }

    return result;
}

//This function removes all values from the specified element if it is not a radio button or a check box (text boxes and drop down lists).
function clearSelections(uidPrefix, name) {
    var elements = document.getElementsByName(name);

    if (elements != null) {
        //alert("Clearing " + elements.length + " elements for " + name);

        for (i = 0; i < elements.length; i++) {
            var attr = _getAttribute(elements[i], "type");

            //alert("Clearing node: " + elements[i].id);

            //only <input> elements have a "type" attribute
            if (attr != null) {
                //uncheck the option or clear the value
                if (elements[i].checked)
                    elements[i].checked = false;

                //only clear the value when it is text, selection values need to stay because the value may be selected again
                if (attr.nodeValue == "text") {
                    elements[i].value = "";
                    //alert("Cleared " + elements[i].nodeName);
                }

                //unload the grids
                if (attr.nodeValue == "hidden") {
                    //this will have the suffix on it so strip that off                    
                    unloadGrid(uidPrefix, elements[i].id.substring(uidPrefix.length).replace(GRID_VALUE_ELEMENT_SUFFIX, ""));
                }
            }
            else {
                //<select> and <textarea> elements
                elements[i].value = "";

                //is an html editor has been applied to a textarea (multitime text field) then see if we can call the clear
                //we are not doing this because it created a editor and i haven't found a way to destroy it, this is a problem when there was not editor originally and the one appears when the textarea is cleared
                if (elements[i].nodeName.toLocaleLowerCase() == "textarea") {
                    try {
                        //Editor code
                        var Editor = window[elements[i].id + "_Editor"];

                        if (Editor != null) {
                            txtAreaValue = Editor.clear();
                        }
                    }
                    catch (err) { }
                }

                //alert("Cleared " + elements[i].nodeName);
            }
        }
    }
}

function showElementsFor(uidPrefix, name) {
    //narrow the scope for performance
    var root = document.getElementById(uidPrefix);

    var labels = root.getElementsByTagName("label");
    var images = root.getElementsByTagName("img");
    var fieldsets = root.getElementsByTagName("fieldset");
    var tables = root.getElementsByTagName("table");
    var tds = root.getElementsByTagName("td");

    //strip off the prefix because these element are referenced by the non-unique field name
    //name = name.substring(uidPrefix.length);

    if (labels != null) {
        //show the label if there is one
        for (i = 0; i < labels.length; i++) {
            var label = labels[i];

            //get the "for" attribute
            if (label.attributes["for"] != null && label.attributes["for"].nodeValue == name)
                showElement(label);
        }
    }

    if (images != null) {
        //show the label if there is one
        for (i = 0; i < images.length; i++) {
            var image = images[i];

            //get the "for" attribute if there is one
            if (image.attributes["for"] != null && image.attributes["for"].nodeValue == name)
                showElement(image);
        }
    }

    if (fieldsets != null) {
        //show the label if there is one
        for (i = 0; i < fieldsets.length; i++) {
            var fieldset = fieldsets[i];

            //get the "for" attribute if there is one
            if (fieldset.attributes["for"] != null && fieldset.attributes["for"].nodeValue == name)
                showElement(fieldset);
        }
    }

    if (tables != null) {
        //show the label if there is one
        for (i = 0; i < tables.length; i++) {
            var table = tables[i];

            //get the "for" attribute if there is one
            if (table.attributes["for"] != null && table.attributes["for"].nodeValue == name)
                showElement(table);
        }
    }

    if (tds != null) {
        //show the label if there is one
        for (i = 0; i < tds.length; i++) {
            var td = tds[i];

            //get the "for" attribute if there is one
            if (td.attributes["for"] != null && td.attributes["for"].nodeValue == name)
                showElement(td);
        }
    }
}

function hideElementsFor(uidPrefix, name) {
    //narrow the scope for performance
    var root = document.getElementById(uidPrefix);

    var labels = root.getElementsByTagName("label");
    var images = root.getElementsByTagName("img");
    var fieldsets = root.getElementsByTagName("fieldset");
    var tables = root.getElementsByTagName("table");
    var tds = root.getElementsByTagName("td");

    //strip off the prefix because these element are referenced by the non-unique field name
    //name = name.substring(uidPrefix.length);

    if (labels != null) {
        //show the label if there is one
        for (i = 0; i < labels.length; i++) {
            var label = labels[i];

            //get the "for" attribute
            if (label.attributes["for"] != null && label.attributes["for"].nodeValue == name) {
                hideElement(label);
            }
        }
    }

    if (images != null) {
        //show the label if there is one
        for (i = 0; i < images.length; i++) {
            var image = images[i];

            //get the "for" attribute if there is one
            if (image.attributes["for"] != null && image.attributes["for"].nodeValue == name)
                hideElement(image);
        }
    }

    if (fieldsets != null) {
        //show the label if there is one
        for (i = 0; i < fieldsets.length; i++) {
            var fieldset = fieldsets[i];

            //get the "for" attribute if there is one
            if (fieldset.attributes["for"] != null && fieldset.attributes["for"].nodeValue == name)
                hideElement(fieldset);
        }
    }

    if (tables != null) {
        //show the label if there is one
        for (i = 0; i < tables.length; i++) {
            var table = tables[i];

            //get the "for" attribute if there is one
            if (table.attributes["for"] != null && table.attributes["for"].nodeValue == name)
                hideElement(table);
        }
    }

    if (tds != null) {
        //show the label if there is one
        for (i = 0; i < tds.length; i++) {
            var td = tds[i];

            //get the "for" attribute if there is one
            if (td.attributes["for"] != null && td.attributes["for"].nodeValue == name)
                hideElement(td);
        }
    }
}

//////////////////////////////////////Element Visibility Changers//////////////////////////////////
function showElement(e) {
    if (e != null) {
        if (e.style) {
            e.style.display = "block";
            e.style.visibility = "visible";
        }
    }
}

function hideElement(e) {
    if (e != null) {
        if (e.style) {
            e.style.display = "none";
            e.style.visibility = "hidden";
        }
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////Group Tracking///////////////////////////////////////////
//var SpawnFields = [];

function _SpawnFields(uidPrefix) {
    return window[uidPrefix + "SpawnFields"];
}

//Appends a group to the tracking list.
function _addToTrackedGroup(uidPrefix, group) {
    //combine with the prefix
    group = uidPrefix + group;

    //add the group to the associative array and define a new associative array as it's value,
    //they will hold the names of spawn elements
    var groupFound = false;

    for (spawn in _SpawnFields(uidPrefix)) {
        if (spawn == group) {
            groupFound = true;
            break;
        }
    }

    if (!groupFound)
        _SpawnFields(uidPrefix)[group] = [];
}

//Returns the specified group in the tracking list.
function getTrackedGroup(uidPrefix, group) {
    //combine with the prefix
    group = uidPrefix + group;

    return _SpawnFields(uidPrefix)[group];
}

//Determines if a specified spawn name is in the specified group of spawn names.
function addSpawnToTrackedGroup(uidPrefix, group, spawn) {
    //combine with prefix
    //group = uidPrefix + group;
    spawn = uidPrefix + spawn;

    //make sure we have the given tracking group
    _addToTrackedGroup(uidPrefix, group);

    //see if we are tracking this spawn in the group    
    var spawnFound = false;
    var spawngroup = getTrackedGroup(uidPrefix, group);

    if (spawngroup != null) {
        for (i = 0; i < spawngroup.length; i++) {
            if (spawngroup[i] == spawn) {
                spawnFound = true;
                break;
            }
        }
    }

    //add to the group list if it was not found
    if (!spawnFound)
        spawngroup[spawngroup.length] = spawn;
}

//Provides a graphical display of the spawn tracking group array.
//function showTrackedGroupArray() {
//    var display = "";

//    for (group in SpawnFields) {
//        display += group + ":\r\n";
//        var spawngroup = getTrackedGroup(group);

//        if (spawngroup != null) {
//            for (j = 0; j < spawngroup.length; j++) {
//                if (j > 0) display += "\r\n";
//                display += spawngroup[j];
//            }
//        }
//        display + "\r\n\r\n";
//    }

//    return display;
//}
////////////////////////////////////////////////////////////////////////////////////////////////////

//Sets the value of the hidden field associated with a rich text editor to html encoded value that will be saved to the database
//This function is called on document.ready as well as every time data in rich text box is changed (validateTextLength function)
function setRichTextHiddenValueField(uidPrefix, elem) {
    var hiddenValueField = jQuery('#' + elem.id + "_HIDDEN");
    var richTextEditor = window[uidPrefix + elem.id + "_Editor"];
    var encodedText = jQuery(richTextEditor.doc.body).html();
    hiddenValueField.val(encodedText);
}
/////////////////////////////////////////////Validators/////////////////////////////////////////////

function validateTextLength(uidPrefix, elem, lbl) {
    var $scope = jQuery('#' + uidPrefix);
    var $textArea = jQuery(elem);
    var $label = jQuery('#' + lbl + '');
    var maxLength = parseInt($textArea.attr("data-maxchars"));

    //the control renders 2 control characters, let's trim them out before calculating,
    //since the behavior is a little funky, don't do this at this time
    var textAreaLength = $textArea.val().replace(/\n/g, "\r\n").length;

    //check for clipboard data (paste), this only works in IE  
    if (window.event && window.event.type == 'paste' && window.clipboardData != null) {
        textAreaLength += window.clipboardData.getData("Text").replace(/\n/g, "\r\n").length;
    }

    //if an editor is being used then just get the text (w/o markup characters)
    var Editor = window[uidPrefix + elem.id + "_Editor"];

    if (Editor != null) {
        //this method call is having a weird effect on the cursor, so we must go about getting just the text a different way
        //txtAreaValue = Editor.selectedText();

        //strip the area currently being edited of HTML (only IE supported .$area.text())
        jQuery(Editor.doc.body).html().replace(/<\/?[^>]+>/gi, '').length;
        textAreaLength = jQuery(Editor.doc.body).text().length;
        //update associated hidden field that stores encoded value
        setRichTextHiddenValueField(uidPrefix, elem);
    }

    if (textAreaLength > maxLength) {
        $label.text("You entered " + textAreaLength + " characters. Please enter " + maxLength + " or fewer characters.");
        $label.css("color", "red");
    }
    else {
        $label.text("Characters remaining: " + (maxLength - textAreaLength));
        $label.css("color", "black");
    }
    showElement($label[0]);

}

//function validateTextLength(uidPrefix, txtArea, labelId) {
//    var $scope = jQuery('#' + uidPrefix);

//    //get reference to the lbl element and the max characters    
//    var $label = $scope.find('#' + labelId);

//    var maxLength = parseInt(txtArea.attributes["data-maxchars"].value);
//    var txtAreaValue = parseInt(txtArea.value);
//    var text;

//    //if an editor is being used then just get the text (w/o markup characters)
//    var Editor = window[uidPrefix + txtArea.id + "_Editor"];

//    if (Editor != null) {
//        //this method call is having a weird effect on the cursor, so we must go about getting just the text a different way
//        //txtAreaValue = Editor.selectedText();

//        //strip the area currently being edited of HTML (only IE supported .$area.text())
//        txtAreaValue = jQuery(Editor.doc.body).text().replace(/<\/?[^>]+>/gi, '');
//    }

//    if (txtAreaValue.length > maxLength) {
//        text = "You entered " + txtAreaValue.length + " characters. Please enter " + maxLength + " or fewer characters.";
//        $label.css("color", "red");
//    }
//    else {
//        text = "Characters remaining: " + (maxLength - txtAreaValue.length);
//        $label.css("color", "black");
//    }

//    $label.text(text);
//}

//function validateTextLengthPaste(txtArea, lbl) {
//    //get reference to the lbl element and the max characters
//    var label = document.getElementById(lbl);
//    var maxLength = parseInt(txtArea.attributes["data-maxchars"].value);
//    var txtAreaValue = txtArea.value;
//    var text;

//    //if an editor is being used then just get the text (w/o markup characters)
//    var Editor = window[txtArea.id + "_Editor"];

//    if (Editor != null) {
//        //this method call is having a weird effect on the cursor, so we must go about getting just the text a different way
//        //txtAreaValue = Editor.selectedText();

//        //strip the area currently being edited of HTML (only IE supported .$area.text())
//        txtAreaValue = jQuery(Editor.doc.body).text().replace(/<\/?[^>]+>/gi, '');
//    }

//    if ((txtAreaValue.length + (window.clipboardData ? window.clipboardData.getData("Text").length : 0)) > maxLength) {
//        text = "You entered " + txtAreaValue.length + " characters. Please enter " + maxLength + " or fewer characters.";
//        label.style.color = 'red';
//    }
//    else {
//        text = "Characters remaining: " + (maxLength - txtAreaValue.length);
//        label.style.color = 'black';
//    }

//    if (document.all)
//        label.innerText = text;
//    else
//        label.textContent = text;
//}

function validateFormat(elem, format) {
    //strip off the beginning and ending slashes

    var regex = new RegExp(format);
    regex.ignoreCase = true;

    var result = regex.test(elem.value);

    if (!result) {
        //write a new element directly above the element
        var labelNode = document.createElement("label");

        labelNode.setAttribute("for", elem.id);
        labelNode.setAttribute("style", "color:red");

        var txt = document.createTextNode("Format is invalid.");

        labelNode.appendChild(txt);
    }
}
////////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////Helpers/Other//////////////////////////////////////////
function getElementByName(uidPrefix, name) {
    var $scope = jQuery('#' + uidPrefix);

    return $scope.find("#" + name)[0];

    //if (document.all) {
    //    //IE only
    //    return eval("document.all." + name);
    //}
    //else if (document.layers) {
    //    //NS4
    //    return eval("document." + name);
    //}
    //else if (!document.all && document.getElementById) {
    //    //NS6
    //    return document.getElementById(name);
    //}
}

function getElementsByAttribute(oElm, strTagName, strAttributeName, strAttributeValue) {
    var arrElements = (strTagName == "*" && oElm.all) ? oElm.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    var oAttributeValue = (typeof strAttributeValue != "undefined") ? new RegExp("(^|\\s)" + strAttributeValue + "(\\s|$)", "i") : null;
    var oCurrent;
    var oAttribute;
    for (var i = 0; i < arrElements.length; i++) {
        oCurrent = arrElements[i];
        oAttribute = oCurrent.getAttribute && oCurrent.getAttribute(strAttributeName);
        if (typeof oAttribute == "string" && oAttribute.length > 0) {
            if (typeof strAttributeValue == "undefined" || (oAttributeValue && oAttributeValue.test(oAttribute))) {
                arrReturnElements.push(oCurrent);
            }
        }
    }
    return arrReturnElements;
}

//IE 8 introduces a bug in getAttribute so we have to wrap attribute getter calls in this method
function _getAttribute(node, name) {
    return node.attributes[name];
}

//textarea auto-sizing function
function autoSizeTextArea(textarea, limit, e) {
    var keyCode = window.event ? window.event.keyCode : e.which;

    // DEL or BACKSPACE key
    if (keyCode === 8 || keyCode === 46) {
        while (textarea.scrollHeight <= textarea.clientHeight && textarea.rows > limit)
            textarea.rows -= 1;
    }

    while (textarea.scrollHeight > textarea.clientHeight)
        textarea.rows += 1;
}

function checkAll(containerID, checked, excludeIDs) {
    var container = document.getElementById(containerID);

    if (container != null) {
        var checkboxes = container.getElementsByTagName("input");

        if (checkboxes != null) {
            var exclusionArray;

            if (excludeIDs != null && excludeIDs != "")
                exclusionArray = excludeIDs.split(',');

            for (var i = 0; i < checkboxes.length; i++) {
                var input = checkboxes[i];
                var excludeCurrent = false;

                if (exclusionArray != null && exclusionArray.length > 0) {
                    //the ID of the checkbox is in this format by "UNIQUE_FIELD_NAME_PREFIX" + "containerID" + _ + ID
                    //var removeThis = containerID.replace(UNIQUE_FIELD_NAME_PREFIX, "") + "_";
                    var removeThis = containerID + "_";
                    var idToSearchFor = input.id.replace(removeThis, "");

                    //any value non -1 means it was found
                    excludeCurrent = exclusionArray.indexOf(idToSearchFor) != -1;
                }

                if (excludeCurrent == false) {
                    if (input.type == 'checkbox') {
                        input.checked = checked;

                        //after changing the value, cause a click event so spawning code will trigger
                        if (input.click == 'undefined')
                            input.onclick();
                        else
                            input.click();
                    }
                }
            }
        }
    }
}

////////////////////////////////////////////////Grid////////////////////////////////////////////////
//this MUST match what is in the class definition
var GRID_ELEMENT_SUFFIX = "_grid";
var GRID_TOOLBAR_ELEMENT_SUFFIX = "_toolbar";
var GRID_VALUE_ELEMENT_SUFFIX = "_value";

function loadGrid(uidPrefix, name, editable) {
    var $scope = jQuery('#' + uidPrefix);

    //combine with prefix
    name = uidPrefix + name;

    //compose an efficient selector based on prefix scope    
    var $table = $scope.find('#' + name + GRID_ELEMENT_SUFFIX);
    var $data = $scope.find('#' + name + GRID_VALUE_ELEMENT_SUFFIX);
    var toolbarId = '#' + name + GRID_TOOLBAR_ELEMENT_SUFFIX;

    //alert("loadGrid('" + uidPrefix + "','" + name + "'," + editable + ")");

    var model = window[name + "_columnModel"]; //eval(colModel);  
    //debugger;


    //initialize the grid
    $table.jqGrid({
        //sortname: "_id_",  //sort order is preserved upon saving, there is no way of knowing what that was so we cannot preset this value
        //width: 700, shrinkToFit: false,   //either hardcode the width or let the colModel width control and then the grid will auto-adjust 
        //sortorder: "desc",
        datatype: "jsonstring",
        jsonReader: { id: "@id", repeatitems: false },
        height: "auto",
        forceFit: true,
        viewrecords: true,
        hoverrows: false,
        pgbuttons: true,
        pginput: true,
        rowNum: 10,
        rowList: [10, 25, 50, 100],
        colModel: model,
        loadonce: false,
        sortable: true,
        reloadAfterSubmit: true,
        //data always comes from the hidden field, which may be encoded
        datastr: jQuery.jgrid.htmlDecode($data.val()),
        dataProxy: function (t) {
            //this function is necessary to enable local data manipulation instead of the calls to url and editurl
            var dataIDsLength = jQuery(this).jqGrid("getDataIDs").length;
            var lastID = dataIDsLength > 0 ? parseInt(dataIDsLength) + 1 : 1;


            if (t.data.id == "_empty") {
                jQuery(this).jqGrid("addRowData", lastID, t.data, "last");

            }
            else {
                if (t.data.oper == "del")
                    jQuery(this).jqGrid("delRowData", t.data.id);
                else
                    jQuery(this).jqGrid("setRowData", t.data.id, t.data);

            }


            //strip off the prefix
            _saveGridData(uidPrefix, name.substring(uidPrefix.length));
        }
        , pager: toolbarId
    });

    //set up the toolbar, editing and searching options
    //var dialogSearch = window[name + "_dialog_search"];
    if (editable) {
        var dialog = window[name + "_dialog"];
        var dialogDel = window[name + "_dialog_delete"];
        $table.jqGrid('navGrid', toolbarId, { add: true, edit: true, del: true, search: false, refresh: false }, dialog, dialog, dialogDel);//, dialogSearch);
    }
    else
    {
        $table.jqGrid('navGrid', toolbarId, { add: false, edit: false, del: false, search: false, refresh: false }, {}, {}, {});//, dialogSearch);
    }

}

function unloadGrid(uidPrefix, name) {
    var $scope = jQuery('#' + uidPrefix);

    //combine with the prefix
    name = uidPrefix + name;

    //alert("Unloading Grid: #" + id);

    //unload the grid, retaining the html elements if we need to reload later    
    jQuery.jgrid.gridUnload('#' + name + GRID_ELEMENT_SUFFIX);

    //remove all the data for the grid (empty array)
    //alert("Looking for: " + name);

    var $data = $scope.find('#' + name + GRID_VALUE_ELEMENT_SUFFIX);

    $data.val("[]");

    //alert("Value is now: " + $data.val());
}

function _saveGridData(uidPrefix, name) {
    var $scope = jQuery('#' + uidPrefix);

    //combine with the prefix
    name = uidPrefix + name;

    var $table = $scope.find('#' + name + GRID_ELEMENT_SUFFIX);

    //returns all the data from the grid in an associative array
    var data = $table.jqGrid('getGridParam','data');

    for (var i = 0; i < data.length; i++) {
        jQuery.each(data[i], function (j, val) {
            if (val == null) {
                val = "";
            }
            if (j == "@id" && (data[i][j] == null || data[i][j] == "" || typeof data[i][j] == 'undefined'))
            {
                data[i][j] = Math.random();
            }
        });
    }

    //convert the array into a format we can work with
    var json = JSON.stringify(data);


    //put the json string in the hiddenfield so it will post back to the server    
    $scope.find('#' + name + GRID_VALUE_ELEMENT_SUFFIX).val(json).trigger('change');

    //needed to save updated grid row data when edited
    //fixes grid column sort issue after row edit previous data displayed 
    $table.jqGrid().trigger('reloadGrid');

    return true;
}

////setup the add/edit dialog form
//var dialogFormOptions = {
//    width: 400,
//    //addCaption: "Add New",
//    //editCaption: "Edit Current",
//    bSubmit: "Submit",
//    //caption: "Delete Current",
//    //msg: "Are you sure you want to delete?",
//    //recreateForm: true,     //fixes a problem with first selection stored is not the same as the current
//    savekey: [true, 13],    //allow the user to save by clicking the enter key
//    closeOnEscape: true,
//    closeAfterAdd: true,
//    closeAfterEdit: true,
//    checkOnUpdate: true,    //if something changes, see if the user wants to save
//    reloadAfterSubmit: false,   //because we are manually handling the data, don't automatically reload the data, this has the adverse affect of sort not being reapplied
//    viewPagerButtons: false,
//    //topinfo: "Please fill out all required fields.",
//    bottominfo: "(*) required",
//    addedrow: "last",
//    afterShowForm: function (formid) {
//        //center the dialog, container is a few up from the form
//        jQuery(formid).parent().parent().parent().position({ of: jQuery(window) });
//    },
//    //afterSubmit: function (response, postdata) {
//    //    //handle this event so we can set our new id properly,
//    //    //since we are not performing any server-side opration, we must manually create id values here
//    //    //it is not important to use this function because we don't care what the id value is

//    //    //add or edit?
//    //    if (postdata["id"] === "_empty") {
//    //        //establish a new unique @id value to simulate the server returning a new record key value
//    //        delete postdata["id"];
//    //        postdata["@id"] = Math.random();

//    //        //add the new row of data
//    //        //gridElement.jqGrid("addRowData", "new", postdata);
//    //    }
//    //    else {
//    //        //get the old value
//    //        postdata["@id"] = postdata["id"];
//    //        delete postdata["id"];

//    //        //must update the row manually because we are changing the "id" key name
//    //        jTable.jqGrid("setRowData", postdata["@id"], postdata);
//    //    }

//    //    return [true, "", postdata["@id"]];
//    //},
//    //this method is not implemented when not rendering in edit mode
//    //afterComplete: function (response, postdata, formid) {
//    //    //after every save operation, save to our hidden field so it can be posted back for server-side processing
//    //    alert("dialogFormOptions.afterComplete() called.");
//    //    saveGridData(id);
//    //}
//};

(function ($) {
    $.fn.extend({
        center: function () {
            $(this).css({
                "position": "absolute",
                "top": (($(window).height() - this.outerHeight()) / 2) + $(window).scrollTop() + "px",
                "left": (($(window).width() - this.outerWidth()) / 2) + $(window).scrollLeft() + "px"
            });
        }
    });
})(jQuery);

////////////////////////////////////////////////////////////////////////////////////////////////////

//IE < 9 does not support Array.indexOf(), so make a prototype that enables this functionality
//this has been depricated in place of the missing function section at the bottom of this script
//if (!Array.prototype.indexOf) {
//    Array.prototype.indexOf = function (searchElement /*, fromIndex */) {
//        "use strict";
//        if (this == null) {
//            throw new TypeError();
//        }
//        var t = Object(this);
//        var len = t.length >>> 0;
//        if (len === 0) {
//            return -1;
//        }
//        var n = 0;
//        if (arguments.length > 0) {
//            n = Number(arguments[1]);
//            if (n != n) { // shortcut for verifying if it's NaN
//                n = 0;
//            } else if (n != 0 && n != Infinity && n != -Infinity) {
//                n = (n > 0 || -1) * Math.floor(Math.abs(n));
//            }
//        }
//        if (n >= len) {
//            return -1;
//        }
//        var k = n >= 0 ? n : Math.max(len - Math.abs(n), 0);
//        for (; k < len; k++) {
//            if (k in t && t[k] === searchElement) {
//                return k;
//            }
//        }
//        return -1;
//    }
//}

////////////////////////////////////////////////////////////////////////////////////////////////////
//missing string and Array function

'use strict';

// Add ECMA262-5 method binding if not supported natively 

if (!('bind' in Function.prototype)) {
    Function.prototype.bind = function (owner) {
        var that = this;
        if (arguments.length <= 1) {
            return function () {
                return that.apply(owner, arguments);
            };
        } else {
            var args = Array.prototype.slice.call(arguments, 1);
            return function () {
                return that.apply(owner, arguments.length === 0 ? args : args.concat(Array.prototype.slice.call(arguments)));
            };
        }
    };
}

// Add ECMA262-5 string trim if not supported natively 

if (!('trim' in String.prototype)) {
    String.prototype.trim = function () {
        return this.replace(/^\s+/, '').replace(/\s+$/, '');
    };
}

// Add ECMA262-5 Array methods if not supported natively 

if (!('indexOf' in Array.prototype)) {
    Array.prototype.indexOf = function (find, i /*opt*/) {
        if (i === undefined) i = 0;
        if (i < 0) i += this.length;
        if (i < 0) i = 0;
        for (var n = this.length; i < n; i++)
            if (i in this && this[i] === find)
                return i;
        return -1;
    };
}

if (!('lastIndexOf' in Array.prototype)) {
    Array.prototype.lastIndexOf = function (find, i /*opt*/) {
        if (i === undefined) i = this.length - 1;
        if (i < 0) i += this.length;
        if (i > this.length - 1) i = this.length - 1;
        for (i++; i-- > 0;) /* i++ because from-argument is sadly inclusive */
            if (i in this && this[i] === find)
                return i;
        return -1;
    };
}

if (!('forEach' in Array.prototype)) {
    Array.prototype.forEach = function (action, that /*opt*/) {
        for (var i = 0, n = this.length; i < n; i++)
            if (i in this)
                action.call(that, this[i], i, this);
    };
}

if (!('map' in Array.prototype)) {
    Array.prototype.map = function (mapper, that /*opt*/) {
        var other = new Array(this.length);
        for (var i = 0, n = this.length; i < n; i++)
            if (i in this)
                other[i] = mapper.call(that, this[i], i, this);
        return other;
    };
}

if (!('filter' in Array.prototype)) {
    Array.prototype.filter = function (filter, that /*opt*/) {
        var other = [], v;
        for (var i = 0, n = this.length; i < n; i++)
            if (i in this && filter.call(that, v = this[i], i, this))
                other.push(v);
        return other;
    };
}

if (!('every' in Array.prototype)) {
    Array.prototype.every = function (tester, that /*opt*/) {
        for (var i = 0, n = this.length; i < n; i++)
            if (i in this && !tester.call(that, this[i], i, this))
                return false;
        return true;
    };
}

if (!('some' in Array.prototype)) {
    Array.prototype.some = function (tester, that /*opt*/) {
        for (var i = 0, n = this.length; i < n; i++)
            if (i in this && tester.call(that, this[i], i, this))
                return true;
        return false;
    };
}

////////////////////////////////////////////////////////////////////////////////////////////////////