JavaScript Examples Part 1

JavaScript Examples Part 1 for solving requirements with the Frontend Web Assets

Note: These features are part of the Visforms Subscription and are not included in the free Visforms version.

Calculate and display sum of many fields

Subjects

The following topics are included in the example:

  • Only run code after the HTML document has been initialized.
  • Respond to user changes.
  • Determine the numerical values of number fields and text fields of the form.
  • Combine fields by assigning a common “CSS class of the field” in the field configuration.
  • Treat input fields as a group using a common CSS class.
  • Address output field using a CSS class.
  • Output to a number field of the form.

Description

The form can contain a lot of number fields. You want to calculate and display a total for some of the number fields or for all number fields. The form reacts to every change made by the user and recalculates the total each time.

The fields are each addressed via their custom CSS classes. This CSS class is set in the field configuration, Tab “Advanced”, “CSS class of field” option. In this case, the other two options for “CSS Class Control Group” and “CSS Class for Label” remain blank.

Calculate and display the sum of many fields.

The 6 total fields

Each field that is to be included in the total must have the same CSS class set in the field configuration.
The total fields are addressed in the JavaScript code via the CSS class css-number-add.

The 6 sum fields.

The result field

The result field that receives and displays the current total must also have a field-specific custom CSS class set.
It is addressed in the JavaScript code via the CSS class css-number-add-result.

The result field.

The JavaScript code

// calculate sum of field group labeled by common CSS-class 'css-number-add'
jQuery(document).ready(function() {
	// console.log('FEWA script loaded');
	jQuery('.css-number-add').bind('change keyup mouseup mousewheel', function() {
		// re-calculate on value change
		calculateSum();
	});
	jQuery('.visform').bind('visformsInitialised', function() {
		// re-calculate on form is initialized
		calculateSum();
	});
});
function calculateSum() {
	let sum = 0;
	jQuery('.css-number-add').each(function() {
		let val = jQuery(this).val();
		// skip all of: is not a number
		if(isNaN(val)) return true;
		// keep multiplication with 1, otherwise it would be a simple string concatenation
		sum += 1 * val;
	});
	jQuery('.css-number-add-result').val(sum);
}

Calculate and display the ISO calendar week for a date

Subjects

The following topics are included in the example:

  • Only run code after the HTML document has been initialized.
  • Respond to user changes.
  • Read in a date and break it down into its components.
  • React to the selected date format from the field configuration.
  • Calculate the calendar week according to ISO-8601 (week starts on Monday).
  • Set the value of a number field.

Description

The form field “birth date” is the date field for selecting a date.
The “ISO Calendar Week” form field automatically displays the calendar week of the currently selected date according to ISO-8601 (week starts on Monday).

Customization to your form

The following needs to be adapted to your form in the JavaScript code:

  • The Visforms field ID for the date field: const dateFieldID = ‘479’;
  • The Visforms field ID for the week field: const numberFieldID = ‘555’;

You can use text or number (as in the example) as the field type for the week field.

Filled date field

The JavaScript code

jQuery(document).ready(function() {
    // console.log(' FEWA script loaded');
    const dateFieldID   = '479'; // Visforms date field ID of field list
    const numberFieldID = '555'; // Visforms number field ID of field list
    jQuery(`#field${dateFieldID}`).on('change', function() {
        let value = jQuery(this).val();
        let parts =value.split('.');
        const date = new Date(`${parts[2]}-${parts[1]}-${parts[0]}`);
        jQuery(`#field${numberFieldID}`).val(getWeekISO8601(date));
    });
    function getWeekISO8601(dt) {
        const tdt = new Date(dt.valueOf());
        const dayn = (dt.getDay() + 6) % 7;
        tdt.setDate(tdt.getDate() - dayn + 3);
        const firstThursday = tdt.valueOf();
        tdt.setMonth(0, 1);
        if (tdt.getDay() !== 4) {
            tdt.setMonth(0, 1 + ((4 - tdt.getDay()) + 7) % 7);
        }
        return 1 + Math.ceil((firstThursday - tdt) / 604800000);
    }
});

Set up a spambot honeypot

Subjects

The following topics are included in the example:

  • Only run code after the HTML document has been initialized.
  • Hide a form field (type “email”) and not show it.
  • Check whether a spambot has set a value in the hidden form field.
  • Respond to form submission.
  • Set a custom event handler for form submission.
  • Prevent form submission.
  • Show a message to the user.

Description

Visforms supports several effective ways to secure the form against spambots. If additional measures need to be taken, there are several simple methods. Here we show how a spambot honeypot can be set up with little effort.

A honeypot can be set up by adding another field of type “Email” that:

  • is not visible to the user,
  • but spambots fill the invisible field nicely.

Before submitting the form, it is checked whether the field is empty. If the invisible field of type “Email” is filled, the form will not be sent. Instead of submitting the form, a modal dialog with a quite misleading message is shown.

In principle it also works with a field of type “Hidden”. A hidden field is automatically not visible on the form. In this case, the one JavaScript line that hides the field would be unnecessary:

jQuery('div.field' + fieldID).css('display', 'none');

However, an invisible field of type ‘email’ is more suitable for spammers.

Empty form: A spambot honeypot has been set up. Spammer at work: A spambot honeypot has been set up.

Customization to your form

The following adjustments are necessary to the JavaScript code and your form:

  • In the form, add an additional field of type “Email” that is not required.
  • Paste the JavaScript code in the form configuration, tab “Frontend Webassets”, tab “Form” into the “JavaScript” field.
  • In the JavaScript code, change the value of the “formID” variable to the ID of your form.
  • In the JavaScript code, change the value of the “fieldID” variable to the ID of your field.

The test code

The JavaScript code contains a test code at the end. The test code plays “spammer” and after waiting 4 seconds fills the invisible email field with an email address.

Note: On the productive side, this test code must be commented out or removed entirely.

The JavaScript code

// suppress form submit in case of spambot filled hidden field
jQuery(document).ready(function() {
	// console.log('FEWA script loaded');
	const formID = '44';
	const fieldID = '464';
	jQuery('div.field' + fieldID).css('display', 'none');
	window['visform' + formID + 'SubmitAction'] = function (form) {
		if('' !== jQuery('#field' + fieldID).val()) {
			alert("Please log in first!");
			return false;
		}
		return true;
	};
	// only for testing purposes: emulate spambot attack
	window.setTimeout(function () {
		jQuery('#field' + fieldID).val('spambot@text.de');
	}, 4000);
});

Record a time period with date fields and time fields

Subjects

The following topics are included in the example:

  • Only run code after the HTML document has been initialized.
  • Respond to user changes.
  • Determine the selected values of date fields.
  • Determine the individually configured date format of the date fields.
  • Determine the values of text fields of the form.
  • Check for completeness of user information
  • Programming and calculating with date values.
  • Programming and calculating with time values.
  • Parse a date in text format into a JavaScript “Date” object.
  • Output to a text field of the form.

Description

The form has a date field and a text field for entering the time you fell asleep and the time you woke up. When the last field is filled, the calculation of the bedtime begins. The time difference in hours is displayed in another field.

Empty form: Enter a time period with date fields and time fields. Filled form: Enter a time period with date fields and time fields.

Note: The calculation takes into account the possible different field settings for the date format. Different date formats can be set for date fields in the field configuration.

The JavaScript code

jQuery(document).ready(function() {
	// console.log('FEWA script loaded');
	const startDateID     = '556'; // Visforms start date field ID of field list
	const startTimeID     = '557'; // Visforms start time (text) field ID of field list
	const endDateID       = '558'; // Visforms end date field ID of field list
	const endTimeID       = '559'; // Visforms end time (text) field ID of field list
	const sleepingTimeID  = '560'; // Visforms start time (text) field ID of field list

	function calculateHours() {
		// Get values from input fields
		const startDateValue  = jQuery(`#field${startDateID}`).val();
		const startTimeValue  = jQuery(`#field${startTimeID}`).val();
		const endDateValue    = jQuery(`#field${endDateID}`).val();
		const endTimeValue    = jQuery(`#field${endTimeID}`).val();
		const startDateFormat = jQuery(`#field${startDateID}_btn`).attr('data-date-format');
		const endDateFormat   = jQuery(`#field${endDateID}_btn`).attr('data-date-format');

		if(startDateValue === '' || startTimeValue === '' || endDateValue === '' || endTimeValue === '' ) {
			return;
		}

		// Create date objects
		const startDate = addTimeToDate(stringToDate(startDateValue, startDateFormat), startTimeValue);
		const endDate = addTimeToDate(stringToDate(endDateValue, endDateFormat), endTimeValue);

		// Calculate time difference in milliseconds
		const timeDifference = endDate - startDate;

		// Convert milliseconds to hours
		let hoursDifference = timeDifference / (1000 * 60 * 60);
		// Round to 2 digits
		hoursDifference = Math.round((hoursDifference + Number.EPSILON) * 100) / 100

		// Display the result
		jQuery(`#field${sleepingTimeID}`).val(hoursDifference);
	}

	// Call the function when any of the relevant fields change
	jQuery(`#field${startDateID}, #field${startTimeID}, #field${endDateID}, #field${endTimeID}`).on('change', calculateHours);

	// You can also call the function initially if needed
	// calculateHours();
});

function stringToDate(date, format) {
	// parsing a string into a date
	const delimiter = format.charAt(2);
	const formatLowerCase = format.toLowerCase();
	const formatItems     = formatLowerCase.split(delimiter);
	const dateItems       = date.split(delimiter);
	const monthIndex      = formatItems.indexOf("%m");
	const dayIndex        = formatItems.indexOf("%d");
	const yearIndex       = formatItems.indexOf("%y");
	const month           = parseInt(dateItems[monthIndex]) - 1;
	return new Date(dateItems[yearIndex], month, dateItems[dayIndex]);
}

function addTimeToDate(date, time) {
	// replace all spaces
	time = time.replace(/\s/g, '');
	// split hours and minutes
	const parts = time.split(':');

	if(parts[0] === '') {
		// empty time string
		return date;
	}
	else if(parts.length == 1) {
		// only hour present
		date.setHours(parseInt(parts[0]));
		return date;
	}
	else {
		// hour and minutes present
		date.setHours(parseInt(parts[0]), parseInt(parts[1]));
		return date;
	}
}

Calculate and display age based on date of birth

Topics

The following topics are included in the example:

  • Only run code after the HTML document has been initialized.
  • Only run code after the form has been initialized by Visforms.
  • React to changes made by the user.
  • Determine the selected values of date fields.
  • Determine the individually configured date format of the date fields.
  • Programming and calculating with date values.
  • Parse a date in text format into a JavaScript “Date” object.
  • Calculate age based on date of birth in a helper function.
  • Output to a text field on the form.

Description

The user enters his date of birth in a date field. The form calculates his age from the date of birth and displays it in a read-only text field.

Form without selecting the date of birth

The birth-date field starts with the current date.
This is a setting in the field configuration, tab Basic settings:

  • Parameter Fill field with is set to Selected date value / Current date.
  • Parameter Current date is activated.

The field age therefore initially shows an age of 0 years.
Its value cannot be changed directly by the user.
This is a setting in the field configuration, tab Basic settings:

  • Parameter Read only is activated.
Form without selecting the date of birth

Form with selecting the date of birth

Form with selecting the date of birth

Form configuration

Form configuration

The JavaScript code

// calculate age based on date field and show the age in a text field
jQuery(document).ready(function() {
    console.log('FEWA script loaded');
    
    const birthDateID = '582'; // Visforms birth date field ID of field list
    const ageID       = '583'; // Visforms text field ID of field list to show the age
    
    // Call the function when any of the relevant fields change
    jQuery(`#field${birthDateID}`).change({birthDateID: birthDateID, ageID: ageID}, function (event) { calculateAge(event.data.birthDateID, event.data.ageID); });
    
    // initialize age field after form is initialized
    jQuery('.visform').bind('visformsInitialised', function() {
        calculateAge(birthDateID, ageID);
    });
});

function calculateAge(birthDateID, ageID) {
    console.log(birthDateID);
    // get values from input fields
    const birthDateValue  = jQuery(`#field${birthDateID}`).val();
    const birthDateFormat = jQuery(`#field${birthDateID}_btn`).attr('data-date-format');
    // helper function to get date object
    const birthDate = stringToDate(birthDateValue, birthDateFormat);
    // helper function to calculate the age
    const age = calculateYear(birthDate);
    // set and show the age
    jQuery(`#field${ageID}`).val(age);
}

function stringToDate(date, format) {
    // parsing a string into a date depending on the date string format
    const delimiter = format.charAt(2);
    const formatLowerCase = format.toLowerCase();
    const formatItems     = formatLowerCase.split(delimiter);
    const dateItems       = date.split(delimiter);
    const monthIndex      = formatItems.indexOf("%m");
    const dayIndex        = formatItems.indexOf("%d");
    const yearIndex       = formatItems.indexOf("%y");
    const month           = parseInt(dateItems[monthIndex]) - 1;
    return new Date(dateItems[yearIndex], month, dateItems[dayIndex]);
}

function calculateYear(date) {
    // calculate the difference in milliseconds
    // between the current date and the provided date of birth
    const diff_ms = Date.now() - date.getTime();
    // create a new Date object representing the difference in milliseconds
    // and store it in the variable age_dt (age Date object)
    const age_dt = new Date(diff_ms);
    // calculate the absolute value of the difference in years
    // between the age Date object and the year 1970 (UNIX epoch)
    return Math.abs(age_dt.getUTCFullYear() - 1970);
}

Adaptation to your form

The following adjustments are necessary to the JavaScript code and your form:

  • In the JavaScript code, change the value of the variable birthDateID to the ID of your date field.
  • In the JavaScript code, change the value of the variable ageID to the ID of your output field.

Initialize form in the detail view with data from the detail view

Subjects

The following topics are included in the example:

  • Only run code after the HTML document has been initialized.
  • Pause code execution for 1 second before initialization.
  • Copy field values from the data detail view to the form fields on the same page.
  • Combine values to be copied as small source-destination arrays into one large array.

Description

In the frontend view Data Detail for the Contact form, a second Hotline request form is embedded with a Visforms module.
This second form Hotline Request should be initialized with the values of the frontend view Data Detail.

This means that all the necessary user information is automatically filled in the Hotline request form.
The user only has to enter the two fields Subject and Message of his hotline request.
He can then submit his form with all user information.

The form

The Form

The form configuration

The form configuration

The JavaScript code

// initialize embedded form fields with data from detail data view
jQuery(document).ready(function() {
    console.log('FEWA script loaded');
    //  set simple window timeout: 1 sec
    window.setTimeout(function () {
        // format: [from-ID , to-ID]
        const IDs = [ [197,552], [198,553], [199,554], [200,555], [201,556], [202,557], [203,558], [204,559] ];
        IDs.forEach((elem, idx, arr) => {
            const srce = elem[0]; // from-ID
            const dest = elem[1]; // to-ID
            jQuery(`#field${dest}`).val(jQuery(`td.vfdvvalue.data-f${srce}`).text());
        });
    }, 1000);
});

The following adjustments to your situation are necessary:

  • The array containing the field IDs to copy:
    const IDs = [ [197,552], [198,553], [199,554], [200,555], [201,556], [202,557], [203,558], [204,559] ];
  • Example: Entry for copying from the data detail with the ID 197 (from-ID) to the form field with the ID 552 (to-ID):
    [197,552],