Ответ 1
самая важная вещь, которую нужно учитывать при объединении всего этого - небольшая часть документации (что не совсем очевидно в документации для xVal, которая абстрагирует вызов на rules("add", options)
в вызове xVal.AttachValidator
) для rules("add", options)
(выделение мое):
Добавляет указанные правила и возвращает все правила для первого совпадающего элемент. Требуется, чтобы родительский форма подтверждается, то есть, $( "form" ). validate() вызывается первый.
Это особенно важно, когда плагин jQuery Form входит в игру, и вы хотите отправить форму через AJAX, так как вам нужно настроить параметр submitHandler
при вызове validate(options)
, например:
<script type="text/javascript">
$(document).ready(function() {
// Initialize the form. Store the validator.
var validator = $("form").validate({
// Called when the form is valid.
submitHandler: function(form) {
// Submit the form via ajax.
$(form).ajaxSubmit({
// The return data type is json.
dataType: "json",
// The callback on a successful form
// submission.
success: function(data, statusText) {
// If the new location is not null, then
// redirect to that location.
if (data.data.newLocation) {
// Go to the new location.
document.location.href = data.data.newLocation;
// Get out.
return;
}
// There are errors, pass them to the validator
// for display.
validator.showErrors(data.data.errors);
}
});
}
});
});
</script>
В связи с приведенной выше ссылкой на вызовы rules("add", options)
, вызов validate(options)
должен появиться перед вызовами rules("add", options)
.
Если они этого не делают, тогда submitHandler игнорируется, никогда не вызывается.
В конце концов, это означает, что ваш код на стороне клиента должен выглядеть следующим образом:
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="jquery.validate.min.js"></script>
<script type="text/javascript" src="jquery.form.js"></script>
<!-- Note this is only needed if using xVal. -->
<script type="text/javascript" src="xVal.jquery.validate.js"></script>
<!-- The call to validate the form must come first. -->
<script type="text/javascript">
$(document).ready(function() {
// Initialize the form.
$("form").validate({
// Called when the form is valid.
submitHandler: function(form) {
// Submit the form via ajax.
$(form).ajaxSubmit({
// The return data type is json.
dataType: "json",
// The callback.
success: function(data, statusText) {
// Alert the users to the message.
window.alert(statusText);
}
});
}
});
});
</script>
<!-- Now make the calls to rules("add", options), AFTER the call to -->
<!-- validate (options). It separated into another block for -->
<!-- emphasis, but could be done in the block above. -->
<script type="text/javascript">
// Make calls to rules("add", options).
</script>
<!-- Or, if you are using xVal, make the following call in the ASP.NET -->
<!-- page but again, note it must come AFTER the call to -->
<!-- validate(options). -->
<%= Html.ClientSideValidation<Model>("model") %>
Наконец, со всем этим подключенным, последнее, что нужно сделать, - это то, что нужно делать, когда возвращается серверный метод.
Вы хотите, чтобы JSON, который возвращался из этих вызовов, был чем-то вроде стандартизованной оболочки viewmodel, где у вас есть контент, специфичный для ответа, завернутый в более стандартизованный фрагмент, который предоставляет информацию, необходимую для однородных вызовов, примерно так:
{
// An integer, non-zero indicates faulure, with predefined ranges
// for standard errors across all operations, with other ranges for custom
// errors which are operation-specific. Examples of shared errors
// are not authenticated, not authorized, etc, etc.
resultCode: 0,
// A string, which is to be displayed to the user (usually in the
// form of a jQuery dialog, usually used for the common ranges of
// errors defined above.
message: null,
// An object with operation-specific results.
data: null
}
Для ошибок на сервере возвращайте то же самое, что и выше, но с местоположением, у которого есть URL, к которому пользователь должен быть перенаправлен на успех (или null, если он не был успешным) и карту, которая может быть передана напрямую к showErrors(errors)
, если в полях есть ошибки:
{
resultCode: 0,
message: null,
data:
{
// Returned as a string. If not null, then this is the url
// that the client should be redirected to, as the server-side
// operation was successful.
newLocation: null,
// If not-null, then this is a map which has the names of the
// fields with the errors, along with the errors for the fields.
errors:
{
"model.title": "The title already exists in the system.",
"model.body": "The body cannot have malicious HTML code in it."
}
}
}
Учитывая, что поле success
параметра options
передано ajaxSubmit
должно быть ясно:
// The callback on a successful form
// submission.
success: function(data, statusText) {
// If the new location is not null, then
// redirect to that location.
if (data.data.newLocation) {
// Go to the new location.
document.location.href = data.data.newLocation;
// Get out.
return;
}
// There are errors, pass them to the validator
// for display.
validator.showErrors(data.data.errors);
}
Все, что он делает, это проверить, определено ли свойство newLocation
. Если он определен, он перенаправляет текущий документ в место (которое обычно будет URL-адресом вновь сохраненного ресурса).
Если он не определен, он берет карту и передает ее на showErrors
в валидаторе, возвращаемом вызовом validate(options)
, устанавливая сообщения об ошибках, используя позиционирование и стиль, указанные вызовом validate(options)
.