Help to display the number of days and then add to calculation between text dates | XM Community
Skip to main content

Hello,

I have a survey that asks respondents to enter periods of ineligible time. The question types are text entry with validation as Content Type/Date Format mm/dd/yyyy. I have my JavaScript to calculate the difference between these dates and include in my calculations, however I have an additional question where the respondent can enter additional ineligible days. This question type is also text entry with validation as content type/number. I need my JavaScript to add the additional ineligible days entered with the ineligible days from the previous date question and include the total in the calculation. This is my current set up: 

  // Function to retrieve and sum ineligible days from Q16, Q17, and Q83
        var getIneligibleDateDifference = function() {
            var startDateStr = "${q://QID16/ChoiceTextEntryValue}";
            var endDateStr = "${q://QID17/ChoiceTextEntryValue}";
            var totalIneligibleDaysFromDates = 0;

            console.log("Ineligible Dates - Start Date:", startDateStr, "End Date:", endDateStr);

            // Calculate ineligible days from Q16 and Q17 if both dates are valid
            if (validateDate(startDateStr) && validateDate(endDateStr)) {
                var startDate = luxon.DateTime.fromFormat(startDateStr, "MM/dd/yyyy");
                var endDate = luxon.DateTime.fromFormat(endDateStr, "MM/dd/yyyy");

                totalIneligibleDaysFromDates = endDate.diff(startDate, 'days').days;
                console.log("Ineligible Days from Q16/Q17:", totalIneligibleDaysFromDates);
            } else {
                console.log("Invalid dates for ineligible days calculation.");
            }

            // Retrieve manually entered ineligible days from Q83
            var totalIneligibleDaysFromQ83 = parseFloat("${q://QID83/ChoiceTextEntryValue}") || 0;
            console.log("Ineligible Days from Q83:", totalIneligibleDaysFromQ83);

            // Sum up both ineligible days (from Q16/Q17 and Q83)
            var totalIneligibleDays = totalIneligibleDaysFromDates + totalIneligibleDaysFromQ83;
            console.log("Total Ineligible Days:", totalIneligibleDays);

            // Display total ineligible days
            $('#ineligible-total-days').text(totalIneligibleDays.toFixed(0));

            // Return the total ineligible days
            return totalIneligibleDays;
        };

My HTML for the display is: 

<div>Ineligible Total Days: <span id="ineligible-total-days"></span></div> 

<div>&nbsp;</div>

 

I’ve included this in my header: <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script><script src="https://cdn.jsdelivr.net/npm/luxon@3.4/build/global/luxon.min.js"></script>

When I preview my survey, only the ineligible days from Q16 and Q17 are displayed and included in the calculation. What am I doing wrong? I confirmed that I am entering in the correct formatted date. Example: 05/01/2016 - 09/01/2016 = 123 and then additional ineligible days = 45. I would expect the “Ineligible Total Days:” 168, however the display is 123.

Help is much appreciated!

Brkwms

@brkwms You only show the function, I need to see the entire set-up to see how this function got called in the real question. You also have log, so turn on F12 to see how the code are behaving with your actions.

You show the correct result from Q16,Q17 so the problem is now only laying in how Q83 got fetched and calculated. If this code is running in Q83, then Embedded Data: ${q://QID83/ChoiceTextEntryValue} might still empty. You might have to get data directly from the text box.

Try: var totalIneligibleDaysFromQ83 = parseFloat(document.getElementById("QR~QID83").value) || 0;

I guess this code is from AI so it might missing out on that


Thank you for your response. Here is the entire code: 

Qualtrics.SurveyEngine.addOnload(function() {
    $(document).ready(function() {

        // Function to validate date format (MM/dd/yyyy)
        var validateDate = function(dateStr) {
            var isValid = luxon.DateTime.fromFormat(dateStr, "MM/dd/yyyy").isValid;
            console.log("Validating date:", dateStr, "Result:", isValid);
            return isValid;
        };

        // Check if jQuery and Luxon are loaded
        console.log("jQuery version:", $.fn.jquery);
        console.log("Luxon loaded:", typeof luxon !== 'undefined' ? "Yes" : "No");

        // Function to get the effective date
        var getEffectiveDate = function() {
            var useCurrentDate = "${q://QID69/ChoiceTextEntryValue}" === "Yes"; // Yes or No question
            var effectiveDateStr = "${q://QID75/ChoiceTextEntryValue}";
            
            console.log("Use current date:", useCurrentDate, "Effective Date String:", effectiveDateStr);

            if (useCurrentDate) {
                return luxon.DateTime.now(); // Use the current date
            } else if (validateDate(effectiveDateStr)) {
                return luxon.DateTime.fromFormat(effectiveDateStr, "MM/dd/yyyy"); // Use the entered effective date
            } else {
                console.log("Invalid effective date, using current date.");
                return luxon.DateTime.now(); // Fallback to current date if invalid
            }
        };

        // Function to calculate credit for prior years
        var getCreditPriorYearsDifference = function() {
            var startDateStr = "${q://QID6/ChoiceTextEntryValue}";
            var endDateStr = "${q://QID7/ChoiceTextEntryValue}";

            console.log("Credit Prior Years - Start Date:", startDateStr, "End Date:", endDateStr);

            if (validateDate(startDateStr) && validateDate(endDateStr)) {
                var startDate = luxon.DateTime.fromFormat(startDateStr, "MM/dd/yyyy");
                var endDate = luxon.DateTime.fromFormat(endDateStr, "MM/dd/yyyy");

                var diffInDays = endDate.diff(startDate, 'days').days;
                console.log("Credit Prior Years Days:", diffInDays);
                $('#credit-prior-years-days').text(diffInDays.toFixed(0));
                return diffInDays;
            } else {
                console.log("Invalid date for credit prior years.");
                $('#credit-prior-years-days').text('Invalid date');
                return 0;
            }
        };

        // Function to retrieve and sum ineligible days from Q16, Q17, and Q83
        var getIneligibleDateDifference = function() {
            var startDateStr = "${q://QID16/ChoiceTextEntryValue}";
            var endDateStr = "${q://QID17/ChoiceTextEntryValue}";
            var totalIneligibleDaysFromDates = 0;

            console.log("Ineligible Dates - Start Date:", startDateStr, "End Date:", endDateStr);

            // Calculate ineligible days from Q16 and Q17 if both dates are valid
            if (validateDate(startDateStr) && validateDate(endDateStr)) {
                var startDate = luxon.DateTime.fromFormat(startDateStr, "MM/dd/yyyy");
                var endDate = luxon.DateTime.fromFormat(endDateStr, "MM/dd/yyyy");

                totalIneligibleDaysFromDates = endDate.diff(startDate, 'days').days;
                console.log("Ineligible Days from Q16/Q17:", totalIneligibleDaysFromDates);
            } else {
                console.log("Invalid dates for ineligible days calculation.");
            }

            // Retrieve manually entered ineligible days from Q83
            var totalIneligibleDaysFromQ83 = parseFloat("${q://QID83/ChoiceTextEntryValue}") || 0;
            console.log("Ineligible Days from Q83:", totalIneligibleDaysFromQ83);

            // Sum up both ineligible days (from Q16/Q17 and Q83)
            var totalIneligibleDays = totalIneligibleDaysFromDates + totalIneligibleDaysFromQ83;
            console.log("Total Ineligible Days:", totalIneligibleDays);

            // Display total ineligible days
            $('#ineligible-total-days').text(totalIneligibleDays.toFixed(0));

            // Return the total ineligible days
            return totalIneligibleDays;
        };

        // Function to calculate age points
        var calculateAgePoints = function() {
            var dateOfBirthStr = "${e://Field/Date%20of%20Birth}";
            var effectiveDate = getEffectiveDate();

            console.log("Date of Birth:", dateOfBirthStr, "Effective Date:", effectiveDate.toISO());

            if (validateDate(dateOfBirthStr)) {
                var dateOfBirth = luxon.DateTime.fromFormat(dateOfBirthStr, "MM/dd/yyyy");
                var age = effectiveDate.diff(dateOfBirth, 'days').days / 365.25;
                console.log("Age Points:", age);
                $('#age-points').text(age.toFixed(6));
                return age;
            } else {
                console.log("Invalid date of birth.");
                $('#age-points').text('Invalid date');
                return 0;
            }
        };

        // Function to calculate service date points
        var calculateServiceDatePoints = function() {
            var partTimeYears = parseFloat("${q://QID54/ChoiceTextEntryValue}") || 0;
            var partTimeYearsInDays = partTimeYears * 365.25;
            var effectiveDate = getEffectiveDate();
            var serviceDateStr = "${q://QID2/ChoiceTextEntryValue}";

            console.log("Service Date:", serviceDateStr, "Part Time Years:", partTimeYears);

            if (validateDate(serviceDateStr)) {
                var serviceDate = luxon.DateTime.fromFormat(serviceDateStr, "MM/dd/yyyy");
                var totalCreditPriorYearsDays = getCreditPriorYearsDifference();
                var totalIneligibleDays = getIneligibleDateDifference();
                var totalDays = effectiveDate.diff(serviceDate, 'days').days + totalCreditPriorYearsDays;

                totalDays -= totalIneligibleDays;

                var fullTimeEquivalentYears = (totalDays - partTimeYearsInDays) / 365.25;
                var proratedPartTimeYears = (partTimeYearsInDays * 10 / 12) / 365.25;

                var serviceDatePoints = fullTimeEquivalentYears + proratedPartTimeYears;
                console.log("Service Date Points:", serviceDatePoints);
                $('#service-date-points').text(serviceDatePoints.toFixed(6));
                return { totalDays, serviceDatePoints };
            } else {
                console.log("Invalid service date.");
                $('#service-date-points').text('Invalid date');
                return { totalDays: 0, serviceDatePoints: 0 };
            }
        };

        // Function to calculate total points
        var calculateTotalPoints = function() {
            var agePoints = calculateAgePoints();
            var { totalDays, serviceDatePoints } = calculateServiceDatePoints();

            var totalPoints = serviceDatePoints + agePoints;
            console.log("Total Points:", totalPoints);
            $('#total-points').text(totalPoints.toFixed(6));

            var pointsNeeded = 80.00 - totalPoints;
            $('#points-needed').text(pointsNeeded.toFixed(6));

            var daysNeeded = (pointsNeeded / 2) * 365.25;
            var effectiveDate = getEffectiveDate();
            var targetDate = effectiveDate.plus({ days: daysNeeded });
            console.log("Date Eligible to Retire:", targetDate.toFormat("MM/dd/yyyy"));
            $('#date-calculation').text(targetDate.toFormat("MM/dd/yyyy"));
        };

        // Initial calculations
        getCreditPriorYearsDifference();
        getIneligibleDateDifference();
        calculateTotalPoints();

        // Register event handlers for changes in date and part-time year inputs
        $('input0type="text"]').on('input', function() {
            getCreditPriorYearsDifference();
            getIneligibleDateDifference();
            calculateTotalPoints();
        });
    });
});
 


@brkwms Turn on the log by pressing F12 as you test to see if Q83 value got in correctly

 


So it’s not picking up for some reason. 

Ineligible Days from Q83: 0

I have the question type as Text entry. Text type single line. validation is set as content type. Content type is Number.


You show the correct result from Q16,Q17 so the problem is now only laying in how Q83 got fetched and calculated. If this code is running in Q83, then Embedded Data: ${q://QID83/ChoiceTextEntryValue} might still empty. You might have to get data directly from the text box.

Try: var totalIneligibleDaysFromQ83 = parseFloat(document.getElementById("QR~QID83").value) || 0;

I guess this code is from AI so it might missing out on that

@brkwms As I said earlier, is this code running at Q83 or at the same page with Q83? If it is, try the other way to get data


No, the Q83 is in a different block. I have the code running in a later block labeled “FT CPYS INELIG YRSPT”. 

 


@brkwms Check back the hidden QID, Q83 is just the auto name that Qualtrics give you, QID might be different especially if you have done some deleting to the surey. To be sure, use pipe-text

In this case, my Q28 actually have QID283

 


Oh Ok, so it’s showing as Q88. So if I change to Q88, then it should work?


Oh Ok, so it’s showing as Q88. So if I change to Q88, then it should work?

@brkwms Yes,if it’s ${q://QID88/ChoiceTextEntryValue} then you should also change it in the code. This time you can see the code work, the log gonna show right answer.


That works! Thank you so much!


That works! Thank you so much!

@brkwms Happy to help 👍


Leave a Reply