eddy eddy - 2 months ago 8
jQuery Question

How to use jquery validate plugin inside a jquery UI dialog and in an asp form, all this in the same asp.net page

I need to use jquery validate plugin to validate both the controls inside a jquery UI Dialog and the controls inside an asp.net form.

JavaScript:

<script type="text/javascript">

var table = [];

$(document).ready(function() {
$("button, input:submit, input:button").button();
$("#<%=txtDate.ClientID %>").datepicker();

// a workaround for a flaw in the demo system (http://dev.jqueryui.com/ticket/4375), ignore!
$("#dialog:ui-dialog").dialog("destroy");
$("#form2").validate({

rules: {
price: {
required: true,
number: true
},

description: {
required: true
}
}

});
$("#dialog-form").dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"Add Detail": function() {
var valid = $("#form2").validate().form();
if (valid) {
$("#save").button("enable");
addDetail();
$("#save").attr('disabled',false);
$(this).dialog("close");
}
},
Cancel: function() {
$(this).dialog("close");
}
},

close: function() {

$("#price").val("");
$("#description").val("");
}
});

$("#newDetail")
.button()
.click(function() {
$("#dialog-form").dialog("open");
});

$("#<%=form1.ClientID %>").validate({
rules: {
<%=txtDate.ClientID %> : {
required: true,
dateEU: true
},
<%=txtCompany.ClientID %> : {
required: true
}
},
submitHandler: function(form) {

form.submit();
}

});
});


function addDetail() {
table.push({
codigo: 0,
documentoCompra: {
"codigo": "0"
},

price: document.getElementById('price').value,
description: document.getElementById('description').value
});

showRow(table.length - 1);
}

function removeDetail(r) {
var node = r.parentNode;
while (node && node.tagName !== 'TR') {
node = node.parentNode;
}

var i = node.rowIndex;

document.getElementById('DetailTable').deleteRow(i);
table.splice(i - 1, 1);

if (table.length == 0) {
document.getElementById('save').disabled=true;
$("#save").button("disable");
}
}

function showRow(i) {
if (table.length > 0) {
var tbl = document.getElementById('DetailTable');

var newRow = tbl.insertRow(tbl.rows.length);

var cell3 = newRow.insertCell(0);
cell3.innerHTML = table[i].description;

var cell4 = newRow.insertCell(1);
cell4.innerHTML = table[i].price;

var cell2 = newRow.insertCell(2);
cell2.innerHTML = '<a href="#"><img src="images/delete.jpg" width="14" height="14" alt="Delete" onclick="removeDetail(this)"/></a>'

document.getElementById('save').disabled=false;

}
}
</script>


Html and Asp.net markup:

<form id="form1" runat="server">
<fieldset style="width: 85%">
<legend>MASTER</legend>
<div id="contenido1" class="ui-widget">
<table width="90%" class="ui-widget ui-widget-content">
<tr>
<td align="left" class="ui-widget-header ">
COMPANY
</td>
<td align="left">
<asp:TextBox ID="txtCompany" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td align="left" class="ui-widget-header ">
DATE
</td>
<td align="left">
<asp:TextBox ID="txtDate" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td align="left" class="ui-widget-header ">
TYPE
</td>
<td align="left">
<asp:DropDownList ID="ddlTipoDoc" runat="server">
<asp:ListItem Text="BOLETA" Value="B" Selected="True"></asp:ListItem>
<asp:ListItem Text="RECIBO CAJA CHICA" Value="R"></asp:ListItem>
<asp:ListItem Text="FACTURA" Value="F"></asp:ListItem>
</asp:DropDownList>
</td>
</tr>
</table>
</div>
<input type="submit" id="save" value="Save" disabled="disabled" />
&nbsp;&nbsp;&nbsp;
<input type="button" id="cancelar" value="Cancel" />
</fieldset>
</form>
<!--Detail -->
<div>
<fieldset style="width: 85%">
<legend>DETAIL</legend>
<div id="dialog-form" title="Add New Detail">
<p>
All the fields are required.</p>
<form id="form2">
<table>
<tr>
<td>
<label for="description" id="lbldescription">
Description</label>
</td>
<td>
<input type="text" name="description" id="description" class="text ui-widget-content ui-corner-all" />
</td>
</tr>
<tr>
<td>
<label for="price" id="lblprice">
Price</label>
</td>
<td>
<input type="text" name="price" id="price" class="text ui-widget-content ui-corner-all" />
</td>
</tr>
</table>
</form>
</div>
<div id="content" class="ui-widget">
<table id="DetailTable" class="ui-widget ui-widget-content" style="text-align: center">
<thead>
<tr class="ui-widget-header ">
<td width="60%">
Description
</td>
<td width="20%">
Price
</td>
<td width="10%">
Delete
</td>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
<table border="0" style="width: 90%">
<tr>
<td colspan="3">
<button id="newDetail" style="float: right">
Add</button>
</td>
</tr>
</table>
</fieldset>
</div>


Although it is true that I almost got it ready, I still have some doubts:


  1. What do I have to do to remove the error messages from the controls inside the dialog, after I have closed the dialog without meeting the validation rules?

  2. How do I do to always show the error messages just below the controls they validate?

  3. Would you be kind enough to check whether it is correct what I've done with the validation of the dialog? I've first added the validation rules and inside the code that is executed when I press the "Add Detail" button, I've added a conditional to check whether the controls have been correctly validated , in which case, I close the dialog and add a new row to the Details" table



I've uploaded a sample project(JqueryDialog_JqueryValidate) to my skydrive , a very simple one indeed

Any ideas or suggestions will be greatly appreciated

Edit :
CSS style needed to place the error label below the inputs

<style type="text/css">
input:focus
{
border: 2px dotted black;
}
input.error
{
border: 2px solid red;
}
label.error
{
color: white;
text-indent:2px;
font-size: 16px;
font-weight:bold;
font-family: Nyala;
background-color: red;
display:block ;

}
</style>

Answer

So, here for your three questions:

1. What do I have to do to remove the error messages from the controls inside the dialog, after I have closed the dialog without meeting the validation rules?

The plugin provides a resetForm() method on the validator object to reset the validation (see doc).

When you call validate(), it actually returns a validator object that you can save and use afterwards:

var dialogFormValidator = $("#form2").validate({...});

In you 'close' button handler, you can then do:

close: function() {
    $("#price").val("");
    $("#description").val("");
    dialogFormValidator.resetForm();
}

Edit

Bind to the event beforeClose resets the form correctly (classes are not removed when binding to the close event:

beforeClose: function() {
    $("#price").val("");
    $("#description").val("");
    dialogFormValidator.resetForm();
}

2. How do I do to always show the error messages just below the controls they validate?

Use the errorPlacement() callback in the validate() options to place the error label wherever you want (see doc).

By default the are added next to the input field. With some CSS you might able to show them 'below' the input though (with something like display:block; for inst.)

3. dialog button handlers

As for the reset you can use the validator object to check the validity:

var valid = dialogFormValidator.form();                       
if (valid) {
     $("#save").button("enable");
     addDetail();
     // why don't you use $("#save").button("disable") ??
     $("#save").attr('disabled',false);  // better use prop() for 'disabled' properties and not attr()              
     $(this).dialog("close");
}

Am not sure about the 'Add Detail' button handler. Why do you enable/disable the #Save element (in two different ways) ?