PDA

View Full Version : mailhandler script and validation



Foundas
12-30-2013, 08:35 PM
hello all and happy new year

I would like to ask for your help please as I cannot figure out how to make the form work....
I am using a JS Animated form with jquery validation that once submitted, it gets redirected to a mailhandler.asp file

the form valuates and submits without a problem but when I add an element file-upload, then the form is not submitting anymore unless the upload file element is completed (user to select a file to upload).

can you please help me out how to make this field optional? i.e. remove the validation for the file-upload element?

thanking you in advance


my form is this:


<form id="form2" enctype="multipart/form-data" method="post">
<div class="success"><div class="success_txt">Contact form submitted!<br /><strong> We will be in touch soon.</strong></div></div>
<fieldset>
<label class="name rel">
<span class="inp">
<input type="text" value="Name:">
</span>
<span class="error">*Not a valid name.</span> <span class="empty">*This field is required.</span>
</label>
<label>
<span class="inp">
<input type="file" name="FILE1" value="no_upload">
</span>
</label>
<label class="verification rel">
<span class="inp">
<input type="text" value="What is the answer? 1 + 1 =" maxlength="1">
</span>
<span class="error">*Not a valid answer.</span> <span class="empty">*This field is required.</span>
</label>
<label class="message rel">
<span class="text_a">
<textarea>Message:</textarea>
</span>
<span class="error">*The message is too short.</span> <span class="empty">*This field is required.</span>
</label>
<div class="buttons"><a class="link3" href="#" data-type="reset">clear</a> &nbsp; <a class="link3" href="#" data-type="submit">send</a></div>
</fieldset>
</form>


the form.js file is this one:


//forms
;(function($){
$.fn.forms=function(o){
return this.each(function(){
var th=$(this)
,_=th.data('forms')||{
errorCl:'error',
emptyCl:'empty',
invalidCl:'invalid',
notRequiredCl:'notRequired',
successCl:'success',
successShow:'4000',
mailHandlerURL:'includes/MailHandlertestim.asp',
stripHTML:true,
targets:'input,textarea',
controls:'a[data-type=reset],a[data-type=submit]',
validate:true,
rx:{
".name":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'input'},
".verification":{rx:/2/,target:'input'},
".message":{rx:/.{20}/,target:'textarea'}
},
preFu:function(){
_.labels.each(function(){
var label=$(this),
inp=$(_.targets,this),
defVal=inp.val(),
trueVal=(function(){
var tmp=inp.is('input')?(tmp=label.html().match(/value=['"](.+?)['"].+/),!!tmp&&!!tmp[1]&&tmp[1]):inp.html()
return defVal==''?defVal:tmp
})()
trueVal!=defVal
&&inp.val(defVal=trueVal||defVal)
label.data({defVal:defVal})
inp
.bind('focus',function(){
inp.val()==defVal
&&(inp.val(''),_.hideEmptyFu(label),label.removeClass(_.invalidCl))
})
.bind('blur',function(){
_.validateFu(label)
if(_.isEmpty(label))
inp.val(defVal)
,_.hideErrorFu(label.removeClass(_.invalidCl))
})
.bind('keyup',function(){
label.hasClass(_.invalidCl)
&&_.validateFu(label)
})
label.find('.'+_.errorCl+',.'+_.emptyCl).css({display:'block'}).hide()
})
_.success=$('.'+_.successCl,_.form).hide()
},
isRequired:function(el){
return !el.hasClass(_.notRequiredCl)
},
isValid:function(el){
var ret=true
$.each(_.rx,function(k,d){
if(el.is(k))
ret=d.rx.test(el.find(d.target).val())
})
return ret
},
isEmpty:function(el){
var tmp
return (tmp=el.find(_.targets).val())==''||tmp==el.data('defVal')
},
validateFu:function(el){
el.each(function(){
var th=$(this)
,req=_.isRequired(th)
,empty=_.isEmpty(th)
,valid=_.isValid(th)

if(empty&&req)
_.showEmptyFu(th.addClass(_.invalidCl))
else
_.hideEmptyFu(th.removeClass(_.invalidCl))

if(!empty)
if(valid)
_.hideErrorFu(th.removeClass(_.invalidCl))
else
_.showErrorFu(th.addClass(_.invalidCl))
})
},
getValFromLabel:function(label){
var val=$('input,textarea',label).val()
,defVal=label.data('defVal')
return label.length?val==defVal?'nope':val:'nope'
}
,submitFu:function(){
_.validateFu(_.labels)
if(!_.form.has('.'+_.invalidCl).length)
$.ajax({
type: "POST",
url:_.mailHandlerURL,
data:{
name:_.getValFromLabel($('.name',_.form)),
verification:_.getValFromLabel($('.verification',_.form)),
message:_.getValFromLabel($('.message',_.form)),
owner_email:_.ownerEmail,
stripHTML:_.stripHTML
},
success: function(){
_.showFu()
}
})
},
showFu:function(){
_.success.slideDown(function(){
setTimeout(function(){
_.success.slideUp()
_.form.trigger('reset')
},_.successShow)
})
},
controlsFu:function(){
$(_.controls,_.form).each(function(){
var th=$(this)
th
.bind('click',function(){
_.form.trigger(th.data('type'))
return false
})
})
},
showErrorFu:function(label){
label.find('.'+_.errorCl).slideDown()
},
hideErrorFu:function(label){
label.find('.'+_.errorCl).slideUp()
},
showEmptyFu:function(label){
label.find('.'+_.emptyCl).slideDown()
_.hideErrorFu(label)
},
hideEmptyFu:function(label){
label.find('.'+_.emptyCl).slideUp()
},
init:function(){
_.form=_.me
_.labels=$('label',_.form)

_.preFu()

_.controlsFu()

_.form
.bind('submit',function(){
if(_.validate)
_.submitFu()
else
_.form[0].submit()
return false
})
.bind('reset',function(){
_.labels.removeClass(_.invalidCl)
_.labels.each(function(){
var th=$(this)
_.hideErrorFu(th)
_.hideEmptyFu(th)
})
})
_.form.trigger('reset')
}
}
_.me||_.init(_.me=th.data({forms:_}))
typeof o=='object'
&&$.extend(_,o)
})
}
})(jQuery)
$(window).load(function(){
$('#form2').forms({
ownerEmail:'#'
})
})

jscheuer1
12-31-2013, 02:22 AM
I'd go for the obvious first and see if that works:


<input class="notRequired" type="file" name="FILE1" value="no_upload">

The browser cache may need to be cleared and/or the page refreshed to see changes.

Foundas
12-31-2013, 06:49 AM
Hi John,

many thanks for the reply...you were on the right track...the class was needed for the <label> ... i.e.. <label class="notRequired">


now it's working perfectly!!!

Thanks

Foundas
01-09-2014, 03:44 PM
Hi everybody,

with the above form, I tried to add a multiple select input



<label class="notRequired mixedlollybartypes rel">
<span class="inp2">
<select name="mixedlollybartypes" multiple size="10" >
<option value="Party Mix">Party Mix</option>
<option value="Snakes">Snakes</option>
<option value="Bananas">Bananas</option>
<option value="Strawberries & Creams">Strawberries & Creams</option>
<option value="Orange Drops">Orange Drops</option>
<option value="Marshmallows">Marshmallows</option>
<option value="Jubes">Jubes</option>
<option value="Teeth">Teeth</option>
<option value="Raspberries">Raspberries</option>
<option value="Liquorice Allsorts">Liquorice Allsorts</option>
</select>
</span>
</label>



in the form.js file I added this (it's not last so that's why there's a comma):



mixedlollybartypes:_.getValFromLabel($('.mixedlollybartypes',_.form)),



when the form is submitted, the variable mixedlollybartypes is empty. If I remove the tag "multiple", then the variable gets a value

can you please advice how I can solve this issue?

thanking you in advance

jscheuer1
01-09-2014, 04:20 PM
In my experience jQuery tries to normalize server side form behavior to javascript. So I would try what is required for a multiple select element there, which is to give it a name which implies an array:


<select name="mixedlollybartypes[]" multiple size="10" >

Hopefully you will not have to change anything else.

jscheuer1
01-09-2014, 04:34 PM
Looking a bit closer, getValFromLabel from the first post in this thread doesn't work for selects. It probably would (at least in some browsers) if it were changed:


getValFromLabel:function(label){
var val=$('input,textarea,select',label).val()
,defVal=label.data('defVal')
return label.length?val==defVal?'nope':val:'nope'
}


But if it does then work, it will be returning an array for a multiple select.

Foundas
01-09-2014, 05:55 PM
Hi John,


thank you for the suggestions. Actually, in the updated js file im using, I have already this function:



getValFromLabel:function(label){
var val=$('input,select,textarea',label).val()
,defVal=label.data('defVal')
return label.length?val==defVal?'nope':val:'nope'
}


and then in the data list, I added:
mixedlollybartypes:_.getValFromLabel($('.mixedlollybartypes',_.form)),


I tried <select name="mixedlollybartypes[]" multiple size="10" >

in the .asp file, I have both options just in case:
body = body & "Mixed Lolly Bar Types: " & Request("mixedlollybartypes") & "<br>"
body = body & "Mixed Lolly Bar Types: " & Request.Form("mixedlollybartypes") & "<br>"
response.write body

but still it doesn't get the values. this code however works if the select has no multiple as option. and without the [] of course that I just added.

any ideas?

thanks

jscheuer1
01-09-2014, 06:36 PM
As I said, it should work in at least some browsers. But if it does, and it's a multiple, it will be an array, not a string. I was using Chrome and it looked to work there. It also occurred to me that the jQuery version might matter. I was using 1.8.3

What browser (include version please), and what jQuery version are you using?

If it doesn't work in some browsers, we can detect a multiple and hopefully figure out how to get the value(s) from it.

And/or if it's 'working' and it's just that the code cannot effectively deal with an array at that point, that can probably be tweaked.

Foundas
01-09-2014, 06:58 PM
Hi John

I tried with IE10 and Chrome 31.0.1650 (latest) and it doesn't work.

I tried this though, (if it helps)

mixedlollybartypes:$('.mixedlollybartypes option:selected').length,

and in my asp file I was getting the number "3" (I did select three out of the 10)... but when I tried:
mixedlollybartypes:$('.mixedlollybartypes option:selected').val(), ---- this gave me only the first option I selected (not the rest)
and
mixedlollybartypes:$('.mixedlollybartypes').val(), ---- this doesn't return any result at all.


as for jquery, the file says: /*! jQuery v1.10.2 |

Foundas
01-09-2014, 07:05 PM
hey John,

finally i got it to work!!!

I put this in the js to collect the data:
mixedlollybartypes:$('.mixedlollybartypes').find(":selected").text(),

only problem is that the result is like this:
Mixed Lolly Bar Types: SnakesBananasJubesTeeth

is there a way to put a , between each option ???

----- update ----

no worries, used simple replace function in asp

thanks for your help on this issue

jscheuer1
01-09-2014, 08:32 PM
I would try (assuming mixedlollybartypes is the class name of the label, and that the label contains the select, and that there's no other element with the class mixedlollybartypes):


mixedlollybartypes:$('.mixedlollybartypes').find('select').val().join(','),

Or (to take account for the possibility that none might be selected):


mixedlollybartypes:(function(){var val = $('.mixedlollybartypes').find('select').val(); return val? val.join(',') : '';})(),

Or (using the method in your post):


mixedlollybartypes:(function(){
var val = [];
$('.mixedlollybartypes').find(":selected").each(function(i, s){
val.push($(s).text());
});
return val.join(',');
})(),

Foundas
01-14-2014, 03:23 PM
Hi John,

I have one more question with this form...I added a confirm-email field and I am looking for a way so that regular expression can check if both fields entered match.

currently, the first email field has this:


rx:{
".email":{rx:/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i,target:'input'},


the new variable is emailconf.... how can I have in the rx:{} section when the form gets validated, a condition if .email==.emailconf ???

thanking you in advance

jscheuer1
01-14-2014, 04:14 PM
I would not use regular expression for that. I would simply confirm that the second is identical (===) to the first. If not, throw an error.

Foundas
01-14-2014, 05:30 PM
Hi John,

thanks for the guideline.

I added the following in the form...


// check if emails are the same
$('.erroremail').hide();
$('#email2').change(function() {
var email1 = $('#email1').val();
var email2 = $('#email2').val();
if(email2 != '' ) {
if(email1 == email2 ){
$('.erroremail').fadeOut();
}
else{
$('.erroremail').fadeIn();
}
}

});



the code works fine but i have a visual issue...the rest of the error messages slideUp or Down instead of fadeIn() i used above.

when i used the slideUp() function, to hide the element, the form elements below the .erroremail message, flicker...like jump up...whereas error message with the other boxes, move fluently

any idea what could be wrong?

jscheuer1
01-14-2014, 05:53 PM
I would have to see the page to know what to do exactly. In general, there should be a container element that's positioned static, or perhaps even relative, that has enough width and height to contain the absolutely positioned message div which can then slide up or down within that without changing the surrounding layout. Often jQuery takes care of part or all of that though, it depends how it's setup.

jscheuer1
01-16-2014, 03:03 PM
I see that all the other error fields are class="error". Why is the confirmation email one different (erroremail)? Also, I cannot find rx from your previous post, where is that?

Foundas
01-16-2014, 03:26 PM
Hi John,

from the link I gave you to see the form, you can see the formsbk.js file

the rx:


rx:{
".name":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'input'},
".email":{rx:/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i,target:'input'},
".telephone":{rx:/^\+?(\d[\d\-\+\(\) ]{5,}\d$)/,target:'input'},
".address":{rx:/.{5}/,target:'input'},
".suburb":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'input'},
".eventtype":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'input'},
".eventdate":{rx:/.{5}/,target:'input'},
".guests":{rx:/.{2}/,target:'input'},
".location":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'select'},
".surfacearea":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'select'},
".verification":{rx:/2/,target:'input'}
},


as for the class name....I couldn't have it as .error since that class is handled (shown or hidden) by the formsbk.js. And also, the error message gets its validation from rx...in the case I want to compare 2 fields, I am not using reg-exp but plain jquery function

The .erroremail appears only if the email1 and email2 fields are not the same (onchange event of email2)

jscheuer1
01-16-2014, 05:25 PM
Right, I figured that out. What I think we should do is get formsbk.js to handle this by editing the isValid function allowing it to use a function instead of an rx if so configured in the main rx object. I'm not certain exactly how that would work so back up everything you have now first. What I think would work is adding this (highlighted) to the rx object:


rx:{
".name":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'input'},
".email":{rx:/^(("[\w-\s]+")|([\w-]+(?:\.[\w-]+)*)|("[\w-\s]+")([\w-]+(?:\.[\w-]+)*))(@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$)|(@\[?((25[0-5]\.|2[0-4][0-9]\.|1[0-9]{2}\.|[0-9]{1,2}\.))((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\.){2}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9]{1,2})\]?$)/i,target:'input'},
".emailconf":{rx:function(v){return v===_.getValFromLabel($('.email',th));},target:'input'},
".telephone":{rx:/^\+?(\d[\d\-\+\(\) ]{5,}\d$)/,target:'input'},
".address":{rx:/.{5}/,target:'input'},
".suburb":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'input'},
".eventtype":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'input'},
".eventdate":{rx:/.{5}/,target:'input'},
".guests":{rx:/.{2}/,target:'input'},
".location":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'select'},
".surfacearea":{rx:/^[a-zA-Z'][a-zA-Z-' ]+[a-zA-Z']?$/,target:'select'},
".verification":{rx:/2/,target:'input'}
},


And changing the isValid function to (additions highlighted, but just replace it with this):


isValid:function(el){
var ret=true
$.each(_.rx,function(k,d){
if(el.is(k))
if(typeof d.rx === 'function'){
ret=d.rx(el.find(d.target).val());
} else {
ret=d.rx.test(el.find(d.target).val());
}
})
return ret
},

That would also mean removing:


// check if emails are the same
$('.erroremail').hide();
$('#email2').change(function() {
var email1 = $('#email1').val();
var email2 = $('#email2').val();
if(email2 != '' ) {
if(email1 == email2 ){
$('.erroremail').slideUp();
}
else{
$('.erroremail').slideDown();
}
}
});

And changing the erroremail span's class to just error.

That should do it.

The browser cache may need to be cleared and/or the page refreshed to see changes.

Let me know what happens. I just did this in a mock up and it worked.

Foundas
01-17-2014, 07:09 AM
You are the best John...works perfectly now!!!!

many thanks for all your support