Populate html table headers based upon dropdown selection [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I am still learning web dev.
Thank you all for your feedbacks...
I would like to choose a month (MMMM-YYYY) from a dropdown and get the html table headers to display the month M, the last month M-1, M-3, M-6, M-11 and M-12
In other words. From the dropdown, if I selected June 2018
the table headers would be:
June 2018 | May 2018 | March 2018 | December 2017 | July 2017 | June 2017
I tried to approach the problem by row first (I just started learning JS) and I stuck on how to flip it.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title> Untitled </title>
<style type="text/css">
</style>
</head>
<body>
<form onsubmit="return false">
<span class="bgthead" >
<select name="features" onchange="alterColumn(this.selectedIndex)">
<option value="1">June 2018</option>
<option value="2">May 2018</option>
<option value="3">April 2018</option>
</select>
</span>
<table>
<thead>
<tr>
</tr>
</thead>
<tbody id="tblBody">
<tr>
<td class="alt">June 2018</td>
</tr>
<tr>
<td class="alt">May 2018</td>
</tr>
<tr>
<td class="alt">March 2018</td>
</tr>
<tr>
<td class="alt">December 2017</td>
</tr>
<tr>
<td class="alt">July 2017</td>
</tr>
<tr>
<td class="alt">June 2017</td>
</tr>
</tbody>
</table>
</form>
The JS part is below:
var columnValues = [
["June 2018","May 2018", "March 2018", "December 2017", "July 2017", "June 2017"],
["May 2018", "April 2018", "February 2018", " November 2017", "June 2017", "May 2017"],
["April 2018", "March 2018", " January 2017", "October 2017", "May 2017", "April 2017"]
];
function alterColumn(grp) {
var sel = document.getElementById('tblBody').getElementsByTagName('td');
var k = 0; grp = Number(grp);
for (var i=0; i<sel.length; i++) {
if (sel[i].className == 'alt') { sel[i].innerHTML = columnValues[grp][k];
k++; }}}
The goal is to have an html table with cells that are filled with data coming from a DB using php. data in table cells changing according to the month displayed in the headers.
The dropdown can be built using the month column in the database table.
my only issue was/is the dynamic table header part using the dropdown...
Thank you again for your feedbacks, corrections... I am learning... I am growing.
Take care!

With this script you should be able to accomplish what you want.
var table = document.getElementsByTagName('td');
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var selectedDate = 'June 2018'; //Selected month from dropdown
var selectedMonth = selectedDate.split(' ')[0]; //Get the data before the frist ' '
var selectedYear = selectedDate.split(' ')[1]; //Get the data after the frist ' '
var wantedMonths = [0, -1, -3, -6, -11, -12]; //List of the month you want
var monthNumber = months.indexOf(selectedMonth); //Returns the month number - 1 (arrays start at 0)
monthNumber++ //True month number
for (i = 0; i < wantedMonths.length; i++) { //Display each month
if (monthNumber + wantedMonths[i] > 0) { //Check if we'll have to go back a year
table[i].innerHTML = months[monthNumber + wantedMonths[i] - 1] + ' ' + selectedYear; //Ouput the month and year
} else { //Not in the same year
table[i].innerHTML = months[(monthNumber + 12) + wantedMonths[i] - 1] + ' ' + (selectedYear - 1); //Taking year, giving 12 months
}
}
<table>
<tr>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
<td></td>
</tr>
</table>
JS Explanation, first I selected the entire table (table), you may want to select just the row. Then there is a list of the months (months) which is used through out the script. After that there is the data from the drop down (selectectedDate)(I just defined in JS for simplification). Then I split is by the space giving me the month and year in separate variables (selectedMonth and selectedYear). Then the list of months that you want outputted repetitive to the selected month (wantedMonths). Then I get the month number (monthNumber) using the array of months. Then the script loops through the wanted months and outputs them to the table checking if it should go back a year or not. If you have any questions let me know.

You can give each select option a value that reflects the month and the year with a space between with which the String can be split. You can then create a new Date object with the month and year and subtract the number of months you want from it each time (after recreating the Date object).
showChange();
function showChange() {
var date = document.getElementById('dates').value;
var split = date.split(' ');
date = new Date(split[1], parseInt(split[0]) - 1, 17, 0, 0, 0, 0);
var month = date.getMonth();
document.getElementById("1").textContent = formatDate(date);
date.setMonth(month - 1);
document.getElementById("2").textContent = formatDate(date);
date = new Date(split[1], parseInt(split[0]) - 1, 17, 0, 0, 0, 0);
date.setMonth(month - 3);
document.getElementById("3").textContent = formatDate(date);
date = new Date(split[1], parseInt(split[0]) - 1, 17, 0, 0, 0, 0);
date.setMonth(month - 6);
document.getElementById("4").textContent = formatDate(date);
date = new Date(split[1], parseInt(split[0]) - 1, 17, 0, 0, 0, 0);
date.setMonth(month - 11);
document.getElementById("5").textContent = formatDate(date);
date = new Date(split[1], parseInt(split[0]) - 1, 17, 0, 0, 0, 0);
date.setFullYear(date.getFullYear() - 1);
document.getElementById("6").textContent = formatDate(date);
}
function formatDate(date) {
const monthNames = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
return monthNames[date.getMonth()] + " " + date.getFullYear();
}
<select onchange="showChange()" id="dates">
<option value="6 2018">June 2018</option>
<option value="5 2018">May 2018</option>
<option value="4 2018">April 2018</option>
</select>
<p/>
<table id="date">
<tr>
<th id="1"></th>
<th id="2"></th>
<th id="3"></th>
<th id="4"></th>
<th id="5"></th>
<th id="6"></th>
</tr>
</table>

Related

How to set date back by n months in Javascript

For example the month is June 2020. I want to be able to go back by 12 months, and retrieve the date as June/July 2019.
let month_val = 6;
let year_val = 2020;
let n_val = 12;
let month_names = ["January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];
let date = new Date();
let end_month_text = month_names[month_val - 1];
end_month_text += " " + year_val;
date.setMonth(month_val); //set to month in URL
date.setMonth(date.getMonth() - n_val); //setting back by n_val months
let start_month_text = month_names[date.getMonth()];
start_month_text += " " + date.getFullYear();
console.log(start_month_text + " - " + end_month_text);
The problem lies with the second to last line, date.getFullYear() returns the current real year (-12) not last year set back 12 months ago. How can I set the date back 12 months so when I attempt to date.getFullYear() I get one year ago?
The problem with using a Date as in the OP is that in setting the month, you may set it to a date that doesn't exist, e.g. on 31 July setting the date to June gives 31 June, which rolls over to 1 July. You can check and correct for those types of errors, but it's better to just avoid them.
If you just want to generate a 12 month date range based on whole months, you don't need to get that fancy. Given an end month and year, the start will be the month + 1 and year - 1, unless the start month is December in which case the end must be January of the same year, e.g.
// month is calendar month number, 1 == Jan
function getMonthName(month = new Date().getMonth() + 1) {
// Use a Date to get the month name
return new Date(2000, month - 1).toLocaleString('en',{month:'long'});
}
// month is end calendar month number
// year is end year
function getDateRange(month, year) {
// If month is 12, don't subtract 1 from year
return `${getMonthName(month+1)} ${year - (month == 12? 0 : 1)} - ` +
`${getMonthName(month)} ${year}`;
}
// Range ending June 2021
console.log(getDateRange(6, 2021)); // July 2020 - June 2021
// Range ending December 2021
console.log(getDateRange(12, 2021)); // January 2021 - December 2021
// Range ending January 2021
console.log(getDateRange(1, 2021)); // February 2020 - January 2021
// Range ending in current month and year
let d = new Date();
console.log(getDateRange(d.getMonth() + 1, d.getFullYear()));
The getMonth function could use any language, or for just one language could be replaced with an array of month names.

Javascript date calculation returns incorrect values

I have a javascript date calculator that sometimes works and sometimes does not. I have read through How do I get the number of days between two dates in JavaScript? but I am not sure where to implement any of the suggestions as it seems to me the dates on this post are predetermined inside the code instead of through the inputs.
For example, if you input the date of October 1, 2019, you will get the results of:
45 days: Thursday, November 14, 2019
180 days: Sunday, March 29, 2020
But, if you input the date of December 1, 2019, you will get the results of:
45 days: Wednesday, January 15, 2020
180 days: Friday, May 29, 2020
This can not be correct because there are 31 days in December. 31 + 15 = 46? Some sort of miscalculation happens in most months.
(function ($) {
var weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var afterTime = function (time, days) {
time = time + (24 * 60 * 60 * 1000) * days;
return time;
};
var getDate = function () {
var yy = $('input#year').val();
var mm = $('select#month').val();
var dd = $('input#day').val();
var wd;
if (yy.trim().length === 0 || mm.trim().length === 0 || dd.trim().length === 0) {
return;
}
var startDate = new Date(yy, mm, dd);
var resultDate;
resultDate = new Date();
resultDate.setTime(afterTime(startDate.getTime(), 45));
yy = resultDate.getFullYear();
mm = resultDate.getMonth();
dd = resultDate.getDate();
wd = resultDate.getDay();
$('#dateAfter45').html('<span>Your 45 Days from now ends on:</span> ' + weekdays[wd] + ', ' + months[mm] + ' ' + dd + ', ' + yy);
resultDate = new Date();
resultDate.setTime(afterTime(startDate.getTime(), 180));
yy = resultDate.getFullYear();
mm = resultDate.getMonth();
dd = resultDate.getDate();
wd = resultDate.getDay();
$('#dateAfter180').html('<span>Your 180 Days from now ends on:</span> ' + weekdays[wd] + ', ' + months[mm] + ' ' + dd + ', ' + yy);
};
$(document).ready(function () {
$('input#year').change(function () {
getDate();
});
$('input#day').change(function () {
getDate();
});
$('select#month').change(function () {
getDate();
});
});
})(jQuery);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="dateselector">
<div class="start-date">
<form class="form">
<div class="form-row align-items-center">
<div class="col-auto">
<!--label for="month">Month</label-->
<select name="month" id="month" class="form-control">
<option value="" disabled selected>- Select a Month -</option>
<option value="0">January</option>
<option value="1">February</option>
<option value="2">March</option>
<option value="3">April</option>
<option value="4">May</option>
<option value="5">June</option>
<option value="6">July</option>
<option value="7">August</option>
<option value="8">September</option>
<option value="9">October</option>
<option value="10">November</option>
<option value="11">December</option>
</select>
</div>
<div class="col-auto">
<!--label for="day">Day</label-->
<input type="text" name="day" id="day" class="form-control" placeholder="Day" maxlength="2">
</div>
<div class="col-auto">
<!--label for="day">Year</label-->
<input type="text" name="year" id="year" class="form-control" placeholder="Year" maxlength="4">
</div>
<div class="col-auto">
<!--label for="day">Year</label-->
<span class="butn hvr-sweep-to-top">Calculate</span>
</div>
</div>
</form>
</div>
<div class="result-date">
<h4 id="dateAfter45"></h4>
<h4 id="dateAfter180"></h4>
</div>
</div>
45 is 31 + 14. 31 days after December 1 is January 1, 14 days after January 1 is January 15.
The result is correct. Date arithmetic that crosses month boundaries is off by 1 because there's no day 0 in months.
The reason you're getting November 14 in the first case is because daylight savings time changes sometime in October. Your afterTime() function treats all days as 24 hours long, but when DST ends we add an extra hour to that day. So you're going from Oct 1 00:00:00 to Nov 14 23:00:00 instead of Nov 15 00:00:00.
Use the built-in date arithmetic in the Date class, it automatically adjusts for this.
resultDate.setTime(afterTime(startDate.getTime(), 45));
this is an example I made for short calculation of weekdays and month hope this will help you too
Date.prototype.calculateDays = function(days) {
var date = new Date(this.valueOf());
//here you can enter the date you picked
date.setDate(date.getDate() + days);
return date;
}
var options = {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
};
let resultDate = new Date();
let firstDate = resultDate.calculateDays(45).toLocaleDateString('en-US', options);
console.log(firstDate);
let secondDate = resultDate.calculateDays(180).toLocaleDateString('en-US', options);
console.log(secondDate);

Make Calendar as 2D Array

I am trying to make a calendar as a HTML table. It should be a single 2D array with each row as a week and each column as a day. The Week start needs to be a Monday and there must be blank spaces for overlapping months.
The Issue is the Start Days are wrong for every month and differently wrong each time. January 1st 2019 was a Tuesday so i expect the Start Day to be a 2, however i get 4 (a Thursday), the same issue is for every other month.
I am using functions to get the amount of days in the month and the day the month starts on
function month_days(month, year) {return new Date(year, month, 0).getDate();}
function month_start(month, year) {return new Date(year, month, 0).getDay();}
My problem is with the month_start function.
//date is an date object generated on the fly using date.setMonth() and date.setYear();
var month_2D_arr = gen_days(date.getMonth()+1, date.getFullYear());
function gen_days(month, year){
var monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var checking = new Date(year, month, 0);
console.log(monthNames[checking.getMonth()]);
console.log(checking.getFullYear());
var days = mondays(month, year);
var start = monstart(month, year);
console.log("start="+start);
}
The outputs are as follows (I induced the actual day names manually) compared to what the are suppose to be (to the right of "||").
My Results || Actual Days
January = 4 - Thursday || January = 2 - Tuesday
February = 4 - Thursday || February = 5 - Friday
March = 0 - Sunday || March = 5 - Friday
April = 2 - Tuesday || April = 1 -Monday
May = 5 - Friday || May = 3 - Wednesday
June = 0 - Sunday || June = 6 - Saturday
July = 3 - Wednesday || July = 1 - Monday
August = 6 - Saturday || August = 4 - Thursday
September = 1 - Monday || September = 0 - Sunday
October = 4 - Thursday || October = 2 - Tuesday
November = 6 - Saturday || November = 5 - Friday
December = 2 - Tuesday || December = 0 - Sunday
Example console log:
December //(month)
2019 //(year)
start=2 //(start day)
I have also switched set/getFullYear() to set/getYear() accounting for the 1900 difference and checking still. There is no difference to it.
Been playing with a calendar for giggle this week, so perhaps I can offer some help.
JS uses Sunday(0) as the first day of the week, yet you'd also like to use Monday(1)
You can create a date object that corresponds to the first day of any given month and then from that, you can deduce the day of the week of the 1st.
The approach I've employed was to create a table with 7 rows and 7 columns. The first row only contains th elements with the day names in em.
The next 42 table-cells can then be collected into an array and the correct date assigned to them. For that, I create a 42 element array using the brilliantly-named function test3.
Here's a screen:
function getFirstDayOfMonth(zeroBasedMonthNum, fullYear)
{
var monthNames = ['January','Febuary','March','April','May','June','July','August','September','October','November','December'];
var dateStr = `${monthNames[zeroBasedMonthNum]} 1, ${fullYear}, 00:00:00`;
var monthStart = new Date( dateStr );
return monthStart;
}
function daysInMonth(zeroBasedMonthNumber)
{
var days = [31,28,31,30,31,30, 31,31,30, 31,30,31 ];
return days[zeroBasedMonthNumber];
}
function MonthDay(number,isThisMonth)
{
this.day = number;
this.thisMonth = isThisMonth;
return this;
}
function test3(monthIndex, year)
{
var firstDay = getFirstDayOfMonth(monthIndex, year).getDay();
if (firstDay == 0)
firstDay = 6;
else
firstDay--;
var daysFromLastMonth = firstDay;
var result = [];
var daysInLastMonth = daysInMonth(monthIndex-1);
var first = daysInLastMonth - daysFromLastMonth + 1;
console.log(first);
for (var i=0; i<daysFromLastMonth; i++)
{
//result.push(first+i);
result.push( new MonthDay(first+i, false) );
}
for (var i=1; i<= daysInMonth(monthIndex); i++)
//result.push( i );
result.push( new MonthDay(i,true) );
var daysDone = result.length;
var daysToGo = (6*7) - daysDone;
for (var i=1; i<=daysToGo; i++)
//result.push( i );
result.push( new MonthDay(i,false) );
return result;
}

new Date() only show the year or month and year

$scope.articles = [
{
link: "http://google.com",
source: "Google",
title: "hello",
"date": new Date(2008, 4, 15)
},
];
<tbody>
<tr ng-repeat = "article in articles | orderBy:sortType:sortReverse | filter:searchArticle ">
<td>{{article.source}}</td>
<td>{{article.title}}</td>
<td class="date-table-td">{{article.date | date:'longDate'}}</td>
</tr>
</tbody><!-- End table body -->
Hi, I currently have this. So the date shows as May 15, 2008. How do I show only the year or only the year+month?
Thanks.
According to the documentation, you can use date.getFullYear() to get the year in YYYY format and date.getMonth() to get the month.
An example:
let list = document.getElementById('test');
let date = new Date(2008, 4, 15);
// year
let yearNode = document.createElement("li");
yearNode.appendChild(document.createTextNode(date.getFullYear()));
list.appendChild(yearNode)
// year + month
let yearMonthNode = document.createElement("li");
yearMonthNode.appendChild(document.createTextNode(date.getFullYear() + " " + date.getMonth()))
list.appendChild(yearMonthNode)
<ul id="test">
</ul>
with date.getMonth() you need +1 to this
var month = date.getMonth() + 1

ng-repeat for nested array in angular

I am getting data in nested array.
I am trying to display my data in this format
Jan
01 Mon newyear
13 sat bhogi
14 sun pongal
Feb
14 tue Valentine's day
Am little bit confused to loop it.
This is what I have tried
<table ng-repeat="list in holidayList" style="width:100%">
<thead>
<tr>
#*<th>{{list.}}</th>*#
</tr>
</thead>
<tbody>
<tr ng-repeat="leave in list">
<td width="14%">{{leave.date}}</td>
<td width="20%">{{leave.monthCode}}</td>
<td>{{leave.holiday_name}}</td>
</tr>
</tbody>
</table>
Converting date is doesn't matter I wrote custom filter and method for that so I can get expected date format by using this filter and method:
app.filter('jsonDate', function () {
return function (date) {
return new Date(date.match(/\d+/)[0] * 1);
}
})
$scope.dateFormat = function (date) {
$scope.formattedDate = date.getFullYear() + "-" + (((date.getMonth() + 1).length) == 2 ? (date.getMonth() + 1) : ("0" + (date.getMonth() + 1))) + "-" + ((date.getDay().length) == 2 ? date.getDay() : ("0" + date.getDay()));
return $scope.formattedDate
}
Current output:
/Date(1484397151447)/ 1 pongal
/Date(1484310751447)/ 1 Bhogi
/Date(1483273951447)/ 1 new year
/Date(1494855933060)/ 5 may day
Can any one tell me that how should I loop to get expected format.
You could just directly access the object: (I am assuming that the month is defined in each array item)
<table ng-repeat="list in holidayList" style="width:100%">
<tbody>
<tr>
<td>{{list[0].month}}</td>
</td>
<tr ng-repeat="leave in list">
<td width="14%">{{leave.date}}</td>
<td width="20%">{{leave.monthCode}}</td>
<td>{{leave.holiday_name}}</td>
</tr>
</tbody>
</table>
If month is not defined then use javascript array for months:
$scope.months = ["Jan", "February, "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
Then on your html:
<td>{{months(list[0].monthCode - 1)}}</td>
or just list[0].monthCode if monthCode starts with 0 for Jan.

Categories

Resources