// @todo find a better solution?
function toggleCountry( sCountry, bKeepData )
{
if( null === oValidator || !document.getElementById('l1b') )
{
return;
}
if( 'boolean' === typeof( bKeepData ) )
{
oValidator.bKeepCountryData = bKeepData;
}
for( pQuestionPointer in oValidator.aQuestions )
{
if( 152 === oValidator.aQuestions[ pQuestionPointer ].iDataNameId )
{
if( 2 === oValidator.aQuestions[ pQuestionPointer ].iInputTypeId )
{
for( var i = 0; i < oValidator.aQuestions[ pQuestionPointer ].aHtmlObjects[0].options.length; i++ )
{
if( sCountry === oValidator.aQuestions[ pQuestionPointer ].aHtmlObjects[0].options[ i ].value )
{
oValidator.aQuestions[ pQuestionPointer ].aHtmlObjects[0].options[ i ].selected = 'selected';
oValidator.aQuestions[ pQuestionPointer ].aHtmlObjects[0].onchange();
}
}
}
}
}
}
function LgValidator( oFormObj )
{
this.oForm = oFormObj
this.aQuestions = new Array();
this.aQuestionGroups = new Array();
this.sDefaultCountry = 'nl';
this.sCurrentCountry = 'nl';
this.bKeepCountryData = false;
this.aErrors = new Array();
this.bIsValid = true;
this.sDefaultRowClassName = 'dai_campaign_table_tr';
this.sErrorRowClassName = 'dai_campaign_table_error_text';
}
LgValidator.prototype.prepareForm = function()
{
var oSelfReference = this;
this.oForm.onsubmit = function()
{
return oSelfReference.isValid();
}
}
LgValidator.prototype.prepareCountry = function( sCountry )
{
if( typeof( sPortalCountry ) === 'undefined')
{
this.sCurrentCountry = this.sDefaultCountry;
}
else
{
this.sCurrentCountry = sPortalCountry;
}
if( this.sCurrentCountry !== this.sDefaultCountry )
{
toggleCountry( this.sCurrentCountry, true );
}
}
LgValidator.prototype.addQuestion = function( iId, bIsRequired, iMin, iMax, iDataTypeId, iDataNameId, iInputTypeId, sValidationFunction, oHtmlObj, oExtraHtmlObj, iGroupId, sGroupName, sGroupType )
{
// Create an LgQuestion object if not set yet.
if( 'undefined' === typeof( this.aQuestions[ iId ] ) )
{
this.aQuestions[ iId ] = new LgQuestion( iId, bIsRequired, iMin, iMax, iDataTypeId, iDataNameId, iInputTypeId, sValidationFunction, oHtmlObj, oExtraHtmlObj, iGroupId );
}
// Add the (extra) HTML object
this.aQuestions[ iId ].addHtmlObject( oHtmlObj );
this.aQuestions[ iId ].addHtmlObject( oExtraHtmlObj, true );
// If the question is part of a question group >
// create an LgQuestionGroup object if not set yet.
// @todo what if the question isnt part of a question group?
if( 'undefined' === typeof( this.aQuestionGroups[ iGroupId ] ) )
{
this.aQuestionGroups[ iGroupId ] = new LgQuestionGroup( iGroupId, sGroupName, sGroupType );
}
// Add the LgQuestion object to the group
this.aQuestionGroups[ iGroupId ].addQuestion( this.aQuestions[ iId ] );
// Reference objects
var oSelfReference = this;
var oQuestionReference = this.aQuestions[ iId ];
var oQuestionGroupReference = this.aQuestionGroups[ iGroupId ];
// Add some extra functionality to certain objects
// For zipcode and housenumber, onkeyup check/update address details
if( 5 === iDataTypeId || 10 === iDataTypeId && 'undefined' !== typeof( oQuestionGroupReference ) )
{
oHtmlObj.onkeyup = function(e)
{
oSelfReference.validateAddress( oQuestionGroupReference, true );
}
}
// For country selection (NL/BE), onclick/onchange change country
if( 152 === iDataNameId )
{
oHtmlObj.onchange = function(e)
{
//oSelfReference.changeCountry( this.value, oQuestionReference.iId );
oSelfReference.changeCountry( this.options[ this.selectedIndex ].value, oQuestionReference.iId );
}
}
}
LgValidator.prototype.resetValidator = function()
{
this.aErrors = new Array();
this.bIsValid = true;
for( pPointer in this.aQuestions )
{
this.resetQuestion( this.aQuestions[ pPointer ] );
}
}
LgValidator.prototype.resetQuestion = function( oLgQuestion )
{
document.getElementById( 'dai_q_'+ oLgQuestion.iId +'_row' ).className = this.sDefaultRowClassName;
for( pPointer in oLgQuestion.aHtmlObjects )
{
if( ( oLgQuestion.aHtmlObjects[ pPointer ].type ) && ( 'radio' === oLgQuestion.aHtmlObjects[ pPointer ].type || 'checkbox' === oLgQuestion.aHtmlObjects[ pPointer ].type ) )
{
continue;
}
oLgQuestion.aHtmlObjects[ pPointer ].value = '';
}
}
LgValidator.prototype.setQuestionIsRequired = function( oLgQuestion, bIsRequired )
{
oLgQuestion.bIsRequired = bIsRequired;
var aChildNodes = document.getElementById( 'dai_t_'+ oLgQuestion.iId ).childNodes;
for( var pPointer = 0; pPointer < aChildNodes.length; pPointer++ )
{
if( 'undefined' !== aChildNodes[ pPointer ].className && 'dai_question_is_required' === aChildNodes[ pPointer ].className )
{
aChildNodes[ pPointer ].innerHTML = ( true === bIsRequired ? '*' : ' ');
}
}
}
LgValidator.prototype.changeCountry = function( sCountry, iQuestionId )
{
this.sCurrentCountry = sCountry.toLowerCase();
var oLgQuestion = this.aQuestions[ iQuestionId ];
if( 'undefined' !== typeof( this.aQuestionGroups[ oLgQuestion.iGroupId ] ) )
{
var oLgQuestionGroup = this.aQuestionGroups[ oLgQuestion.iGroupId ];
if( true === oLgQuestionGroup.bHasCountrySelection ) // extra check, which might not even be needed.
{
if( false === this.bKeepCountryData )
{
// Reset questions in this group
for( pPointer in oLgQuestionGroup.aQuestions )
{
if( iQuestionId === oLgQuestionGroup.aQuestions[ pPointer ].iId )
{
continue;
}
this.resetQuestion( oLgQuestionGroup.aQuestions[ pPointer ] );
}
}
switch( this.sCurrentCountry )
{
case 'be':
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oStreetnameQuestion.iId +'_row' ).style.display = '';
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oCityQuestion.iId +'_row' ).style.display = '';
// Streetname and city are required for belgium addresses
this.setQuestionIsRequired( oLgQuestionGroup.oStreetnameQuestion, true );
this.setQuestionIsRequired( oLgQuestionGroup.oCityQuestion, true );
var oLgQuestionZipcode = oLgQuestionGroup.oZipcodeQuestion;
oLgQuestionZipcode.aHtmlObjects[ 1 ].style.display = 'none';
break;
default:
case 'nl':
if( null !== oLgQuestionGroup.oStreetnameQuestion )
{
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oStreetnameQuestion.iId +'_row' ).style.display = '';
this.setQuestionIsRequired( oLgQuestionGroup.oStreetnameQuestion, false );
}
if( null !== oLgQuestionGroup.oCityQuestion )
{
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oCityQuestion.iId +'_row' ).style.display = '';
this.setQuestionIsRequired( oLgQuestionGroup.oCityQuestion, false );
}
var oLgQuestionZipcode = oLgQuestionGroup.oZipcodeQuestion;
for( pHtmlObjPointer in oLgQuestionZipcode.aHtmlObjects )
{
oLgQuestionZipcode.aHtmlObjects[ pHtmlObjPointer ].style.display = '';
}
break;
}
}
}
}
LgValidator.prototype.validateAddress = function( oLgQuestionGroup, bIsDirectValidation )
{
switch( this.sCurrentCountry )
{
case 'nl':
var bZipcodeOk = false;
var bHousenumberOk = false;
// If either one field is empty, we don't really have to continue this validation.
// this only works of bIsDirectValidation = true. bIsDirectValidation = false when this function is triggered via
// validateQuestionGroup, which is called before submitting the form.
if( true === bIsDirectValidation && ( ( oLgQuestionGroup.oZipcodeQuestion && '' === this.getValues( oLgQuestionGroup.oZipcodeQuestion ) ) || ( oLgQuestionGroup.oHousenumberQuestion && '' === this.getValues( oLgQuestionGroup.oHousenumberQuestion ) ) ) )
{
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oZipcodeQuestion.iId +'_row').className = this.sDefaultRowClassName;
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oHousenumberQuestion.iId +'_row').className = this.sDefaultRowClassName;
return true;
}
else
{
// If all values are given, we can validate
if( oLgQuestionGroup.oZipcodeQuestion && this.validateZipcode( this, oLgQuestionGroup.oZipcodeQuestion ) )
{
bZipcodeOk = true;
}
if( oLgQuestionGroup.oHousenumberQuestion && this.validateHousenumber( this, oLgQuestionGroup.oHousenumberQuestion ) )
{
bHousenumberOk = true;
}
if( true === bZipcodeOk && true === bHousenumberOk )
{
// Set street, city, etc if possible;
// set proper classnames (no error)
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oZipcodeQuestion.iId +'_row').className = this.sDefaultRowClassName;
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oHousenumberQuestion.iId +'_row').className = this.sDefaultRowClassName;
// Use our core zipcode check to validate the given data
var goCoreAjax = new coreAjax();
var sUrl = '/ajax/checkZipCode/?zipcode='+ oLgQuestionGroup.oZipcodeQuestion.aHtmlObjects[ 0 ].value +'&zipcode_additive='+ oLgQuestionGroup.oZipcodeQuestion.aHtmlObjects[ 1 ].value +'&homenumber='+ oLgQuestionGroup.oHousenumberQuestion.aHtmlObjects[ 0 ].value +'&country_id=121';
goCoreAjax.bUseXRequestedWithHeader = true;
goCoreAjax.setShowErrorMessage(true);
var sResponse = goCoreAjax.requestGetTextSynchrone(sUrl);
if( sResponse !== 'invalid' || sResponse !== 'not found' )
{
var aResponse = sResponse.split( '|' );
if( aResponse[ 0 ] && aResponse[ 1 ] )
{
// Set these values to their corresponding questions
if( oLgQuestionGroup.oStreetnameQuestion )
{
oLgQuestionGroup.oStreetnameQuestion.aHtmlObjects[ 0 ].value = aResponse[ 0 ];
}
if( oLgQuestionGroup.oCityQuestion )
{
oLgQuestionGroup.oCityQuestion.aHtmlObjects[ 0 ].value = aResponse[ 1 ];
}
}
else
{
this.setInvalidAddress( oLgQuestionGroup );
}
}
else
{
this.setInvalidAddress( oLgQuestionGroup );
}
}
else
{
this.setInvalidAddress( oLgQuestionGroup );
}
}
break;
case 'be':
default:
return true;
break;
}
}
LgValidator.prototype.setInvalidAddress = function( oLgQuestionGroup )
{
// Set error class for zipcode and housenumber
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oZipcodeQuestion.iId +'_row').className = this.sErrorRowClassName;
document.getElementById( 'dai_q_'+ oLgQuestionGroup.oHousenumberQuestion.iId +'_row').className = this.sErrorRowClassName;
// Reset streetname and city question
if( null !== oLgQuestionGroup.oStreetnameQuestion )
{
this.resetQuestion( oLgQuestionGroup.oStreetnameQuestion );
}
if( null !== oLgQuestionGroup.oCityQuestion )
{
this.resetQuestion( oLgQuestionGroup.oCityQuestion );
}
}
LgValidator.prototype.isValid = function()
{
var sReturnMessage = new String();
this.bIsValid = true;
// We start off this validation by checking each single (required) question
for( pPointer in this.aQuestions )
{
var bIsValidQuestion = this.isValidQuestion( this.aQuestions[ pPointer ] );
if( false === bIsValidQuestion )
{
this.bIsValid = false;
}
document.getElementById( 'dai_q_'+ this.aQuestions[ pPointer ].iId +'_row').className = ( true === bIsValidQuestion ? this.sDefaultRowClassName : this.sErrorRowClassName );
}
// Followed by group question validation (which is all about the NL zipcode check, really)
for( pPointer in this.aQuestionGroups )
{
var bIsValidQuestionGroup = this.isValidQuestionGroup( this.aQuestionGroups[ pPointer ] );
if( false === bIsValidQuestionGroup )
{
this.bIsValid = false;
}
}
if( true === this.bIsValid )
{
return true;
}
else
{
alert('U heeft niet alle vragen correct ingevuld.\n\nVul de ingevulde gegevens in of aan waar nodig en klik op verstuur om verder te gaan.');
return false;
}
}
LgValidator.prototype.isValidQuestion = function( oLgQuestion )
{
var bIsValidQuestion = false;
// If the question if required, we'll check the data in the input(s)
if( true === oLgQuestion.bIsRequired )
{
if( 1 === oLgQuestion.aHtmlObjects.length )
{
switch( oLgQuestion.aHtmlObjects[0].type )
{
case 'radio':
case 'checkbox':
bIsValidQuestion = ( true === oLgQuestion.aHtmlObjects[0].checked );
break;
case 'select-multiple':
for( var pOptionPointer = 0; pOptionPointer < oLgQuestion.aHtmlObjects[0].options.length; pOptionPointer++ )
{
if( oLgQuestion.aHtmlObjects[0].options[ pOptionPointer ].selected )
{
bIsValidQuestion = true;
}
}
break;
default:
bIsValidQuestion = ( '' !== this.trimString( oLgQuestion.aHtmlObjects[0].value ) );
break;
}
// If the question is already validated as invalid, return.
if( false === bIsValidQuestion )
{
return bIsValidQuestion
}
}
else // more than one html object refers to radios, checkboxes or special fields like housenumber and addition.
{
switch( oLgQuestion.aHtmlObjects[0].type )
{
case 'radio':
for( pHtmlObjPointer in oLgQuestion.aHtmlObjects )
{
if( oLgQuestion.aHtmlObjects[ pHtmlObjPointer ].checked )
{
bIsValidQuestion = true;
}
}
// If no radio is checked, it's already considered invalid. Let's return false right away.
if( false === bIsValidQuestion )
{
return bIsValidQuestion;
}
break;
case 'checkbox':
var iCheckedAnswers = 0;
for( pHtmlObjPointer in oLgQuestion.aHtmlObjects )
{
if( oLgQuestion.aHtmlObjects[ pHtmlObjPointer ].checked )
{
iCheckedAnswers++;
}
}
// Slightly more advanced check for checkboxes; we're taking in account that there might be a minimum OR maximum number of items that may be checked.
if( 0 === iCheckedAnswers || ( 0!== oLgQuestion.iMin && iCheckedAnswers < oLgQuestion.iMin ) || ( 0 !== oLgQuestion.iMax && iCheckedAnswers > oLgQuestion.iMax ) )
{
return bIsValidQuestion;
}
else
{
bIsValidQuestion = true;
}
break;
case 'text':
var iFilledObjects = 0;
for( pHtmlObjectPointer in oLgQuestion.aHtmlObjects)
{
if( '' !== this.trimString( oLgQuestion.aHtmlObjects[ pHtmlObjectPointer ].value ) )
{
iFilledObjects++;
}
}
// Fix for required housenumber and addition where housenumber is required but addition isnt.
if( 16 === oLgQuestion.iDataNameId && ( oLgQuestion.aHtmlObjects[ 1 ] && '' === this.trimString( oLgQuestion.aHtmlObjects[ 1 ].value ) ) )
{
iFilledObjects++;
}
// Fix for required zipcode where zipcode letters arent required (country = be).
if( 17 === oLgQuestion.iDataNameId && ( oLgQuestion.aHtmlObjects[ 1 ] && '' === this.trimString( oLgQuestion.aHtmlObjects[ 1 ].value ) && 'be' === this.sCurrentCountry ) )
{
iFilledObjects++;
}
if( iFilledObjects < oLgQuestion.aHtmlObjects.length )
{
return bIsValidQuestion;
}
else
{
bIsValidQuestion = true;
}
break;
}
}
}
// Questions with extra html objects (checkboxes or radios) have an additional check: if the base object is checked,
// the extra object has to have a value as well.
for( pHtmlObjectPointer in oLgQuestion.aHtmlObjects )
{
if( 'undefined' !== typeof( oLgQuestion.aExtraHtmlObjects[ pHtmlObjectPointer ] ) && null !== oLgQuestion.aExtraHtmlObjects[ pHtmlObjectPointer ] )
{
if( oLgQuestion.aHtmlObjects[ pHtmlObjectPointer ].checked && '' === this.trimString( oLgQuestion.aExtraHtmlObjects[ pHtmlObjectPointer ].value ) )
{
return bIsValidQuestion = false;
}
}
}
// Required or not, if this question has value(s), it'll be validated by the given validation function
if( 'function' !== typeof( oLgQuestion.sValidationFunction ) )
{
alert( oLgQuestion.iId );
}
bIsValidQuestion = oLgQuestion.sValidationFunction( this, oLgQuestion );
return bIsValidQuestion;
}
LgValidator.prototype.isValidQuestionGroup = function( oLgQuestionGroup )
{
switch( oLgQuestionGroup.sType )
{
case 'full_address':
// @todo we might want to extend this function
return this.validateAddress( oLgQuestionGroup, false );
break;
default:
return true;
break;
}
}
LgValidator.prototype.trimString = function( sString )
{
var oString = new String( sString );
return oString.replace(/^\s+|\s+$/g,"");
}
LgValidator.prototype.isValidValueByCharset = function( sValue, sCharset )
{
var iValueLength = sValue.length;
if( 0 === iValueLength )
{
return false;
}
for( var p = 0; p < iValueLength; p++)
{
if( sCharset.indexOf( sValue.substr( p, 1 ) ) < 0 )
{
return false;
}
}
return true;
}
LgValidator.prototype.getValues = function( oLgQuestion )
{
var sValue = new String();
for( pHtmObjectPointer in oLgQuestion.aHtmlObjects )
{
sValue += oLgQuestion.aHtmlObjects[ pHtmObjectPointer ].value;
}
return sValue;
}
LgValidator.prototype.validateNumber = function( oValidator, oLgQuestion )
{
if( '' !== oValidator.trimString( oLgQuestion.aHtmlObjects[ 0 ].value ) )
{
// Number validation is required only for and textarea fields
if( 5 === oLgQuestion.iInputTypeId || 1 === oLgQuestion.iInputTypeId )
{
// Basicly, a number is invalid only if not empty, less than or more than the minimum or maximum value or if it consits of characters.
if( '' !== oValidator.trimString( oLgQuestion.aHtmlObjects[ 0 ].value ) )
{
if( 0 !== oLgQuestion.iMin || 0 !== oLgQuestion.iMax )
{
if( true === oValidator.isValidValueByCharset( oLgQuestion.aHtmlObjects[ 0 ].value, '0123456789,.' ) )
{
if( oLgQuestion.aHtmlObjects[ 0 ].value < oLgQuestion.iMin || oLgQuestion.aHtmlObjects[ 0 ].value > oLgQuestion.iMax )
{
return false;
}
}
}
}
}
}
return true;
}
LgValidator.prototype.validateCurrency = function( oValidator, oLgQuestion )
{
// Until we have a proper currency validation, validate this by using this.validateNumber()
return this.validateNumber( oLgQuestion );
}
LgValidator.prototype.validateString = function( oValidator, oLgQuestion )
{
if( '' !== oValidator.trimString( oLgQuestion.aHtmlObjects[ 0 ].value ) )
{
// A string (text) is invalid only if shorter than the given minimum value or longer than the maximum value of the question.
// This check goes for and