我正在使用免费的jqGrid v4.12.1。 (不能发布链接到小提琴,所以代码跟在后面)
主要问题是我们正在尝试使用filterToolbar进行所有搜索/过滤。 Oleg几周后帮助将日期推送到搜索模式,但是要求已经改变,以便在filterToolbar中使用日期范围选择器。我们大多在那里。使用Dan Grossman的bootstrap日期范围选择器并调用自定义函数,它就像一个魅力。 Entering DateRangeFirst
当您选择其他值(如发票金额)时,最初会出现此问题。然后它将覆盖日期范围并提供所有值" ge"到开始日期。所以它看到了字符串的开始日期。为了避免这种情况,我在beforeSearch中再次调用了invoiceDateSearch函数。这样它再次运行该功能并识别开始日期和结束日期以及我们要求的新值。
现在发生的事情是,如果我先放入任何其他值然后选择一个日期范围,那么日期范围就会激活,直到我键入其他一些搜索条件并将其退出。 AnyOther value first 它甚至无法识别已经输入的日期范围,当它明显存在时。 triggerToolbar,在发票日期搜索功能中调用重新加载网格。
使用beforeSearch时,将日期范围保留为日期范围而不是字符串...无论工具栏被触发的频率如何,值都会从其他任何字段中退出,这很好。它的缺点是,如果用户输入的日期范围不是FIRST,则日期范围不起作用......除非输入后续字段。不使用它,在第一次使用它之后将日期范围转换为字符串,输入或过滤的任何其他值都需要重新运行日期参数,因为它会给每个日期大于开始日期。
我在排除故障时已将高级搜索放在网格上。我想将它取下(或者至少是按钮),因为用户只想使用toolbarFilter。
我的问题是,如何让日期范围选择器与其他列值一致?是否有问题同时运行两个日期选择器?单日期日期选择器在使用时根本没有响应。它会将日期放在那里,一旦另一个字段被触发,它就会响应,但从不自行。
很抱歉,如果我"信息被转储"我对此很新。我已经搜索了很多这方面的帮助,但找不到任何东西。如果我继续黑客攻击,我会撕毁我的工作! :o
提前感谢您的任何帮助或指导! $(function(){ "使用严格的&#34 ;;
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);
}
});
答案 0 :(得分:0)
在我看来,使用自定义操作是解决问题的最佳方法。因为你可以使用beforeSearch
的{{1}}回调来修改过滤器,但它的操作级别太低而且在搜索对话框中不起作用。
我建议您阅读描述该功能的the wiki article。它提供了filterToolbar
操作的示例,您可以根据需要轻松修改。 "numeric IN"
回调在filter
中获取您需要的所有信息,回调应该只验证测试项目(options
)的数据是否在由来自的值提供的区间内日期范围选择器(options.item
)。我认为你会得到一些小代码,它可以解决你的问题。
最后评论:我建议您升级到最新的4.13.0版本,修复一些错误,在某些情况下提高性能并提供the readme中描述的新功能。