Javascript jqGrid FilterToolbar,主要使用工作日期范围选择器

Javascript jqGrid FilterToolbar,主要使用工作日期范围选择器,javascript,jquery,date,jqgrid,free-jqgrid,Javascript,Jquery,Date,Jqgrid,Free Jqgrid,我正在使用免费的jqGrid v4.12.1。(还不能将链接发布到fiddle,所以代码跟随帖子) 主要问题是,我们正在尝试使用filterToolbar进行所有搜索/筛选。Oleg已经帮助将日期推回到搜索模式,但要求已经改变,让日期范围选择器在filterToolbar中工作。我们大部分时间都在那里。使用Dan Grossman的引导日期范围选择器并调用自定义函数,它的工作方式就像一个符咒。 当您选择另一个值(如发票金额)时,问题最初出现。然后,它将覆盖日期范围,并将所有值“ge”指定为开始

我正在使用免费的jqGrid v4.12.1。(还不能将链接发布到fiddle,所以代码跟随帖子)

主要问题是,我们正在尝试使用filterToolbar进行所有搜索/筛选。Oleg已经帮助将日期推回到搜索模式,但要求已经改变,让日期范围选择器在filterToolbar中工作。我们大部分时间都在那里。使用Dan Grossman的引导日期范围选择器并调用自定义函数,它的工作方式就像一个符咒。

当您选择另一个值(如发票金额)时,问题最初出现。然后,它将覆盖日期范围,并将所有值“ge”指定为开始日期。所以它看到了字符串的开始日期。为了避免这种情况,我在beforeSearch中再次调用了invoiceDateSearch函数。通过这种方式,它再次运行函数并识别开始日期和结束日期以及我们要求的新值

现在发生的事情是,如果我先输入任何其他值,然后选择daterange,daterange将不会启动,直到我键入其他搜索条件并将其退出。 它甚至还不能识别输入的日期范围,而很明显它就在那里。triggerToolbar,在发票日期搜索函数中调用重新加载网格

使用beforeSearch时,将日期范围保留为日期范围而不是字符串…无论触发工具栏的频率有多高,值也会从任何其他字段中退出,这非常好。缺点是,如果用户先输入日期范围以外的值,则日期范围不起作用……除非输入后续字段。如果不使用它,则在第一次使用日期范围后将其转换为字符串,并且输入或筛选的任何其他值都需要重新运行日期参数,因为它给出的每个日期都大于开始日期

在进行故障排除时,我已将高级搜索置于网格上。我想去掉它(或者至少是按钮),因为用户只想使用工具栏过滤器

我的问题是,如何使日期范围选择器与其他列值协同工作?同时运行两个日期选择器是否存在问题?单一日期选择器在使用时根本没有响应。它将把日期放在那里,一旦另一个字段被触发,它将做出响应,但不会自行响应

对不起,如果我“信息倾销”我是相当新的在这方面。我已经找了很多人帮忙,但什么都找不到。如果我继续这样做,我会撕毁我的作品O

提前感谢您的帮助或指导! $(函数(){ “严格使用”

var$grid=$(“#vGrid2”),
拉塞尔;
函数modifySearchingFilter(分隔符){
var i,
L
规则,
规则,
部分,
J
集团,,
str,
filters=$.parseJSON(this.p.postData.filters);
if(filters&&typeof filters.rules!='undefined'&&filters.rules.length>0){
规则=过滤器。规则;
对于(i=0;i1){
if(typeof filters.groups==‘未定义’){
filters.groups=[];
}
组={
groupOp:'和',
组:[],
规则:[]
};
filters.groups.push(组);
对于(j=0,l=parts.length;j=0;i--){
if(postData.filters.rules[i].field==field){
postData.过滤器.规则.拼接(i,1);
}
}
}
var dateRangeString=$(“#gs_InvoiceDate”).val();
如果(dateRangeString.length>0){
var dateRange=dateRangeString.split(“-”);
var startDate=dateRange[0];
var结束日期;
如果(dateRange.length==1){
endDate=日期范围[0];
}否则{
endDate=日期范围[1];
}
postData.filters.rules.push({“field”:field,“op”:“ge”,“data”:startDate.trim()});
postData.filters.rules.push({“field”:field,“op”:“le”,“data”:endDate.trim()});
postData.filters=JSON.stringify(postData.filters);
//需要将网格的搜索设置为true,而不是pos
var $grid = $("#vGrid2"),
lastSel;
function modifySearchingFilter(separator) {
    var i,
        l,
        rules,
        rule,
        parts,
        j,
        group,
        str,
        filters = $.parseJSON(this.p.postData.filters);
    if (filters && typeof filters.rules !== 'undefined' && filters.rules.length > 0) {
        rules = filters.rules;
        for (i = 0; i < rules.length; i++) {
            rule = rules[i];
            if (rule.op === 'cn') {
                // make modifications only for the 'contains' operation
                parts = rule.data.split(separator);
                if (parts.length > 1) {
                    if (typeof filters.groups === 'undefined') {
                        filters.groups = [];
                    }
                    group = {
                        groupOp: 'AND',
                        groups: [],
                        rules: []
                    };
                    filters.groups.push(group);
                    for (j = 0, l = parts.length; j < l; j++) {
                        str = parts[j];
                        if (str) {
                            // skip empty '', which exist in case of two separators of once
                            group.rules.push({
                                data: parts[j],
                                op: rule.op,
                                field: rule.field
                            });
                        }
                    }
                    rules.splice(i, 1);
                    i--; // to skip i++
                }
            }
        }
        this.p.postData.filters = JSON.stringify(filters);
    }
};
//TODO: search is filtering in the grid but only from start date and either ge or le start date based on which is first in the column
//TODO: (cont)model.  Need to see why end date is not picking up from function.

function invoiceDateSearch($subGrid) {
    var postData = $subGrid.getGridParam("postData");
    // If there is no post data for some reason, get outta here
    if (!postData) {
        return;
    }
    // Make sure the filters object is constructed
    var field = "InvoiceDate";
    if (!postData.filters) {
        postData.filters = {
            groupOp: "AND",
            rules: []
        }
    } else {
        postData.filters = jQuery.jgrid.parse(postData.filters);
        // Need to clear out existing invoice date rules
        for (var i = postData.filters.rules.length - 1; i >= 0; i--) {
            if (postData.filters.rules[i].field === field) {
                postData.filters.rules.splice(i, 1);
            }
        }
    }

    var dateRangeString = $("#gs_InvoiceDate").val();
    if (dateRangeString.length > 0) {
        var dateRange = dateRangeString.split("-");
        var startDate = dateRange[0];
        var endDate;
        if (dateRange.length == 1) {
            endDate = dateRange[0];
        } else {
            endDate = dateRange[1];
        }
        postData.filters.rules.push({ "field": field, "op": "ge", "data": startDate.trim() });
        postData.filters.rules.push({ "field": field, "op": "le", "data": endDate.trim() });
        postData.filters = JSON.stringify(postData.filters);
        // Need to set the grid's search to true, not the postData's

        $subGrid.setGridParam({ search: true });
        $subGrid.trigger("reloadGrid", [{ current: true, page: 1 }]);
    }
}
function paymentDateSearch($subGrid) {
    var postData = $subGrid.getGridParam("postData");
    // If there is no post data for some reason, get outta here
    if (!postData) {
        return;
    }
    // Make sure the filters object is constructed
    var field = "PaymentDate";
    if (!postData.filters) {
        postData.filters = {
            rules: []
        }
    } else {
        postData.filters = jQuery.jgrid.parse(postData.filters);
        // Need to clear out existing invoice date rules
        for (var i = postData.filters.rules.length - 1; i >= 0; i--) {
            if (postData.filters.rules[i].field === field) {
                postData.filters.rules.splice(i, 1);
            }
        }
    }

    var dateString = $("#gs_PaymentDate").val();
    if (dateString.length > 0) {
        var startDate = dateRange[0];

        postData.filters.rules.push({ "field": field, "op": "eq", "data": startDate.trim() });
        postData.filters = JSON.stringify(postData.filters);
        // Need to set the grid's search to true, not the postData's

        $subGrid.setGridParam({ search: true });
        $subGrid.trigger("reloadGrid", [{ current: true, page: 1 }]);
    }
}
//**TO overwrite jquery.ui icons and use fontAwesome.  extending allows for customization of fA icons set as default in grid**//
$.extend(true, $.jgrid.icons.fontAwesome, {
    common: "fa",
    sort: {
        common: "fa-sort fa-lg"
        //asc: "fa-sort",
        //desc: "fa-sort"
    },
    nav: {
        common: "fa",
        refresh: "fa-recycle fa-lg"
    }

});
//**TOOLTIP ADD ON**//
$("[title]").qtip({
    position: {

        my: "bottom center",
        at: "top center",
        viewport: $(window)
    }
});



//**PRIMARY GRID**//  
$grid.jqGrid({
    url: "VendInvoice/Vendor",
    datatype: "local",
    data: gridData,
    colNames: ["ID", "Vendor Number", "Vendor Name", "dba", "VendorDbaCombo"],
    colModel: [
        { key: true, name: "ID", width: 0, hidden: true, sortable: false, search: false },
        {
            key: false,
            title: false,
            name: "VendorNo",
            index: "VendorNo",
            width: 100,
            sortable: true,
            search: true,
            stype: "text",
            searchoptions: {
                sopt: ["cn"],
                attr: { title: "Enter all or part of a Vendor Number." },
                clearSearch: false
            }
        },
        {
            key: false,
            title: false,
            name: "VendorName",
            //index: "VendorName",
            width: 500,
            sortable: true,
            search: true,
            clearSearch: false,
            stype: "text",
            searchoptions: {
                sopt: ["cn"],
                clearSearch: false, //removes X in column filters
                attr: {
                    title: "Enter a Vendor Name. SEARCHTIP: Once you start typing, you will begin returning filtered data. To broaden results returned provide less information, to narrow results provide more.",
                    maxlength: 9080,
                    dataInit: function (elem) {
                        $(elem).width(600);
                    }
                }
            }
        },
        {
            key: false,
            title: false,
            name: "Dba",
            index: "Dba",
            width: 500,
            sortable: true,
            search: true,
            stype: "text",
            searchoptions: {
                sopt: ["cn"],
                attr: { title: "Enter all or part of a dba." },
                clearSearch: false
            }
        },
        { key: false, name: "VendorDbaCombo", index: "VendorDbaCombo", width: 1, hidden: true }
    ],

    //**PRIMARY GRID PROPERTIES**//
    cmTemplate: { autoResizable: true, editable: true },
    iconSet: "fontAwesome",
    hidegrid: false,
    forceFit: true,
    caption: "Vendor Results",
    ignoreCase: true,
    gridview: true,
    autoencode: true,
    pager: "#Pager",
    toppager: true,
    rowNum: 25,
    rowList: [5, 10, 25],
    autowidth: true,
    height: "auto",
    viewrecords: true,
    loadonce: true,
    sortName: "VendorName",
    sortOrder: "ASC",
    viewsortcols: [true, "vertical", true],
    forceClientSorting: true,
    multiselect: true,
    setGridWidth: 980,
    loadtext: "Fetching your data, back in a jiff!",
    emptyrecords: "There were no records, try narrowing your search criteria",
    loadComplete: function () {
        $(this).find(">tbody>tr.jqgrow:visible:odd").addClass("myAltRowClass");
    },
    onSelectRow: function (row_id) {
        $grid.jqGrid("toggleSubGridRow", row_id);
        if (row_id !== lastSel && typeof lastSel !== "undefined") {
            $grid.jqGrid("setRowData", row_id, false, "myNormal");
        }
        $grid.jqGrid("setRowData", row_id, false, "myBold");
        lastSel = row_id;



    },

    //**SET SUBGRID**//
    subGrid: true,
    subGridOptions: {
        plusicon: "fa fa-plus-square-o",
        minusicon: "fa fa-minus-square-o",
        reloadOnExpand: false,
        expandOnLoad: false,
        delayOnLoad: 50

    },
    jsonReader: {
        id: "id",
        root: "rows",
        total: "total",
        records: "records",
        subgrid: {
            root: "rows",
            repeatitems: true, //must be true in subgrid and false in main grid
            cell: ""
        }

    },
    subGridRowExpanded: function (subgrid_id, row_id) {
        var subgrid_table_id, pager_id;
        subgrid_table_id = subgrid_id + "_t";

        var selectedrow = $(this).jqGrid('getRowData', row_id);
        pager_id = "p_" + subgrid_table_id;

        var stat = function (subgrid_id, row_id) {
            $("#vGrid2").jqGrid("setSelection", "row_id"); //Test to set selection for toggle
        }


        //**SUBGRID**//
        $("#" + subgrid_id).html("<table id='" + subgrid_table_id + "'class='scroll'></table><div id='" + pager_id + "'class='scroll'></div>");
        $("#" + subgrid_table_id).jqGrid({
            url: "VendInvoice/VendInvoiceSubGridData?vendorID=" + row_id,
    datatype: "local",
            data: subgridData[rowId],
            postData: {
                vendorID: row_id,

            },
            colNames: ["vendorID", "Invoice Status", "Invoice No", "Invoice Date", "Invoice Amount($)", "Payment Date", "Check or ACH Number", "Check or ACH Amount($)", "Encashment Date"],
            colModel: [
                { name: "vendorID", key: true, index: "vendorID", hidden: true, width: 0 },
                {
                    name: "InvoiceStatus",
                    title: false,
                    index: "InvoiceStatus",
                    width: 140,
                    sortable: true,
                    search: true,
                    formatter: "select",
                    stype: "select",
                    searchoptions: {
                        sopt: ["cn"],
                        attr: { title: "If part of your search criteria, select an invoice status from the drop-down menu." },
                        value: ":Select (All);Paid:Paid;Processing for Payment:Processing for Payment;Reviewing:Reviewing"
                    }

                },
                {
                    name: "InvoiceNo",
                    title: false,
                    index: "InvoiceNo",
                    width: 125,
                    sortable: true,
                    search: true,
                    stype: "text",
                    searchoptions: {
                        sopt: ["cn", "eq"],
                        attr: { title: "Enter all or part of an invoice number." },
                        clearSearch: false

                    }

                },
                {
                    name: "InvoiceDate",
                    title: false,
                    index: "InvoiceDate",
                    width: 135,
                    formatter: "date",
                    formatoptions: { srcformat: "m/d/Y", newformat: "m/d/Y" },
                    jsonmap: function (obj) {
                        var d = new Date(parseInt(obj.matchstartDate, 10));


                        return d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate()
                    },
                    sortable: true,
                    sorttype: "date",
                    editable: true,
                    search: true,
                    stype: "text",
                    searchoptions: {
                        sopt: ["ge", "le"],
                        clearSearch: false,
                        attr: { title: "Click in the box to open the date range picker." },
                        dataInit: function (elem) {
                            $(elem).daterangepicker({
                                dateFormat: 'mm/dd/yy',
                                changeYear: true,
                                changeMonth: true,
                                todayHighlight: true,
                            });
                            //ranges: {
                            //  "Yesterday": [moment(), subtract(1, 'days'), moment().subtract(1, 'days')],
                            //  "Last 7 days": [moment().subtract(6, 'days'), moment()],
                            //  "Last Month": [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')],
                            //  "This YTD": [moment().startOf('year'), moment().endOf('year')],
                            //  "LastYear": [moment().subtract(1,'year').startOf('year'), moment.subtract(1,'year').endOf('year')]
                            //    }

                            $(document).on('apply.daterangepicker', function () {
                                var $subGrid = $("#" + subgrid_table_id);
                                invoiceDateSearch($subGrid);

                            });
                        }
                    }

                },
                {
                    name: "InvoiceAmount",
                    title: false,
                    index: "InvoiceAmount",
                    width: 95,
                    sortable: true,
                    sorttype: "float",
                    formatter: "currency",
                    formatoptions: {
                        //prefix: "$",
                        suffix: "", thousandsSeparator: ",", decimalPlaces: 2
                    },
                    search: true,
                    stype: "text",
                    searchoptions: {
                        sopt: ["eq"],
                        attr: { title: "Enter an invoice amount." },
                        clearSearch: false
                    }
                },
                {
                    name: "PaymentDate",
                    title: false,
                    index: "PaymentDate",
                    width: 135,
                    formatter: "date",
                    formatoptions: { srcformat: "m/d/Y", newformat: "m/d/Y" },
                    jsonmap: function (obj) {
                        var d = new Date(parseInt(obj.matchstartDate, 10));


                        return d.getFullYear() + "/" + (d.getMonth() + 1) + "/" + d.getDate()
                    },
                    sortable: true,
                    sorttype: "date",
                    editable: true,
                    search: true,
                    stype: "text",
                    searchoptions: {
                        sopt: ["eq"],
                        clearSearch: false,
                        attr: { title: "Click in the box to open the date range picker." },
                        dataInit:

                            function (el) {
                                $(el).datepicker({
                                    dateFormat: 'mm/dd/yy',
                                    changeYear: true,
                                    changeMonth: true,
                                    todayHighlight: true,
                                    orientation: "bottom",
                                    immediateUpdates: true,
                                    autoclose: true
                                }).on('changeDate', function () {
                                    var $subGrid = $("#" + subgrid_table_id);
                                    paymentDateSearch($subGrid);
                                    $subGrid.setGridParam({ search: true });
                                    $subGrid.trigger("reloadGrid", [{ current: true, page: 1 }]);

                                });

                        }
                    }


                },
                {
                    name: "PaymentNo",
                    title: false,
                    index: "PaymentNo",
                    width: 115,
                    sortable: true,
                    search: true,
                    stype: "text",
                    searchoptions: {
                        sopt: ["cn", "eq"],
                        attr: { title: "Enter all or part of a Check or ACH Number." },
                        clearSearch: false
                    }
                },
                {
                    name: "CheckAmount",
                    title: false,
                    index: "CheckAmount",
                    width: 95,
                    sortable: true,
                    sorttype: "float",
                    formatter: "currency",
                    formatoptions: { suffix: "", thousandsSeparator: ",", decimalPlaces: 2 },
                    search: true,
                    stype: "text",
                    searchoptions: {
                        sopt: ["eq"],
                        attr: { title: "Enter a payment amount." },
                        clearSearch: false
                    }
                },
                {
                    name: "EncashmentDate",
                    title: false,
                    index: "EncashmentDate",
                    width: 100,
                    sortable: true,
                    sorttype: "date",
                    formatter: "date",
                    formatoptions: { srcformat: "m/d/Y", newformat: "m/d/Y" },
                    search: false
                }
            ],

            //**SUBGRID PROPERTIES**//

            cmTemplate: {
                align: "center",
                autoResizeable: true
            },
            idPrefix: "_s",
            iconSet: "fontAwesome",
            loadonce: true,
            loadtext: "Grabbing those invoice, this may take a second!",
            autoencode: true,
            toppager: true,
            autowidth: true,
            sortable: true,
            showOneSortIcon: true,
            autoResizing: { widthOfVisiblePartOfSortIcon: 13 },
            viewsortcols: [true, "vertical", true],
            multiselect: true,
            height: "auto",
            rowNum: 500,
            rowList: [25, 50, 100, 250, 500],
            gridview: true,
            viewrecords: true,
            emptyrecords: "There were no records, try narrowing your search criteria",
            prmNames: {
                id: "vendorID"
            },
            pager: "#" + pager_id,
            loadComplete: function () {
                $(this).find(">tbody>tr.jqgrow:visible:odd").addClass("myAltRowClass2");
            },
            beforeSelectRow: function () {
                return false;
            }

        });
        jQuery("#" + subgrid_table_id).jqGrid("navGrid", "#" + pager_id, {
            edit: false,
            add: false,
            del: false,
            search: true,
            refresh: true,
            refreshtext: "Refresh Invoice Results",
            cloneToTop: true
        },
            {},
            {},
            {},
            {
            multipleSearch: true,
        });
        jQuery("#" + subgrid_table_id).jqGrid("navButtonAdd", "#" + pager_id, {
            caption: "Export to Excel",
            buttonicon: "fa-file-excel-o",
            onClickButton: function (e) {
                exportData(e, "#" + subgrid_table_id);
            },
            position: "last"
        });
        jQuery("#" + subgrid_table_id).jqGrid("filterToolbar", {
            stringResult: true,
            searchOnEnter: false,
            ignoreCase: true,
            autoSearch: true,
            autosearchDelay: 1000,
            attr: {
                style: "width: auto;padding:0;max-width:100%"
            },
            defaultSearch: "cn",
            //beforeSearch: function () {
            //  var $subGrid = $("#" + subgrid_table_id);
            //  invoiceDateSearch($subGrid);
            //  $subGrid.trigger("reloadGrid", [{ current: true, page: 1 }]);
            //}
        });
        $("[title]").qtip({
            position: {
                my: "bottom center",
                at: "top center",
                viewport: $(window)

            }
        });
        var names = [
            "Invoice Status", "Invoice No", "Invoice Date", "Invoice Amount", "Payment Date",
            "Check or ACH No", "Check or ACH Amount", "Encashment Date"
        ];
        var mydata = [];
        var i, j;
        if (mydata != null) {
            for (i = 0; i < mydata.length; i++) {
                mydata[i] = {};
                for (j = 0; j < mydata[i].length; j++) {
                    mydata[i][names[j]] = mydata[i][j];
                }
            }
        }
        for (var i = 0; i <= mydata.length; i++);
        $("#" + subgrid_table_id).jqGrid('addRowData', i + 1, mydata[i]);

    }
}).jqGrid("navGrid", "#Pager", {
    edit: false,
    add: false,
    del: false,
    search: false,
    refresh: true,
    refreshtext: "Refresh Results",
    cloneToTop: true
}).jqGrid("filterToolbar", {
    stringResult: true,
    searchOnEnter: false,
    ignoreCase: true,
    autoSearch: true,
    autosearchDelay: 1000,
    attr: {
        style: "width: auto;padding:0;max-width:100%"
    },
    defaultSearch: "cn",
    beforeSearch: function () {
        modifySearchingFilter.call(this, " ");
    }
}).jqGrid("gridResize");

//**TOOLTIP ADD ON**//
$("[title]").qtip({
    position: {

        my: "bottom center",
        at: "top center",
        viewport: $(window)
    }
});

//**HIDE 'SELECT ALL' CHECKBOX**  call after grid is loaded//
$("#cb_" + $grid[0].id).hide();
$("#vGrid2").jqGrid("hideCol", "subgrid");


//**CUSTOM TOOLTIP TEXT FOR COLUMN HEADERS IN PRIMARY GRID**//   
var setTooltipsGrid = function (grid, iColumn, text) {
    var thd = jQuery("thead:first", grid[0].grid.hDiv)[0];
    jQuery("tr.ui-jqgrid-labels th:eq(" + iColumn + ")", thd).attr("title", text);

};
$(".hasTooltip").each(function () {
    $(this).qtip({
        content: {
            text: $(this).next("div")
        }
    });

});

//setTooltipsGrid($("#vGrid2"), 0, "If exporting, ensure ONLY the row you wish to export is selected. Remove any unnecessary checks in this column.");

//**EXPORT TO EXCEL-CSV**//

function exportData(e, row_id) {

    var subGrid = jQuery(row_id).getDataIDs(); // Get all the ids in array
    var label = jQuery(row_id).getRowData(subGrid[0]); // Get First row to get the labels

    var selRowIds = jQuery(row_id).jqGrid('getGridParam', 'selarrrow');

    var obj = new Object();
    obj.count = selRowIds.length;

    if (obj.count) {

        obj.items = new Array();

        var elem;

        for (elem in selRowIds) {
            if (selRowIds.hasOwnProperty(elem)) {
                obj.items.push(jQuery(row_id).getRowData(selRowIds[elem]));
            }
        }

        var json = JSON.stringify(obj);

        JSONToCSVConvertor(json, "csv", 1);
    }
}


function JSONToCSVConvertor(JSONData, ReportTitle, ShowLabel) {

    //If JSONData is not an object then JSON.parse will parse the JSON string in an Object
    var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
    var CSV = '';
    //This condition will generate the Label/Header
    if (ShowLabel) {
        var row = "";

        //This loop will extract the label from 1st index of on array
        for (var index in arrData.items[0]) {
            //Now convert each value to string and comma-seprated
            row += index + ',';
        }
        row = row.slice(0, -1);
        //append Label row with line break
        CSV += row + '\r\n';
    }

    //1st loop is to extract each row
    for (var i = 0; i < arrData.items.length; i++) {
        var row = "";
        //2nd loop will extract each column and convert it in string comma-seprated
        for (var index in arrData.items[i]) {
            row += '"' + arrData.items[i][index].replace(/(<([^>]+)>)/ig, '') + '",';
        }
        row.slice(0, row.length - 1);
        //add a line break after each row
        CSV += row + '\r\n';
    }

    if (CSV == '') {
        alert("Invalid data");
        return;
    }

    //*** FORCE DOWNLOAD ***//
    //will generate a temp "a" tag
    var link = document.createElement("a");
    link.id = "lnkDwnldLnk";

    //this part will append the anchor tag and remove it after automatic click
    document.body.appendChild(link);

    var csv = CSV;
    var blob = new Blob([csv], { type: 'text/csv' });

    var myURL = window.URL || window.webkitURL;

    var csvUrl = myURL.createObjectURL(blob);
    var filename = 'UserExport.csv';
    jQuery("#lnkDwnldLnk")
    .attr({
        'download': filename,
        'href': csvUrl
    });

    jQuery('#lnkDwnldLnk')[0].click();
    document.body.removeChild(link);

}