Removing past and current month options from selectbox based on year selected - javascript

I am creating a form that includes two select boxes to allow users to choose a month and year to cancel a membership. The month selected should not be the current month nor past months. I added some jQuery to pre-select the month after the current one, but it still allows users to select a previous month if they want.
What I would like to implement is a script that removes options based on the year selected. For example: If 2016 is selected (and we're in October 2016 now), the script should remove options 1 through 10.
I suspect it is not too complicated, but my knowledge of jQuery is very limited. Thanks in advance.
Codepen: http://codepen.io/ricardoh/pen/vXpdvQ
Here is the HTML:
<select id="month">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<select id="year">
<option value="2016">2016</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
</select>
And the jQuery:
$(function(){
var month = new Date().getMonth() + 1;
if( month > 12 ) month = 1;
document.getElementById("month").options[month].selected = true;
});

How about something like this? JSFiddle
function adjustMonths() {
var thisYear = new Date().getFullYear() + ""; //Get current year
var nextMonth = new Date().getMonth()+2 + ""; //Get next month
var selectedYear = $('#year option:selected').val(); //Selected Year
if (nextMonth .length == 1) {
nextMonth = "0" + nextMonth ; //Add preceding "0" to single-digit month
}
var yearAndMonth = parseInt(thisYear+nextMonth); //Create integer of year+month
$('#month option').each(function() { //Loop through all month options
var selectMonth = $(this).prop('value'); //Get option value
if (selectMonth.length == 1) {
selectMonth = "0" + selectMonth; //Add preceding "0" to single-digit month
}
if (parseInt(selectedYear + selectMonth) < yearAndMonth) {
$(this).hide(); //If the selected year + this month are less than the current year and month, hide this month
} else {
$(this).show(); //Otherwise, show it
}
});
$("#month option").prop('selected', false); //Unselect all
$("#month").find("option:visible:first").prop('selected', true); //Select first visible month from dropdown
}
$(document).ready(function() {
adjustMonths(); //run script on pageload
$('#year').change(function() {
adjustMonths(); //run script when changing the year dropdown
})
});

I was working on this while I noticed that the question had been answered and accepted, figured a second answer couldn't hurt.
$(function(){
var monthElem = document.getElementById('month');
var yearElem = document.getElementById('year');
var months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
var createOption = function(monthID) {
var elem = document.createElement('option');
elem.value = monthID+1;
elem.text = months[monthID];
return elem;
};
var evt = document.createEvent('HTMLEvents');
yearElem.addEventListener('change', function() {
var now = new Date(), tmp;
var month = now.getMonth();
if(now.getFullYear() === parseInt(this.value)) {
tmp = month;
while(tmp >= 0) monthElem.remove(tmp--);
}
else {
tmp = monthElem.length = 0;
while(tmp < 12) monthElem.add(createOption(tmp), tmp++);
}
}, false);
evt.initEvent('change', false, true);
yearElem.dispatchEvent(evt);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="month">
<option value="1">January</option>
<option value="2">February</option>
<option value="3">March</option>
<option value="4">April</option>
<option value="5">May</option>
<option value="6">June</option>
<option value="7">July</option>
<option value="8">August</option>
<option value="9">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</select>
<select id="year">
<option value="2016">2016</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
</select>

Related

How to get any day's date in a month?

I need to correct this code to to retrieve date of day selected for a certain month from the select. For example when user select October for month and Tuesday for day, it will list out Tuesday's date on October.
This code works for Monday only.
Full code here: Fiddle
function getAllInstancesOfDayInMonth(fordate, forday) {
fordate.setDate(1);
var start = getStartDay(fordate, forday)
,month = fordate.getMonth()
,result = [start];
while (fordate.getMonth() == month) {
result.push(new Date(fordate.setDate(fordate.getDate()+7)));
}
return result.slice(0,-1);
function getStartDay(d, forday) {
return d.getDay() != +forday
? ( d.setDate( d.getDate() + 1 ), getStartDay(d, forday) )
: new Date(d);
}
}
(function () {
document.querySelector('#ddlMonths')
.addEventListener('change', getDays);
var result = document.querySelector('#result');
result.innerHTML = '<h3>Selected day </h3>';
result.innerHTML += getAllInstancesOfDayInMonth(
new Date([2015,1,1].join('/')), 1
).join('\n');
function getDays(e){
var year = this.getAttribute('data-year')
,month = +this.options[this.selectedIndex].value
,monthstr = this.options[this.selectedIndex].innerHTML;
result.innerHTML = '<h3>all mondays in '+monthstr+' '+ year+'</h3>';
result.innerHTML += getAllInstancesOfDayInMonth(
new Date([year,month+1,1].join('/')), 1
).join('\n');
}
function getAllInstancesOfDayInMonth(fordate, forday) {
fordate.setDate(2);
var start = getStartDay(fordate, forday)
,month = fordate.getMonth()
,result = [start];
while (fordate.getMonth() == month) {
result.push(new Date(fordate.setDate(fordate.getDate()+7)));
}
return result.slice(0,-1);
function getStartDay(d, forday) {
return d.getDay() != +forday
? ( d.setDate( d.getDate() + 1 ), getStartDay(d, forday) )
: new Date(d);
}
}
}())
There are multiple problems in your code. Let's go through them one by one.
The values in the select element for days are not all unique. Fix them as follows:
<select id="ddlDay" class="form-control">
<option value="0">Monday</option>
<option value="1">Tuesday</option>
<option value="2">Wednesday</option>
<option value="3">Thursday</option>
<option value="4">Friday</option>
<option value="5">Saturday</option>
<option value="6">Sunday</option>
</select>
Now on to the javascript...
First of all, your getDays function is only called when you change the months select element, not the days select element. We add the following so that your display will also update when the day is changed:
document.querySelector('#ddlDay')
.addEventListener('change', getDays);
Inside the getDays function, the user-selected day is never called, so that is why the display is stuck to Monday. We can fix this with the following:
var year = document.querySelector("#ddlMonths").getAttribute('data-year'),
month = parseInt(document.querySelector("#ddlMonths").value)+1,
monthstr = document.querySelector("#ddlMonths option:checked").innerText,
day = parseInt(document.querySelector("#ddlDay").value)+1,
daystr = document.querySelector("#ddlDay option:checked").innerText;
This code could definitely use some simplification, but it just works. Notice that the month and day variables should also be converted to the appropriate ints before being fed into the getAllInstancesOfDayInMonth function.
Finally, we update the display and run the above function accordingly:
result.innerHTML = '<h3>all '+daystr+'s in '+monthstr+' '+ year+'</h3>';
result.innerHTML += getAllInstancesOfDayInMonth(
new Date([year,month,1].join('/')), day % 7
).join('\n');
I think that should be all. The working fiddle can be found here: https://jsfiddle.net/m9nvekhd
I think you got everything really complicated
const
myForm = document.forms['my-form']
, dateYM = { year: 'numeric', month: 'long'}
, dateLong = { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric' }
, setDays =_=>
{
let dt = new Date(`${myForm.Months.dataset.year}-${myForm.Months.value}-1`)
, mRef = dt.getMonth()
;
myForm.result.innerHTML = `<h3>All ${myForm.Day.selectedOptions[0].textContent}in ${dt.toLocaleDateString('en-US',dateYM)} </h3>\n`
;
while ( mRef === dt.getMonth() )
{
if ( dt.getDay() == myForm.Day.value )
myForm.result.innerHTML += dt.toLocaleDateString('en-US',dateLong) + '\n'
dt.setDate(dt.getDate() + 1)
} }
myForm.oninput = setDays
setDays() // init
body {
font : 12px/15px normal verdana, arial;
margin : 1.5em;
}
output {
display : block;
white-space : pre;
margin-top : 2em;
}
<form name="my-form">
<select name="Months" data-year="2021">
<option value="1" > January </option>
<option value="2" > February </option>
<option value="3" > March </option>
<option value="4" > April </option>
<option value="5" > May </option>
<option value="6" > June </option>
<option value="7" > July </option>
<option value="8" > August </option>
<option value="9" > September </option>
<option value="10"> October </option>
<option value="11"> November </option>
<option value="12"> December </option>
</select>
Select a month to retrieve all
<select id="Day">
<option value="1" >Monday </option>
<option value="2" >Tuesday </option>
<option value="3" >Wednesday </option>
<option value="4" >Thursday </option>
<option value="5" >Friday </option>
<option value="6" >Saturday </option>
<option value="0" >Sunday </option> <!-- sunday JS is 0 -->
</select>
of it
<output name="result"></output>
</form>

Sorting/reorganising a select option list in Javascript

I have a Select Option List where I have fruit in a random order, some with a "Out Of Stock" label on them. What i want to do is sort them all by alphabetical order then move the "Out Of Stock" label from the start of the flavour to the end of the flavour so they would display as: "Lemon - Out Of Stock" instead of how it currently is: "Out Of Stock - Lemon". So far I have the following where I'm looking for the "Out Of Stock" label and then adding it to the end, but not sure how I would go about removing it from the start or if there is a better way to achieve what i'm looking to do.
document.querySelectorAll('.form-dropdown').forEach(function(select) {
Array.from(select.options).forEach(function(option) {
if (option.innerText.includes("Out of stock")) {
select.insertBefore(option, select.options[1]);
option.innerText += (' - Out of stock');
}
});
var cl = document.querySelector('.form-dropdown');
var clTexts = new Array();
for (i = 1; i < cl.length; i++) {
clTexts[i - 1] =
cl.options[i].text.toUpperCase() + "," +
cl.options[i].text + "," +
cl.options[i].value;
}
clTexts.sort();
for (i = 1; i < cl.length; i++) {
var parts = clTexts[i - 1].split(',');
cl.options[i].text = parts[1];
cl.options[i].value = parts[2];
}
});
<select class="form-dropdown">
<option disabled="" value="">Choose option</option>
<option value="6">Watermelon</option>
<option value="2">Out of stock - Cherry</option>
<option value="3">Kiwi</option>
<option value="0">Apple</option>
<option value="4">Out of stock - Lemon</option>
<option value="1">Banana</option>
<option value="5">Out of stock - Melon </option>
<option value="4">Out of stock - Pineapple</option>
<option value="1">Strawberry</option>
<option value="5">Out of stock - Khaki</option>
</select>
You can use a function inside sort, in which you will sort the strings by some condition, in this case alphabetic order. It's used localCompare() built-in method to perform so.
Take a look:
const pattern = " - "
const chooseText = "Choose option"
const select = document.querySelector(".form-dropdown")
const children = [...select.children]
// brings "Out of stock" to the end
children.forEach(child => child.textContent = child.textContent.split(pattern).reverse().join(pattern))
children.sort(compareChild)
function compareChild(a, b){
const str_a = a.textContent
const str_b = b.textContent
// remember to not consider disabled option while sorting
if(str_a === chooseText || str_b === chooseText) return 0;
return str_a.localeCompare(str_b)
}
select.replaceChildren(...children)
<select class="form-dropdown">
<option disabled="" value="">Choose option</option>
<option value="6">Watermelon</option>
<option value="2">Out of stock - Cherry</option>
<option value="3">Kiwi</option>
<option value="0">Apple</option>
<option value="4">Out of stock - Lemon</option>
<option value="1">Banana</option>
<option value="5">Out of stock - Melon</option>
<option value="4">Out of stock - Pineapple</option>
<option value="1">Strawberry</option>
<option value="5">Out of stock - Khaki</option>
</select>

How to stop the days in appending after I select the month

To make the issue short. I have 3 dropdowns for picking a date. The date picker display the range of the days within the month if it's only 29 or 31 days. It's working fine now except that when I changed in different month the value in my days is repeating.
For example I choose February. The days that is display is 28 days.
Then I changed to March. The days displays as 31 days. The problem is they are only combining so the value in my day dropdown become many. How can I fixed this, any help?
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
function onMonthChange(){
var year = document.getElementById("yeardialog").value;
var month = document.getElementById("monthdialog").value;
var endOfTheMonth = daysInMonth(month, year);
console.log(endOfTheMonth);
var select = document.getElementById('datedialog');
for (var i = 0; i < endOfTheMonth; i++) {
select.options[select.options.length] = new Option(i + 1, i);
}
}
<select id="yeardialog" name="yeardialog">
<option value="">--</option>
<option value="1990">1990</option>
<option value="1991">1991</option>
<option value="1992">1992</option>
</select>
<select id="monthdialog" onchange="onMonthChange()">
<option value="">--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select id="datedialog">
<option></option>
</select>
var select = document.getElementById('datedialog');
select.innerHTML = ""; // clear the select.
for (var i = 0; i < endOfTheMonth; i++) {
select.options[select.options.length] = new Option(i + 1, i);
}
The solution is plain and simple. Delete the contents of the select before populating them.
Solution inside the snippet:
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
function onMonthChange(){
var year = document.getElementById("yeardialog").value;
var month = document.getElementById("monthdialog").value;
var endOfTheMonth = daysInMonth(month, year);
console.log(endOfTheMonth);
var select = document.getElementById('datedialog');
var selectedvalue = select.querySelector('option:checked');
if (selectedvalue)
{
var store = selectedvalue.getAttribute("value");
}
select.innerHTML = "";
for (var i = 0; i < endOfTheMonth; i++) {
select.options[select.options.length] = new Option(i + 1, i);
}
var retrieved = select.querySelector("option[value='"+store+"']");
if (retrieved)
{
retrieved.setAttribute("selected", "true");
}
}
<select id="yeardialog" name="yeardialog">
<option value="">--</option>
<option value="1990">1990</option>
<option value="1991">1991</option>
<option value="1992">1992</option>
</select>
<select id="monthdialog" onchange="onMonthChange()">
<option value="">--</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
<select id="datedialog">
<option></option>
</select>
Updated question. Store the original value before deleting:
We look for the selected value using:
select.querySelector('option:checked');
Then we look if the value can be found in the new list. If so select the value. If not revert to 1. This happens when you select 31 and the month loaded only has 30 days.
I wouldn't modify the innerHTML, I prefer removing the nodes
var select = document.getElementById('datedialog');
while(select.hasChildNodes())select.removeChild(select.firstChild);// clear the select.
for (var i = 0; i < endOfTheMonth; i++) {
select.options.add(new Option(i + 1, i));
}
Try this:
function onMonthChange(){
var year = document.getElementById("yeardialog").value;
var month = document.getElementById("monthdialog").value;
var endOfTheMonth = daysInMonth(month, year);
console.log(endOfTheMonth);
var select = document.getElementById('datedialog');
select.innerHTML = '';
select.options[0] = new Option("Pick a date", 0);
for (var i = 1; i < endOfTheMonth; i++) {
select.options[select.options.length] = new Option(i + 1, i);
}
}

Credit card expiry date validation in HTML

HTML code:
<tr>
<td><label for="expiry_day">Expiry date(MM/YYYY):<span id="imp">*</span></label></td>
<td>
<select id="expiry_month" tabindex="4">
<optgroup label="Month">
<option value="01">January</option>
<option value="02">February</option>
<option value="03">March</option>
<option value="04">April</option>
<option value="05">May</option>
<option value="06">June</option>
<option value="07">July</option>
<option value="08">August</option>
<option value="09">September</option>
<option value="10">October</option>
<option value="11">November</option>
<option value="12">December</option>
</optgroup>
</select>
<select id="expiry_year" tabindex="5">
<optgroup label="Year">
<script>generate_year();</script>
</optgroup>
</select>
</td>
</tr>
JavaScript code:
function generate_year() /*For generate cc year*/
{
for (var i = 2014; i <= 2104; i++)
{
document.write ("<option value='" + i + "'>" + i + "</option>");
}
}
function val_cc () {
var expiry_month = document.getElementById("expiry_month").value;
var expiry_year = document.getElementById("expiry_year").value;
var today = new Date();
var expiry_date = today.setFullYear(expiry_year, expiry_month);
if (today.getTime() > expiry_date.getTime())
{
alert ("\u2022Expiry month and year cannot be blank/Expiry month and year is before today month and year.");
return false;
}
}
These codes are basically used to validate the expiry date for credit card.For example,if today is March 2014 and the user chooses February 2014,I want the form to return false.However,if he chooses April 2014,I want the form to return true and proceed to the next page.If there are mistakes,can you please point them out and do a simple explanation?
You should update values from select-boxes every time user changes values, please see this fiddle http://jsfiddle.net/shershen08/wcFC4/
function runMyCheck(){
//update value every run
var expiry_month = document.getElementById("expiry_month").value;
var expiry_year = document.getElementById("expiry_year").value;
var today = new Date();
var selDate = new Date();
if (today.getTime() > selDate.setFullYear(expiry_year, expiry_month)){
//too late
alert ("\u2022Expiry month and year cannot be blank/Expiry month and year is before today month and year.");
return false;
} else {
//do good stuff...
}
}
Try this:
var today = new Date();
var expDate = new Date($("#cart-expyear").val(),($("#cart-expmonth").val()-1)); // JS Date Month is 0-11 not 1-12 replace parameters with year and month
if(today.getTime() > expDate.getTime()) {
console.log("Your Card is expired. Please check expiry date.");
}
Try this:
function generate_year() /*For generate cc year*/
{
for (var i = 2014; i <= 2104; i++)
{
var x = document.getElementById("expiry_year");
var option = document.createElement("option");
option.text = i;
option.value=i
x.add(option);
}
}
var expiry_month = document.getElementById("expiry_month").value;
alert(expiry_month);
var expiry_year = document.getElementById("expiry_year").value;
var today = new Date();
var expiry_date = today.setFullYear(expiry_year, expiry_month);
var from=new Date();
if (today.getTime() >from.setFullYear(expiry_year, expiry_month) )
{
alert ("\u2022Expiry month and year cannot be blank/Expiry month and year is before today month and year.");
//return false;
}

What is wrong with that select options?

I am just trying to make a simple calculation with the values of selected options, however I get false result:
pickUp 9 and returnTime 10, it gives no (which must be yea)
but pickUp time 11 and returnTime 14, it gives yea(which is right) so it gives the right result with some specific numbers and with some numbers not..
Here is the (pickUp)select options:
<select id="ophalenUur" class="timePicker selectOption">
<option value="-">Kies Tijd</option>
<option value="8">08.00</option>
<option value="8.5">08.30</option>
<option value="9">09.00</option>
<option value="9.5">09.30</option>
<option value="10">10.00</option>
<option value="10.5">10.30</option>
<option value="11">11.00</option>
<option value="11.5">11.30</option>
<option value="12">12.00</option>
<option value="12.5">12.30</option>
<option value="13">13.00</option>
<option value="13.5">13.30</option>
<option value="14">14.00</option>
<option value="14.5">14.30</option>
<option value="15.">15.00</option>
<option value="15.5">15.30</option>
<option value="16">16.00</option>
<option value="16.5">16.30</option>
<option value="17">17.00</option>
<option value="17.5">17.30</option>
<option value="18">18.00</option>
<option value="18.5">18.30</option>
<option value="19">19.00</option>
<option value="19.5">19.30</option>
<option value="20">20.00</option>
</select>
and js:
var pickUp = 0;
var returnTime =0;
$('#ophalenUur').change(function() {
pickUp = $('#ophalenUur option:selected').val();
$('.pickUp').text("PickUp: " + pickUp);
});
$('#inleverenUur').change(function() {
returnTime = $('#inleverenUur option:selected').val();
$('.returntime').text("return: " + returnTime);
if(returnTime > pickUp){ alert("yea");
} else { alert("no"); }
});
Fiddle: http://jsfiddle.net/jLAaq/27/
What is wrong here? I am looking for hours and I can't see:/
because you are doing a string comparison
var pickUp = 0;
var returnTime = 0;
var totalExtra = 0;
$('#ophalenUur').change(function () {
//conver the value string to number by prfixing it with + or you can use parseFloat(this.value)
pickUp = +this.value;
$('.pickUp').text("PickUp: " + pickUp);
});
$('#inleverenUur').change(function () {
returnTime = +this.value;
$('.returntime').text("return: " + returnTime);
if (returnTime > pickUp) {
alert("yea");
} else {
alert("no");
}
});
Demo: Fiddle
I think the reason could be returnTime and pickUp is string. so "9">"10".
Try to use parseFloat function to parse returnTime and pickUp.
You were comparing the integer as string. You can use the parseFloat method
Demo Link
CODE:
var pickUp = 0;
var returnTime =0;
var totalExtra = 0;
$('#ophalenUur').change(function() {
pickUp = $('#ophalenUur option:selected').val();
$('.pickUp').text("PickUp: " + pickUp);
});
$('#inleverenUur').change(function() {
returnTime = $('#inleverenUur option:selected').val();
$('.returntime').text("return: " + returnTime);
if(parseFloat(returnTime) > parseFloat(pickUp)){
alert("yea");
}else{
alert("no");
}
});

Categories

Resources