How to create an AJAX multiple dropdown filter bar in WordPress based on custom field date range? - ajax

What is the best way to create this AJAX filter bar in WordPress?
dropdown ajax facetwp filter bar
I have tried using WP Facet plugin to achieve this but came up against issues. I need to be able to compare two ACF date fields event_date_start and event_date_end and determine if the date range they produce is within the pre-set date selections on a dropdown:
dropdown ajax facetwp filter bar
I have managed to get this far:
Use Time Since Facet type
Can only choose one source, the ACF field,
event_date_start
Used the following custom code in functions.php to enable to check if the start date is on Christmas or Easter
//Christmas Date Range
add_filter( 'facetwp_time_since_date_range', function( $range, $format ) {
if ( 'Christmas' == $format ) {
$year = date('Y');
$dt1 = new \DateTime( $year . '-12-1' );
$dt2 = new \DateTime( $year . '-12-31' );
$range['lower'] = $dt1->format( 'Y-m-d' );
$range['upper'] = $dt2->format( 'Y-m-d' );
}
return $range;
}, 10, 2);
//Easter Date Range
add_filter( 'facetwp_time_since_date_range', function( $range, $format ) {
if ( 'Easter' == $format ) {
$easterdt = date('Y-m-d', easter_date());
$easterdt3 = date('Y-m-d', strtotime($easterdt . ' +1 day'));
$dt1 = new \DateTime( $easterdt );
$dt2 = new \DateTime( $easterdt3 );
$range['lower'] = $dt1->format( 'Y-m-d' );
$range['upper'] = $dt2->format( 'Y-m-d' );
}
return $range;
}, 10, 2);
Which seems to work well but it is radio buttons. I need dropdown (it is at this point I considered converting the radio buttons to dropdown by exploring this: html convert radio button list into dropdown
I thought this might be the correct route to go down: https://facetwp.com/help-center/facets/facet-types/custom-facet-types but unsure how to:
i) Pull in the two separate ACF start and end dates
ii) Compare the date range against the set date ranges (today, tomorrow, christmas, easter etc).
I like FacetWP as it uses ajax for instant results and also has the user selection bar under the filter which matches the design here: dropdown ajax facetwp filter bar
If someone can tell me the best way to approach please. I do not want to start customising FacetWP if there is another plug in that can handle the set dates dropdown. But I would be willing to learn to code the whole ajax filter bar from scratch if this was suggested as best approach in terms of coding knowledge, time and performance.

Related

Automatically fill the current date in a cell if the data is not empty in Google sheet

I have 9 columns of data. With the requirement in column 9 that there are data, the first column will dynamically fill in the current date.
I use the formula "= ArrayFormula (IF (ISTEXT (D7), TODAY ()," "))" but the problem is that if it passes the next day it will change to the next day's date. I do not want it to change the day after the new day, what should I do?
I am not sure if it is possible using a simple google sheet function.
If you want to use a google script to solve this then you can apply below:
function onEdit(){
dateStamp();
}
function dateStamp() {
const ss = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Data')//change sheet name per your requirement;
const date = new Date();
const lr = ss.getDataRange().getLastRow();
const dataRange = ss.getRange(2,9,lr-1).getValues() //change range per your requirement;
const dateRange = ss.getRange(2,2,lr-1).getValues() //change range per your requirement;
for (i=0; i<dataRange.length; i++){
if(dataRange[i] !=''){
if (dateRange[i] == '')
ss.getRange(i+2,2).setValue(date);
}
}
}

How to add filter result to select menu

I'm stuck with my first dashboard project with d3, dc and crossfilter. Cannot find a solution.
"ETCBTC","BUY","0.002325","1.04","0.00241800","0.00104","ETC"
"ETCBTC","SELL","0.002358","1.04","0.00245232","0.00000245","BTC"
"LTCETH","SELL","0.30239","0.006","0.00181434","0.00000181","ETH"
"LTCETH","SELL","0.30239","0.149","0.04505611","0.00004506","ETH"
I have different trading pairs in first column and from it i need to use only last pair BTC and ETH in this example.
I found the filter that helps me to do that.
The thing is I need to have BTC and ETH in my select menu which can apply filter.
function show_market_selector(ndx) {
var marketDim = ndx.dimension(dc.pluck("Market"));
var selectorMenu = marketDim.group();
function filterItems(query) {
return ndx.dimension(dc.pluck("Market")).filter(function(el) {
return el.toLowerCase().indexOf(query.toLowerCase()) > 0;
});
}
filterItems("BTC");
var select = dc.selectMenu("#market-selector")
.dimension(marketDim)
.group(selectorMenu);
select.title(function (d){
return "BTC";
});
}
Now I get all pair in group in this menu. But my target is just to have BTC and ETH in the select menu.
I hope someone can give me advice. Thank you.
I think it would be easier just to use the currency as your dimension key:
var currencyDim = ndx.dimension(d => d.Market.slice(3)),
currencyGroup = marketDim.group();
var select = dc.selectMenu("#market-selector")
.dimension(currencyDim)
.group(currencyGroup);
You don't really want to create a new dimension every time filterItems is called - dimensions are heavy-weight indices which are intended to be kept around.
The name of dimension.filter() is confusing - it's nothing like JavaScript's Array.prototype.filter(), which returns the matching rows. Instead, it's an imperative function which sets the current filter for that dimension (and changes what all the other dimensions see).
If you need a "from currency" dimension, that would be
var fromCurrencyDim = ndx.dimension(d => d.Market.slice(0,3))

How to pass two parameters in a template function in series.Line in kendo line chart

I have implemented a Kendo line chart using ASP.NET. As in the kendo examples shown i have used series{} to display lines. I have written my own custom template in series.Line to display the labels for markers when mouse hovered.But i need to pass two parameters to that function.
series.Line(m => m.Values[0].value).Labels(lbl => lbl.Position(ChartPointLabelsPosition.Above).Visible(true).Template("#= formatLabelForEffort(category#"))
In the above code formatLabelForEffort() is the function call written in the template which has only one arguement called category. I want to send another arguement in the same function. The second arguiement would be an array. How would i achieve this. Please help me out to resolve this issue. Thank you in advance.
I have prepared a demo of this for you:
custom template passing in options.
All you need to do is change your existing function from:
.Template("#= formatLabelForEffort(category)#")
to
.Template("#= formatLabelForEffort(category, dataItem)#")
as long as the array is part of the original data model that is being bound within the series you should be able to alter your function to handle the code.
then using my version of your function:
function formatLabelForEffort(category,dataItem){
var retString = '';
console.log(dataItem);
if (dataItem.myArray !== undefined &&
dataItem.myArray !== null &&
dataItem.myArray !== null &&
dataItem.myArray.length > 0)
{
retString = 'Category is:: ' + category + '\r\n' ;
retString += kendo.stringify(dataItem.myArray) ;
}
else
{
retString = 'Category is:: ' + category;
}
console.log(retString);
return kendo.htmlEncode(retString);
}
we simply check to ensure the array is present and then return a string accordingly.
for more info on what you can pass to the series labels check this link:
series label template configuration
any further issues give me a shout and I will expand where I can.

JQGrid Grouping GroupText formatting and modification

I have a grid that implements grouping but would like to expand on the details that display in the groupText: area. Ideally I would be able to take data about that grouping and display in that group row with the group name ({0} default value).
In other words what I am trying to achieve is a way to display not only the group name but also some other data items contained in the JSON feed to the grid.
My searching seems to be coming up short on anyone being able to achieve this but I'm hoping someone can shed some light on expanding this setting and providing access to formating this area.
I find your question interesting, but the implementation is not simple. In the answer I showed before how one could use custom formatter in summary rows of the grouping.
In the demo you can see how to implement custom formatting of the grouping text. The demo display the following:
The implementation consist just from the implementation of the custom formatter which can be used for both purpose: formatting of the content of the corresponding column and formatting of the grouping text in case of grouping by the column. The code is a little tricky, but I hope that all will be able follow it. The code use the differences of the input parameters to define whether the formatter will be called to format the column content or to format the grouping text.
One part of the code which get the texts like "(test4,test7)" is not so effective in case of the usage of large number of rows, but it works.
Below is the code of formatter of the "Date" column which would by typically used with the predefined formatter: 'date'. I called in the part of the code the original Date-formatter, but used for the the grouping text more sophisticated code:
formatter: function (cellval, opts, rowObject, action) {
var fullOpts = $.extend({}, $.jgrid.formatter.date, opts),
formattedDate = $.fmatter.util.DateFormat('Y-m-d', cellval, 'd-M-Y', fullOpts),
groupIdPrefix = opts.gid + "ghead_",
groupIdPrefixLength = groupIdPrefix.length,
month = Number(cellval.split('-')[1]), // input format 'Y-m-d'
names = [], data, i, l, item;
// test wether opts.rowId start with opts.gid + "ghead_" and integer
// and rowObject is the array and action is undefined.
if (opts.rowId.substr(0, groupIdPrefixLength) === groupIdPrefix && typeof action === "undefined") {
// custom formating of the group header
// we just simulate some login by testing of the month > 9
// the next code fragment is not effective, but it can be used
// in case of not so large number of groups and the local data
data = $(this).jqGrid("getGridParam", "data");
for (i = 0, l = data.length; i < l; i++) {
item = data[i];
if (item.invdate === cellval) {
names.push(item.name);
}
}
return (month > 9 ? ('<span class="ui-icon ui-icon-alert" style="float: left;"></span>' +
'<span style="color:tomato; margin-left: 5px;">') : "<span>") +
formattedDate + ' (' + names.join() + ')</span>'
}
return formattedDate;
}
UPDATED: The fixed version of the demo is here. It uses $.fn.fmatter instead of currently removed from jqGrid method $.fmatter.util.DateFormat.

Get all rows not filtered from jqGrid

I have local data in a grid. How can I get all of the rows or IDs that are not removed after a user uses the filter toolbar? I need to get all filtered rows, regardless of pagination.
For example, say I begin with 50 rows in the grid. The user uses the filter toolbar and the set of rows decreases to 10 rows. How can I get those ten rows?
There are no direct way to get the information which you need. Internally jqGrid uses $.jgrid.from to filter local data. The main code which uses $.jgrid.from in inside of addLocalData. To get results which you need without studying all the code I suggest to use the fact that all filtered data will be returned by select method of $.jgrid.from (see the line of code). My suggestion is to catch the data before the data will be cut to the page size.
To do this I suggest to use sub-classing: overwriting of the method select method of $.jgrid.from. I demonstrate the technique in the examples created for the answer and this one.
In your case the code will be
var oldFrom = $.jgrid.from,
lastSelected;
$.jgrid.from = function (source, initalQuery) {
var result = oldFrom.call(this, source, initalQuery),
old_select = result.select;
result.select = function (f) {
lastSelected = old_select.call(this, f);
return lastSelected;
};
return result;
};
Now the variable lastSelected will save the array of elements which are results of the last sorting or filtering operation. Because $.jgrid.from is global the data are not connected to the grid. If you have more as one grid on the page it will be uncomfortable. One can fix the small disadvantage with the following line in the code of loadComplate of every grid:
loadComplete: function () {
this.p.lastSelected = lastSelected; // set this.p.lastSelected
}
In the way we introduce new jqGrid parameter lastSelected which will have close structure as data parameter, but will hold only last filtered data.
The following code will display the ids of filtered data in alert message
$("#getIds").click(function () {
var filteredData = $grid.jqGrid('getGridParam', 'lastSelected'), i, n, ids = [],
idName = $grid.jqGrid('getGridParam', 'localReader').id;
if (filteredData) {
for (i = 0, n = filteredData.length; i < n; i++) {
ids.push(filteredData[i][idName]);
}
alert("tolal number of filtered data: " + n + "\n" +
"ids of filtered data:\n" + ids.join(', '));
}
});
I used localReader.id parameter because property name used for local data are typically id or _id_. The _id_ will be used in case of data loaded from the server if one uses loadonce: true option.
The demo demonstrate the approach. If one filter for example only the data from FedEx and then clicks on "Show Ids" button one will see information about all filtered and not only about the data displayed on the current page:
UPDATED: free jqGrid provides new lastSelectedData option. See the demo in the list of demos.
You colud use afterSearch option of the search toolbar:
var filteredIDs = new Array(); //Global variable
$("#"+gridId).jqGrid("filterToolbar", { stringResult:true, searchOnEnter:false,
afterSearch:function(){
filteredIDs = $("#"+gridId).getDataIDs();
}
});
If you want to get the filtered rows instead the filtered IDs, use getRowData() instead of getDataIDs().
All, I found another answer which is far easier to include
loadComplete: function (gridData) {
var isSearchPerformed = $grid.getGridParam("postData")._search;
if (isSearchPerformed) {
$("#spanFilterTotal").text(gridData.records);
}
All you want is below:
$.each($grid.getRowData(), function( index, value ) {
a.push(value["COLUMN_NAME"]); //Get the selected data you want
});

Resources