In the database, project_details table is there. I am fetching the data from database and result like json given below;
Recurrence start date is there in the database table but I am not saving the end date in the database. End date is depending upon the user selection from the fields (from date and to date)
{
"projectremindshow":[
{
"project_ID":"8",
"project_title":"abc",
"period_type":"Yearly",
"recurrence_date":"2021-10-28",
"reminder_set_days":"12",
"recur_every":"2",
"start_date":"2021-09-28"
},
{
"project_ID":"10",
"project_title":"xyz",
"period_type":"Yearly",
"recurrence_date":"2021-10-05",
"reminder_set_days":"13",
"recur_every":"4",
"start_date":"2021-09-05"
},
{
"project_ID":"11",
"project_title":"mno",
"period_type":"Monthly",
"recurrence_date":"2021-10-01",
"reminder_set_days":"10",
"recur_every":"8",
"start_date":"2021-09-21"
}
]
}
const inputList = [
{
date: new Date("2021-01-01"),
date2: new Date(todate_recu_view),
daysBefore: reminder_set_days,
period: period_type,
skip: recur_every
}]
const frequencyList = inputList.map((el, index) => {
return getPaymentPlan(el)
})
How to pass each for loop values to inputList?
From these project list, i want to find out the reminder dates for a month or week or year like by user select from and to date option to select the date period.
Based on the above JSON i want to show an HTML table with all reminder dates.
I have two fields from and to date and search button.Once click search button result table will be shown.
expecting output example1 is if user choose from-date= 2021-01-01 and to_date=2026-01-30 and display the result like below Html table look with two columns like below:
project Title reminderdate
abc 2021-09-28 /*show from start_date value from json and recur every 2 years (count upto to_date=2026-01-30) */
abc 2023-09-28 /*recur every 2 years*/
abc 2025-09-28 /*recur every 2 years*/
xyz 2021-09-05 /*recur every 4 years*/
xyz 2025-09-05 /*recur every 4 years*/
mno 2021-09-21 /*recur every 8 months*/
mno 2022-05-21 /*recur every 8 months*/
mno 2023-01-21 /*recur every 8 months*/
mno 2023-09-21 /*recur every 8 months*/
mno 2024-05-21 /*recur every 8 months*/
mno 2025-01-21 /*recur every 8 months*/
mno 2025-09-21 /*recur every 8 months becoz user select to_date=2026-01-30*/
expecting output example2 is
if suppose user choose from-date= 2025-01-01 and to_date=2026-01-30 and display the result like below
project Title reminderdate
abc 2025-09-28 /*recur every 2 years*/
xyz 2025-09-05 /*recur every 4 years*/
mno 2025-01-21 /*recur every 8 months*/
mno 2025-09-21 /*recur every 8 months*/
can anyone plz help me to do this?
code i tried:
$('#find_recurrence').click(function(event) {
var getID_comp = $('#getID_comp').val();
var fromdate_recu_view = $('#fromdate_recu_view').val(); //2025-01-01
var todate_recu_view = $('#todate_recu_view').val(); //2026-01-30
$.ajax({
url: base_url "index.php/welcome/list_all_projects_reminder/",
type: "POST",
data: {
"company_id": getID_comp
},
success: function(data) {
var new_data = JSON.parse(data);
console.log(new_data) //above mentioned JSON result
for (var i = 0; i < new_data.projectremindshow.length; i ) {
var sl = i 1;
var project_ID = new_data.projectremindshow[i].project_ID;
var project_title = new_data.projectremindshow[i].project_title;
var recur_every = new_data.projectremindshow[i].recur_every;
var period_type = new_data.projectremindshow[i].period_type;
var reminder_set_days = new_data.projectremindshow[i].reminder_set_days;
const getPaymentPlan = ({
date,
date2,
daysBefore,
period,
skip
}) => {
const originalDate = new Date(date.getTime()); // original copy before mutating
const startDate = new Date(date.setDate(date.getDate() - daysBefore))
// date has been mutated. giving it previous value
date = new Date(originalDate.getTime())
const recurObj = {
"recurrenceList": []
}
while (startDate.getTime() <= date2.getTime()) {
recurObj.recurrenceList.push(startDate.toISOString().split('T')[0])
switch (period) {
case 'monthly':
startDate.setMonth(startDate.getMonth() skip)
break;
case 'yearly':
startDate.setFullYear(startDate.getFullYear() skip)
break;
default:
recurObj.recurrenceList.push("wrong period type is given")
break;
}
}
return recurObj
}
const inputList = [{
date: new Date("2021-01-01"),
date2: new Date(todate_recu_view),
daysBefore: reminder_set_days,
period: period_type,
skip: recur_every
}]
const frequencyList = inputList.map((el, index) => {
return getPaymentPlan(el)
})
console.log(frequencyList)
}
}
});
});
CodePudding user response:
Although you hadn't got past the point of assigning the results from the AJAX into an array (because you had inputList
outside the for
loop, where the values were not defined or looped over), in the end there were so many other small things wrong with the code, especially inside the getPaymentPlan
function that it's impossible to list them all here. Instead I simply provide a working version for you to study and learn from.
Also your expected results as stated in the question are incorrect - you've asked for it to show the reminder date, but then what you've listed are the recurrence dates. All the reminder dates are several days earlier (as controlled by the reminder_set_days
property).
The results my demo produces show the actual reminder date instead:
$('#find_recurrence').click(function(event) {
var fromdate_recu_view = $('#fromdate_recu_view').val(); //2025-01-01
var todate_recu_view = $('#todate_recu_view').val(); //2026-01-30
//hard-code data instead of AJAX, for this demo:
let new_data = {
"projectremindshow": [{
"project_ID": "8",
"project_title": "abc",
"period_type": "Yearly",
"recurrence_date": "2021-10-28",
"reminder_set_days": "12",
"recur_every": "2",
"start_date": "2021-09-28"
},
{
"project_ID": "10",
"project_title": "xyz",
"period_type": "Yearly",
"recurrence_date": "2021-10-05",
"reminder_set_days": "13",
"recur_every": "4",
"start_date": "2021-09-05"
},
{
"project_ID": "11",
"project_title": "mno",
"period_type": "Monthly",
"recurrence_date": "2021-10-01",
"reminder_set_days": "10",
"recur_every": "8",
"start_date": "2021-09-21"
}
]
};
let inputList = [];
for (var i = 0; i < new_data.projectremindshow.length; i ) {
var proj = new_data.projectremindshow[i];
//add a new entry to inputList for each entry returned from the AJAX call
inputList.push({
dateFrom: new Date(fromdate_recu_view),
dateTo: new Date(todate_recu_view),
daysBefore: proj.reminder_set_days,
recurrenceDate: new Date(proj.start_date),
period: proj.period_type,
skip: proj.recur_every,
title: proj.project_title
});
}
const frequencyList = inputList.map((el, index) => {
return getPaymentPlan(el)
});
console.log(frequencyList);
});
/* the getPaymentPlan function is standalone, it should not be within a loop or within any other callback functions! */
const getPaymentPlan = ({
dateFrom,
dateTo,
recurrenceDate,
daysBefore,
period,
skip,
title
}) => {
//start from either the recurrence start date, or the start date in the form - whichever is later
let startDate = (recurrenceDate.getTime() > dateFrom.getTime() ? recurrenceDate : dateFrom);
//reminders go out several days before the actual recurrence start date
startDate = startDate.subtractDays(daysBefore);
let recurObj = {
"project": title,
"recurrenceList": []
}
while (startDate.getTime() <= dateTo.getTime()) {
recurObj.recurrenceList.push(startDate.toISOString().split('T')[0]);
switch (period) {
case 'Monthly':
startDate = startDate.addMonths(parseInt(skip));
break;
case 'Yearly':
startDate.setFullYear(startDate.getFullYear() parseInt(skip));
break;
default:
recurObj.recurrenceList.push("wrong period type is given")
break;
}
}
return recurObj;
}
/* below are some functions to correctly add / subtract days and months from a Date, accounting for leap years, differing month lengths, etc */
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() days);
return date;
}
Date.prototype.subtractDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() - days);
return date;
}
Date.prototype.addMonths = function(months) {
var date = new Date(this.valueOf());
var d = date.getDate();
date.setMonth(date.getMonth() months);
if (date.getDate() != d) {
date.setDate(0);
}
return date;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
From date: <input type="date" id="fromdate_recu_view" /><br/> To date: <input type="date" id="todate_recu_view"><br/>
<button id="find_recurrence">Find Recurrence</button>
Here is an alternative version of the getPaymentPlan function which will output the data in a format which may be easier to sort, and also to output later according to your desired HTML format:
const getPaymentPlan = ({
dateFrom,
dateTo,
recurrenceDate,
daysBefore,
period,
skip,
title
}) => {
//start from either the recurrence start date, or the start date in the form - whichever is later
let startDate = (recurrenceDate.getTime() > dateFrom.getTime() ? recurrenceDate : dateFrom);
//reminders go out several days before the actual recurrence start date
startDate = startDate.subtractDays(daysBefore);
let recurrenceList = [];
while (startDate.getTime() <= dateTo.getTime()) {
recurrenceList.push({ "project": title, "reminderDate": startDate.toISOString().split('T')[0] });
switch (period) {
case 'Monthly':
startDate = startDate.addMonths(parseInt(skip));
break;
case 'Yearly':
startDate.setFullYear(startDate.getFullYear() parseInt(skip));
break;
default:
recurrenceList.push({ "project": "wrong period type is given", "reminderDate": null })
break;
}
}
return recurrenceList;
}