basically, im calling Html.TextAreaFor to display a form, which is great/not a problem...
people enter text in it, and it gets submitted, and if it is successful, i want to return an empty Html.TextAreaFor... but after it's submitted, in the action method i am clear to set the Comment that people are making in the TextArea to an empty string "", however, when it's loaded, it always has the text from the previous load.
i am loading everything in ajax by just updating a Div... and to make sure everything is normal, i have (as a text) a normal Html.TextArea where i specify the name and value. the Html.TextArea is right under the Html.TextAreaFor and acts exactly as it should, but the Html.TextAreaFor for some reason is not!
this is strange because i am reloading the entire DIV which the form is contained in, from a PartialView, at evey submission!!
im also making sure the div is loading with a typical system.datetime.now string returned with everything, and the mentioned Html.TextArea working as it should, it's driving me insane... am i missing something guys? are there any perculiar properties about ...For's that i should be aware of?
Try clearing the ModelState object, which is the HTML helpers read the value from.
Also see What am I misunderstanding about how Html.TextBoxFor works?.
Related
Using MVC2 I have an AJAX form which is posting to a bound model. The ActionResult is returned as Content and is inserted into an element on the page by the magic of AJAX forms. All is well.
Now I need a button that will print the returned Content. I've tried returning the result wrapped in a full HTML doc with javascript along the lines of window.print(), but of course this won't execute and even if it did I don't want the whole window.
What is the best way to have my ContentResult printed instead of updated in an element?
I've used jqPrint for this same scenario. It basically either copies the content into an iframe and calls print() on that.
I tried using jqPrint which works for the most part but it was causing problems in IE, I was printing a model dialog.
I ended up using a print style sheet:
http://www.webcredible.co.uk/user-friendly-resources/css/print-stylesheet.shtml
I basically hided all the content of the page except for my dialog, div or whatever it is you are trying to hide.
This was the solution with the most consistent results across browsers.
I have a form built using ASP.NET MVC and the form data is being shown with controls like so:
<%: Html.TextBoxFor(model => model.thisJob.postcodeto)%>
<%: Html.ValidationMessageFor(model => model.thisJob.postcodeto)%>
So far so good. However I have just written some backend processing of the submitted information to remove training spaces:
ie " postcode" becomes "postcode".
These changes are written to the returned ViewModel. I want this change to appear when the form reloads with relevant error messages.
When I debug and check the ViewModel the spaces have been removed however when the page returns the original un-cleaned input is there. It seems that the display controls read the information from the ModelState rather than the object passed into the View.
I have tried finding the values in the ModelState and updating them with the cleaned values but [set] seems to be disallowed.
What I am trying to do seems pretty standard.
Any pointers / ideas / bits of code will be gratefully received.
This is a known behaviour because the ModelState contains all the errors and values that need to go back. You can use ModelState.Clear() and then add your own errors, or just try modifying relevant ModelState values.
(Update)
Really, in the heart of MVC, we are not supposed to make modifications to the Model while we are sending it back to the form - only when saving back to database.
I do not think it is wise to trim the spaces since you end up loosing the benefits of default model binder and then having to work around it. So you are trying to solve a problem - which I believe - does not exist.
Before starting, I do have a very particular question and if you want to answer it go straight to the end. But I do welcome comments and advices hence the lengthy post.
OK, we deal with a lot of forms and some of these forms are quite lengthy and have many fields. We also have a requirement - in addition to top level fields - to be able to have variable number of repating rows - as we call them. For example, let's think of a customer which has name, surname and age while it can have zero or many addresses (say 0 to 10) so the user must be able to add or remove contacts from the form while filling it in. So typically user gets and "Add" button to add more addresses and next to each address, a delete button. Potentially there could be more than one repeating section in the same form but I am not going there. The point is, because of legal and historical reasons, all the forms must be saved at once so while the forms can be edited, we cannot accept a half-filled form and have another page for users to add and remove addresses, e.g.
I am using ASP NET MVC 2 (strongly typed views with a single generic controller) with client side validation and heavy jquery scripting for flashy features. We are probably going to migrate to ASP NET MVC 3 very soon and I am already playing with 3 for finding a good solution. These addresses are defined on the Model as List<Address>, e.g.
I currently have a working solution for this issue but I am not satisfied with it: I have an HTML Helper that names the add or delete buttons and a bit of JavaScript to disable validation and allow the form to be posted back (even invalid) and since I can find out the name of the button that was clicked, I have all the necessary logic to handle add or delete and works really well.
But I am posting back and the form is reloaded and I am looking for an aletrnative solution. Here are what I can do:
Do everything in the client side. "Add" button will clone one of such addresses and "Delete" button will remove() the element. I only have to rename the indexes which I have done. We were using jquery calendar and it was breaking on the new elements which I have also fixed. But the validation is not working which can probably work with ASP NET MVC but this solution looks like a very brittle one - a house of card which looks great before you add another card.
Post the whole page usin Ajax and then load it back again: This is probably better than my current solution but only slightly.
Use ajax to post the form and get back JSON and use the data to build the elements or remove them: Again a house of card because of extensive client side scripting
Serialize the form and post using Ajax to a particular action and get back only the repating section (as a partial view). The action on the controller can be reused and called from the view itself to return the partial view
OK last one is the one I am working on but there is an issue. ASP NET MVC 3 with unobtrusive validation works only if the form is engulfed in a BeginForm() while my top level view has a BeginForm() but not my partial view. It works well when I call it from the view but not on the ajax call to get just the repeating section.
(Question)
So is there a way to tell ASP NET MVC 3 to spit out validation data atttributes regardless being in a BeginForm() block?? To be honest if this is not a bug, this is definitely an important feature request. I have in fact used reflector to disassemble the code and the condition seems to be there.
Short Answer:
Add this to the partial view:
if (ViewContext.FormContext == null)
{
ViewContext.FormContext = new FormContext();
}
I don't think it is possible using the default unobtrusive libraries supplied. If you look at jquery.validate.js and jquery.validate.unobtrusive.js it looks like it only validates what is inside the form.
There's a few posts about it if Googled and a few work arounds.
I had a similar issue (although much simpler) where I had a validation summary at the top of the page and multiple forms but the unobtrusive javascript would only populate the view summary if its inside the form (jquery.validate.unobtrusive.js line 39 if interested...).
I'm not sure if the validation library is extendible but most things in jquery are so that might be an option if you want to go down that road.
As far a possible solution to your problem I'll put in my 2 cents for whats its worth.
You could have two actions that are posted to. The first action is you post your model with no js validation and all validation is handled in the code - this will catch all user with javascript turned off.
Your second action is you serialized the model. In mvc 3 using the Ajax.BeginForm has an AjaxOption for Url where you can specify an action for the jquery to call (where it serializes the form form you and you can decorate your action with your strongly typed model). Here you can check the model and return a json result and handle this in the javascript.
I've got an MVC app that gives the user textarea's to update some description fields. It's strongly-typed to a table object, and the fields are wrapped in a form with a Submit button.
Occaisionally they don't want any data in a field, but when they delete the text and try to save, the blanked-out field comes back with its original text (i.e. the table object passed to the Save action contains other edits, but attempts to blank out fields result in the original text staying in the field).
I'm assuming this is LINQ trying to determine which fields have been edited, but how do you tell it that it's blank on purpose?
UPDATE: It appears this may be a problem with the TinyMCE jQuery plugin. It adds rich-text functionality to textarea controls. If I turn it off, I can remove text with no problems.
UPDATE 2: It seems to be some kind of javascript bug or something. If I put another dummy field after the problem fields, they work. If I move them to another place in my code, they work. They just don't want to work where they are. Very peculiar.
I'm pretty sure that TinyMCE, by default, puts in <p></p> when the control is emptied.
So if you are checking for "" then you may be disapointed.
This initially caused me some issues but never with saving. I was checking if the field was "" and then doing something else. Once I realised that "" was never going to happen, I adapted my validation accordingly.
I just check that on a recent project using TinyMCE editor, but it indeed send "" for an empty input, and during the implementation we had no issues with that.
alt text http://diarioplus.com/files/pictures/tiny.PNG
The body property is the one with a tinyMCE editor on the client side.
I really think it will be something with the modelBinder or the way you set the values back to the model.
I am trying to trace through why my ASP.NET MVC 2 validation isn't working, but I cant find enough about HOW it works to be able to do this.
I have followed the steps in this useful article by David Hayden which seems to be the best documentation currently out there, but nothing actually happens.
I get validation when i submit to the server (as I did since Preview 1 when i added data annotations to my model) but I'm not getting any client side validation.
How can i trace through to test? So far I have verified the following obvious things
MicrosoftMvcJQueryValidation.js and jquery.validate.min.js files are being downloaded
Html.ClientValidationEnabled = true
I cant see easily what is hooking up to which events to know quite how to debug it.
Here's what I've learnt:
MOST IMPORTANT
Your HTML Form must be created with the using directive, not just BeginForm and EndForm.
You must set Html.ClientValidationEnabled = true BEFORE you start your 'Form'
You must use Html.ValidationMessage for each field
You must set Html.ClientValidationEnabled = true on each partial control (ascx)
HOW IT WORKS (very simple overview)
When you do Html.BeginForm it creates a 'FormContext' in the ViewContext
When ValidationMessage helpers are used, metadata is put into the form context
When the form is disposed (by the using statement) it writes out all the validation code
MISC
I cannot seem to get validation working when I have a partial control, if that control uses a different model from the view that defines the Form.
You do NOT need to use Html.TextBoxFor or Html.ValidationMessageFor, you can use Html.TextBox and Html.ValidationMessage
In order for a field to be validated client-side you have to specify a call to Html.ValidationMessage/Html.ValidationMessageFor<> for the field (just like David did in the tutorial you linked) within the view. This is essentially a trigger to the client-side validation logic that you want to run validation for that field.
If there are situations where you don't actually want a validation message to visually appear for each field (i.e. by using Html.ValidationMessage), but would rather allow a summary to be the sole source of validation error messages (i.e. by using Html.ValidationSummary), you still need some way to "trigger" the validation to occur for the specific fields you want it to. This can be achieved by using the Html.Validate/Html.ValidateFor<> methods within your view. Those helpers won't render anything, but will simply register the specified field for client-side validation.
Both of those requirements exist since you might not want the client-side validation to automatically validate every property on your model object, since some of them might not even be part of the form that you're wanting validated.