How to dynamically fetch dates from database table to disable dates - php

I'm selling 20 cupcakes per day. I need to disable dates that have fulfilled 20 orders. I have a database table for date and quantity sold.
How can I dynamically fetch dates from database table into
var dates = [ ]
var dates = ["20/07/2020", "21/07/2020", "22/07/2020", "23/07/2020"];
function disableDates(date) {
var string = jQuery.datepicker.formatDate('dd/mm/yy', date);
let isDefaultDisabled = false;
if(date.getDay()===2 || date.getDay()==3 || date.getDay()==4){
isDefaultDisabled = true;
}
return [ isDefaultDisabled && dates.indexOf(string) == -1 ];
}
$(function() {
$("#date").datepicker({
beforeShowDay: disableDates
});
});

Related

Set different prices according to country with response

I'm trying to do a onchange event with ajax and php according to country selected from a dropdown. My problem is that the response set the last price in the array on every item and I can't figure out a way to solve this.
Here is my code so far:
$("#field-organization-country-iso").on('change', (e) => {
e.preventDefault();
e.stopPropagation();
const CountryIso = $('#field-organization-country-iso').val();
Request.get(`/myrequested_file`, {
data: { CountryIso },
})
.done((response) => {
for (let i = 0; i < response.data.itemPrice.length; i++) {
const price = response.data.itemPrice[i];
$('.checkout-table tr').find('.hide-if-odd-or-sub').eq(i).html(price);
}
});
});
And the php-function:
public function change_currencyIso(Request $request, $summaryService): JSONResponse
{
$countryIso = $request->query->get('CountryIso');
$response = new JSONResponse();
$orderSummary = $summaryService->Summary(Cart::getCurrentCart(), User::currentUserOrNull(), $countryIso, null, null);
$items = $orderSummary->getItems();
$currencies = new ISOCurrencies();
$numberFormatter = new NumberFormatter(Environ::getLocale(), NumberFormatter::CURRENCY);
$moneyFormatter = new IntlMoneyFormatter($numberFormatter, $currencies);
$prices = [];
foreach ($items as $item) {
$price = $moneyFormatter->format($item->getLocalPrice());
$prices[] = $price;
}
$response->setVar('itemPrice', $prices);
return $response;
}
$prices returns the array with item prices but I know response writes over it. Can I loop through the array and add the response to each price?
My response with 'itemPrice' is only returning one of the existing prices.
{itemPrice: Array(2)}
itemPrice: Array(2)
0: "245,00 US$"
1: "32,90 US$"
length: 2
Now itemPrice returns the array but still puts everything on the same row. Tried a each but that didn't help.
You should add more details about the html structure, however I suppose you have a table with a row for each item, and the cells with the price have the class "hide-if-odd-or-sub". Also table rows are in the same order of the prices returned by the server. So, you have to assign each price to the correspondig table row:
foreach (var i in response.data.itemPrice) {
var price = response.data.itemPrice[i];
$('.checkout-table tr').eq(i).find('.hide-if-odd-or-sub').html(price);
}
This is not mush robust, because if the user change the items in the cart in another browser's tab and goes back to previous tab and updates the country, then the prices returned by the server won't correspond to items in the table, however it should work under normal usage.

PHP - Google Charts

I'm trying to use Google Charts and i'm having some trouble to create array for API.
https://developers.google.com/chart/interactive/docs/gallery/linechart#creating-material-line-charts
My source of data has 3 columns, which is quantity, date and user name.
(you can see in attachment).
How to convert his form of array to use with google charts api (line charts)?
I think i need to convert each different value from column "responsavel" to a new column and set these column the value of column "qt_pedido"
In this example, the final array should be something like this:
Date | user1 | user2
-------------------------------
03/09/2018 | 58 | 19
05/09/2019 | 23 | 5
Result from sql server
it would be easier to use google data table methods to transform the rows to columns,
see following working snippet...
google.charts.load('current', {
packages: ['line']
}).then(function () {
// create data table
var data = google.visualization.arrayToDataTable([
['Date', 'responsavel', 'qt_pedido'],
['20/10/2018', 'user1', 10],
['20/10/2018', 'user2', 20],
['20/10/2018', 'user3', 30],
['20/11/2018', 'user1', 40],
['20/11/2018', 'user2', 50],
['20/11/2018', 'user3', 60],
['20/12/2018', 'user1', 70],
['20/12/2018', 'user2', 80],
['20/12/2018', 'user3', 90],
]);
// create data view
var view = new google.visualization.DataView(data);
// column arrays
var aggColumns = [];
var viewColumns = [0];
// build view & agg columns for each responsibility
data.getDistinctValues(1).forEach(function (responsibility, index) {
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === responsibility) {
return dt.getValue(row, 2);
}
return null;
},
label: responsibility,
type: 'number'
});
aggColumns.push({
aggregation: google.visualization.data.sum,
column: index + 1,
label: responsibility,
type: 'number'
});
});
// set view columns
view.setColumns(viewColumns);
// sum view by date
var aggData = google.visualization.data.group(
view,
[0],
aggColumns
);
// draw chart
var chart = new google.charts.Line(document.getElementById('chart_div'));
chart.draw(aggData);
});
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart_div"></div>

Parent-child sorting

I am trying to sort a table that has parent- and child-rows. Sorting should always be performed based on the parent rows, but the childrows should always immediately follow the parent. Table data is in format of
[
{name: 'xxx', group: 'A', type: 'parent'},
{name: 'yyy', group: 'B', type: 'parent'},
{name: 'zzz', group: 'A', type: 'child'},
{name: 'qqq', group: 'A', type: 'child'}
]
So, sorted by name the correct order would be xxx,qqq,zzz,yyy.
The data comes from a Laravel/Eloquent ajax query and is displayed in a datatables table, so sorting it either client or server side would be fine.
Not related to multisort (comment below)
Use orderFixed option to always apply ordering to a certain column before/after any other columns.
For example:
var table = $('#example').DataTable({
ajax: {
url:'https://api.myjson.com/bins/4n6ey',
dataSrc: ''
},
orderFixed: {
pre: [[1, 'asc'], [2, 'desc']]
},
columns: [
{ data: 'name' },
{ data: 'group' },
{ data: 'type'}
]
});
See this jsFiddle for code and demonstration.
Couldn't figure out how to do it in SQL, DataTables callbacks/sorters (although a plugin would be an workable option), Eloquent callbacks or Yajra DataTables adapter options. So I just went the brute force way.
sort by intended column using sql
separate master/child (debt/guarantee) lines
look up each child lines' master record for the correct sorting index and create a new indexing column for the "true" order
$dataTable_column_map = $claimPortfolio->getColumnMap();
$claimPortfolioLines = $claimPortfolio->lines()->orderBy($dataTable_column_map[$request->get('order')[0]['column']]['name'], $request->get('order')[0]['dir'])->get();
$claimPortfolioLines = ClaimPortfolioService::orderGuarantees($claimPortfolioLines);
$claimPortfolioLines = ClaimPortfolioService::filterLines($claimPortfolioLines, Input::get('search.value'));
Session::put('claimPortfolioLineIdList', $claimPortfolioLines->lists('id')->toArray());
return Datatables::of($claimPortfolioLines)
->order(function() {
return true; // cancel built-in ordering & filtering
})
->filter(function() {
return true;
})
->make(true);
public static function orderGuarantees(Collection $claimPortfolioLines)
{
$claimPortfolioLinesGuarantees = $claimPortfolioLines->filter(function ($claimPortfolioLine) {
return $claimPortfolioLine->line_type == 'GUARANTEE';
});
$claimPortfolioLines = $claimPortfolioLines->filter(function ($claimPortfolioLine) {
return $claimPortfolioLine->line_type == 'DEBT';
});
foreach ($claimPortfolioLines as $idx_line => $claimPortfolioLine)
{
$claimPortfolioLine->sortOrder = $idx_line;
foreach ($claimPortfolioLinesGuarantees as $idx_guaranteeLine => $claimPortfolioLineGuarantee)
{
if ($claimPortfolioLineGuarantee->contract_no == $claimPortfolioLine->contract_no && $claimPortfolioLine->line_type == 'DEBT')
{
$claimPortfolioLineGuarantee->sortOrder = "{$idx_line}.{$idx_guaranteeLine}";
$claimPortfolioLines->push($claimPortfolioLineGuarantee);
}
}
}
$claimPortfolioLines = $claimPortfolioLines->sortBy('sortOrder');
return $claimPortfolioLines;
}
The general solution for this in SQL is to self join and order by multiple columns, including whether it's a parent. In OP's case, assuming a table of data d (t an alias meaning table, and s meaning sort):
SELECT t.*
FROM d AS t
INNER JOIN d AS s
ON s.group = t.group
AND t.type = 'parent'
ORDER BY s.name, t.type = 'parent' DESC, t.name

How to sum all rows when using filter

I have been reading many jQuery Datatables examples on how to use footerCallback to sum all rows of a MySQL table, but I can get the total sum of a column, when I'm using records per page filter. In the Footer callback example, they show a demo, that do that, here is the code:
$(document).ready(function() {
$('#example').dataTable( {
"footerCallback": function ( row, data, start, end, display ) {
var api = this.api(), data;
// Remove the formatting to get integer data for summation
var intVal = function ( i ) {
return typeof i === 'string' ?
i.replace(/[\$,]/g, '')*1 :
typeof i === 'number' ?
i : 0;
};
// Total over all pages
data = api.column( 4 ).data();
total = data.length ?
data.reduce( function (a, b) {
return intVal(a) + intVal(b);
} ) :
0;
// Total over this page
data = api.column( 4, { page: 'current'} ).data();
pageTotal = data.length ?
data.reduce( function (a, b) {
return intVal(a) + intVal(b);
} ) :
0;
// Update footer
$( api.column( 4 ).footer() ).html(
'$'+pageTotal +' ( $'+ total +' total)'
);
}
} );
} );
But when I apply in my PHP script, total gives me the same amount of pageTotal, when My records per page filter is on 10, if I change to 50 it gives me a new total, but how in the example, when the filter is on 10, it show the sum of all records in the table. I have been on this for two days, can anybody can give me a hint please?
Total over this page
data = api.column( 4, {filter:'applied'} ).data();
pageTotal = data.length ?
data.reduce( function (a, b) {
return intVal(a) + intVal(b);
} ) :
0;

jQuery tablesorter range sorting

I want to sort the price range properly. How can I do that?
$.tablesorter.addParser({
// set a unique id
id: 'pricerange',
is: function(s) {
// return false so this parser is not auto detected
return false;
},
format: function(s,table,cell) {
// format your data for normalization
var cellTxt = s.replace("USD", "").replace(",","");
console.log(cellTxt);
return cellTxt;
},
// set type, either numeric or text
type: 'nemeric'
});
http://jsfiddle.net/Lnd4t6uy/2/
Your question got me thinking about how to determine if the number entered as a search query would be within a listed range within the table. So, now I have a demo that shows you how to add a new filter search type.
This code only works with my fork of tablesorter
$(function() {
// Add insideRange filter type
// ============================
// This allows you to enter a number (e.g. 8) and show the
// resulting rows that will have that query within it's range
var ts = $.tablesorter,
isDigit = /\d+/,
nondigit = /[^\d,.\-()]/g,
range = /\s+-\s+/;
ts.filter.types.insideRange = function( c, data ) {
if ( isDigit.test( data.iFilter ) && range.test( data.iExact ) ) {
var t, val, low, high,
parts = data.iExact.replace( nondigit, '' ).split( '-' );
// the cell does not contain a range
if ( isNaN( parts[0] ) || isNaN( parts[1] ) ) {
return null;
}
low = ts.formatFloat( parts[0], c.table );
high = ts.formatFloat( parts[1], c.table );
val = ts.formatFloat( data.iFilter.replace( nondigit, '' ), c.table );
if ( high < low ) {
// swap high & low
t = high; high = low; low = t;
}
return low <= val && val <= high;
}
return null;
};
// call the tablesorter plugin
$("#table").tablesorter({
theme: 'blue',
widthFixed : true,
widgets: ["zebra", "filter"],
widgetOptions : {
// set to false because it is difficult to determine if a filtered
// row is already showing when looking at ranges
filter_searchFiltered : false
}
});
});
And here is a jsfiddle if you want to mess around with the code.

Categories