Examples

Examples 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:

  • 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.
  • Run code after the form has been completely initialized.

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, “Advanced” tab, “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:

  • 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:

  • 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:

  • 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;
	}
}