Dear All,
I have a page at this link http://183.78.169.54/v3/addTab.php. Then you can click the Driver Employment tab and add just two rows and press the Add button. Then it will take to Driver Details and show all the fields are required. The problem here is that the Driver Employment part I done using jquery the rest I did using normal javascript. So now how to get both working is my problem.
newbie14 0 Posting Pro
Airshow 416 WiFi Lounge Lizard Team Colleague
There's nothing to prevent raw javascript and jquery co-existing.
You just need to invoke appropriate code in response to relevant user events.
The code will typically be organised in functions, each of which can contain raw js or jquery or a mixture of the two.
You probably just need to reorganise the code that you have already written.
In this context, it is probably worth noting that any code sitting inside a $(document).ready(...) structure has access to all functions and variables in the global namespace - but not the other way round.
The preferred way ahead would be to recast everything in jquery.
Airshow
Edited by Airshow because: n/a
newbie14 0 Posting Pro
Dear Airshow,
Now what I want to do is actually those in the Driver Employment tab I want to validate using the jquery method. But the rest of I want to validate via the normal javascript. How to assign that accordingly. There is where I am stuck. Now both validation is working and messing things.
Airshow 416 WiFi Lounge Lizard Team Colleague
It's hard to describe what to do in general terms.
Can you post the relevant code? In particular, I need to see how event handlers are attached because that's the most likely area where conflict might arise.
Airshow
newbie14 0 Posting Pro
Dear Airshow,
Below is my codes and it is located here http://183.78.169.54/v3/addTab.php if you would like to test the site. One function is the javascript called validateForm() and another is the other is $(document).ready(function() {
. But when I pressed the add button it called the validateForm(); because I do this onSubmit="return validateForm();
<?php
session_start();
require "KoolTabs/kooltabs.php";
require_once('config.php');
$searchcm=$_POST['searchcm'];
$formType="Add";
$submitTag="Add";
//$driverID=$_GET['driverID'];
?>
<html>
<head>
<link rel="stylesheet" type="text/css" href="my1.css" media="all">
<link rel="stylesheet" type="text/css" href="epoch_styles.css" />
<script type="text/javascript" src="epoch_classes.js"></script>
<script type="text/javascript">
/*You can also place this code in a separate file and link to it like epoch_classes.js*/
var driverLicenseExpiryCal,driverGDLExpiryCal;
var dp_cal,ms_cal;
window.onload = function () {
driverLicenseExpiryCal = new Epoch('epoch_popup','popup',document.getElementById('driverLicenseExpiryDate'));
driverGDLExpiryCal = new Epoch('epoch_popup','popup',document.getElementById('driverGDLExpiryDate'));
document.getElementById("driverDetails").className = "show";
document.getElementById("driverLicenses").className = "hide";
document.getElementById("driverEmployment").className = "hide";
};
</script>
<script type="text/javascript">
function showTab(_id)
{
var tabID=_id;
//var class1 = document.getElementById("driverDetails").className;
//var class2 = document.getElementById("driverLicenses").className;
//var class3 = document.getElementById("driverNextOfKin").className;
<?php
$driverDetails=true;
$driverLicenses='';
$driverEmployment='';
?>
if(tabID=="driverDetails")
{
<?php
$driverDetails=true;
$driverLicenses=false;
$driverEmployment=false;
?>
//alert("driverDetails : "+tabID);
//document.getElementById(tabID).style.display = 'block';
document.getElementById("driverDetails").className = "show";
document.getElementById("driverLicenses").className = "hide";
document.getElementById("driverEmployment").className = "hide";
}
else if(tabID=="driverLicenses")
{
//alert("DD : "+tabID);
document.getElementById("driverDetails").className = "hide";
document.getElementById("driverLicenses").className = "show";
document.getElementById("driverEmployment").className = "hide";
<?php
$driverDetails='';
$driverLicenses=true;
$driverEmployment='';
?>
}
else if(tabID=="driverEmployment")
{
//alert("DD : "+tabID);
document.getElementById("driverDetails").className = "hide";
document.getElementById("driverLicenses").className = "hide";
document.getElementById("driverEmployment").className = "show";
<?
$driverDetails='';
$driverLicenses='';
$driverEmployment=true;
?>
}
}
function validateForm()
{
//alert("TEST");
//Get the controls
var driverNameControl = document.getElementById("driverName");
var dateOfBirthDayControl = document.getElementById("dateOfBirthDay");
var dateOfBirthMonthControl = document.getElementById("dateOfBirthMonth");
var dateOfBirthYearControl = document.getElementById("dateOfBirthYear");
var driverNewICNoControl = document.getElementById("driverNewICNo");
var driverLicenseNoControl = document.getElementById("driverLicenseNo");
var driverLicenseExpiryDateControl = document.getElementById("driverLicenseExpiryDate");
var driverGDLNoControl = document.getElementById("driverGDLNo");
var driverGDLExpiryDateControl = document.getElementById("driverGDLExpiryDate");
//Create expressions
var isNumeric = /^[0-9]+$/;
var isLetters = /^[a-zA-Z ]+$/;
var isEmail = /^([\w-]+(?:\.[\w-]+)*)@((?:[\w-]+\.)*\w[\w-]{0,66})\.([a-z]{2,6}(?:\.[a-z]{2})?)$/i;
//Cheack each one and if it fails, set an appropriate error message
var gotDriverNameError="false";
var gotDateOfBirthError="false";
var gotDriverNewICNoError="false";
var gotDriverLicenseNoError="false";
var gotDriverLicenseExpiryDateError="false";
var gotDriverGDLNoError="false";
var gotDriverGDLExpiryDateError="false";
//alert("client ID:"+clientNameControl.value+"TEST");
//If name is empty or invalid
if(driverNameControl.value == "")
{
driverNameError.innerHTML = " * Driver Name is empty";
gotDriverNameError="true";
}
else if(driverNameControl.value.search(isLetters))
{
driverNameError.innerHTML = " * Driver Name must only contain letters";
gotDriverNameError="true";
}
else
{
driverNameError.innerHTML = "";
gotDriverNameError="false";
}
if(dateOfBirthDayControl.value>0 && dateOfBirthMonthControl.value>0 && dateOfBirthYearControl.value >0)
{
var myDate = new Date();
//alert("day : "+ dateOfBirthDayControl.value+"month : "+dateOfBirthMonthControl.value+"year : "+dateOfBirthYearControl.value);
myDate.setFullYear( dateOfBirthYearControl.value, dateOfBirthMonthControl.value-1, dateOfBirthDayControl.value );
//alert("my date : "+myDate+"get month :"+myDate.getMonth());
if ( myDate.getMonth() != dateOfBirthMonthControl.value-1 )
{
driverDateOfBirthError.innerHTML = "In Valid Date";
gotDateOfBirthError="true";
}
else
{
//alert(" valid date");
driverDateOfBirthError.innerHTML = "";
gotDateOfBirthError="false";
}
}
else
{
driverDateOfBirthError.innerHTML = "Select Data Of Birth";
gotDateOfBirthError="true";
}
if(driverNewICNoControl.value == "")
{
driverNewICNoError.innerHTML = " * Driver New IC No is empty";
gotDriverNewICNoError="true";
}
else if(driverNewICNoControl.value.search(isNumeric))
{
driverNewICNoError.innerHTML = " * Driver New IC No must only contain numbers";
gotDriverNewICNoError="true";
}
else
{
driverNewICNoError.innerHTML = "";
gotDriverNewICNoError="false";
}
if(driverLicenseNoControl.value == "")
{
driverLicenseNoError.innerHTML = " * License No. is empty";
gotDriverLicenseNoError="true";
}
else
{
driverLicenseNoError.innerHTML = "";
gotDriverLicenseNoError="false";
}
if(driverLicenseExpiryDateControl.value == "")
{
driverLicenseExpiryDateError.innerHTML = " * License Expiry Date is empty";
gotDriverLicenseExpiryDateError="true";
}
else
{
driverLicenseExpiryDateError.innerHTML = "";
gotDriverLicenseExpiryDateError="false";
}
if(driverGDLNoControl.value == "")
{
driverGDLNoError.innerHTML = " * GDL No. is empty";
gotDriverGDLNoError="true";
}
else
{
driverGDLNoError.innerHTML = "";
gotDriverGDLNoError="false";
}
if(driverGDLExpiryDateControl.value == "")
{
driverGDLExpiryDateError.innerHTML = " * GDL Expiry Date is empty";
gotDriverGDLExpiryDateError="true";
}
else
{
driverGDLExpiryDateError.innerHTML = "";
gotDriverGDLExpiryDateError="false";
}
//If any errors occurred, return false, otherwise true
if(gotDriverNameError=="true" || gotDateOfBirthError=="true" || gotDriverNewICNoError=="true")
{
showTab("driverDetails");
return false;
}
else if(gotChild1DateOfBirthError=="true" || gotChild2DateOfBirthError=="true" || gotChild3DateOfBirthError=="true" )
{
showTab("driverNextOfKin");
return false;
}
else
return true;
};
</script>
<script src="http://code.jquery.com/jquery-1.5.1.min.js"></script>
<script src="jquery.validate.js"></script>
<script>
$(document).ready(function() {
function setupSingleRowValidation(form) {
function filledFields(array) {
// when given ['name', 'age'] this function will return the following string
// '[name="name"]:filled, [name="age"]:filled'
var selectors = [];
$(array).each(function (i, name) {
selectors.push('[name="' + name + '"]:filled');
});
//alert("Selector : "+selectors);
return selectors.join(', ');
}
function createSingleRowRule(field) {
var suffix = /\[.*\]/.exec(field),
name = 'name' + suffix,
durationOfEmployment = 'durationOfEmployment' + suffix,
reasonLeaving = 'reasonLeaving' + suffix;
previousRecords = 'previousRecords' + suffix;
//alert("sffux:"+suffix);
return {
required: filledFields([name, durationOfEmployment, reasonLeaving, previousRecords]),
number: (field === durationOfEmployment)
};
}
// clean up pre-existing rules before adding new ones
$('tr td:not(:first) input', form).each(function () {
if ($(this.form).validate().currentElements.has(this).length) {
$(this).rules('remove');
}
var rule = createSingleRowRule(this.name);
$(this).rules('add', rule);
});
$('tr td:not(:first) textarea', form).each(function () {
if ($(this.form).validate().currentElements.has(this).length) {
$(this).rules('remove');
}
var rule = createSingleRowRule(this.name);
$(this).rules('add', rule);
});
// prepare single row rules
var nameField = $('tr td input[name^="name"]', form);
//var singleRowRules = createSingleRowRules(nameField.attr('name'));
// initialize validation with single row rules
$(form).validate({
/*rules: singleRowRules,*/
debug: true
});
}
function setupMultipleRowValidation(form) {
// clean up fields so that they contain the multiple row validation rules
/*$(form).validate().currentElements.each(function () {
$(this).rules('remove');
});*/
$('td:not(:first) input', form).each(function () {
$(this).rules('add', {required: true});
});
$('td:not(:first) textarea', form).each(function () {
$(this).rules('add', {required: true});
});
$('[name^="durationOfEmployment"]', form).each(function () {
$(this).rules('add', {number: true});
});
};
function setupFormValidation(form) {
$(form).validate().resetForm();
//alert("LEnght : "+$('tbody tr', form).length);
if ($('tbody tr', form).length > 1) {
//alert("Call setup multiple row");
setupMultipleRowValidation(form);
} else {
$(form).validate().resetForm();
setupSingleRowValidation(form);
}
}
var form = $("#form1");
setupFormValidation(form);
var prot = $('tr.prototype').clone().removeClass('prototype');
$(form).data('prototype', prot);
var id = $(document).data('idCounter') || 0;
// Add button functionality
$("table.dynatable button.add").click(function() {
var form = this.form;
id++;
// Get a new row based on the prototype row
//var prot = master.find(".prototype").clone();
var prot = $(form).data('prototype').clone();
prot.find('[name^="id"]').attr("value", id);
prot.find('[name^="name"]').attr('name', 'name[' + id + ']');
prot.find('[name^="name"]').attr('value', '');
prot.find('[name^="duration"]').attr('name', 'durationOfEmployment[' + id + ']');
prot.find('[name^="duration"]').attr('value', '');
prot.find('[name^="reasonLeaving"]').attr('name', 'reasonLeaving[' + id + ']');
prot.find('[name^="reasonLeaving"]').attr('value', '');
prot.find('[name^="previousRecords"]').attr('name', 'previousRecords[' + id + ']');
prot.find('[name^="previousRecords"]').attr('value', '');
$(form).find("tbody").append(prot);
setupFormValidation(form);
return false;
});
// Remove button functionality
$("table.dynatable button.remove").live("click", function() {
var form = this.form;
$(this).closest("tr").remove();
setupFormValidation(form);
});
jQuery('.dOnly').live('keyup', function ()
{
this.value = this.value.replace(/[^0-9\.]/g,'');
});
});
</script>
<style>
.dynatable {
border: solid 1px #000;
border-collapse: collapse;
}
.dynatable th,
.dynatable td {
background-color:#ccc;
font-size:14px;
font-color:#ffffff;
font-family:Calibri;
}
.dynatable .prototype {
}
label.error
{
display: block;
color:red;
}
td { vertical-align: top; }
</style>
</head>
<body>
<?
$driverDetails=true;
$driverLicenses='';
$driverEmployment='';
echo "TEst DriverDetails : ".$driverDetails;
$kts = new KoolTabs("kts");
//Step 3: Set properties for kooltabs
$kts->styleFolder = "KoolTabs/styles/silver";
//Step 4: Add tabs for KoolTabs: addTab($parentid,$id,$text,$link)
$kts->addTab("root","Driver Details","Driver Details","javascript:showTab(\"driverDetails\")",$driverDetails);
$kts->addTab("root","Driver Licenses","Driver Licenses","javascript:showTab(\"driverLicenses\")",$driverLicenses);
$kts->addTab("root","Driver Employment","Driver Employment","javascript:showTab(\"driverEmployment\")",$driverEmployment);
echo $kts->Render();
?>
<div >
<h2 class="form_desicription">Add Driver (Draft)<?=$status?></h2>
</div>
<form action="<?=$_SERVER['PHP_SELF']?>" method="post" name="form1" enctype="multipart/form-data" id=form1 onSubmit="return validateForm();">
<div id="driverDetails" class="show" style="position:relative" >
<table>
<tr>
<td>
<label class=description for=element_1>Name<font color="red">*</font></label>
</td>
<td>
<input class="text" id="driverName" name="driverName" value="<?php echo $driverName?>">
</td>
</tr>
<tr>
<td><p class=error id="driverNameError" ></p></td>
<td></td>
</tr>
<tr>
<td>
<label class="description">Date of Birth<font color="red">*</font></label>
</td>
<td>
<?php
echo "<select class='select' id='dateOfBirthDay' name='dateOfBirthDay' > ";
echo "<option value=''>-Day-</option>";
for($d=1;$d<32;$d++)
{
if($d<10)
{
$d="0".$d;
}
if($d==$dateOfBirthDay)
{
echo "<option selected value=".$d.">".$d."</option>";
}
else
{
echo "<option value=".$d.">".$d."</option>";
}
}
echo "</select>";
?>
<?php
echo "<select class='select' id='dateOfBirthMonth' name='dateOfBirthMonth' > ";
echo "<option value=''>-Month-</option>";
for($m=1;$m<13;$m++)
{
if($m<10)
{
$m="0".$m;
}
if($m==$dateOfBirthMonth)
{
echo "<option selected value=".$m.">".$m."</option>";
}
else
{
echo "<option value=".$m.">".$m."</option>";
}
}
echo "</select>";
?>
<?php
echo "<select class='select' id='dateOfBirthYear' name='dateOfBirthYear' > ";
echo "<option value=''>-Year-</option>";
for($y=1940;$y<1995;$y++)
{
if($y==$dateOfBirthYear)
{
echo "<option selected value=".$y.">".$y."</option>";
}
else
{
echo "<option value=".$y.">".$y."</option>";
}
}
echo "</select>";
?>
<label class="description">(dd/mm/yyyy)</label>
</td>
</tr>
<tr>
<td><p class=error id="driverDateOfBirthError" ></p></td>
<td></td>
</tr>
<tr>
<td>
<label class=description >New I/C No:<font color="red">*</font></label>
</td>
<td>
<input class="text" id="driverNewICNo" name="driverNewICNo" value="<?php echo $driverNewIcNo?>">
</td>
</tr>
<tr>
<td><p class=error id="driverNewICNoError" ></p></td>
<td></td>
</tr>
<tr>
<td>
<label class=description for=element_1>Recent Image</label>
</td>
<td>
<input type="file" class="file" id="driverImage" name="driverImage" value="" size="50px">
</td>
</tr>
<tr>
<td>
<label class=description >Address:</label>
</td>
<td>
<textarea rows="5" cols="20" class="textarea" id="driverAddress" name="driverAddress"></textarea>
</td>
</tr>
<tr>
<td>
<label class=description for=element_1>Home Tel No:</label>
</td>
<td>
<input class="text" id="driverTelHome" name="driverTelHome" value="<?php echo $driverTelHome?>">
</td>
</tr>
<tr>
<td><p class=error id="driverTelHomeError" ></p></td>
<td></td>
</tr>
<tr>
<td>
<label class=description for=element_1>Mobile Tel No:</label>
</td>
<td>
<input class="text" id="driverTelMobile" name="driverTelMobile" value="<?php echo $driverTelMobile?>">
</td>
</tr>
<tr>
<td><p class=error id="driverTelMobileError" ></p></td>
<td></td>
</tr>
</table>
</div>
<div id="driverLicenses" class="show" style="position:relative" >
<table>
<tr>
<td>
<label class=description for=element_1>License No:<font color="red">*</font></label>
</td>
<td>
<input class="text" id="driverLicenseNo" name="driverLicenseNo" value="<?php echo $driverLicenseNo?>">
</td>
</tr>
<tr>
<td><p class=error id="driverLicenseNoError" ></p></td>
<td></td>
</tr>
<tr>
<td>
<label class=description for=element_1>License Expiry Date:<font color="red">*</font></label>
</td>
<td>
<input class="text" id="driverLicenseExpiryDate" name="driverLicenseExpiryDate" value="<?php echo $driverLicenseExpiryDate?>">
<input class="buttons" type="button" value="Pick" onclick="driverLicenseExpiryCal.toggle();"/>
</td>
</tr>
<tr>
<td><p class=error id="driverLicenseExpiryDateError" ></p></td>
<td></td>
</tr>
<tr>
<td>
<label class=description for=element_1>License Image</label>
</td>
<td>
<input type="file" class="file" id="driverLicenseImage" name="driverLicenseImage" value="" size="50px">
</td>
</tr>
<tr>
<td>
<label class=description for=element_1>GDL License No:<font color="red">*</font></label>
</td>
<td>
<input class="text" id="driverGDLNo" name="driverGDLNo" value="<?php echo $driverGDLNo?>">
</td>
</tr>
<tr>
<td><p class=error id="driverGDLNoError" ></p></td>
<td></td>
</tr>
<tr>
<td>
<label class=description for=element_1>GDL License Expiry Date:<font color="red">*</font></label>
</td>
<td>
<input class="text" id="driverGDLExpiryDate" name="driverGDLExpiryDate" value="<?php echo $driverGDLExpiryDate?>">
<input class="buttons" type="button" value="Pick" onclick="driverGDLExpiryCal.toggle();"/>
</td>
</tr>
<tr>
<td><p class=error id="driverGDLExpiryDateError" ></p></td>
<td></td>
</tr>
<tr>
<td>
<label class=description for=element_1>GDL License Image</label>
</td>
<td>
<input type="file" class="file" id="driverGDLImage" name="driverGDLImage" value="" size="50px">
</td>
</tr>
</table>
</div>
<div id="driverEmployment" class="hide" style="position:relative" >
<table class="dynatable">
<thead>
<tr>
<th>ID</th>
<th>Name Of Former Emp.</th>
<th>Duration of Emp.</th>
<th>Reason for Leaving Emp.</th>
<th>Previous Incidents or Records</th>
<th><button class="add">Add</button></th>
</tr>
</thead>
<tbody>
<tr class="prototype">
<td><input type="text" name="id[]" value="0" /></td>
<td><input type="text" name="name[]" value="" /></td>
<td><input type="text" name="durationOfEmployment[]" value="" /></td>
<td><textarea rows=2 cols=15 name="reasonLeaving[]" /></textarea></td>
<td><textarea rows=2 cols=15 name="previousRecords[]" /></textarea></td>
<td><button class="remove">Remove</button>
</tr>
</tbody>
</table>
<input class="buttons" type="Submit" name="<?php echo $submitTag?>" value="<?php echo $submitTag?>">
<input class="buttons" type="Reset" name="Reset" value="Reset" onclick="location.href='addDriverDraft.php'">
</div>
</form>
</body>
</html>
Airshow 416 WiFi Lounge Lizard Team Colleague
I guess that the jquery validator hijacks the onSubmit="return validateForm()
handler. If so, then it's a question of invoking validateForm() from inside $(document).ready(...) somehow. Will probably need to penetrate the jquery.validate plugin.
Currently using my netbook. Will have a closer look on my desktop machine later today/tomorrow.
Airshow
newbie14 0 Posting Pro
Dear Airshow,
Yes you are right. The problem is that find that jquery is best for the Driver Employment as it can cater well for the dynamic rows added and do the error checking. So I am like stuck at one hand I need the javascript and on the other hand I need the jquery. Thank you for looking into it.
Airshow 416 WiFi Lounge Lizard Team Colleague
Hi,
The first and easiest thing to try is
- Remove
onsubmit="return validateForm()"
from the form tag. - Add
$(form).submit(validateForm);
to setUpFormValidation:
function setupFormValidation(form) {
$(form).validate().resetForm();
//alert("LEnght : "+$('tbody tr', form).length);
if ($('tbody tr', form).length > 1) {
//alert("Call setup multiple row");
setupMultipleRowValidation(form);
} else {
$(form).validate().resetForm();
setupSingleRowValidation(form);
}
$(form).submit(validateForm);
}
If $(form).validate()
conforms to a standard "observer pattern" then I think this will work. If it doesn't work, then try adding the new line at the top of the function instead of the bottom.
Airshow
Edited by Airshow because: n/a
newbie14 0 Posting Pro
Dear Airshow,
Actually I managed to solve my problem my splitting into two forms those with javascript into one form tag and the last tab Driver Employment is into another tab. You can see here http://183.78.169.54/v3/addTab.php. The problem now when you use chrome and try to submit it will go back to Driver Details and show you the error. But that is not the case in IE. Why do you think so?
Airshow 416 WiFi Lounge Lizard Team Colleague
n14,
I can't immediately see why the browsers should behave differently and I'm not sure that splitting the form is the right solution because only one of the two forms will be submitted.
I think the approach in my previous post has more mileage in it even if it's not yet 100% correct.
Airshow
newbie14 0 Posting Pro
Dear Airshow,
If I put this at the bottom $(form).submit(validateForm); the jquery error overide the javascript error. If put right at the top no validation done and straight submit the form. You can try here http://183.78.169.54/v3/addTab.php.
Airshow 416 WiFi Lounge Lizard Team Colleague
n14,
OK, the simple approach doesn't work then.
If you can't live with your two form approach, then I think the way ahead is to redefine your current validateForm function as one or more custom validation methods of the validate plugin.
I've not done this myself but the API seems pretty clear.
Airshow
newbie14 0 Posting Pro
Dear Airshow,
I dont quite get the custom validation method? It have to be linked to which form the non Driver Employee is it? Thank you.
Airshow 416 WiFi Lounge Lizard Team Colleague
n14,
If your application is OK with two forms, then do nothing more.
If you need to recombine the two forms into one, then the custom validation method is a possible way ahead.
Airshow
newbie14 0 Posting Pro
Dear Airshow,
The problem is that it works fine in chrome wheere it will validate my other tabs when the Driver Employment is empty. Where as in IE it will just submit the form wihout validating the rest of the tabs. So how to work around this custom validation can you give a hint or example?
Airshow 416 WiFi Lounge Lizard Team Colleague
n14,
Before trying custom validation, I have discovered a "submitHandler" option, which provides a "callback for handling the actual submit when the form is valid."
Thus, we have a mechanism for calling validateForm()
, without using onsubmit="validateForm()"
, which we know gets hijacked by .validate()
.
If I'm right, you just need to specify a submitHandler in your setupFormValidation
function, like this.
function setupFormValidation($form) {
$form.validate({
submitHandler: function(form) {
if(validateForm()) {
form.submit();
}
}
}).resetForm();
if ($('tbody tr', $form).length > 1) {
setupMultipleRowValidation($form);
} else {
setupSingleRowValidation($form);
}
}
This should allow you to re-combine your two forms into one.
Airshow
Edited by Airshow because: n/a
newbie14 0 Posting Pro
Dear Airshow,
You can try here http://183.78.169.54/v3/addTab.php. The problem is that it still get hijacked by .validate() . So any other solution ?
Airshow 416 WiFi Lounge Lizard Team Colleague
I will see if I can make a working copy of the page when I get home later this weekend.
Airshow
Airshow 416 WiFi Lounge Lizard Team Colleague
n14,
The main problem is that the function setupFormValidation
expects a jquery object $("#form1")
to be passed to it, but in two of three calls the DOM node form
is passed.
This is easily fixed but we can go further. It would make for much more efficient code if the result of $("#form1")
was used directly throughout $(document).ready(function(){...}
thus avoiding the need to pass form, and re-evaluating $(form)
in several places. We can do this, even in the inner functions, by exploiting javascript's "closure" feature.
The code simplifies in several places giving:
$(document).ready(function() {
var $form = $("#form1");//this line moved to top of function for clarity
//$form is then used throughout the function, including inner functions.
function setupSingleRowValidation() {
function filledFields(array) {
// when given ['name', 'age'] this function will return the following string
// '[name="name"]:filled, [name="age"]:filled'
var selectors = [];
$(array).each(function (i, name) {
selectors.push('[name="' + name + '"]:filled');
});
//alert("Selector : "+selectors);
return selectors.join(', ');
}
function createSingleRowRule(field) {
var suffix = /\[.*\]/.exec(field),
name = 'name' + suffix,
durationOfEmployment = 'durationOfEmployment' + suffix,
reasonLeaving = 'reasonLeaving' + suffix;
previousRecords = 'previousRecords' + suffix;
//alert("sffux:"+suffix);
return {
required: filledFields([name, durationOfEmployment, reasonLeaving, previousRecords]),
number: (field === durationOfEmployment)
};
}
// clean up pre-existing rules before adding new ones
$('tr td:not(:first) input', $form).each(function () {
if ($form.validate().currentElements.has(this).length) {
$(this).rules('remove');
}
var rule = createSingleRowRule(this.name);
$(this).rules('add', rule);
});
$('tr td:not(:first) textarea', $form).each(function () {
if ($form.validate().currentElements.has(this).length) {
$(this).rules('remove');
}
var rule = createSingleRowRule(this.name);
$(this).rules('add', rule);
});
// prepare single row rules
var nameField = $('tr td input[name^="name"]', $form);
//var singleRowRules = createSingleRowRules(nameField.attr('name'));
// initialize validation with single row rules
$form.validate({
/*rules: singleRowRules,*/
debug: true
});
}
function setupMultipleRowValidation() {
// clean up fields so that they contain the multiple row validation rules
/*
$form.validate().currentElements.each(function () {
$(this).rules('remove');
});
*/
$('td:not(:first) input', $form).each(function () {
$(this).rules('add', {required: true});
});
$('td:not(:first) textarea', $form).each(function () {
$(this).rules('add', {required: true});
});
$('[name^="durationOfEmployment"]', $form).each(function () {
$(this).rules('add', {number: true});
});
};
function setupFormValidation() {
$form.validate({
submitHandler: function(form) {//DOM node "form" is correct here
if(validateForm()) {
form.submit();//safer than the jquery equivalent to avoid possibilitry of recursive validation
}
},
//*** start: optional ***
invalidHandler: function() {//call validateForm when $form.validate() indicates form is invalid.
validateForm();
}
//*** end: optional ***
}).resetForm();
if ($('tbody tr', $form).length > 1) {
setupMultipleRowValidation();
}
else {
setupSingleRowValidation();
}
}
setupFormValidation();
var prot = $('tr.prototype').clone().removeClass('prototype');
$form.data('prototype', prot);
var id = $(document).data('idCounter') || 0;
// Add button functionality
$("table.dynatable button.add").click(function() {
id++;
// Get a new row based on the prototype row
//var prot = master.find(".prototype").clone();
var prot = $form.data('prototype').clone();
prot.find('[name^="id"]').attr("value", id);
prot.find('[name^="name"]').attr('name', 'name[' + id + ']').attr('value', '');
prot.find('[name^="duration"]').attr('name', 'durationOfEmployment[' + id + ']').attr('value', '');
prot.find('[name^="reasonLeaving"]').attr('name', 'reasonLeaving[' + id + ']').attr('value', '');
prot.find('[name^="previousRecords"]').attr('name', 'previousRecords[' + id + ']').attr('value', '');
$form.find("tbody").append(prot);
setupFormValidation();
return false;
});
// Remove button functionality
$("table.dynatable button.remove").live("click", function() {
$(this).closest("tr").remove();
setupFormValidation();
});
$('.dOnly').live('keyup', function () {
this.value = this.value.replace(/[^0-9\.]/g,'');
});
});
Several comments in code
You will see that I've added an optional invalidHandler
function. Delete this if you want validateForm()
not to be called when .validate() fails.
I also had to fix an error in validateForm()
(gotClientNameError doesn't exist) but maybe this was just in my copy (which I tidied and may have mis-edited).
Something else you might like to consider is your "prototype" implementation. As it stands, the prototype can be removed. It's safer for prototype HTML to be permanently hidden such that it is never itself used, and its "remove" button cannot be clicked. The user only ever sees the clones.
Airshow
newbie14 0 Posting Pro
Dear Airshow,
Great your changes work but the problem I notice now is that both the error appear meaning that my javascript and also jquery error appears. What is the invalidHandler is for exactly? Can you see how to avoid this problem? Thanks.
Airshow 416 WiFi Lounge Lizard Team Colleague
Great your changes work but the problem I notice now is that both the error appear meaning that my javascript and also jquery error appears.
That is exactly what we have been trying to achieve; to make both the .validate plugin AND your validateForm() function to run!
What is the invalidHandler is for exactly? Can you see how to avoid this problem? Thanks.
- invalidHandler is a .validate() option that defines a custom handler (function). If, on form submission, validation by .validate() fails, this handler runs thus allowing other code of your choosing to be executed. The custom code can allow form submission despite .validate() having failed.
- submitHandler is a .validate() option that defines a custom handler (function). If, on form submission, validation by .validate() is successful, this handler intercepts form submission such that other code of your choosing can be executed. The custom code can allow or suppress form submission.
You can read more here.
The two handlers can be edited/deleted to give the exact behaviour you want.
Airshow
Edited by Airshow because: n/a
newbie14 0 Posting Pro
Dear Airshow,
I have read some details now.Please corrcet me here so first under the submitHandler I call the validateForm() if is true I call the form.submit. So I guess then next it will submit the form via jquery am I right? Then why do we call the invalidateHandler? When it will be called? So then why do we resetForm? Why still the jquery error appear together with the javascript error?
if(validateForm()) { form.submit();//safer than the jquery equivalent to avoid possibilitry of recursive validation } }, //*** start: optional *** invalidHandler: function() {//call validateForm when $form.validate() indicates form is invalid. validateForm();
}
Airshow 416 WiFi Lounge Lizard Team Colleague
Please corrcet me here so first under the submitHandler I call the validateForm() if is true I call the form.submit. So I guess then next it will submit the form via jquery am I right?
Nearly correct. form.submit()
is regular javascript, not jquery.
Then why do we call the invalidateHandler? When it will be called?
submitHandler and invalidHandler are mutually exlusive; on any particular occasion that the user attempts to submit the form, one or the other of these handlers is called, not both.
So then why do we resetForm?
I don't know why the form is reset at that point. That is a remnant of your original code. It seems wrong to me too because it will blitz all user entries every time setupFormValidation()
is called.
Why still the jquery error appear together with the javascript error?
All I know is that you wanted the jquery validate
plugin AND the function validateForm()
, written in standard javascript, to run. In the code I have given you, all the functionality of both approaches is maintained. I have not attempted to detect or resolve any conflicts. If they conflict, then you will need to make changes to make them compatible with each other.
Airshow
Edited by Airshow because: n/a
newbie14 0 Posting Pro
Dear Airshow,
How is the decision made to call either of this submitHandler and invalidHandler ? Another then when the regular form submit happen then how will this effect the jquery part of it?
Airshow 416 WiFi Lounge Lizard Team Colleague
How is the decision made to call either of this submitHandler and invalidHandler ? Another then when the regular form submit happen then how will this effect the jquery part of it?
That is explained in the validate
plugin documentation and I gave a further (better?) explanation in my post above (2 days ago).
In short, on attempted form submission, validate
will determine either "valid" or "invalid" depending on what the user has entered. If "valid", then the submitHandler will run; alternatively if "invalid" then the invalidHandler will run.
You are not obliged to have both a submitHandler and an invalidHandler. If either of these actions is not appropriate, then you can delete the corresponding block of code.
Airshow
Edited by Airshow because: n/a
newbie14 0 Posting Pro
Dear Airshow,
When the form.submit is called the whole form is submit is it? Another thing when you say "In short, on attempted form submission, validate will determine either "valid" or "invalid" depending on what the user has entered. If "valid", then the submitHandler will run; alternatively if "invalid" then the invalidHandler will run" The validate will determing the jquery part only rite?
Airshow 416 WiFi Lounge Lizard Team Colleague
When the form.submit is called the whole form is submit is it?
Correct. Standard HTML form submission. Not ajax.
Another thing when you say "In short, on attempted form submission, validate will determine either "valid" or "invalid" depending on what the user has entered. If "valid", then the submitHandler will run; alternatively if "invalid" then the invalidHandler will run" The validate will determing the jquery part only rite?
Correct (or more correctly, the validate plugin part). As written, the submitHandler and invalidHandler add the functionality of validateForm()
.
Airshow
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.