Cannot set property error in javascript - javascript

so i have this code that checks for dates and updates lists accordingly, now what i am trying to achieve is that when the for both the month and the year are set to null "mm" "yyyy" is set the day select list with one element "dd" with a value of null. but i have been having an error cannot set property 'value' of undefined. The first element in both the year and month s is set to a value of null.
this is the javascript function a guy here helped me come up with:
function monthDays (type) {
if(document.getElementById('monthof' + type).value == null || document.getElementById('yearof' + type).value == null)
{
var mod = document.getElementById('dayof' + type);
mod.length = 1;
mod[0].value = null;
mod[0].text = "DD";
}
else{
var month = parseInt(document.getElementById('monthof' + type).value, 10),
days = new Date(document.getElementById('yearof' + type).value, month + 1, 0).getDate(),
i;
var mod = document.getElementById('dayof' + type);
mod.length = days + 1;
mod[0].value = null;//this is where i am getting the error
mod[0].text = "DD";
for(i = 1; i < days+1; i++) {
mod[i].value = i;
mod[i].text = i;
}
}
}
html
Birth:
MM
<select id="dayofbirth" class="date" name="dayhofbirth">
<option value=null>DD</option>
</select>
<select id="monthofbirth" class="year" name="monthofbirth" onchange="monthDays('birth')">
<option value=null>MM</option>
</select>
<select id="yearofbirth" class="year" name="monthofbirth" onchange="monthDays('birth')">
<option value=null>YYYY</option>
</select>
</div>
the type is there to tell the function which it should edit, since in my html I have 2 date of births.

The object returned by getElementById( ) returns a reference to an element, not an array of options when you're selecting a select element. You can access the options through a property on the object but you don't need to do that to set the selected option. To set the selected option, just set the value like you are but remove the [0] part. You also need to set null as a string ('null') because it is a string value in the HTML.
Here's what I came up with for you:
HTML
<select id="dayofbirth" class="date" name="dayhofbirth">
<option value=null>DD</option>
<option value=01>01</option>
</select>
<select id="monthofbirth" class="year" name="monthofbirth" onchange="monthDays('birth')">
<option value=null>MM</option>
<option value=12>12</option>
</select>
<select id="yearofbirth" class="year" name="monthofbirth" onchange="monthDays('birth')">
<option value=null>YYYY</option>
<option value=1900>1900</option>
</select>
Javascript
function monthDays(type) {
if(document.getElementById('monthof' + type).value == null || document.getElementById('yearof' + type).value == null)
{
var mod = document.getElementById('dayof' + type);
mod.length = 1;
mod.value = 'null';
}
else{
var month = parseInt(document.getElementById('monthof' + type).value, 10),
days = new Date(document.getElementById('yearof' + type).value, month + 1, 0).getDate(),
i;
var mod = document.getElementById('dayof' + type);
mod.value = 'null';
for(i = 1; i < days+1; i++) {
mod.add(i);
}
}
}
See it in action here: http://jsfiddle.net/CT54h/
It probably doesn't do everything you want it to, but within the scope of the question it does.

I found out what I had to do, I set the values at the beginning of each to 'null' not null, and than when I checked for their value I also checked for 'null'. I think there might be some concept that I do not fully understand when it comes to but my method seemed to have solved my problem.

Related

I am looking for a way to set "selectBox" be selected when selectedIndex is unknown

I would like to set YYYY-MM-DD (that comes from GET parameter)
I can set it by selectedIndex
When selectedIndex is unknown,
How can I set the default selected box?
I would like to set "the default selected" by value
e.g GET = 2021-08-06 I want it to be selected 2021-08-06
but HTML changes dynamically.
document.getElementById("select_date").selectedIndex = 1;
=> 2021-07-30 will be sleeted.
var param = decodeURIComponent(element[1]);
document.getElementById("select_date").value = param;
console.log("param"+param)
//log result = param2021-7-23
<form method="GET" action="http://">
<select id="select_date" name="delivery_date">
<option value="2021-07-23">2021-07-23</option>
<option value="2021-07-30">2021-07-30</option>
<option value="2021-08-06">2021-08-06</option>
</select>
When document.getElementById("select_date").value = paramValue
When param = "2021-7-23"; work well then.
Simply set the value of selectbox:
var elemnt = "2021-8-6";
var date = new Date(elemnt);
var format = convertDate(date)
var seolectedval = decodeURIComponent(format)
document.getElementById("select_date").value = seolectedval;
function convertDate(date) {
var yyyy = date.getFullYear().toString();
var mm = (date.getMonth()+1).toString();
var dd = date.getDate().toString();
var mmChars = mm.split('');
var ddChars = dd.split('');
return yyyy + '-' + (mmChars[1]?mm:"0"+mmChars[0]) + '-' + (ddChars[1]?dd:"0"+ddChars[0]);
}
<form method="GET" action="http://">
<select id="select_date" name="delivery_date">
<option value="2021-07-23">2021-07-23</option>
<option value="2021-07-30">2021-07-30</option>
<option value="2021-08-06">2021-08-06</option>
</select>
</form>

getting current year in a dropdown of years

This is my dropdown in html
<select name="select" class="form-control" id="dropdownYear" style="width: 120px;" onchange="getProjectReportFunc()">
<option value="2015">2015</option>
<option value="2016">2016</option>
<option value="2017" selected="selected">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
<option value="2020">2020</option>
I have hard coded the year values, i want to populate this dropdown
with current year selected and 3 years before and after that.Eg for
current year=2017 i want the list to be 2013-2020 with 2017
automatically selected. How do i do this in js?
To achieve this, using Date is required, be it directly or with some external library. With the native method getFullYear:
Date.prototype.getFullYear()
Returns the year (4 digits for 4-digit years) of the specified date according to local time.
We can set the current year and then loop through desired values. You specified 2013 - 2020, so we'll use the current year minus 4 up to the current year plus 3.
for (var i = year - 4; i <= year + 3; i++)
In the body of the loop, create Options and add them to the Select. To display the values, the innerHTML needs to be set, and if you want to use the value somewhere else in your javascript, the value also needs to be set:
option.value = option.innerHTML = i;
If the index equals the current year, set the selected attribute.
if (i === year) option.selected = true;
Then, all you need to do is append each option element to the select element. After the select has been created, insert it into your HTML (here I am appending to the body).
var select = document.createElement('select');
var date = new Date();
var year = date.getFullYear();
for (var i = year - 4; i <= year + 3; i++) {
var option = document.createElement('option');
option.value = option.innerHTML = i;
if (i === year) option.selected = true;
select.appendChild(option);
}
document.body.appendChild(select);
You may try something like this :
$('#dropdownYear').each(function() {
var year = (new Date()).getFullYear();
var current = year;
year -= 3;
for (var i = 0; i < 6; i++) {
if ((year+i) == current)
$(this).append('<option selected value="' + (year + i) + '">' + (year + i) + '</option>');
else
$(this).append('<option value="' + (year + i) + '">' + (year + i) + '</option>');
}
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="select" class="form-control" id="dropdownYear" style="width: 120px;" onchange="getProjectReportFunc()">
</select>
var i, currentYear, startYear, endYear, newOption, dropdownYear;
dropdownYear = document.getElementById("dropdownYear");
currentYear = (new Date()).getFullYear();
startYear = currentYear - 4;
endYear = currentYear + 3;
for (i=startYear;i<=endYear;i++) {
newOption = document.createElement("option");
newOption.value = i;
newOption.label = i;
if (i == currentYear) {
newOption.selected = true;
}
dropdownYear.appendChild(newOption);
}
<select name="select" class="form-control" id="dropdownYear"
style="width: 120px;" onchange="getProjectReportFunc()">
</select>
This is very simple logic,
First get current year,
Then run loop starting from currentyear -2 to currenct year + 3
Make current year selected
See code below:
console.clear();
var curYear = new Date().getFullYear();
for(i = curYear-2 ; i <= curYear+3 ; i++) {
var selected = (curYear === i) ? 'selected="selected"': '';
console.log('<option '+selected+' value="'+i+'">'+i+'</option>');
}
You can use ES6 array features.
let currentYear=new Date().getFullYear();
let array=Array.from(Array(7), (_, i) => currentYear-3+i);
array.forEach(function(item){
let option=$('<option></option>').html(item).attr('selected', item == currentYear);
$('select').append(option);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="select" class="form-control" id="dropdownYear">
</select>
A simple example, without using JQuery -
var currentYear = new Date().getFullYear();
var yearSelect = document.getElementById('dropdownYear');
for(var i = -2; i < 3; i++) {
var isSelected = currentYear === currentYear - i
yearSelect.options[yearSelect.options.length] = new Option(currentYear - i, currentYear - i, isSelected, isSelected);
}
and the HTML:
<select name="select" class="form-control" id="dropdownYear" style="width: 120px;" onchange="getProjectReportFunc()" />
HTML:
<select
name="select"
class="form-control"
id="dropdownYear"
style="width: 120px;"
onchange="getProjectReportFunc()">
</select>
Javascript:
let select = document.getElementById('dropdownYear');
let currYear = new Date().getFullYear();
let futureYear = currYear+3;
let pastYear = currYear-3;
for(let year = pastYear; year <= futureYear; year++){
let option = document.createElement('option');
option.setAttribute('value', year);
if(year === currYear){
option.setAttribute('selected', true);
}
option.innerHTML = year;
select.appendChild(option);
}
While I appreciated a lot of these answers, I felt like these could and should be done using the modern tools .map and Array constructor, so I created the below:
const CreateYearDropdown = () => {
const nYearsPrior = 20;
const nYearsPost = 20;
const yearRange = Array(nYearsPrior+nYearsPost).fill(0);
const currentYear = new Date().getFullYear();
const years = yearRange.map(
(item, index) => (item[index] = currentYear - nYearsPrior + index)
);
return (
<select defaultValue={currentYear}>
{years.map((year, index) => (
<option key={index} value={year}>
{String(year)}
</option>
))}
</select>
)
}
Without the above explanation/breakdown, it can be written like so:
const CreateYearDropdown = () => {
const currentYear = new Date().getFullYear();
const yearRange = Array(40).fill(0);
const years = yearRange.map(
(item, index) => (item[index] = currentYear - 20 + index)
);
return (
<select defaultValue={currentYear}>
{years.map((year, index) => (
<option key={index} value={year}>
{year}
</option>
))}
</select>
);
};
Alternatively you can have it running in a single direction (before or after):
const CreateYearDropdown = () => {
const currentYear = new Date().getFullYear();
const yearRange = Array(20).fill(0);
const years = yearRange.map(
(item, index) => (item[index] = currentYear /* - or + */ + index)
);
return (
<select defaultValue={currentYear}>
{years.map((year, index) => (
<option key={index} value={year}>
{year}
</option>
))}
</select>
);
};

Is there a way to select all option values in selectbox?

I have a function that creates many select boxes. I need an option value to select all the values in one select, because if I give "all" as value, I have to do a lot of switches and if / else statements, and it would be great if I could avoid that.
Here is the function:
function creaselect(nomeoggetto, oggetto, nome) {
var P_P_comodo = _(A_Punti_dati).groupBy(oggetto).map(function(item, itemId) {
console.log(oggetto);
var result = {};
result[itemId] = item[0][nome];
return result
}).value();
document.write("Seleziona " + nomeoggetto + "<select id=my" + nomeoggetto + ">");
document.write("<option value=all selected>Tutti</option>");
_.each(P_P_comodo, function(value, key) {
_.each(value, function(value, key) {
P_P[key] = value;
document.write("<option value=" + key + ">" + value + "</option>");
});
});
document.write("</select><br>");
}
You'll need to do 2 things:
Set up a function to iterate through each option and set the "selected" attribute to true
Set up a handler to call this function when the user selects "all"
HTML
<select id='control'>
<option value=''>(Select one)</option>
<option value='all'>All</option>
<option value='none'>None</option>
</select>
<select id='sel' name="sometext" size='5' multiple>
<option value='1'>text1</option>
<option value='2'>text2</option>
<option value='3'>text3</option>
<option value='4'>text4</option>
<option value='5'>text5</option>
</select>
Javascript
var control = document.getElementById('control');
control.onchange = setOptions;
function setOptions() {
var control = document.getElementById('control');
var val = control.value;
if (val == 'all' || val == 'none') {
var mySelectObj = document.getElementById('sel');
var bool = val == 'all'
setSelect(mySelectObj, bool);
}
}
function setSelect(sel, bool){
for(var i = 0; i <sel.length; i++) {
sel.options[i].selected = bool;
}
}
jsFiddle: https://jsfiddle.net/mspinks/qqp7w1qk/11/
Please note: in order to allow multi-select on a select input, you must specify the attribute "multiple". Otherwise, you'll need to use a third-party select control.

reset a drop down list value to previous value

I am using javascript to validate some drop down list selections. One selection is for the length of a buildings frame. The other 3 drop down are for garage doors that can be added to the side. I have the code alerting me if the total door widths have exceeded the frame length. I need the if condition to take the previous value of the last selected door drop down list and reset it to the amount before it if the amount exceeds my conditions in my if statement.
This is my html
Frame Length:
<select id="framewidth" onchange="doorsrightsideFunction()">
<option value="20">21</option>
<option value="25">26</option>
<option value="30">31</option>
<option value="35">36</option>
<option value="40">41</option>
</select>
<br>
<input type="hidden" name="eight_by_seven_width_right_side"
id="eight_by_seven_width_right_side" value="8">
<br>
<input type="hidden" name="eight_by_seven_height_right_side"
id="eight_by_seven_height_right_side" value="7">
<br>8x7:
<select id="eight_by_seven_right_side" onchange="doorsrightsideFunction()">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<br>
<input type="hidden" name="nine_by_seven_width_right_side"
id="nine_by_seven_width_right_side" value="9">
<br>
<input type="hidden" name="nine_by_seven_height_right_side"
id="nine_by_seven_height_right_side" value="7">
<br>9x7:
<select id="nine_by_seven_right_side" onchange="doorsrightsideFunction()">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
<br>
<input type="hidden" name="ten_by_eight_width_right_side"
id="ten_by_eight_width_right_side" value="10">
<br>
<input type="hidden" name="ten_by_eight_height_right_side"
id="ten_by_eight_height_right_side" value="8">
<br>10x8:
<select id="ten_by_eight_right_side" onchange="doorsrightsideFunction()">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
This is my javascript so far
function doorsrightsideFunction() {
function getValue(idElement) {
return document.getElementById(idElement).value;
}
var eightwidth = getValue("eight_by_seven_width_right_side");
var ninewidth = getValue("nine_by_seven_width_right_side");
var tenwidth = getValue("ten_by_eight_width_right_side");
var eightwidthamount = getValue("eight_by_seven_right_side");
var ninewidthamount = getValue("nine_by_seven_right_side");
var tenwidthamount = getValue("ten_by_eight_right_side");
var framewidth = getValue("framewidth");
var totaldoorwidth;
var totaldooramount;
var framewidthtotaldoorwidth;
var framespace;
totaldoorwidth = eightwidth * eightwidthamount
+ ninewidth * ninewidthamount
+ tenwidth * tenwidthamount;
totaldooramount = parseInt(eightwidthamount, 10)
+ parseInt(ninewidthamount, 10)
+ parseInt(tenwidthamount, 10);
framewidthtotaldoorwidth = framewidth - totaldoorwidth;
framespace = totaldooramount + 1;
if (framewidthtotaldoorwidth < framespace) {
alert("You have to many doors on the right side");
} else { }
}
here is a link to my fiddle http://jsfiddle.net/steven27030/M52Hf/
http://jsfiddle.net/M52Hf/84/
you could use the data attribute and be sure to pass in the current element as a parameter on your doorsrightsideFunction call:
<select id="framewidth" onchange="doorsrightsideFunction(this)">
var previousValue = currentelement.getAttribute("data-prev");
if(previousValue == null)
previousValue = currentelement[0].value;
You will need to store the previous value so you can switch back when necessary, and update the previous value after a successful change. I would use arrays in various places.
var prevValue = Array();
function doorsrightsideFunction() {
function getValue(idElement) {
return document.getElementById(idElement).value;
}
function setValue(idElement,val) {
return document.getElementById(idElement).value = val;
}
var ids = Array("eight_by_seven_right_side","nine_by_seven_right_side","ten_by_eight_right_side");
var widths = Array(
getValue("eight_by_seven_width_right_side"),
getValue("nine_by_seven_width_right_side"),
getValue("ten_by_eight_width_right_side")
);
var values = Array();
for(i=0;i<ids.length;i++) {
if (!prevValue[i]) { prevValue[i]=0; }
values[i] = getValue(ids[i]);
}
var framewidth = getValue("framewidth");
var totaldoorwidth = 0;
var totaldooramount = 0;
var framewidthtotaldoorwidth;
var framespace;
for(i=0;i<ids.length;i++) {
totaldoorwidth += values[i] * widths[i];
totaldooramount += parseInt(values[i], 10);
}
framewidthtotaldoorwidth = framewidth - totaldoorwidth;
framespace = totaldooramount + 1;
if (framewidthtotaldoorwidth < framespace) {
alert("You have to many doors on the right side");
for(i=0;i<ids.length;i++) { setValue(ids[i],prevValue[i]); }
} else {
prevValue = values;
}
}
updated fiddle
Edit: In answer to your follow on question in the comment:
is there a way to make it loop through and find the next size down that would work if they choose to many?
Yes, you can have it iterate the values to find one that fits, as long as the initial values are valid (in this case no doors is a perfect initial value). This also means you don't need to worry about storing any previous value.
I had some fun with this a took some liberties with your code.
First, a few changes in the HTMl:
for each element with an onChange, have it pass the element that was changed so we can tell which one to modify:
<select ... onchange="doorsrightsideFunction(this)">
change the IDs of the _width and _height hidden inputs so they are of the form <id of select element>_width (i.e. the width element for the select with id="eight_by_seven_right_side" should be "eight_by_seven_right_side_width" so you just need to take id + "_width" to find it)
wrap all of the door select elements in a <div id="doorchoices"> ... </div> so they can be found programmatically. This way adding a new door to the system is as simple as adding the select and height/width hidden inputs within the containing div, and the javascript finds and uses them automagically.
The javascript changes, I tried to comment inline:
//make ids and widths global to this page so we only have to construct it on page load
var ids;
var widths;
function getValue(idElement) {
var el = document.getElementById(idElement);
if (el) {
return parseInt(el.value);
} else {
return null;
}
}
function setValue(idElement, val) {
return document.getElementById(idElement).value = val;
}
window.onload = function () {
//construct id list from elements within the containing div when the page loads
ids = Array("framewidth");
widths = Array(null);
var container = document.getElementById("doorchoices");
var selections = container.getElementsByTagName("select");
var i;
for (i = 0; i < selections.length; i++) {
ids.push(selections[i].id);
// get each door's width from the _width element that matches the id
widths.push(getValue(selections[i].id + "_width"));
}
}
// el is the 'this' passed from the select that changed
function doorsrightsideFunction(el) {
console.log(widths);
console.log(ids);
var changedIndex = ids.indexOf(el.id);
//get all of the option elements of the changed select
var possibleValueEls = el.getElementsByTagName("option");
var values = Array();
var possibleValues = Array();
var framewidth;
var curValue;
var totaldoorwidth;
var totaldooramount;
var framewidthtotaldoorwidth;
var framespace;
var i;
function calcWidth() {
totaldoorwidth = 0;
totaldooramount = 0;
var i;
framewidth = values[0];
//start with 1 since index 0 is the frame width
for (i = 1; i < ids.length; i++) {
console.log(i + ")" + ids[i] + " " + values[i] + "(" + widths[i] + ")");
totaldoorwidth += values[i] * widths[i];
totaldooramount += parseInt(values[i], 10);
}
framewidthtotaldoorwidth = framewidth - totaldoorwidth;
framespace = totaldooramount + 1;
}
// get all possible values from the option elements for the select that was changed
for (i = 0; i < possibleValueEls.length; i++) {
possibleValues.push(parseInt(possibleValueEls[i].value));
}
// values should be increasing in order
possibleValues.sort();
// except framewidth should be decreasing
if (el.id == "framewidth") {
possibleValues = possibleValues.reverse()
};
// get the value of each element
for (i = 0; i < ids.length; i++) {
values[i] = getValue(ids[i]);
if (changedIndex == i) {
curValue = values[i]
};
}
calcWidth();
console.log(framewidthtotaldoorwidth);
console.log(framespace);
if (framewidthtotaldoorwidth < framespace) {
alert("You have to many doors on the right side");
// start with the current value and try each until it fits
for (validx = possibleValues.indexOf(curValue); validx >= 0, framewidthtotaldoorwidth < framespace; validx--) {
//change the value in the values array
values[changedIndex] = possibleValues[validx];
//change the select to match
setValue(el.id, possibleValues[validx]);
//see if it fits
calcWidth();
}
}
}
New fiddle
and the simplicity of adding another door size - just add this to the HTML:
<input type="hidden" name="twelve_by_ten_right_side_width" id="twelve_by_ten_right_side_width" value="12" />
<input type="hidden" name="twelve_by_ten_right_side_height" id="twelve_by_ten_right_side_height" value="10" />
<br />
<label for="twelve_by_ten_right_side">12x10:</label>
<select id="twelve_by_ten_right_side" onchange="doorsrightsideFunction(this)">
<option value="0">0</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
New door fiddle

HTML Connected dropdown (more than one)with number as value

Basically, I want to create more then 1, dropdowns, which contains numbers as value eg.
<select id="dp1">
<option value='op1'>1</option>
<option value='op2'>2</option>
<option value='op3'>3</option>
</select>
<select id="dp2">
<option value='op1'>1</option>
<option value='op2'>2</option>
<option value='op3'>3</option>
</select>
<select id="dp3">
<option value='op1'>1</option>
<option value='op2'>2</option>
<option value='op3'>3</option>
</select>
this is just one dropdown. lets say I have 3 dropdown lists with same numbers with different default value eg. dp1 -> 1, dp2 -> 2, dp3 -> 3 . So, Now if user changes value of dp3 to 1 the value of other dropdown list should get change automatically as per sequence like dp1 -> 2 and dp2 -> 3.
if i explain it with other example if user changes value of dp3 to 2 the value dp1 should not change and value of dp2 -> 3should change.
How is it possible to do using Javascript / jquery. (I am using php to populate dropdown from database)
Thank you in advance.
if you just want to change the previous dropdownlists buy changing the current dropdownlist maybe this sample code can help you :
$("select").change(function(){
var selectValue = $(this).val();
var toRemove = 'op';
var value = selectValue.replace(toRemove,'');
var selectId = $(this).attr('id');
var toRemove = 'dp';
var id = selectId.replace(toRemove,'');
id = id-1;
for(var i = id; i>=1; i--){
value = value -1;
var newValue = "op"+value;
$("#dp"+i).val(newValue);
}
});
If the data you're using is really just numeric, then something like this will work. Click here for a jsfiddle example that demonstrates the behavior I think you're looking for.
<select id="dp1" class="dropdown"></select>
<select id="dp2" class="dropdown"></select>
<select id="dp3" class="dropdown"></select>
<script type="text/javascript">
var values = [1, 2, 3];
$(function() {
initDropdowns();
$('select.dropdown').change(function() {
setDropdownValues($(this).attr('id'));
});
});
function initDropdowns() {
var optionsHtml = '';
for(var i = 0; i < values.length; i++) {
var value = values[i];
optionsHtml += '<option value="' + value + '">' + value + '</option>';
}
$('select.dropdown').append(optionsHtml);
setDropdownValues();
}
function setDropdownValues(excludeListId) {
var valuesClone = values.slice();
var $dropdowns = $('select.dropdown');
if(excludeListId) {
valuesClone.splice(Number($('#' + excludeListId).val()) - 1, 1);
}
$('select.dropdown').each(function() {
if($(this).attr('id') !== excludeListId) {
$(this).val(valuesClone[0]);
valuesClone.splice(0, 1);
}
});
}
</script>

Categories

Resources