Client SideValidation is not working

Oct 27, 2011 at 12:52 AM

Hi,

continuing my tests, i have failed to make the Client Side Works.

the funny part is that when i debug the model state, i can see SpecExpress Error kicking in, so SpecExpress is validating the model, but not kicking on the client side 

i  went further to make sure that i have any application missing steps, so  i disabled SpecExpress and used the MVC 3 regular data annotation Validation, and it worked fine

 

i have followed everything in the Documentation

1- Globla.cs 

 

protected void Application_Start()
{
    // Initialize the Validation Catalog.  This must be done before adding SpecExpress' Model Validator
    // Provider to the ModelValidatorProviders collection.
    ValidationCatalog.Scan(a => a.TheCallingAssembly());

    // Don't imply that value types are required
    DataAnnotationsModelValidatorProvider.AddImplicitRequiredAttributeForValueTypes = false;

    // Add the SpecExpressModelProvider to the collection of ModelValidators
    ModelValidatorProviders.Providers.Add(new SpecExpressModelProvider());

    // Register Routes, GlobalFilters, etc.
}
2- my Validation

 

public class UserSpecification : Validates<User>
	{
		public UserSpecification()
		{
			Check(c => c.Name).Required().MaxLength(3);
			Check(c => c.NameCol).Required().CountGreaterThan(0);
			 
		}
	}

3- View

 

 

@{
	Layout = null;

	if (ViewContext.FormContext == null)
	{
		ViewContext.FormContext = new FormContext();
	}
}
@using Newtonsoft.Json
@model MyApp.Areas.Administration.Models.User
<script src="@Url.Content("~/Areas/ApplicationShared/Scripts/Jquery.js")" type="text/javascript"> </script>
<script src="@Url.Content("~/Areas/ApplicationShared/Scripts/MVC/KnockOut.js")" type="text/javascript"> </script>
<script src="@Url.Content("~/Areas/ApplicationShared/Scripts/MVC/knockout.mapping.js")" type="text/javascript"> </script>
<script src="@Url.Content("~/Areas/ApplicationShared/Scripts/MVC/jquery.unobtrusive-ajax.js")" type="text/javascript"> </script>
<script src="@Url.Content("~/Areas/ApplicationShared/Scripts/jquery.jqtransform.js")" type="text/javascript"> </script>
<script src="@Url.Content("~/Areas/ApplicationShared/Scripts/MVC/jquery.validate.js")" type="text/javascript"> </script>
<script src="@Url.Content("~/Areas/ApplicationShared/Scripts/MVC/jquery.validate.unobtrusive.js")" type="text/javascript"> </script>
<script src="@Url.Content("~/Areas/ApplicationShared/Scripts/MVC/specexpress.unobtrusive.js")" type="text/javascript"> </script>
<div id="actions-bar">
	@ViewBag.CurrentAction</div>
@Html.ValidationSummary()
<form class="jqtransform" id="editform" method="Post" data-bind="submit: addItem">
	<fieldset>
		<legend>Test</legend>
		<div class="rowElem sidegroup">
			@Html.LabelFor(m => m.Name)
			<input type="text" name="Name" id="Name" data-bind="value:Name" />
			@Html.ValidationMessageFor(m => m.Name)
		</div>
 
		<div class="rowElem">
			<label>
				Submit button:</label>
			<input type="submit" id="submit" name="submit" value="Submit" /></div>
	</fieldset>
</form>
@{ var serializer = JsonConvert.SerializeObject(Model);  }
 
<script type="text/javascript">
	
	$(function() {

	    var initialData = @Html.Raw(serializer) ;

	    var viewModel = ko.mapping.fromJS(initialData);
	    viewModel.addItem = function(  ) {
	        $.validator.unobtrusive.parse($('#editform'));
	        $.ajax({
	                type: "POST",
	                data: "{'User':" + ko.mapping.toJSON(this) + "}",

	                url: '@Url.Action("Edit", "User")',
	                datatype: "json",
	                contentType: "application/json; charset=utf-8",
	                cache: "false",
	                success: function(html) {
	                    alert(html);
	                }
	            });
	        return false;
	    };


	    ko.applyBindings(viewModel);


	    //find all form with class jqtransform and apply the plugin
	    $("form.jqtransform").jqTransform();
	    $("form.jqtransform").addClass("formfix");


	});
</script>

 

 

 

Coordinator
Oct 28, 2011 at 1:56 AM

I discovered some of the same issues today.  I also found an issue with client side validation of DateTime types.  I am working on repairing them and the fix will be included in the release with Silverlight compatablility.

Randy

Oct 28, 2011 at 8:48 AM

Deeply appreciate the response,

i am waiting eagerly, as my project depend on it for usability.

hope the release will come out soon, all the best for your great efforts.

Coordinator
Oct 30, 2011 at 6:17 PM

devmondo,

I just release the Silverlight updates to both nuget and codeplex.

Coordinator
Oct 31, 2011 at 12:43 PM

devmondo,

In order to get the clien side date comparable rules to work, I had to include one additional java script file called date.js that is really good at date parsing and other date operations.  If, after updating SpecExpress and including date.js on you page, if you still do not have client side validation working, its most likely an overlooked scenario that is causing the javascript to error.  Please use either FireBug or IE's developer tools to determine where in the specexpress.js file the issue lies and I can take a look into it.  Thanks!

Randy

Nov 1, 2011 at 3:22 PM

man i so much appreciate the efforts,

but sadly it is not working, and there are no errors either :( 

i have kept the above configuration and upgraded SpecExpress from nuget and added hte date.js refrence to the page but nothing is happening.

and again i have tried the normal ASP MVC Client validationa and it is working, so i dont think there is anything missing in my code specially that SPexExpress Serverside Validation is working too.

Coordinator
Nov 1, 2011 at 5:43 PM

Can you try using the HTML helper for the input? I.e. change:

<input type="text" name="Name" id="Name" data-bind="value:Name" />

to:

@Html.TextBoxFor(m => m.Name) 

Nov 2, 2011 at 8:36 AM

thanks man for the reply, 

i did what you suggested but it is not working 

i have tried both the following

	@Html.TextBoxFor(m=>m.Name)
 	@Html.TextBoxFor(m => m.Name, new Dictionary<string, object> { { "data-bind", "value: viewModel.Name" } })

 

do you think it has something to do with you Clientside submit handler ? as the above line 

   $.validator.unobtrusive.parse($('#editform'));

works with MVC Default Validation

Coordinator
Nov 2, 2011 at 1:49 PM

Possibly.  I have mocked up the same specification in the MVC 3 example and it works just fine.  However I did not implement the submit the same way you did.  What I would suggest is download the source from GitHub.  In the solution, there is an example MVC application.  Ensure it is working and then start changing it to match what your doing. 

I appriciate your feedback and hearing what you find.  We love hearing suggestions on how to improve the library. 

As for your contribution question: the best way for you to contribute to our project is give feedback and tell others.  We never intended to make any money on this project directly.  The experience is of much more value to us.

Nov 2, 2011 at 4:08 PM

i totally appreciate your answer,

but i am not good at javascript and i don't know how to customize the file, can you please tell me what is the command to fire SpecExpress validation manually? i think this would solve hte problem.

 

as for contribution, i already started telling my peers about it, and they are amazed and will start implementing it for sure, we just have to solve the client side, as Knockout is all hte way to go now adyas and it makes life so much easier :) 

Coordinator
Nov 2, 2011 at 7:17 PM

SpecExpress' client side rule functions are called by JQuery Validate plugin.  According to the plugin documentation (http://plugins.jquery.com/project/jqueryvalidate), you should simply be able to invoke the form validation by doing a $("#editform").validate();

Nov 2, 2011 at 8:14 PM

thanks again man,

i have tried the manual way but it is not working with SpecExpress, it is working fine with normal MVC Validation, i am usre there is something that is not kicking SpecExpress, client side, but sadly i am not Javascript Ninja :(

Coordinator
Nov 3, 2011 at 12:39 AM

I you would like to mock up a project or solution that demonstrates the issue, I would be glad to look at it.  If you have a dropbox or someplace I can pick it up at that would be perfect.

Randy

Nov 3, 2011 at 6:27 AM

Man,

after spending hte night on making all sort of tests, i have solved the issue :)  it is so stupid and simple, it is Jquery live  and SpecExpress.

 

what i mean is i am using Ajax to load the form view and though jquery is already loaded on the parent page specexpress and the form fields are dynamically loaded in the ajax process so, after i included jquery in the Ajax loaded form view, specexpress client side is working awesomely :) 

 

so my guess is that your specexpress.unobtrusive is not being registered with jquery if it loads dynamically, notice that this same problem does not exist with MVC default client side validation, so how do you think we can fix this ? because i cant load jquery twice, once on

parent page and second on ajax loaded formview, this means duplicated code and i need the Jquery on the parent page so i cant just included only in the ajax view

 

and again thanks alot for your paitance and kind words and support, this is truly one of he best time saving libs i have worked with.


Coordinator
Nov 3, 2011 at 12:47 PM

Sorry, it must be some how the page is rendered where the SpecExpress.Unobtrusive.js is inaccessable.  It seems that with web development, there is always so many ways to approach the solution that getting every piece to work with every approach is difficult.  My offer still stands.  If you would like me to look at it further, I would need a specific example project that I can use.  Otherwise, I am grasping at straws.

Randy

Nov 3, 2011 at 6:23 PM

Thanks man, for you paitance :)

i will try to set up a demo as soon as possible 

for the time being here is what i did as alternative to load jquery twice

 

in the ajax loaded form view i added the following lines and it worked

    var $form = $("#editform");
// Unbind existing validation
	    $form.unbind();
	    $form.data("validator"null);
// Check document for changes
	    $.validator.unobtrusive.parse(document);
// Re add validation with changes
	    $form.validate($form.data("unobtrusiveValidation").options);