Calculating AGE from MM and YYYY (not DD) collected via a side by side question using Javascript
Hello,
Does anyone know how to calculate approximate age using the following side by side question design in the simple layout using Javascript? i.e., Assuming all respondents are born in the middle of the month.
The question asks for the month and year respondents were born, but not the day/date they were born.
// Store different ages as their respective EDs Qualtrics.SurveyEngine.setEmbeddedData("monthDiff", JSON.stringify(monthDiff)); Qualtrics.SurveyEngine.setEmbeddedData("ageDecimal", JSON.stringify(ageDecimal)); Qualtrics.SurveyEngine.setEmbeddedData("ageExtraMonths", JSON.stringify(ageExtraMonths)); Qualtrics.SurveyEngine.setEmbeddedData("ageYearsOnly", JSON.stringify(ageYearsOnly)); Qualtrics.SurveyEngine.setEmbeddedData("ageYearMonth", JSON.stringify(ageYearMonth)); };
// Add listeners to update the ED on every selection qc.querySelector(".SBS1 select").oninput = getAge; qc.querySelector(".SBS2 select").oninput = getAge; });
Thanks @ahmedA but that unfortunately didn’t work.
I asked ChatGPT to adapt code I have to calculate age/time difference from a DDMMYYYY question where respondents select the date from a calendar. It suggested the below but this doesn’t work either. Any ideas?
Qualtrics.SurveyEngine.addOnready(function() { let questionContainer = this.getQuestionContainer(); let monthInput = questionContainer.querySelector("select(name$='M']"); // Ensure this targets a select element for the month let yearInput = questionContainer.querySelector("inputrname$='Y']");
let that = this; // Store reference to Qualtrics object
function calculateAgreeTime() { let day = 15; // Hardcoded day (fixed to the 15th) let monthText = monthInput.value.trim(); // Get the full month name from the dropdown let year = parseInt(yearInput.value, 10); // Get the year from the input field
let month = monthMapmmonthText]; // Map month name to month index
// If either the month or year is invalid, just return without performing any calculation if (month === undefined || isNaN(year)) { console.log("Invalid date input, skipping calculation."); return; }
// Create a new Date object for the 15th of the selected month and year let agree_date = new Date(year, month - 1, day); // Adjust month for zero-based index let today = new Date(); // Get the current date
// Calculate the difference in months between today and the agree_date let agree_yearDiff = today.getFullYear() - agree_date.getFullYear(); let agree_monthDiff = today.getMonth() - agree_date.getMonth(); let agree_time = agree_yearDiff * 12 + agree_monthDiff;
// Adjust for the day if today's date is before the 15th of the selected month if (today.getDate() < agree_date.getDate()) { agree_time--; }
// Log the results for debugging console.log("Agree Date entered:", agree_date.toDateString()); console.log("Calculated Agree Time:", agree_time);
// Set the calculated time difference as an embedded data field in Qualtrics that.setEmbeddedData("GTAgreeTime", agree_time); }
// Event listeners to recalculate when the month or year is changed monthInput.addEventListener("change", calculateAgreeTime); yearInput.addEventListener("change", calculateAgreeTime); });
Try this: Do check the id’s and update as required Do load jQuery in header by including <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> the embedded data would be __js_CalculatedAge
Qualtrics.SurveyEngine.addOnload(function() { var qid= this.questionId;
// Attach event listener to both dropdowns (assuming similar structure for year) jQuery('#question-'+qid).find(".menu-item").click(function() { setTimeout(calculateAge, 100); // Delay to allow selection update }); function calculateAge() { // Get selected month text let selectedMonthText = jQuery("#select-menu-sbs-dropdown-"+qid+"-1-1 .menu-item.selected .rich-text").text().trim(); let selectedYearText = jQuery("#select-menu-sbs-dropdown-"+qid+"-1-2 .menu-item.selected .rich-text").text().trim(); if (!selectedMonthText || !selectedYearText || selectedMonthText === "Select one" || selectedYearText === "Select one") { return; // Ensure both values are selected } // Convert month name to number const monthMap = { "January": 1, "February": 2, "March": 3, "April": 4, "May": 5, "June": 6, "July": 7, "August": 8, "September": 9, "October": 10, "November": 11, "December": 12 }; let selectedMonth = monthMaptselectedMonthText] || 0; let selectedYear = parseInt(selectedYearText, 10); if (!selectedMonth || !selectedYear) return; // Assume birth date is the 15th of the selected month let birthDate = new Date(selectedYear, selectedMonth - 1, 15); let today = new Date(); // Calculate age let age = today.getFullYear() - birthDate.getFullYear(); let monthDiff = today.getMonth() - birthDate.getMonth(); // Adjust age if birth month hasn't been reached yet if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < 15)) { age--; }
// Save to Qualtrics Embedded Data if needed Qualtrics.SurveyEngine.setJSEmbeddedData("CalculatedAge", age); console.log(age) } });
Thanks @Deepak! Is it possible to avoid having to specify the QID? I need to use this formula multiple times across various surveys and I’m keen to avoid having to specify this.
Also, can I please ask for more information about: “Do load jQuery in header by including <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>” - what does this mean?
@sally_ I have made the code generalized only where it would autopickup the QID so you don’t have to worry about it. But if it doesn’t work, do check by hovering over the two dropdowns after inspecting you should be able to see the id of those and modify as required. For loading jQuery you can simply navigate to Look and feel - General -header section click on source and paste this <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>”. Since simple layout doesn’t support jQuery this is an additional step.
Hi @Deepak - thank you so much for your help! Unfortunately, no data is appearing in the embedded data field column. I’ve attached screenshots of the question JavaScript code and the general header section. Do you have any idea as to what I might be doing wrong?
The embedded data name is “__js_CalculatedAge”, have you included this? or just CalculatedAge @sally_ can you also check console if the data is coming there?
Hi @Deepak - it’s defined as “__js_CalculatedAge” (screenshot below).
If I hit F12 and have this panel open when I complete the survey, the following error appears when I complete the date question and move to the next page (screenshot also below).
The code does work on my end I am using simple layout. Cannot attach the QSF here, hence unable to help.