The issue:
I have a single page with two email forms (one <form>, two divs inside this which look like forms to the user). When you submit either form, the C# behind looks at the values of the form and sends them in an email. This works well, and now I want a little validation, but I can't add required attributes to the inputs as the code doesn't know it's two separate "forms" and needs to handle the required attributes separately for each one.
I understand why this issue occurs, but I want to know if there's a way to tell the page to handle the required attributes in groups.
What I've tried: Both "forms" are handled by the code behind, and so need to be run server-side, so separate <form> elements wouldn't work. I have tried nesting the "forms" as <form> elements inside the server-side <form>, which separates the required attributes as desired, but seemingly breaks a number of things and I've read this is generally bad practice anyway.
What I'm not asking: To validate the form in the code behind.
Edit:
David's answer works great to validate groups of textboxes, which is what I needed.
To additionally validate a checkbox, I used javascript. onclientclick we can check if the checkbox is checked AND validate using Page_ClientValidate('validationgroup') and then return true, else return false. onclick is only fired when onclientclick returns true.
use one form with two submit buttons. Use validationgroup to distinguish
http://msdn.microsoft.com/en-us/library/ms227424(v=vs.100).aspx
if you write your own validation function for each submit button it should be possible
<input type='submit' onclick='return validateFirstButton()'/>
To validate checkboxes follow the instructions here:
http://codeclimber.net.nz/archive/2007/07/19/How-to-add-a-required-validator-to-a-CheckBoxList.aspx
Because this derives from BaseValidator you will be able to use groups. Hope this helps
Related
Is it necessary to write and place all controls inside
#using (Html.BeginForm())
{
// HTML Elements and HTML Helpers.
}
while using [Required] DataAnnotations ?
I am facing strange issue in MVC5 based application. The problem is that I have used one property named e.g "Credit" in model and the datatype of this property is integer and set[Required] DataAnnotations above that property.
But I haven't used Begin form. So in this case validation doesn't fire. whereas If I write BeginForm then validation works.
So, Is it necessary to place all html elements & html helpers inside BeginForm to validate controls ?
Thanks
-Nimesh.
If you want the client-side validation to work, then yes the form controls etc. need to be within a <form> tag (as generated by the HTML.BeginForm helper). Server-side validation would still work regardless of this.
Like the commenter above, I would question why you want to have controls outside a form tag in the first place. Even if you plan to submit the data back using Ajax, it's better semantic design to use a form tag, because it's clear which data items belong together, and it also makes it much easier to gather the data to submit via ajax (e.g. if you have jQuery, you can use $("#myForm").serialize() to automatically collect the values from all the controls within a form and pass that to the ajax request).
We need to validate something when we post some data to the server, right. And for posting some data to the server you will need form tag, whether you use BeginForm() or the <form> tag. You need tags inside the form those will be validated by the server.
I guess, this will give the answer to your question. Enjoy!
I'm trying to build a very specific search page for a project and I'm having lot of trouble dealing with multiple postbacks invoked by dynamically-generated controls on a single page.
The page has to work like this:
There is a single checkbox, "Detailed search", that causes a postback on checking/unchecking.
When detailed search is not active, a simple grid with contents and buttons is displayed. Nothing special.
When detailed search is active, N checkboxes must be generated from some dynamic data, that represent the sections where you want the search to happen. Below the checkboxes, an AJAX-enabled tab control will appear, initially with no tab pages.
When checking one of the section checkboxes, a postback will occur. After the postback, data will be searched in the section selected by the user, then a new tab page containing a grid view of results and the name of the section will be added to the tab control. If the checkbox is unchecked, the tab page will disappear from the control, again, after a postback.
Now, the issue is that pretty much everything has to be generated dynamically, and that pretty much everything is connected to something else.
First issue: dealing with the "Detailed search" checkbox. Sounds easy, doesn't it? My initial idea was to set Page.Viewstate["DetailedSearchEnabled"] to true or false during the check/uncheck event handler, then create controls dynamically checking the value of DetailedSearchEnabled during Page_Load.
Nope. The postback event-handling happens between Page_Load and Page_LoadComplete. It would take an additional refresh for things to work as intended.
<< Then I'll just generate the controls on Page_LoadComplete! >>
Nope. Those controls need event handling as well, and if they're generated after Page_Load they will not be wired up correctly.
A possible solution would be generating everything in advance, on Page_Load, and only hiding/showing controls on Page_LoadComplete. But that is inefficient, and one important point of this search page is that only the minimum amount of controls should be generated.
The difficulty of this task seems to come from the way event wiring and the page life cycle work.
Surely there must be a better way of approaching this problem.
First issue: dealing with the "Detailed search" check box.
The correct approach (if you want to use page post-backs) is as follows:
In the CheckChanged event handler, save the value of the Checked property to ViewState["DetailedSearchEnabled"]. If the value is true, add the dynamic check boxes to the page. If the value is false, find and remove them.
Override LoadViewState. After calling base.LoadViewState, re-create the dynamic check boxes and wire up their events if ViewState["DetailedSearchEnabled"] is true. Note that neither Page_Load nor Page_LoadComplete is the appropriate place to do this.
Yes, you should create the dynamic check boxes at two points in the page life cycle. I recommend a helper method.
In general, your event handlers should add or remove just the dynamic controls (if any) affected by those particular events, but LoadViewState should re-create all dynamic controls that existed from the previous page request. You must store enough information in view state for LoadViewState to do so.
My answer to this other question demonstrates how to add and remove dynamic controls. You may want to use it as a reference.
Sounds to me like you should be using a CheckBoxList control to handle your dynamic checkboxes. You can add an remove items to the CheckBoxList during your post back and not have to worry about dynamically adding/removing actual controls/events to the form.
Here is a link to the msdn:
https://msdn.microsoft.com/en-us/library/14atsyf5(v=vs.85).aspx
Here is some sample code:
Protected void Button1_Click (object sender, System.EventArgs e)
{
CheckBoxList.Items.Add(new ListItem("TextValue1", "Value1"));
CheckBoxList.Items.Add(new ListItem("TextValue2", "Value2"));
}
If all else fails, you could still fall back on the quick-and-dirty old-fashioned ASP way.
Use Response.Write or <%...%> to generate your dynamic controls as plain old HTML (simple form fields, e.g. <input type="checkbox" name="foo" value="1" />).
Make sure you have a form field for every piece of information you may need after the postback(s). If necessary, use hidden form fields to 're-post' values across subsequent postbacks.
After postback, retrieve the values of the controls with the Request object.
Use those values to adjust the generation of controls as you see fit.
You should be able to do all of this in Page_Load. The advantage is total freedom. The disadvantage is total freedom to make a big mess of your aspx. So you may want to migrate all this dirty code out of your aspx, and into a custom-made control, which you can then add to your aspx.
When generating your own HTML, be careful not to introduce XSS vulnerabilities. Use HtmlEncode where necessary.
As you suggested yourself, there is a better way to tackle it.
If I was in the same situation, I would create web methods for interacting with the page, and use client side to do the UI. I'm currently working mostly with angular JS, although it does come with a learning curve. You could use ng-hide/ng-show to bind to the checkbox event to display the detailed search. When the n number of checkboxes needs to be displayed, you can then just fill them in with ng-repeat, for each of the items you need to display, after a check/uncheck you can dynamically populate new controls etc. through web method calls if extra data is needed.
Pure ASP postbacks are quite clunky from my experience, and not really suited for building a maintainable dynamic UI.
Instead of making so many postbacks, it would be better to use jquery and ajax calls to load the controls as needed and then attach events to it or you can even use UpdatePnael for that. Help Links:
https://www.simple-talk.com/dotnet/asp.net/ajax-basics-with-jquery-in-asp.net/
http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/
I have a set of controls which take inputs, some of them require validation.
However, a few controls at the bottom of this form, don't actually have anything to do with form itself but still do postback, which requires the form to be validated. This is a hinderence.
I want to be able to trigger a function to update the form view with out having to fill in any information yet.
Stuff like, if i want to add multiple products to a page from a dropdown list but do not want to cause the form to post back, how do I do that?
You have several options, but your question is not yet clear. What controls should not cause postbacks?
Most controls have a AutoPostback property which you can set to false(although this is default for the most)
Another option is to use HTML controls instead which don't post back to the server
You can also set CausesValidation to false
You could use ValidationGroups to prevent validation for different controls
u can simply use HTML contols like this one
<input type="Button">value</input>
this wont post back
You can use ajax library control to prevents auto post back. In ajax library there is one control **Update panel you put your some controls only which require post back and other which have not you put out side update panel...
My plan is to create a a two-pane page using ASP MVC 3. The left pane should be a small filter pane and the right the main content, showing a list of objects (say products).
Initially all products will be shown since no filter is applied. When selecting "only red", only red products are shown in the list. When further selecting a price range, only products in that price range will be shown.
Functionally the plan is to implement the filtering pane as a treeview with checkboxes (to be able to drill down to more and more specific filtering options), graphically it will probably be enhanced in some way to improve usability.
What is the best way to implement the coupling between the filter pane and the main list? Everything should work server side, but should of course use javascript (jQuery) when possible for direct feedback.
The simplest way is probably to make it closely coupled solution, calling a specific Asp MVC action using a custom-built javascript (with fallback to a form post). Doable enough, sure, but how to make the solution reusable? Also it would be nice to not loose all filtering data when navigating forward and back, i suppose GET arguments is the only decent way to do that?
Are there any best practices, any guidelines or anything to base this on to make a nice modular structure for filtering.
Victor, I recently had to solved this same problem. I'm not promising it's the best way but it's pretty clear and should even work well in case JavaScript is disabled (who even does that anymore?).
Create a that calls the action with all the field-selectable search options like "only red".
To that same form, add empty, hidden value for the things not directly as fields (paging, sorting...)
Setup your form with the excellent and very easy to use JQuery.Forms (http://www.malsup.com/jquery/form/) to make you form submit via JQuery (all your form values will be passed as JSON on form submit).
Make your back/next/paging/sorting links pass their individual values via query (no-JS fallback) and use JQuery to capture their click events. The JQuery click events on those links should assign the value of the value passed by the link (page number, sort column name...) to the corresponding hidden field in the form and call submit (with thanks to Jquery.Forms will submit via AJAX).
When you configure JQuery.Forms, you can define a callback method. In the callback method take the result (the HTML returned by your action that should contained your filtered+sorted+paged result) and replace the document (or DIV if you used a partial action + view) with that.
The result is a JQuery solution that works when JS is off. You also have very minimal JS code to write other than wiring the event handlers.
I'm not sure if it will be helpful but in MVC 3 you have access to a property called IsAjax from the view so you can do specific things to server a slightly different view when called from AJAX.
Cheers
I have an asp.net form with bunch of sections that can be expanded/collapsed and are normally collapsed. Now, most controls on the form have RequiredFieldValidator or some other validators attached. If the user tries to submit the form with required fields not filled out, for m is not submitted but because most sections are normally collapsed, the user doesn't see the validator text (like exclamation mark on the right of a text box) prompting to fix the error.
What I want to do is for the controls that fail validation, to expand their parent containers so user could see those failed controls, but for that I need to hook up some client sode javascript that woudl execute when client side validation failed. I haven't foudn any way of doing it - validators naturally dont' expose those "validation events" to hookup to. Of course I can create my custom validators but that would mean rewriting (and duplicating functionality) completely all existing asp.net validators which sounds a big chunk of work.
Any ideas?
Thank you in advance!
Andrey
Here is how I solved a similar issue. For every validator that is added to the accordion, I store the validator id in an array, along with the accordion panel that it is contained in. I then pass this list to the client. I also hook into the OnSubmit event by calling Page.ClientScript.RegisterOnSubmitStatement. The javascript function that executes during the onSubmit first checks to see if the page is valid, if so then it just exits, if not then it loops through the list of validators looking for ones that are not valid, when it finds one, it expands the section associated with that validator.