I'm creating this form (.net) where i have a select with a postback, that will trigger a action depending on which option i select. I'm trying to use the jQuery Validate Plugin (plugin website) to validate my form.
My problem is, when i validate the form, and my select is marked as invalid, the validation plugin overwrite it's onChange method to make it unmark when i change the value, the thing is that it's deleting my __dopostback from the onchange, making the form 'useless'.
Is there a way to the plugin validate my selects without deleting my postback action from the onchange?
I know this is an old post, but I had a similar situation and was able to resolve it like this. Just thought I'd post it just in case someone else found there way here. I'm using jQuery Validation Plugin 1.9.0:
$('#aspnetForm').validate({
errorLabelContainer: "#messageBox",
wrapper: "li"
});
$("input[id$='myButton']").click(function () {
SetRules();
if ($('#aspnetForm').valid()) {
// form passed validation
} else {
$('#aspnetForm').resetForm();
return false;
}
});
function SetRules(){
$("select[id$='myDropDown']").rules("remove");
$("select[id$='myDropDown']").rules("add", {required:true});
}
My validator is set up so errors display together in one designated div. When I click the button, the validation fires and displays all the elements in that div and marks the fields that are invalid, including the select (all choices are red), and when I change the selection my autopostback fires and the colors of the select change back to their old value (assuming the choice passed the validation).
I am pretty new at this plugin, so I can't explain it too well but my thought process was to try and get the form to validate and show the errors, and then reset the controls back to their original state while still keeping the error messages visible. I was expecting to lose the red error highlighting, but somehow that retained while also bringing back the select's postback.
Also, I do not know if setting the rules in this manner contributed to this working or not; I had to set them like this for various reasons, the biggest one due to needing the selector for .NET's automatically generated IDs.
Related
Working on MVC5 web app.
I have a view based on a complex viewmodel. In the main GET method I'm filling this viewmodel, setting certain ViewBag items, etc.... I'll refer to this as the "load code" for now.
So, my view is basically a data entry form. Business rules are fairly complex. When the user hits the save button I do a POST and run some c# code which checks rules, etc... If it FAILS, I simply want to "abort" the action and show the user the same GET view.
My question involves all that was done to initially load the view: The ViewBag code, filling of viewmodel, etc.... Do I have to write this "load code" again in my POST? This seems very redundant. Is there a way I can just "abort" the ActionResult/POST and show the GET view?
I hope this makes sense. Thanks!
**** update/clarification - based on comments ****
I suppose this question is more of a "general" one. Can you "abort" the POST and go "back" to the GET View without re-running all the "load code" (for the dropdowns, populating the viewmodel, etc....)
If you want to go to server and validate and then decide if you want to accept the POST or Fails/Abort and keep the previous page with all the values
then I'll suggest you to handle this in AJAX.
Create a third action/API Method and keep your validation logic there. then on the form submit hit the validation action using ajax and server will return True/False (with any error message) if you get True from server then let the javascript post your form otherwise show any error message and return false to stop posting the form and stay on the page.
For example use a javascript method to validate.
<form onsubmit="return isValidForm()" />
function
function isValidForm(){
//// hit the server and see if you want to proceed with the POST
//// if fails return false so your form will not be posted and all of your values will remains the same, here before return false you can clear the form if needed.
}
let me know if you need more information.
Lightswitch HTML Client
After a query has been executed, I'm curious how to perform changes on the client immediately after. For example, i have a search box (textbox) that takes the input and passes it along to a parameterized query. On the client, i would like to set the focus back to the search box after the query has finished. I have working java script code to set the foucs, i just don't know when and where to use it. I need something like the server methods _Executed and _Executing but on the client. Is this possible?
I don't think you'll know when the query has completed, since it's done asynchronously, and by default only loads a portion of the results. Have you tried putting the javascript to set the focus in the postRender of the control associated with the search box? You can find it in the designer for the screen by selecting the control, and selecting the drop down next to Write Code.
Don't forget to use the setTimeout method to ensure the element is properly rendered before your javascript is applied. For a proper explanation refer to Why is setTimeout(fn, 0) sometimes useful?.
I used the following and it shifted focus to the button:
myapp.BrowseMyEntity.MyButton_postRender = function (element, contentItem) {
setTimeout(function () {
element.focus();
}, 0);
};
If you really want to set focus after you've deliberately called a query and it has completed, use the promise mechanism ".then(...)", for example:
screen.details.dataWorkspace.ApplicationData.MyQuery().execute().then(function (result) {
// Do whatever you want here
}
});
EDIT
Figured it out.. $.ajaxSetup({ cache: false }); wasn't working because i had data-ajax set to turned off on the form and therefore i wasn't able to set no cache ajax on it.. just for completeness if anybody knows how to get this done WHILE dada-ajax is set to false then please post so here
Something else that I just tried and it worked was to simply add data-ajax="false" to any link that you want a page refresh on. Meaning that if I have data-ajax="false" on a link it will always refresh the page before showing it!
For example the link I had a problem with was
Add a new weekly update
and the problem was that for some reason that page was caching and always showing the cached page.. So one of the easy fixes was to add data-ajax="false" to it and that forced a reload of the page everytime
Add a new weekly update
````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````
Question:
I have a options menu which brings up a form which also has a cancel and submit button.
Once the form is submitted there is certain validation that runs and if something is missing it returns to the form with some validation text.
Now if I click the cancel button at anytime i should be brought back to the options menu and if I click on the same button that brings up the form i should see a brand new clean form and this works fine if I do it before the validation.
The problem is that if I submit a non valid form which returns with the error validation messages and THEN press cancel it seems that the page becomes cached or something similar because from that point on anytime I click on the form options menu button the same form shows up each with the validation errors and data. I put a break point in the method that returns the form View() and they are never hit so for some reason it skips the entire method which creates a new form and somehow just shows the old page.
The cancel button is the following
Cancel
Does anybody know what is happening? is it being cached somehow when it returns to the same page with the validation errors??
** EDIT **
I Tried adding [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")] in front of the controller by to no avail..
I also now added
$.ajaxSetup({ cache: false });
to the top of my $(document).ready(function () but that also does not seem to be doing anything, do I just put it there or do I have to call it somehow?
I checked System.Web.HttpContext.Current.Cache and the page doesn't show up there.
Have you tried setting the output cache options on the controller action like
[OutputCache(Duration=600,VaryByParam="id")]
You might also want to try making sure jquery is not caching the request as well. You can globally turn off jquery ajax caching using the information here: How to set cache: false in jQuery.get call
You can try using $.mobile.changePage() to transition to the page, it allows you to set some options, one of which is reloadPage.
reloadPage (boolean, default: false) Forces a reload of a page, even if it is already in the DOM of the page container. Used only when
the 'to' argument of changePage() is a URL.
Source: http://jquerymobile.com/demos/1.1.1/docs/api/methods.html
You could work this into your link with something like:
<script>
function changeMyPage(url) {
$.mobile.changePage(url, { reloadPage : true });
}
</script>
Cancel
jquery Mobile pulls multiple pseudo-pages into the DOM at one time and normally deletes (.removes()) a pseudo-page after you've navigated away from it. It however sounds like that's not happening so you may need to use my above code (or something similar) to force a refresh of the page.
You need to clear your ModelState before hand.
This should work:
if (ModelState.IsValid)
{
//saving
if (result > 0)
{
**ModelState.Clear();**
return View(new CategoryViewModel());
}
}
How to Clear model after submit the data in database in MVC3
In my current asp.net-mvc project one of my pages allows the user to select a value in a dropdown box after wich a post request is made that updates several values.
To make sure the delay from the postback doesn't confuse the user into selecting another value (and thus creating another post, creating another delay etc) I set the select's disabled attribute to true.
Disabled inputs aren't submitted to the post call however.
How can I make it visually clear to the user that work is in progress and make it imposible to select a new value without removing the input from the post?
Yes, this annoys me too.
Basically what you need to do is hide the old button and replace it with a disabled one so it looks the same to the user. That way it's still submitted but can't be doubly submitted.
Actually I've found what seems to be a duplicate of this at Problem with disabling submit buttons on form submit.
From your answer, I gather you are already using jQuery. In that case why don't you get the value of the select box, disable it, then post the value yourself?
Bonus : BlockUI is a nice jQuery plugin to, well, block the UI.
None of the answers I found in Cletus' post was entirely what I was looking for.
Here is what I came up with. It's not 100% reusable, but it does what I need and feel free to improve/edit.
$('#productMixSelectorForm').change(function() { $(this).ChangeSelection() });
jQuery.fn.ChangeSelection = function() {
var html = $('<div class="hidden">');
$(this).find('select, input').each(function() {
if ($(this).hasClass('hidden') == false) {
//Clone the original one into the hidden div
html.append($(this).clone());
//Disable the original (visible) one and make it's name unique again
$(this).attr("disabled", true);
var name = $(this).attr("name");
$(this).attr("name", name + "disabledDummy");
}
});
//Add the collection of clones to the form so they get submitted
$(this).append(html);
$(this).submit();
}
I have a menu usercontrol called LeftMenu that has a bulletedlist of linkitems. It's on the ascx page as such:
<asp:BulletedList ID="PublisherList" DisplayMode="LinkButton" OnClick="PublisherList_Click" cssClass="Menu" runat="server"></asp:BulletedList>
I databind the list in the page_load under if(!isPostBack)
I'm having an issue on a page that loads the control. When the page first loads, the event handler fires. However, when the page posts back it no longer fires and in IE8, when I'm debugging, I get "Microsoft JScript runtime error: Object expected" in Visual Studio pointing at "__doPostBack('LeftMenu$PublisherList','0')." In FF I don't get the error, but nothing happens. I'm not loading the control dynamically, it's loaded on the aspx page using:
<%# Register TagPrefix="Standards" TagName="LeftMenu" Src="LeftMenu.ascx" %>
<Standards:LeftMenu ID="LeftMenu" runat="server"/>
Any ideas of where I'm losing the event handler?
I just realized this is happening on another user control I have as well. A text box and a button and I'm using the default button to make sure pressing the enter key uses that button. .Net converts that in the html to:
<div id="SearchBarInclude_SearchBar" onkeypress="javascript:return WebForm_FireDefaultButton(event, 'SearchBarInclude_QuickSearchButton')">
so as soon as i enter a key in the box I get a javascript error at the line saying "object expected." It seems like the two issues are related.
Edit Again: I think I need to clarify. It's not that I'm clicking on the menu item and it can't find the selected item on postback. I have this search page with the left navigation on it and then the main content of the page is something that causes a postback. Everything is fine with this postback. Once that page has been posted back, now if I click on the bulleted list in the left navigation I get a javascript error and it fails. The page_init for the LeftMenu control is never called.
It sounds like you might be losing the click because you are not DataBinding the list on PostBack. Therefore, the post back is trying to refer to a control (a specific bulleted list item) that does not exist.
You should try binding the list again on PostBack just to see if that fixes your issue. BUT, what should REALLY happen is that the LeftMenu and the BulletedList should store their information into ViewState so that you can ensure that the data that was shown to the user on their initial page load is the same data that the PostBack is processing and working with.
If you have EnableViewState=true for your UserControl and all controls within it, everything should work fine. With ViewState enabled, ASP will reinflate your controls from ViewState after Init has fired. This means that the postback event arg (which points to an index in your control list) will still find the control in that list position. Otherwise the list is empty on postback.
However, ViewState is the work of the devil and was designed simply to foster the illusion that you are working in a stateful environment. It is okay to use it for small amounts of data but typically not advisable for templated controls like repeaters and lists because you have no idea how much data is going to be created in ViewState.
If you are dealing with static, or relatively static data, store it in the application cache and rebind your lists in Page.Init every time (note that it has to be in Init because post-init is when ASP rebinds from ViewState; if you get in there first, your data will be used instead).
If you are dealing with volatile data, you have a problem because the data you rebind must be exactly the same as the original page request, otherwise the postback events will be firing against the wrong rows. In that case you need to either store your initial data in Session or you simply store the list of rows ids (in a hidden variable or Session) and you recreate the data to bind against from the ids each time.
An even better solution is to not use postback events at all. Try to turn all your events into GETs that have an ID on the query string. You can still create the list using binding the first time through the page (as you are currently doing), and you can even GET the same page with a new ID.
If you need to keep state on the same page but need to respond to the user changing a radio button selection (or something else), think about using Ajax calls to update the screen. You also do that with an ID that you pass to the Ajax call.
In general, the more you move from using stateful ASP, the lighter and more responsive your pages will become. You will also be in a better position to move to stateless MVC if necessary. You will also save lots of time lost to debugging obscure problems because ViewState is not available when you need it to be.
The best analysis of ViewState I've read is in the link below. If you fully understand how it works, you can continue to use it without necessarily incurring the costs.
http://weblogs.asp.net/infinitiesloop/archive/2006/08/03/truly-understanding-viewstate.aspx
It's possible that this might be javascript related, and that a script that is loading earlier in the page is throwing an error and causing the page to not be loaded properly.
Are your usercontrols loading any javascript onto the page? Can you check for javascript errors on the initial load of the page?
I moved the code into an existing project we have and for some strange reason, I stopped getting the javascript errors and instead got:
"Invalid postback or callback argument. Event validation is enabled using <pages enableEventValidation="true"/> in configuration or <%# Page EnableEventValidation="true" %> in a page.
For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them. If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation."
I haven't quite figured out where I'm supposed to put the register event validation with a user control, but in the mean time I just set enableeventvalidation=false and it seems to work now.
It looks like the doPostBack function is missing since its arguments are literals so they couldn't be the cause. Is that one of your own functions or did you mean to call the ASP __doPostBack function?
Have a look at the Firefox error console or allow script debugging in IE and see exactly what object can't be found. Even better, download Firebug and debug it.
I had a similar issue. It turned out that Akamai was modifying the user-agent string because an setting was being applied that was not needed.
This meant that some .NET controls did not render __doPostBack code properly. This issue has been blogged here.