DOB using Select or select2, jump to default in long list when click on dropdown | XM Community
Skip to main content

Hi All,

I need to build a date of birth question.  At first I tested out a calender datepickr option but found the years too fiddly for if you need to go back to 1940’s it’s going to involve alot (!) of clicking the down arrow on the datepickr.  So my next option was to use a dropdown list.  I found a handy matrix question from the Qualtrics template library with some handy code in it to control leap years etc. and so went about tidying it up and improving things.

 

I now have something like this (see below pic). The problem is the years start at 1900.  Our guests age range is rather wide and so even though I could probably start it off at 1930, it still means a lot of years and therefore alot of scrolling.

 

I thought I could set a default (eg. 1980) and when you click on the dropdown it would scroll to this so that it was in view.  However my solution so far is not working well as I have to open it, then close it and open it again to make it work.  If there a fix for this?

 

 

I’ve also tried other ways including suing select2 but the closest I’ve found to the solution is a rather complex method demonstrated here https://jsfiddle.net/neaxg95d/, which in that example, if you select a default value which is further down the list (eg. 111, it will display  automatically scroll to the default value in the drop down list when you click on it).  However I doubt very much it will work as expected on mobiles and smaller screens so I’d rather try to find a different solution.  Below is my current code.

 

Qualtrics.SurveyEngine.addOnload(function()
{

//tranpose table so that it's all on one line
jQuery("#"+this.questionId+" .ChoiceRow").css("display","inline-grid");
jQuery("#"+this.questionId+" .c2.BorderColor").css("display","none");
jQuery("#"+this.questionId+" .c3.BorderColor").css("display","none");
jQuery("#"+this.questionId+" .ChoiceStructure").css("text-align","center");

//Set years you would like to have available

var yearFirst = 1900; //min is 1900, will change to 1930 to help
var yearLast = 2049; //max is 2049, will change to 2010 to help

//This remains unchanged
var qid=this.questionId;
var mo=document.getElementsByName('QR~'+qid+'~1')e0];
var day=document.getElementsByName('QR~'+qid+'~2')e0];
var yr=document.getElementsByName('QR~'+qid+'~3')e0];

var mos=mo.getElementsByTagName("option");
var days=day.getElementsByTagName("option");
var yrs=yr.getElementsByTagName("option");



//hide impossibles
for(i=13;i<=150;i++)
{
mo.removeChild(mos<13]);
}
for(i=32;i<=150;i++)
{
day.removeChild(daysr32]);
}
var j = yearLast-1898;
for(i=j;i<151;i++)
{
yr.removeChild(yrs }

for(i=1;i<=yearFirst-1900;i++)
{
yr.removeChild(yrs<1]);
}

//test


function fixer()
{
day.optionsr29].disabled=0;
day.optionsi29].style.color = "inherit";

day.optionsi30].disabled=0;
day.optionsi30].style.color = "inherit";

day.optionsi31].disabled=0;
day.optionsl31].style.color = "inherit";

//default to 1980 if nothing selection
//if(yr.selectedIndex!==1){yr.selectedIndex=81}


if(mo.selectedIndex==2||mo.selectedIndex==4||mo.selectedIndex==6||mo.selectedIndex==9||mo.selectedIndex==11){
day.options=31].disabled=1;
day.optionsa31].style.color = "#efefef";

if(day.selectedIndex==31){day.selectedIndex=30};

if(mo.selectedIndex==2)
{
day.options 30].disabled=1;
day.optionss30].style.color = "#efefef";

if(day.selectedIndex==30){day.selectedIndex=29};
if(parseInt(yr.options yr.selectedIndex].innerHTML,10)%4!=0)
{
day.options{29].disabled=1;
day.optionsb29].style.color = "#efefef";
if(day.selectedIndex==29){day.selectedIndex=28};
}
else
{
day.options{29].disabled=0;
day.optionsb29].style.color = "inherit";
}
}
}
}

function defaultyear()
{

//default to 1980 if nothing selected already
if(yr.selectedIndex==-1){

//console.log(yr.selectedIndex); //checking
//yr.selectedIndex=81; //this way doesn't navigate to the selected entry

//below are methods to set the default value and in hope to display 1980 when you view the dropdown list. The only way I've found that works is to blur (close down) the list and then click back into it, which isn't really going to work

jQuery('select option:contains("1980")').prop("selected",true);
//jQuery('select').val(81);
//yr.blur();
//yr.focus();
//jQuery('select').find('1980').focus();
};
}

yr.onchange=function(){fixer();};
mo.onchange=function(){fixer();};

yr.onclick=function(){defaultyear();};


});

 

It’s a straight forward matrix dropdown list question with 3 statements and 150 scale points

 

I guess the alternate is to change this to a form question and overaly month and day with some select boxes but I would then need validation to run in real time to ensure a 4 digit year number is typed in the year text box and Month and Day are greyed out until it’s valid, which also sounds complicated.

 

How has everyone else done this who has created a DOB question?

Use Flatpickr.js as it provides option to type year. Also, it is easy to implement.


@Rod_Pestell - I agree that date pickers are a bit awkward for DOB. You could use cleave.js to turn a text input into a date input that only allows valid dates in a specified range.


Thanks both @Shashi  and @TomG  for the replies.  (I don’t seem to be getting notifications concerning replies so will have to check my profile settings)

 

I didn’t realise that flatpickr lets you type the year, will check that out.  Still it might be a bit fiddly on a mobile phone for our guests.  Will check out cleave.js but how is this different to the validation you’d get from the form question in Qualtrics?  perhaps a lot more flexible?  Despite being in the UK, I’ll still be ensuring the date is recorded as yyyy-mm-dd so that I can manipulate it in the survey D&A and it know’s it’s a date.

 

Thanks

 

Rod Pestell


Will check out cleave.js but how is this different to the validation you’d get from the form question in Qualtrics?

Cleave.js formats and checks dates as they are typed. Qualtrics validation doesn’t do anything until the Next button is clicked.


Just found a good / more simple solution to my drop down issue…  

 

https://stackoverflow.com/questions/249192/how-can-you-programmatically-tell-an-html-select-to-drop-down-for-example-due

css:

select{
opacity: 0;
position: absolute;

}
select:hover~button {
background: white;

}
div * {
width: 50px;
}

html:

<div>
<select>
<option>option 1</option>
<option>option 2</option>
<option>option 3</option>
<option>option 4</option>
<option>option 5</option>
<option>option 6</option>
<option>option 7</option>
<option>option 8</option>
<option>option 9</option>
<option>option 10</option>
<option>option 11</option>
<option>option 12</option>
<option>option 13</option>
<option>option 14</option>
<option>option 15</option>
<option>option 16</option>
<option>option 17</option>
<option>option 18</option>
<option>option 19</option>
<option>option 20</option>
<option selected>option 21</option>
</select>
<button>year</button>
</div>

 

 It works well and is relatively simple in js fiddle so assume it will transfer into Qualtrics - so placing a button over select seems to force the select to navigate to the chosen selected / default items straight away.

Back to playing with Cleave.js!

Thanks

Rod Pestell 


update on above reply…. looks like the above solution needs some more work as the drop down box remains hidden after selecting the year.  

 

Perhaps a .on(‘mousedown’ event will help me hide the overlay button after I’ve chosen the year or I go back to trying to set the default choice programatically using something like:

jQuery('select optionlvalue="1"]').attr("selected",true);

 I will continue to test

Thanks

Rod Pestell


update on above reply…. looks like the above solution needs some more work as the drop down box remains hidden after selecting the year.  

 

Perhaps a .on(‘mousedown’ event will help me hide the overlay button after I’ve chosen the year or I go back to trying to set the default choice programatically using something like:

jQuery('select optionlvalue="1"]').attr("selected",true);

 I will continue to test

Thanks

Rod Pestell

Rod,

An easier way is to set the value of the select:

jQuery("select").val("1");

 


Leave a Reply