Friday, April 24, 2015

/// <reference path="./jquery-1.10.2-vsdoc.js" />
/// <reference path="./jquery-ui-1.10.3.js" />
/// <reference path="./jquery.jqGrid.src.js" />

window.jqGridSettings = {};


function bindConfiguration(key, options) {

    var p = window.jqGridSettings[options.idPrefix];

    if (p === null || p === undefined) {
        // do init work here.
        p = $.extend(true, {
            cols: [
            ],
            gridTitle: "",
            idPrefix: "grid",
            containerId: "gridContainer",
            exportUrl: "/Export/Excel",
            oDataEndPoint: "/odata/States",
            useVirtualScrolling: 1,
            gridHeight: 500,
            windowResizeDelay: -1, // windowResizeDelay is a marker to be able to clear the setTimeout function in case the window is still being resized.
            quoteFilters: [],

            container: null,
            form: null,
            filenameField: null,
            oDataField: null,
            filterField: null,
            orderByField: null,

            list: null,
            table: null,
            pager: null,

            multiSelect: false,
            onRowSelection: undefined,
            onPageChange: undefined,
            onGridReload: undefined,
            onAllSelection: undefined,
            onSortColumnClick: undefined
        }, options || {});

        p.quoteFilters = getQuoteFlags(p.cols);

        // this is the container on the html page where the grid will be rendered.
        p.container = $("#" + p.containerId);


        // this form (and the four elements below) are what allow us to do the server-side rendering of the excel file.
        p.form = document.createElement("form");
        p.form.id = p.idPrefix + "-form";
        p.form.method = "POST";
        p.form.action = p.exportUrl;
        document.body.appendChild(p.form);


        // filename
        p.filenameField = document.createElement("input");
        p.filenameField.type = "hidden";
        p.filenameField.id = p.idPrefix + "-filename";
        p.filenameField.name = "Filename";
        p.filenameField.value = "";
        p.form.appendChild(p.filenameField);

        // ODataUrl
        p.oDataField = document.createElement("input");
        p.oDataField.type = "hidden";
        p.oDataField.id = p.idPrefix + "-ODataUrl";
        p.oDataField.name = "ODataUrl";
        p.oDataField.value = p.oDataEndPoint;
        p.form.appendChild(p.oDataField);

        // Filter
        p.filterField = document.createElement("input");
        p.filterField.type = "hidden";
        p.filterField.id = p.idPrefix + "-Filter";
        p.filterField.name = "Filter";
        p.filterField.value = "";
        p.form.appendChild(p.filterField);

        // OrderBy
        p.orderByField = document.createElement("input");
        p.orderByField.type = "hidden";
        p.orderByField.id = p.idPrefix + "-OrderBy";
        p.orderByField.name = "OrderBy";
        p.orderByField.value = "";
        p.form.appendChild(p.orderByField);

        // The grid definition.  It takes 3 components:
        //        a div for the "list"
        p.list = document.createElement("div");
        p.list.id = p.idPrefix + "-list";
        p.container.append(p.list);

        p.table = document.createElement("table");
        p.table.id = p.idPrefix + "-table";
        p.container.append(p.table);

        p.pager = document.createElement("div");
        p.pager.id = p.idPrefix + "-pager";
        p.container.append(p.pager);

        window.jqGridSettings[p.idPrefix] = p;
    }

    return p;
}


function generateGrid(options) {

    var oKey = options.idPrefix || "grid";

    // our default options... the expectation is that the end developer sets all of these in the *.html code.
    var p = bindConfiguration(oKey, options);

    // building the grid here.
    var grid = $(p.table).jqGrid({
        url: p.oDataEndPoint,
        datatype: "json",
        height: p.gridHeight,
        autowidth: true, // allows the grid to expand to the max. width given its parent container.
        pager: "#" + p.pager.id,
        viewrecords: true,
        caption: p.gridTitle,
        gridview: true,
        // allows the user to sort by multiple columns.  the catch here is that the column ordering in the grid sets the prescedence for the
        // hierarchy of the sort.. so if you have id first, then date, then name, it's going to sort by id, date, and name.  to sort by date,
        // then name, the user will need to drag the "name" field to the first position, then the "date" field to the second position, then
        // click the columns to get the ordering (asc/desc) that they wish.
        multiSort: true,
        sortable: true, // allows the user to sort the ordering of the columns.
        colNames: getHeaders(p.cols),
        colModel: getColumDefinitions(p.cols),
        rowNum: 50,
        rowList: [10, 25, 50, 75, 100],
        multiselect: p.multiSelect,
        scroll: p.useVirtualScrolling, // turns on/off scrolling vs. paging.
        onSelectRow: p.onRowSelection, // Added by Sarthak Joshi : Allows event to be triggered after a particular row is selected [Note : onSelectRow is original jQGrid event]
        onPaging: p.onPageChange,
        gridComplete: p.onGridReload, // Added by Sarthak Joshi : Allows event to be triggered after grid is reloaded when paging is enabled [Note : loadComplete is original jQGrid event]
        onSelectAll: p.onAllSelection, // Added by Sarthak Joshi : Allows event to be triggered after select all checkbox is checked when MultiSelect is true [Note : onSelectAll is original jQGrid event]
        onSortCol: p.onSortColumnClick, // Added by Sarthak Joshi : Allows event to be triggered when sortable column header is clicked [Note : onSortCol is original jQGrid event]
        ajaxGridOptions: {
            contentType: "application/json charset=utf-8"
        },
        serializeGridData: function (postData) { return setupWebServiceData(postData, p); },
        beforeProcessing: function (data, textStatus, jqXHR) {
            // builds out the total page count for the data returned.
            var rows = parseInt($(this).jqGrid("getGridParam", "rowNum"), 10);
            data.total = Math.ceil(data["Count"] / rows); // change to odata.count if using Odata API
        },
        jsonReader: {
            root: "Items", // the root node of the Json, change to value for OData api.
            repeatitems: false, // tells the grid to find the data by property name.
            records: "Count" // the path to get the record count., change to OData.count for OData api.
        },
        loadError: function (jqXHR, textStatus, errorThrown) {
            alert('HTTP status code: ' + jqXHR.status, +'\n' +
                'textStatus: ' + textStatus + '\n' +
                'errorThrown: ' + errorThrown);
        }
    });

    buildNavigation(grid);





    var parentContainer = $("#" + p.containerId);
    $("#sidenav-flyout-btn").on("click", function () {
        setTimeout(function () {
            p.windowResizeDelay = beginResize(grid, parentContainer, p.windowResizeDelay);
        }, 200);
    });

    $(window).resize(function (event, ui) {
        p.windowResizeDelay = beginResize(grid, parentContainer, p.windowResizeDelay);
    });

    return grid;
};

function setupWebServiceData(postData, p) {
    // basic posting parameters to the OData service.
    var params = {
        $top: postData.rows,
        $skip: (parseInt(postData.page, 10) - 1) * postData.rows,
        $inlinecount: "allpages"
    };

    // if we have an order-by clause to use, then we build it.
    if (postData.sidx) {

        // two columns have the following data:
        // postData.sidx = "{ColumnName} {order}, {ColumnName} "
        // postData.sord = "{order}"
        // we need to split sidx by the ", " and see if there are multiple columns.  If there are, we need to go through
        // each column and get its parts, then parse that for the appropriate columns to build for the sort.

        var splitColumnOrdering = (postData.sidx + postData.sord).split(", ");

        if (splitColumnOrdering.length == 1) {
            params.$orderby = buildColumnSort(splitColumnOrdering[0], quoteFilters);
        } else {
            var colOrdering = $.map(splitColumnOrdering, function (element, idx) {
                return buildColumnSort(element, quoteFilters);
            });
            params.$orderby = colOrdering.join(", ");
        }
    }

    // if we want to support "in" clauses, we need to follow this stackoverflow article:
    //http://stackoverflow.com/questions/7745231/odata-where-id-in-list-query/7745321#7745321
    // this is for basic searching, with a single term.
    if (postData.searchField) {
        var quoteFilter = findQuoteFilter(postData.searchField, quoteFilters);
        params.$filter = ODataExpression(postData.searchOper, postData.searchField, postData.searchString, quoteFilters);
    }

    // complex searching, with a groupOp.  This is for if we enable the form for multiple selection criteria.
    if (postData.filters) {
        var filterGroup = $.parseJSON(postData.filters);
        params.$filter = parseFilterGroup(filterGroup, p.quoteFilters);
    }

    // sets the form elements with the filter/group parameters, so that the user can
    // export the data to excel if they so choose.
    $("#" + p.idPrefix + "-Filter").val(params.$filter);
    $("#" + p.idPrefix + "-OrderBy").val(params.$orderby);

    return params;
}

function buildNavigation(grid) {


    var key = grid.context.id.split("-")[0];

    var p = bindConfiguration(key, { idPrefix: key });

    grid.navGrid("#" + p.pager.id, { search: true, edit: false, add: false, del: false },
        {}, // default settings for edit
        {}, // default settings for add
        {}, // delete
        {closeOnEscape: true, multipleSearch: true, closeAfterSearch: true, multipleGroup: true} // search options.
    );
    // adds a little space between buttons
    grid.navSeparatorAdd("#" + p.pager.id, { sepclass: "", sepcontent: " " })
    // creates the "Save" button.
    grid.jqGrid("navButtonAdd", "#" + p.pager.id, {
        caption: "Save Filter",
        buttonicon: "none",
        onClickButton: function () { showSaveFilterUI(p); },
        position: "last",
        title: "Save Filter",
        cursor: "pointer"
    });
    // adds a little space between buttons
    grid.navSeparatorAdd("#" + p.pager.id, { sepclass: "", sepcontent: " " });
    // creates the "Save" button.
    grid.jqGrid("navButtonAdd", "#" + p.pager.id, {
        caption: "Load Filter",
        buttonicon: "none",
        onClickButton: function () { showLoadFilterUI(p, p.pager); },
        position: "last",
        title: "Load Filter",
        cursor: "pointer"
    });
    // adds a little space between buttons
    grid.navSeparatorAdd("#" + p.pager.id, { sepclass: "", sepcontent: " " });
    // Creates the "Excel" button.
    grid.jqGrid("navButtonAdd", "#" + p.pager.id, {
        caption: "Excel",
        buttonicon: "none",
        onClickButton: function () { showExportExcelUI(p); },
        position: "last",
        title: "Export to Excel",
        cursor: "pointer"
    });
};

// sets up resizing the grid in the event that the user shows/hides navigation, or
// resizes the window.
function beginResize(grid, container, delay) {
    if (delay !== -1) {
        clearTimeout(delay);
        delay = -1;
    }

    delay = setTimeout(function () {
        var newWidth = container.width();
        grid.setGridWidth(newWidth, true);
        delay = -1;
    }, 100);

    return delay;
}


// tools to load the settings
function showLoadFilterUI(p, pager) {

    $.get("/GridFilters/Load/?prefix=" + p.idPrefix)
        .then(function (htmlPartial) {

            var loadFilterDialog = $("<div>" + htmlPartial + "</div>").dialog({
                title: "Load Saved Filter...",
                height: 150,
                width: 300,
                modal: true,
                buttons: [{
                    text: "Ok",
                    click: function () {


                        var grid = $("#" + p.idPrefix + "-table");
                        var dd = $("#gridFilterSelection");

                        $.get("/api/GridFilters/" + dd.val())
                        .then(function (data) {

                            loadFilterDialog.dialog("close"); // should get rid of dailog here.

                            //$("#" + p.table.id).jqGrid("getGridParam", "postData"); gives the search/sort params.
                            //$("#" + p.table.id).jqGrid("getGridParam", "colModel"); do a grep/each and take the index for saving.
                            //$("#" + p.table.id).jqGrid("getGridParam", "colNames"); titles of each column.
                            //$("#" + p.table.id).jqGrid("remapColumns", newOrder, true, true); reorders the columns (and headers)

                            var options = $.parseJSON(data);

                            // reorder the columns.
                            var gridCols = grid.jqGrid("getGridParam", "colModel");



                            var newOrder = $.map(options.colOrder, function (arg, idx) {

                                var colObj = $.grep(gridCols, function (col, colIdx) {
                                    return col.index === arg;
                                })[0];

                                var columnIndex = gridCols.indexOf(colObj);
                                return columnIndex;
                            });

                            // set the post data.
                            var gridPostData = grid.jqGrid("getGridParam", "postData");
                            gridPostData.filters = options.postData.filters;
                            gridPostData.rows = options.postData.rows;
                            gridPostData.page = options.postData.page;
                            gridPostData.sidx = options.postData.sidx;
                            gridPostData.sord = options.postData.sord;

                            grid.jqGrid("remapColumns", newOrder, true, false);

                            grid.trigger("reloadGrid");
                            //grid.jqGrid("remapColumns", newOrder, true, true);
                        }, function (data) {
                            alert("An error occurred?");
                        });

                    }
                }, {
                    text: "Cancel",
                    click: function () {
                        $(this).dialog("close");
                    }
                }],
                close: function (event, ui) {
                    $(this).dialog("destroy");
                    $(this).remove();
                }
            });
        });
};

function showExportExcelUI(p) {

    // the dialog to prompt the user for the respective file name.
    $("<div></div>").dialog({
        title: "Save As...",
        height: 150,
        width: 300,
        modal: true,
        buttons: [{
            text: "Ok",
            click: function () {

                // copy the value from the dialog's text box to the form to be sumbitted's field to hold the file name.
                var formFileField = $("#" + p.idPrefix + "-filename");
                var dialogValue = $("#" + p.idPrefix + "-dlgFilename");
                formFileField.val(dialogValue.val());

                if (formFileField.val()) {
                    p.form.submit();
                    $(this).dialog("close");
                } else {
                    alert("File name was not provided!");
                }
            }
        }, {
            text: "Cancel",
            click: function () {
                // closes the file.
                $(this).dialog("close");
            }
        }],
        close: function (event, ui) {
            // desconstructs the Dailog and removes the html elements that are added to the page.
            $(this).dialog("destroy");
            $(this).remove();
        }
    }).html("<label for=\"" + p.idPrefix + "-dlgFilename\">Filename:</label>" +
                "<input type=\"text\" id=\"" + p.idPrefix + "-dlgFilename\" style=\"float: right; width: 175px;\" />");
}
// builds the grid search/filter export settings ui.
function showSaveFilterUI(p) {

    $.get("/GridFilters/Save?prefix=" + p.idPrefix).then(function (data) {
        var dialog = $("<div id='settingsExportDialog'>" + data + "</div>").dialog({
            title: "Export Grid Settings...",
            modal: true,
            width: 500,
            height: 300,
            close: function () {
                $(this).dialog("destroy");
                $(this).remove();
            },
            buttons: [
                {
                    text: "Save",
                    click: function (event, ui) {
                        var form = $($("#gridFilterSaveForm")[0]);
                        var settings = $("#gridFilterSaveForm input[name=Settings]");

                        var colIds = $.map($("#" + p.table.id).jqGrid("getGridParam", "colModel"), function (element, index) {
                            return element.index;
                        });

                        var options = {
                            postData: $("#" + p.table.id).jqGrid("getGridParam", "postData"),
                            colOrder: colIds
                        };

                        settings.val(JSON.stringify(options));

                        $.post(form.context.action, form.serialize(), function (data) {
                            dialog.html(data);
                        });
                    }
                },
                {
                    text: "Close",
                    click: function (event, ui) {
                        $(this).dialog("close");
                    }
                }
            ]
        });
    });
}

// builds the column headers array from the Json we pass to the
// main grid builder class.
function getHeaders(cols) {
    return $.map(cols, function (element, idx) {
        return element.headerTitle;
    });
}

// builds the jqGrid column definition from the data we pass.  We need
// to alter for dates that I can think of, and need to discuss other data
// types to decide what we'd want to do for each (specifically the search options.)
function getColumDefinitions(cols) {
    return $.map(cols, function (element, idx) {

        var ele = $.extend(true, {
            allowSearch: true
        }, element || {});

        var col = {
            name: ele.fieldName,
            index: ele.fieldName,
            search: ele.allowSearch
        };

        if (ele.formatter) {
            col = $.extend(true, { formatter: ele.formatter }, col || {});
        }
        if (ele.width) {
            col = $.extend(true, { width: ele.width }, col || {});
        }

        switch (ele.dataType) {
            case "hidden":
                col = $.extend(true, {
                    sortable: false,
                    hidden: true,
                    searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge', 'bw', 'bn', 'ew', 'en', 'cn', 'nc', 'nu', 'nn'], searchhidden: true }
                }, col || {});
                break;
            case "hidden-number":
                col = $.extend(true, {
                    sortable: false,
                    hidden: true,
                    searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'], searchhidden: true }
                }, col || {});
                break;
            case "number":
                col = $.extend(true, {
                    sortable: true,
                    search: ele.allowSearch,
                    searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'] },
                    cellattr: function (rowId, tv, rawObject, cm, rdata) {
                        return 'style="vertical-align: middle;"';
                    }
                }, col || {});
                break;
            case "link":
                col = $.extend(true, {
                    sortable: false,
                    formatter: ele.linkFormatter,
                    cellattr: function (rowId, tv, rawObject, cm, rdata) {
                        return 'style="vertical-align: middle;"';
                    }
                }, col || {});
                col.search = false;
                break;
            case "boolean":
                col = $.extend(true, {
                    sortable: true,
                    cellattr: function (rowId, tv, rawObject, cm, rdata) {
                        return 'style="vertical-align: middle;"';
                    },
                    stype: "select",
                    formatter: function (cellvalue, options, rowObject) {
                        return cellvalue ? "Enabled" : "Disabled";
                    },
                    searchoptions: { sopt: ['eq', 'ne'], value: "bool-true:Enabled;bool-false:Disabled" }
                }, col || {});
                break;
            case "list-number":
            case "list":
                var searchops = { sopt: ["eq"] };

                if (ele.searchItems !== undefined) {
                    searchops = $.extend(true, { value: ele.searchItems }, searchops || {});
                };

                col = $.extend(true, {
                    sortable: false,
                    cellattr: function (rowId, tv, rawObject, cm, rdata) {
                        return 'style="white-space: normal; vertical-align: middle;"';
                    },
                    stype: "select",
                    searchoptions: searchops
                }, col || {});
                break;
            case "lookup":
                var searchOps = { sopt: ["eq"] };

                if (ele.searchItems !== undefined) {
                    searchOps = $.extend(true, { value: ele.searchItems }, searchOps || {});
                };

                col = $.extend(true, {
                    sortable: true,
                    cellattr: function (rowId, tv, rawObject, cm, rdata) {
                        return 'style="white-space: normal; vertical-align: middle;"';
                    },
                    stype: "select",
                    searchoptions: searchOps
                }, col || {});
                break;
            default:
                col = $.extend(true, {
                    sortable: true,
                    searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge', 'bw', 'bn', 'ew', 'en', 'cn', 'nc', 'nu', 'nn'] },
                    searchrules: {},
                    cellattr: function (rowId, tv, rawObject, cm, rdata) {
                        return 'style="white-space: normal; vertical-align: middle;"';
                    }
                }, col || {});
                break;
        }

        return col;
    });
}

// when dealing with the advanced query dialog, this parses the encapsulating Json object
// which we will then build the advanced OData expression from.
function parseFilterGroup(filterGroup, filters) {

    var filterText = "";

    if (filterGroup.groups) {
        if (filterGroup.groups.length) {
            for (var i = 0; i < filterGroup.groups.length; i++) {
                filterText += "(" + parseFilterGroup(filterGroup.groups[i]) + ")";

                if (i < filterGroup.groups.length - 1) {
                    filterText += " " + filterGroup.groupOp.toLowerCase() + " ";
                }
            }

            if (filterGroup.rules && filterGroup.rules.length) {
                filterText += " " + filterGroup.groupOp.toLowerCase() + " ";
            }
        }
    }

    if (filterGroup.rules.length) {

        // fields that are considered as a list should get built as a single
        // odata expression.
        var listFields = $.grep(filterGroup.rules, function (rule, idx) {
            var foundFilter = findQuoteFilter(rule.field, filters);
            if (foundFilter.isList !== undefined) {
                return foundFilter.isList;
            }
            return false;
        });

        var allListNames = $.map(listFields, function (rule, idx) {
            return rule.field;
        });

        var distinctFieldNames = $.unique(allListNames);

        $.each(distinctFieldNames, function (idx, fieldName) {

            var fieldValues = $.grep(listFields, function (fieldValue, idx) {
                return fieldValue.field === fieldName;
            });

            var fieldDataValues = $.map(fieldValues, function (rule, idx) {
                return rule.data;
            });

            var foundFilter = findQuoteFilter(fieldName, filters);

            filterText += ODataListExpression(filterGroup.groupOp.toLowerCase(), fieldName, fieldDataValues, foundFilter);
        });

        var elementFields = $.grep(filterGroup.rules, function (rule, idx) {
            var foundFilter = findQuoteFilter(rule.field, filters);
            if (foundFilter.isList !== undefined) {
                return !foundFilter.isList;
            }
            return true;
        });

        for (var i = 0; i < elementFields.length; i++) {
            var rule = filterGroup.rules[i];

            var filter = findQuoteFilter(rule.field, filters);
            filterText += ODataExpression(rule.op, rule.field, rule.data, filter);

            if (i < filterGroup.rules.length - 1) {
                filterText += " " + filterGroup.groupOp.toLowerCase() + " ";
            }
        }
    }

    return filterText;
}

// comparer should be a value of 'and' or 'or'.
// quoteFlags = { col: element.fieldName, quoteValue: false, isList: true, baseQuery: element.baseQuery, baseQueryParam: element.baseQueryParam };
function ODataListExpression(comparer, field, dataItems, filter) {

    var quoteData = $.grep(filter, function (element, idx) {
        return element.col === field;
    });

    var params = $.map(dataItems, function (element, idx) {
        var param = quoteDataVal(element, filter);
        return filter.baseQueryParam.replace("{0}", param);
    });

    var paramstring = params.join(" " + comparer + " ");
    return filter.baseQuery.replace("{0}", paramstring);
}

// builds out OData expressions... the condition.
function ODataExpression(op, field, data, filter) {

    var dataVal = quoteDataVal(data, filter);

    // lists are a unique concern.  with lists, we have to provide an xml/json path
    // for OData to query against.  The best way to handle this is to define the base
    // path query within each Index() page, and use that here with some sort of string.replace
    // or string.format javascript function.

    switch (op) {
        case "cn":
            return "substringof(" + dataVal + ", " + field + ") eq true";
        case "nc": // does not contain.
            return "substringof(" + dataVal + ", " + field + ") eq false";
        case "bw":
            return "startswith(" + field + ", " + dataVal + ") eq true";
        case "bn": // does not begin with
            return "startswith(" + field + ", " + dataVal + ") eq false";
        case "ew":
            return "endswith(" + field + ", " + dataVal + ") eq true";
        case "en": // does not end with.
            return "endswith(" + field + ", " + dataVal + ") eq false";
        case "nu":
            return field + " eq null";
        case "nn":
            return field + " ne null";
        default:
            return field + " " + op + " " + dataVal;
    }
};

/// cols is an array.
function getQuoteFlags(cols) {
    return $.map(cols, function (element, idx) {
        //sortCols
        var quoteFlags;

        switch (element.dataType) {
            case "hidden":
                quoteFlags = { col: element.fieldName, quoteValue: true, isList: false };
                break;
            case "hidden-number":
                quoteFlags = { col: element.fieldName, quoteValue: false, isList: false };
                break;
            case "number":
                quoteFlags = { col: element.fieldName, quoteValue: false, isList: false };
                break;
            case "link":
                quoteFlags = { col: element.fieldName, quoteValue: false, isList: false };
                break;
            case "boolean":
                quoteFlags = { col: element.fieldName, quoteValue: false, isList: false };
                break;
            case "list-number":
                quoteFlags = { col: element.fieldName, quoteValue: false, isList: true, baseQuery: element.baseQuery, baseQueryParam: element.baseQueryParam };
                break;
            case "list":
                quoteFlags = { col: element.fieldName, quoteValue: true, isList: true, baseQuery: element.baseQuery, baseQueryParam: element.baseQueryParam };
                break;
            default:
                quoteFlags = { col: element.fieldName, quoteValue: true, isList: false };
                break;
        };

        if (element.sortCols !== undefined) {
            quoteFlags = $.extend(true, {
                sortCols: element.sortCols
            }, quoteFlags || {});
        };

        return quoteFlags;
    });
};

// primarily used for the bid text code, the idea here is that we
// can do the sorting for numerics and codes so that all of the 13's
// are grouped together for the UI.
function buildColumnSort(gridColCommand, filters) {
    var parts = gridColCommand.split(" ");

    if (parts.length !== 2) {
        throw new Error("Cannot build a sort command without the column name and the direction.");
    }

    var col = parts[0];
    var direction = parts[1];

    if (col === "" || direction === "") {
        throw new Error("We need to know both the column name and the sort direction.");
    }

    var quoteData = $.grep(filters, function (element, idx) {
        return element.col === col;
    });

    if (quoteData.length === 0) {
        // if we don't have a definition for the field, then we can't filter/search for it.
        return "";
    };

    quoteData = quoteData[0];

    if (quoteData.sortCols !== undefined) {
        var colSorts = [];

        for (var i = 0; i < quoteData.sortCols.length; i++) {
            colSorts.push(quoteData.sortCols[i] + " " + direction);
        };

        return colSorts.join(", ");
    }

    return col + " " + direction;
}

function quoteDataVal(data, filter) {

    if (filter.quoteValue) {
        return "'" + data + "'";
    }

    return data;
}

function findQuoteFilter(field, filters) {
    var quoteFilter = $.grep(filters, function (element, idx) {
        return element.col === field;
    });

    if (quoteFilter.length === 0) {
        throw new Error("Cannot find appropriate quote filter for field: " + field);
    };

    return quoteFilter[0];
}

No comments: