Dynamic date dependent dialog - html

This is my first Question posted to Stack Overflow, so please forgive me if i'm approaching this incorrectly.
What I am trying to accomplish: creating a dynamic pop up that displays one of two messages depending on a set range of dates.
An example of the parameters for this message would be:
The fee from September 1 of an odd year to April 30 of an even year is $149
The fee from May 1 of an even year to August 31 of an odd year is $249
Dependent on these date ranges, I would like the pop-up to display only the current fee
Currently, I have a static pop-up that I created, but am unsure as to how I would re-factor this to dialog display the aforementioned content dynamically. I realize this is an extremely simple script in its current state, but any help would be greatly appreciated. I've searched for help, but have been unable to find anything on this specific type of pop-up
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>TEST</title>
<script>
function MyFunction()
{
alert("The fee from September 1st of an odd year to April 30th of an even year is $149 \nThe fee from May 1st of an even year to August 31st of an odd year is $249");
}
</script>
</head>
<a id="myLink" title="Click to display fee" href="Service_Pack_93_Planned_VR.pdf" onclick="MyFunction()">Application Form</a>
<body>
</body>
</html>
EDIT
After digging deeper into conditional statements and date functions in JavaScript, I came up with the code below. This was before I saw aholmes's response (which is incredibly helpful). I plan to refactor what I currently have so that my code is more effective and accommodates what I have learned from your responses.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
<script>
function myFunction()
{
var x="";
var startDate1=new Date('09/01/2013');
var endDate1=new Date('04/30/2014');
var startDate2=new Date('05/01/2014');
var endDate2=new Date('08/31/2015');
var today = new Date();
var dd = today.getDate();
var mm = today.getMonth()+1; //January is 0!
var yyyy = today.getFullYear();
if(dd<10){dd='0'+dd} if(mm<10){mm='0'+mm} today = mm+'/'+dd+'/'+yyyy;
if (startDate1 < today < endDate1)
{
x="The fee is $" + "149"
}
else if (startDate2 < today < endDate2)
{
x="The fee is $" + "249"
}
document.getElementById("test").innerHTML=x;
}
</script>
</head>
<body>
<button onclick="myFunction()">Try it</button>
<p id="test"></p>
</body>
</html>
EDIT
I had been trying to get my code working since updating my variables using the information aholmes provided me with, but had been unsuccessful. Today I came into work and modified some of the variables and I believe it is working. Thank you again for ALL of your help. If there is anything you see that could be cleaned up or modified, please let me know
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>
</head>
<script>
function myFunction()
{
var x="";
// get the current date
var date = new Date(); // Fri Feb 07 2014 11:34:32 GMT-0800 (PST)
// this will return an integer, counting months starting from 0 (January). Since it is February at the moment, this will return 1.
var month = date.getMonth(); // 1
// this returns the full year as an integer - so 2014.
var year = date.getFullYear(); // 2014
var yearIsOdd = (year % 2 === 1); // false
// remember, months are 0-based, so September (the 9th month) is represented by an 8.
if (month >= 8 && yearIsOdd) {} // false - only month is checked due to short-circuiting.
console.log("month:" + month + " Year:" + year + " Odd?" + yearIsOdd)
// Remember order of operations. Division (and thus, modulo) happens before addition without parentheses!
var nextYearIsEven = !((year + 1) % 2); // false
if ((month >= 8 && yearIsOdd) || (month <= 3 && !yearIsOdd))
{x="The fee is $" + "149"} // false - again, only month is checked
else
{x="The fee is $" + "249"}
document.getElementById("test").innerHTML=x;
}
</script>
<body>
<button onclick="myFunction()">Try it</button>
<p id="test"></p>
</body>
</html>
Thank you in advance!

You can solve this problem by checking what the current month and year are, and using the modulo operator to determine whether the current or next year is even or odd.
JavaScript has an object called Date that can help get you on the right track. The two methods we'll use are getFullYear() and getMonth().
Here are your original parameters.
The fee from September 1 of an odd year to April 30 of an even year is $149
The fee from May 1 of an even year to August 31 of an odd year is $249
So, we need to first check whether the current month is "greater than or equal to September" and whether the current year is an odd number.
Here's how you can do that in JavaScript.
// get the current date
var date = new Date(); // Fri Feb 07 2014 11:34:32 GMT-0800 (PST)
// this will return an integer, counting months starting from 0 (January). Since it is February at the moment, this will return 1.
var month = date.getMonth(); // 1
// this returns the full year as an integer - so 2014.
var year = date.getFullYear(); // 2014
Great! Now we have all the numbers we need to solve this problem. Now how can we determine whether your first case is true?
The first part is easy:
// remember, months are 0-based, so September (the 9th month) is represented by an 8.
if (month >= 8) {} // false
Now how do we determine whether the current year is even or odd? I'm going to use the modulo operator to find the remainder of dividing the year by 2. Even numbers have no remainder, while odd numbers have a remainder of one.
Next, I'm going to cast it to a bool. This isn't necessarily required, but explicitly using bools makes me feel better. I will use two "not" operators in conjunction: !!
This first converts the number (0 or 1) to a bool (false or true). The second ! then negates the result, and flips false to true, and true to false.
Let's see it in action.
var yearIsOdd = !!(year % 2); // false
if (month >= 8 && yearIsOdd) {} // false - only month is checked due to short-circuiting.
Cool! Now we know whether the year is odd, and if the month is or is after September.
Lastly, we need to determine whether the month is or is before April, and whether the year is even. I'm reading your question as if you need to check a range. So, my interpretation for the current date is "is the current month between September 2014 and April 2015?"
We're going to do the exact same thing we did to set yearIsOdd, only we have to add 1 to the current year.
Also note that I'm not using two ! not operators this time. This is because I want a 0 (meaning even) to set the variable to true, and a 1 (meaning not even) to set the variable to false.
// Remember order of operations. Division (and thus, modulo) happens before addition without parentheses!
var nextYearIsEven = !((year + 1) % 2) // false
if (month >= 8 && yearIsOdd && month <= 3 && nextYearIsEven) {} // false - again, only month is checked
There you go! I leave it to you as an exercise to solve the second constraint of your question.
As for the content of the dialog, checkout this answer: jQuery dialog with dynamic content

Two things you need to look up: conditional statements in Javascript and the Date object in Javascript.
You need a conditional statement in your popup function to display one message or the other.
if (condition) {
alert("The fee from September 1 of an odd year to April 30 of an even year is $149.");
} else if (other condition) {
alert("The fee from May 1 of an even year to August 31 of an odd year is $249.");
}
I'm not sure what your condition should be, but I imagine you want to compare today's date with those ranges. Javascript has a Date object that you can use to get certain dates.
Then all you would need to do is:
var currentDate = new Date(); // today's date
var oddStartDate = new Date(something here); // one date to compare
var oddEndDate = new Date(something here); // other date to compare
if (currentDate > oddDate && currentDate < oddEndDate ) {
alert("Display one thing");
} else if (other condition) {
alert("Display other thing");
}
Note the above logic might not be correct, but it shows what you need to do in your Javascript function in order for it to do what you want. There also might be a better way to do this!

Related

Cypress does not select a date on calendar

I want to test a calendar using cypress but it is not possible to select the date I need or any date, the ideal is a dynamic code, where I can enter number of days and it will select the correct number.
I am using this code and I am getting a error saying 'Cannot read property 'includes' of undefined'
let date = new Date()
date.setDate(date.getDate() + 5)
let futureDay = date.getDate()
console.log(futureDay)
let futureMonth = date.toLocaleString('default', { month: 'long' })
cy.get('.flatpickr-current-month')
.invoke('attr', 'flatpickr-monthDropdown-month')
.then(dateAttribute => {
if (!dateAttribute.includes(futureMonth)) {
cy.get('.flatpickr-next-month').click()
} else {
cy.get('.dayContainer')
.contains(futureDay)
.click()
}
})
I am able to add unique attributes in the elements if necessary (I tried and still it did not worked).
I was well tried a more simples code as:
cy.get('#inception_date').click()
cy.get('.flatpickr-days > .dayContainer',)
.contains('17')
.click({force: true})
cy.get('#inception_date')
.invoke('prop', 'value')
.should('contain', '2021-07-17')
and in this code I get an error of Timed out retrying after 4000ms: expected '2021-07-27' to include '2021-07-17' because it does not select the any date, it continues to be the date of today.
I am attaching 2 images if the DOM, maybe it can help to figure out what is the issue on my code.
Looking at the examples for flatPickrJS, you want
let date = new Date() // July 28
date.setDate(date.getDate() + 5) // Aug 2
let futureDay = date.getDate() // get 2 (integer)
let futureMonth = date.getMonth() // gets 6 (integer) for July
cy.get('.flatpickr-current-month select') // <select> is nested inside
.invoke('val') // this is the currently selected month
.then(dateAttribute => { // this is "6" for July (months are 0-based)
if (+dateAttribute !== futureMonth) { // +dateAttribute converts string to integer
cy.get('.flatpickr-next-month').click() // change month to Aug
}
cy.get('.dayContainer') // selects Aug 2
.contains(new RegExp(`^${futureDay}$`)) // which is July 28
.click() // plus 5 days
})
cy.get('input.flatpickr')
.invoke('val')
.should('eq', '2021-08-02') // passes
Summary of changes
get the numeric futureMonth not the string month name.
get the value of the current month from the <select> using .invoke('val').
compare current month to futureMonth, if not the same click next-month button.
take the day container click out of } else {, because you always need to select the day.
NOTE
Thanks to #SyedMuhammadAwais for finding a bug in the day selection code.
Using .contains(futureDay) does a partial match, but the calendar sometimes shows some days from the previous month, but they are disabled (not clickable).
So, if futureDay === 6 and the 26th of the previous month is showing, this disabled day will be selected and fail the test.
The solution is to use an exact text match, which can be done with a regex like this
.contains(new RegExp(`^${futureDay}$`))
This is the correct code with some amendments in code of #Steve Zodiac
date.setDate(date.getDate() + 8)
let futureDay = date.getDate()
let futureMonth = date.getMonth()
cy.log(futureDay) // get 6 (integer)
cy.log(futureMonth) // gets 7 (integer) for August
cy.get('input[placeholder="Day"]').click({force:true})
cy.wait(5000)
cy.get('.flatpickr-current-month > select > option').eq(0)
.invoke('val') // this is the currently
selected month
.then(dateAttribute => { // this is "6" for July
(months are 0-based)
if (+dateAttribute !== futureMonth) { // +dateAttribute converts string to integer
cy.get('.flatpickr-next-month').click({force: true}
}
cy.get('.dayContainer') // selects Aug 6
.contains(new RegExp(futureDay, "g"))
.click({force:true}) // plus 8 days
})
Here is my solution for the datepicker "previous days" exist or not issue when testing with Cypress.
Cypress.Commands.add(
'selectDate',
(picker, date) => {
let pickerDate = date.split('-')
let year = pickerDate[0]
let month = pickerDate[1]
let day = pickerDate[2]
cy.get(picker).click()
cy.get('.numInput.cur-year').eq(0).filter(':visible').clear().type(year)
let selectedMonth = parseInt(month, 10)
cy.get('.flatpickr-monthDropdown-months')
.eq(0)
.select(selectedMonth - 1)
//set day -> count how many 'prevMonthDay' is int the calendarMonth and add the number to the day we wants
//filtering here for get the correct day
// if there is any prev day !!
cy.get('.flatpickr-rContainer')
.then($body => {
if ($body.find('.flatpickr-day.prevMonthDay').length) {
return ['.flatpickr-day.prevMonthDay', ($body.find('.flatpickr-day.prevMonthDay').length).toString()];
}else{
return ['.flatpickr-day', '0'];
}
})
.then(selector => {
if(selector[0] === '.flatpickr-day.prevMonthDay'){
cy.log('prev days')
cy.get(`.dayContainer span:nth-child(${parseInt(day, 10) + parseInt(selector[1])})`)
.eq(0)
.click()
}else{
cy.log('no prev days')
cy.get(`.dayContainer span:nth-child(${parseInt(day, 10)})`)
.eq(0)
.click()
}
});
}
)

Bootstrap DatePicker, how to set the start date as next day 12AM?

I was trying to make use of bootstrap date picker, and make the user to select next day or above in the calendar.
How to make the (data-date-start-date="12AM next day") instead of (data-date-start-date="+1d").
To be precise, the selected insurance policy needs be covered from next day 12AM.
I'm banging my head from last couple of days, tried most of the known probabilities.
It needs to be set via Bootstrap date picker! Any help would be highly appreciated.
<div class="input-group date" data-provide="datepicker" data-date-autoclose="true" data-date-start-view="0" data-date-force-parse="false" data-date-start-date="+1d"></div>
Try this:
<script type="text/javascript">
$(function () {
var d = new Date();
d.setDate(d.getDate() + 1); //this will set tomorrow
d.setHours(0, 0, 0, 0); //this will set 12 AM
$('#datetimepicker1').datetimepicker({
defaultDate: d,
});
});
</script>
bootstrap-datepicker is not designed to be concerned with time (search the documentation for the word "time").
There are other libraries that help with picking dates and times.

Display separate text strings each day

I want to display a text string, or a bit of code each day of the week for two weeks, then it will repeat. So through the days it will display Monday 1, Tuesday 1...Friday 1, Monday 2, Tuesday 2...Friday 2. Then it will revert back to Monday 1. If there is a way without using I-frame (have to spell like this so it will let me post the question) from another site then please say. I have tested out with I-frame but it never seems to work. So maybe a counter which when reaching 14 will revert to 1 again. Thank you in advance!
You should be able to achieve it with pure JavaScript using the following:
Date.prototype.getWeek = function() {
var onejan = new Date(this.getFullYear(),0,1);
var today = new Date(this.getFullYear(),this.getMonth(),this.getDate());
var dayOfYear = ((today - onejan +1)/86400000);
return Math.ceil(dayOfYear/7)
};
var sentences = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth", "tenth", "eleventh", "twelvth", "thirsteenth", "fourteenth"];
var date = new Date();
var day = (date.getDay()+6)%7+1;
day = day * ((date.getWeek()%2)+1);
document.getElementById("container").innerHTML = sentences[day-1];
Fiddle: https://jsfiddle.net/04wha99e/1/
Using simple JavaScript, you create an array of sentences you wish to have, and basically get the current day of the week (JavaScript Date.getDay() returns Sunday as 0, hence the workaround) and based on the week number being odd or even you multiply it by 1 on 2 getting a range of 1-14 and then return the sentence from the array (starting index 0, hence the minus 1)
The above script assumes, you have a div with the id container, where the inner html gets replaced:
<div id="container">
This is where the sentence goes
</div>

Disable certain dates from html5 datepicker

Is it possible to disable dates when I use
I want to disable current date for one scenario and future dates for other scenario.
How should I disable the dates?
You can add a min or max attribute to the input type=date. The date must be in ISO format (yyyy-mm-dd). This is supported in many mobile browsers and current versions of Chrome, although users can manually enter an invalid date without using the datepicker.
<input name="somedate" type="date" min="2013-12-25">
The min and max attributes must be a full date; there's no way to specify "today" or "+0". To do that, you'll need to use JavaScript or a server-side language:
var today = new Date().toISOString().split('T')[0];
document.getElementsByName("somedate")[0].setAttribute('min', today);
http://jsfiddle.net/mblase75/kz7d2/
Ruling out only today, while allowing past or future dates, is not an option with here. However, if you meant you want tomorrow to be the min date (blanking out today and all past dates), see this question to increment today by one day.
As in all other cases involving HTML forms, you should always validate the field server-side regardless of how you constrain it client-side.
In pure HTML, the only restrictions you can put on dates are its lower and upper bounds through the min and max attributes. In the example below, only the dates of the week I'm posting this question are allowed, other appear greyed out and clicking on them doesn't update the input value:
<input type="date" min="2019-06-02" max="2019-06-08"/>
You can also disable any invalid date by using a few lines of JavaScript, but this doesn't ship with all the native <input type="date"> features like greyed-out dates. What you can do is set the date value to '' in case of an invalid date, an error message could also be displayed. Here is an example of an input that doesn't accept weekend dates:
// Everything except weekend days
const validate = dateString => {
const day = (new Date(dateString)).getDay();
if (day==0 || day==6) {
return false;
}
return true;
}
// Sets the value to '' in case of an invalid date
document.querySelector('input').onchange = evt => {
if (!validate(evt.target.value)) {
evt.target.value = '';
}
}
<input type="date"/>
HTML datepicker (<input type=date>) supports min/max attribute, but it is not widely supported.
At the meantime you may consider using bootstrap-datepicker, v1.2.0 is on github.
References:
W3C spec
You could use this to disable future dates :
Inside you document.ready function, place
//Display Only Date till today //
var dtToday = new Date();
var month = dtToday.getMonth() + 1; // getMonth() is zero-based
var day = dtToday.getDate();
var year = dtToday.getFullYear();
if(month < 10)
month = '0' + month.toString();
if(day < 10)
day = '0' + day.toString();
var maxDate = year + '-' + month + '-' + day;
$('#dateID').attr('max', maxDate);
and in form
<input id="dateID" type="date"/>
Here is the working jFiddle Demo
For react and similar libraries, you may use this to disable all dates before today.
<input type='date' min={new Date().toISOString().split('T')[0]} >
Depending on what you need, you can also use the step attribute to only enable specific dates - e.g. every Monday, or every other day. You can use it in combination with min and max
e.g. every Monday
<input type="date" step="7" value="2022-04-04">
Every Thursday
<input type="date" step="7" value="2022-04-07">
Every other day
<input type="date" step="2">

Convert UK date to US date in Flex

Hi there seems to be plenty out there to convert a US formatted date (MM/DD/YYYY) to a UK date (DD/MM/YYYY), but I'm trying to do the opposite: i receive a load of UK dates (DD-MM-YYYY) from the server which I'm trying to format as DD-MMM-YYYY (eg: 11 Jan 2013 ), but Flex thinks it's trying to convert American days and so when it gets 17-02-2013, it returns an empty string because there is no month 17.
How do i tell it I'm giving it UK dates and not US dates?
Thanks in advance.
Short answer, you can't.
Longer answer, there's not enough information to determine the date format. As you saw, in some cases you CAN determine that the date is not valid for the expected format (17-02-2013 - since 17 isn't a valid month, it must be DD-MM-YYYY rather than MM-DD-YYYY), but for just under half of the dates you just can't tell (is 01-02-2013 supposed to be Jan 2 or Feb 1?)
If you DO know that the dates are supposed to be in a particular format, you can use DateField.stringToDate to parse the string:
var value:Date = DateField.stringToDate(dateString, 'DD-MM-YYYY');
OK, got round it in the end with this ugly hack: ended up converting the string into an array and re-organising it so that it would fit the american format before using the DateFormatter.format on the result. There must be a more elegant way...
<Script>
public convertDateStringToUS( date : String ) : String
{
var dateArray : Array = date.split( "-" );
var day = dateArray[0];
var month = dateArray[1];
var year = dateArray[2];
date = month + "-" + day + "-" + year;
return date
}
</Script>
<declarations>
<mx:DateFormatter id="dateFormatter"
formatString="DD-MMM-YYYY" />
</declarations>
<s:Label id="myDateLabel"
text =" { dateFormatter.format( convertDateStringToUS( date ) ) } "/>