/* (c) Crown copyright You may use and re-use this code free of charge under the terms of the Open Government Licence v3.0 http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3 */ /*Changes to Legislation Search Functionality * One-liner: common form interactivity Requirements: jQuery framework: http://jquery.com/ Detailed info: Adds show/hide functionality for sub groups Validates forms before sending form The different tests need each other to work correctly History: v0.01 2010-12-08 GE Created */ $.fn.clearDefaultValues = function () { // Remove these values from the submitted form so that the backend doesn't need to handle these values return this.each(function () { $(this).on('submit', function (e) { if (!$(this).hasClass("error")) { $(".jsDefaultVal").each(function () { if ($(this).val() == $(this).data("defaultText")) $(this).val(""); }); $("#errorBar").remove(); } else { e.preventDefault(); } }); }); } $.fn.addDefaultText = function (defaultText) { // Add default values to text boxes that disappear when clicked on but // are added back if the user doesn't input anything return this.each(function () { // Save the field for later use var $field = $(this); // Add this information to the object for detection upon form submissal $field.data("defaultText", defaultText); $field.addClass("jsDefaultVal"); if ($field.val() == "") $field.val(defaultText); $field .on('focus',function () { if ($(this).val() == defaultText) $(this).val(""); }) .on('blur', function () { if ($(this).val() == "") $(this).val(defaultText); }); }); } $.fn.validate = function (type) { // Provide validtion for call later // Provide default argument if left blank if (!type) { type = "year"; } return this.each(function () { var errorMsg, $errorBlock, testRegexp, $fieldValTrimmed, $form, $fieldParent, $field = $(this); $field.closest("form").on('submit', function (event) { // Clear the previous error messages and start process again $field.parent().find(".errorMessage").remove(); $field.parent().find(".error").removeClass("error"); $form = $(this); // Paterns and responses for each data type switch (type) { case "year": testRegexp = /(^$)|(YYYY)|(BBBB)|(Unrhyw un)|(Any)|(^\d{4}$)/; errorMsg = config.forms.errormsg1[LANG]; break; case "date": testRegexp = /(^$)|(^(\d{1,2}\/\d{1,2}\/\d{4})*$)|(^^DD\/MM\/BBBB$)|(^^DD\/MM\/YYYY$)/; errorMsg = config.forms.errormsg2[LANG]; break; case "number": testRegexp = /(^$)|(^\d*$)|(Unrhyw un)|(Any)/; errorMsg = config.forms.errormsg3[LANG] break; } // If the field is enabled run the test if ($field.parent().find("input:enabled").length) { // Tes that the string matches the 'type' testRegexp, trim it of whirespace first if (!$field.val().replace(/^\s+|\s+$/g, "").match(testRegexp)) { // Create the error message area containing the appropriate error text $errorBlock = $("").addClass("error errorMessage").html(errorMsg); // If the error message hasn't been added yet, add it if (!$("#errorBar", $form).length) { $form .prepend('
' + config.errorBar.error[LANG] + '
' ) } $form.addClass("error"); // Add error details to the field if (!$field.hasClass("error")) { $field .addClass("error") .closest("div") .append($errorBlock); // add error class to associated label $("label[for=" + $field.attr("id") + "]").addClass("error"); // Add the layover back to the fields $(".jsController", $form).showHideFields(); // If fields have a default value, fake a user clicking on them to restore it // This currently stops the prevent action... unsure of fix //$(".jsDefaultVal", $form).click().blur(); } event.preventDefault(); // Scroll to error message if ($("#newSearch").length) { $(window).scrollTop($("#newSearch").position().top) } else { $(window).scrollTop($("#errorBar").position().top) } } } }); }); } $.fn.showHideFields = function () { // Grab the array of jQuery Objects (necessary to loop over in a non-jquery way) var controller = this; return this.each(function () { // purpose: disabled inputs don't fire events, put overlay span over input to capture click. once click registered // set the fields focus, enable them and remove overlays. The child fields of the non-selected radio buttons are then disabled // Requires: a div surrounding each group of related fields to the checkbox named .formGroup // create variables with scope of the .each function var $field, controllerParent; // On initilaisation, gives default view enableDisableFields(); // A normal user click kicks off the function, also add a class to let other scripts pick this up as a controller $(controller).addClass("jsController").on('click', function () { enableDisableFields(); }); function enableDisableFields($focusField) { for (i = 0; i < controller.length; i++) { controllerParent = controller.parent("div")[i]; $field = $(controllerParent).find("input:text, select"); $field.addClass("jsControlledField"); // find the checked radioBtn, easier using regular JS for this bit rather than jQuery if (controller[i].checked) { // Show the relevant children $field.prop("disabled", false).removeClass("disabled"); // Set the focus if this parameter has been set if ($focusField) { $focusField.trigger('focus'); } } else { // disable these children $field .attr('disabled', 'disabled') .addClass('disabled'); // For IE consistent CSS to be applied } // Once the view has been amended add/remove the appropriates overlays addRemoveOverlays(); } } function addRemoveOverlays() { // Don't add any overlays on the side refine search bar if ($('#refineSearch').length) { return false; } // Expect a jQuery obj with one or more objects in $field.each(function () { var $currentField = $(this); var $parent = $(this).parent(); var $overlay = $(''); var $formGroup = $(this).closest(".formGroup"); // remove previously set overlays to provide a clean form for new ones to be applied $parent.children(".overlay").remove(); if ($(this).hasClass("disabled")) { // Add the overlay to the selected element $parent.append($overlay); // Style the overalys $overlay.css({ backgroundColor: "#FFFFFF", opacity: 0, position: "absolute", top: $(this).position().top + parseInt($(this).css("margin-top")), left: $(this).position().left + parseInt($(this).css("margin-left")), width: $(this).outerWidth(), height: $(this).outerHeight(), zIndex: 200 }).on('click', function () { // Gives the same functionality as if the user had clicked on the radio $formGroup.find("input:radio").trigger('click'); // emulate a click event on the input so that other functions can find when a user accesses it $currentField.trigger('click'); //alert($currentField.attr("id")); enableDisableFields($currentField); }); } else { // Destroy existing overlay to access item $parent.children(".overlay").remove(); } }); } }); }