Control Month Year in Dropdown list - javascript

I am trying to control "Month" and "Year" in drop down list. I am having two fields, "Start Date" and "End Date". In that "Start Date" I am listing the "Current Month" and "Year" like "March 2020". I want to control my "End Date" based of "Start Date". For example if there is no "Month" selected in "Start Date" I should not allow user to select the "End Date". If user select's "MAY 2020" in "Start Date" and in "End Date" I want to display from "May 2020 to next May 2021". Like wise if user select's "June 2020" in "Start Date" and in "End Date" I want to display from "June 2020 to next June 2021". As of now I am displaying the current month and year in both Start and End date. Any one can guide me to achieve this. Thanks in Advance. Below is the code where I am getting current year month to next year.
const fareMon = () => {
const monthList = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const currDate = new Date();
const year = currDate.getFullYear();
const months = [];
let currentMonthIndex = currDate.getMonth();
let yearsToAdd = 0;
for (let i = 0; i < 13; i += 1) {
if (currentMonthIndex === 12) {
currentMonthIndex = 0;
yearsToAdd += 1;
}
const futYear = year + yearsToAdd;
months.push(<option value={`${monthList[currentMonthIndex]} ${futYear}`}>{`${monthList[currentMonthIndex]} ${futYear}`}</option>);
currentMonthIndex += 1;
}
return <>{months}</>;
};

So, what I have done is, created a getFullYear function, where you can pass year and you will get all the months
Does this help:
const monthList = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const getFullYear = (year) => {
const currentDate = new Date(`01 01 ${year}`);
const monthYear = [];
for(;currentDate.getFullYear() === year;){
const currentMonth = currentDate.getMonth();
monthYear.push(`${monthList[currentMonth]} ${year}`)
const nextMonth = currentMonth+1;
currentDate.setMonth(nextMonth);
}
return monthYear;
}
More cleaner and less compute intensive approach would be:
const monthList = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const getYear = (year) => {
return monthList.map((month) => `${month} ${year}`);
}

Related

I cant use a part of data directly I have to use another variable in between

I am really new to programming and my questions are very really not good
Please forgive me if I am wasting your time
Why when I use labels indirectly in DatatoBarChartJS (using a "label") it works
const DataFromDataBase = {
label :['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets : [ {datasetName:'Dataset 1', data:[1,3,5,2,5,2,6]},{datasetName:'Dataset 2', data:[4,6,5,2,5,2,6]} ],
}
const label =dataFromDataBase.label;
const color = tinycolor();
const DatatoBarChartJS = {
label,
datasets : dataFromDataBase.datasets.map((dataset)=>{
return{
label:dataset.datasetName,
data : dataset.data,
backgroundColor:color.toRgbString ,
}
}
)
}
but when I use it inderectly it dosnt work?
const DataFromDataBase = {
label :['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets : [ {datasetName:'Dataset 1', data:[1,3,5,2,5,2,6]},{datasetName:'Dataset 2', data:[4,6,5,2,5,2,6]} ],
}
const label =dataFromDataBase.label;
const color = tinycolor();
const DatatoBarChartJS = {
DataFromDataBase.label,
datasets : dataFromDataBase.datasets.map((dataset)=>{
return{
label:dataset.datasetName,
data : dataset.data,
backgroundColor:color.toRgbString ,
}
}
)
}
the problem is
problem
When creating an object using the curly bracket syntax, you usually need to provide the name of the fields and their associated value.
const cat = {
cute: true,
legCount: 4,
sound: 'miaw'
};
Depending on what "version of Javascript" you are using, there is a shorthand syntax that you can use:
const cute = true;
const legCount = 4;
const sound = 'miaw';
const cat = {
legCount,
sound,
cute
}
When doing this, the name of the field will be the name of the variable, and the value of the field will be the value of the variable.
The reason you cannot use that syntax in your case is because what you are referencing is not a variable, it's a field within an object. And it kind of makes sense, because the result would be ambiguous:
// Would the result be this?
{ DatatoBarChartJS: { label: ['January', 'February', 'March', 'April', 'May', 'June', 'July'] } }
// Or this?
{ 'DatatoBarChartJS.label': ['January', 'February', 'March', 'April', 'May', 'June', 'July'] }
// Or this?
{ label: ['January', 'February', 'March', 'April', 'May', 'June', 'July'] }
You can find more information in Mozilla's object initialization documentation

Text to object with JS in simple way

I wrote simple script that make an object from some formatted text. It works, but for me, it seems a little complicated. May be you can advise more a simpler way?
let myText = document.getElementById('element').innerText; //get text from div
let myObj = {};
let arrText = myText.replaceAll('\n', '').split(';') //split text
let monthesCodes = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
arrText.forEach(element => {
for (let i = 0; i < 12; i++) {
if (element.includes(monthesCodes[i])) {
let arrString = element.split(' – ') //split line one by one by '-'
if (!myObj.hasOwnProperty(i + 1)) { //if there are no key with month nomber in object - create it
myObj[i + 1] = {}
}
let keyDay = arrString[0].replace(' ' + monthesCodes[i], '').replaceAll('and', ',') //left only numbers and delimeters in left part of string
if (keyDay.includes(',')) { //if the left part have delimeters write in sub-object a key (number) with the value as name of the holiday
for (let keyDays of keyDay.split(',')) {
myObj[i + 1][+keyDays] = arrString[1];
}
} else { //else if we have only one number in left string
myObj[i + 1][keyDay] = arrString[1];
}
}
}
});
console.log(myObj)
<body>
<div id="element">
<br>1, 2, 3, 4, 5, 6 and 8 January – NY hollidays;
<br>7 January – Orthodox Christmas;
<br>23 February – Man's day;
<br>8 March – Woman's Day;
<br>1 May – Labor Day;
<br>9 May – Memorial Day;
<br>12 June – Country Day;
<br>4 November – People uniting day
</div>
</body>
Output
{
"1": {
"1": "NY hollidays",
"2": "NY hollidays",
"3": "NY hollidays",
"4": "NY hollidays",
"5": "NY hollidays",
"6": "NY hollidays",
"7": "Orthodox Christmas",
"8": "NY hollidays"
},
"2": {
"23": "Man's day"
},
"3": {
"8": "Woman's Day"
},
"5": {
"1": "Labor Day",
"9": "Memorial Day"
},
"6": {
"12": "Country Day"
},
"11": {
"4": "People uniting day"
}
}
I think that separating the part of the code where you get the info from the strings from the part where this gets organised into the object should help in understanding as you can focus more on the details of what each part is doing:
const event_listings = document.getElementById('element').innerText
.replaceAll('\n', '').split(';');
const months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
const parse_event_listing = (string) => {
const [date_info, title] = string.split(' – ');
let date_parts = date_info.replace(/,/g, '').replace(' and', '').split(' ');
const month = date_parts.pop();
return [months.indexOf(month) + 1 + '', date_parts, title];
};
const myObj = event_listings
.map(parse_event_listing)
.reduce(
(acc, [month, days, title]) => Object.assign(acc, {
[month]: Object.assign(
acc[month] || {},
Object.fromEntries(days.map((d) => [d, title]))
)
}), {}
);
console.log(myObj);
<body>
<div id="element">
<br>1, 2, 3, 4, 5, 6 and 8 January – NY hollidays;
<br>7 January – Orthodox Christmas;
<br>23 February – Man's day;
<br>8 March – Woman's Day;
<br>1 May – Labor Day;
<br>9 May – Memorial Day;
<br>12 June – Country Day;
<br>4 November – People uniting day
</div>
</body>
Here's another way that uses reduce(), filter(), some simple regex and array manipulation. The benefit (I think) is one: it spits out the data in 2 different usable formats and two: it is easier to read
It first compiles a tidy array of objects, each having
{
month: month name,
event: event name,
dates: list of dates associated
}
That might be useful to have the data in that format. But it then takes that and runs it through a map() to format it the way you have in your example.
let myText = document.getElementById('element').innerText; //get text from div
let arrText = myText.replaceAll('\n', '').split(';') //split text
let months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
let event_list = arrText.reduce((acc, a) => {
let nums = a.replace("and", ",").replace(/[^,\d.-]/g, "").split(",");
let month = months.filter(m => a.includes(m));
let event = a.split("–")[1].trim();
acc.push({
event: event,
month: month[0],
dates: nums.join(",")
});
return acc;
}, []);
console.log(event_list)
// now the same format you have
let event_list2 = {};
event_list.map(obj => {
let monthnum = months.indexOf(obj.month) + 1;
if (!event_list2.hasOwnProperty(monthnum)) event_list2[monthnum] = {};
obj.dates.split(",").forEach(dt => event_list2[monthnum][dt] = obj.event);
})
console.log(event_list2)
<div id="element">
<br>1, 2, 3, 4, 5, 6 and 8 January – NY hollidays;
<br>7 January – Orthodox Christmas;
<br>23 February – Man's day;
<br>8 March – Woman's Day;
<br>1 May – Labor Day;
<br>9 May – Memorial Day;
<br>12 June – Country Day;
<br>4 November – People uniting day
</div>

Convert custom string into Angular Date

I have a string like "August 24th, 2020" that I need to convert into the "Date" type in Angular. Is there any simple way to do this please?
I've tried this:
const deadline = new Date ("August 24th, 2020")
But that results in "Invalid Date".
Maybe moment.js is capable to parse that outside of the box, however, if you're not willing to attach external library and maintain its compatibility to the rest of your environment for this purpose only, you may parse that yourself:
const dateStr = "August 24th, 2020",
parseDate = s => {
const [, month, dd, yyyy] = s.match(/([a-z]+)\s(\d+)[a-z]+,\s(\d+)/i)||[],
months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']
return new Date(Date.UTC(yyyy, months.indexOf(month), dd))
}
console.log(parseDate(dateStr))

JS includes from array to momentjs current date

I am wanting true or false return when using includes to see if the current month using moment().format('MMMM') is also in an array.
const splitMonths = ['April', 'May', 'June', 'July', 'August', 'September'];
const currentDate = moment().format('MMMM');
const seasonData = currentDate.includes(splitMonths);
console.log(seasonData);
The above returns false and I cannot understand why.
If I change splitMonths to splitMonths = ['May']; it will return true.
If I run console.log(currentDate) it returns May.
Why isn't this returning true?
You are checking array existence within the string currentDate.includes(splitMonths);. Instead it should be splitMonths.includes(currentDate);
const splitMonths = ['April', 'May', 'June', 'July', 'August', 'September'];
const month = "May";
const seasonData = splitMonths.includes(month);
console.log(seasonData);

ng-repeat parse array into string

Is it possible to parse in ng-repeat a array value into a string? I'll explain what I mean.
<tr ng-repeat="(key,property) in obj.properties">
<td>{{key}}</td>
<td>{{property}}</td>
</tr>
This {{property}} is an array e.g [ 7 , 8 ], but I would like to show "Jully - August". Is it possible through a filter? Or I need to parse it in the controller.
Use filter convert number to name of month:-
<td>{{property|monthName}}</td>
app.filter('monthName', [function() {
return function (monthNumber) {
//1 = January
var monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December' ];
var nameList="";
for(var i=0;i<monthNumber.length;i++){
if(i==monthNumber.length-1){
nameList+=monthNames[monthNumber[i] - 1];
}else{
nameList+=monthNames[monthNumber[i] - 1]+"-";
}
}
return nameList;
}
}]);
Plunker
You can do it as well
<td>{{property|showMonthName}}</td>
app.filter('showMonthName', function() {
return function (months) {
var monthNames = [ 'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December' ];
months = months.map(function(i){
return monthNames[i-1];
});
return months.join(' - ');
}
});
So I tried this in my own system. I created one filter and applied inside ng-repeat. It works perfectly. You can modify your own filter based on this one.
<test-directive keyword = "view.ctrlKeywordinput" ng-repeat="movie in [1,2]" ><div> {{movie | monthfilter}}</div></test-directive>
and here is my filter:
app.filter("monthfilter", function(){
return function(input){
switch(input){
case 1:
return "january";
break;
case 2:
return "february";
break;
}
};
});

Categories