I have a web service that validates some form data. The service is a ScriptService, and I am calling it from the client. I need to display a modal popup if the validation fails. If the user clicks "OK" on the modal popup, then I want to post back and save my data. "Cancel" should allow them to close the modal popup and let the user correct data, allowing one to resubmit. Currently, the modal popup displays every time regardless of the result of the validation.
I tried calling hide() and returning false, but neither worked.
I tried approaching this problem from a different perspective by assigning the TargetControlID property of the modalpopupextender to a hidden button and then calling show() on the modal popup if validation failed, but this did not cancel the postback. The modalpopup displays for approximately one second and the page posts back.
So you want to do something like:
function ValidateInput() {
MyScriptService.ValidateInput({however you are passing form data}, OnValidateComplete);
}
function OnValidateComplete(response) {
if ({response is bad}) {
$find('<%= ModalPopupExtender.ClientID %>').show();
}
}
You can then keep your TargetControlID, OnOkScript, etc. all the same. Perhaps with some code we can actually see what you are doing.
Related
I have a form page that opens a dialog in order to enter new information. I open the dialog in the "standard" jQM way:
Open dialog
What I need to do is pass back some of the values that were entered so that I can update the page with those values. How do I do that?
As an added bonus, I also really need to be able to submit the values. It seems like jQuery Mobile is setup close the page on any link click. This is an ASP.NET application, and so I need for the page to last long enough to hit the Button_Click() event in the code behind.
Here's the pieces you need:
Html in the dialog:
Cancel
Submit
In pagecreate:
$("#btnSave", pagediv).live('click', function () {
var s = page.Model;
s.serverName = $("#txtName", pagediv).val();
s.Save(function () {
$('.ui-dialog').dialog('close');
});
});
s.Save is a function that writes to the datastore, updates a global model object that is accessible to all pages, then calls the callback function.
In the pageshow handler for the parent page, update the controls from the model. You can't update the parent page directly from the dialog as the parent page may not exist at that point - if data-dom-cache isn't set, it will be removed as soon as the dialog is displayed and will not be recreated until you call close.
I have a composite User control for entering dates:
The CustomValidator will include server sided validation code. I would like the error message to be cleared via client sided script if the user alters teh date value in any way. To do this, I included the following code to hook up the two drop downs and the year text box to the validation control:
<script type="text/javascript">
ValidatorHookupControlID("<%= ddlMonth.ClientID%>", document.getElementById("<%= CustomValidator1.ClientID%>"));
ValidatorHookupControlID("<%= ddlDate.ClientID%>", document.getElementById("<%= CustomValidator1.ClientID%>"));
ValidatorHookupControlID("<%= txtYear.ClientID%>", document.getElementById("<%= CustomValidator1.ClientID%>"));
</script>
However, I would also like the Validation error to be cleared when the user clicks the clear button. When the user clicks the Clear button, the other 3 controls are reset. To avoid a Post back, the Clear button is a regular HTML button with an OnClick event that resets the 3 controls. Unfortunately, the ValidatorHookupControlID method does not seem to work on HTML controls, so I thought to change the HTML Button to an ASP button and to Hookup to that control instead. However, I cannot seem to eliminate the Postback functionality associated by default with the ASP button control. I tried to set the UseSubmitBehavior to False, but it still submits. I tried to return false in my btnClear_OnClick client code, but the code sent to the browser included a DoPostback call after my call.
btnClear.Attributes.Add("onClick", "btnClear_OnClick();")
Instead of adding OnClick code, I tried overwriting it, but the DoPostBack code was still included in the final code that was sent to the browser.
What do I have to do to get the Clear button to clear the CustomValidator error when clicked and avoid a postback?
btnClear.Attributes.Item("onClick") = "btnClear_OnClick();"
Try adding a return false; at the end of your onClick call. That should prevent the default behavior (in this case submit).
btnClear.Attributes.Add("onClick", "btnClear_OnClick(); return false;")
Are you wanting to clear the error message on the client side if they fix the error without having to click on anything right?
I did something like this if I have your issue right but calling a revalidation function that called some client side javascript code and then hides the span that the error message is in if they fixed the issue.
See my blog article and let me know if this is what you are wanting to solve. The part you want to read is towards the bottom.
http://coding.infoconex.com/post/ASPNET-CustomValidator-that-validates-multiple-controls-using-both-Server-Side-and-Client-Side-scripting.aspx
I need to pop up a jquery dialog as confirmation before a submit happens. I don't want the dialog to always pop up, that depends upon the setting of a dropdown.
The submitting control (which I can't change by the way) is a custom control with a save and a cancel button and handlers for the save and cancel buttons.
So when the user has selected a particular item from the drop down I hook up the click event (on the clientside) of the save button (that has been rendered by the custom control) to a js function using jQuery, that calls my showDialog() function and then returns false (to prevent the postback).
I now need, when the user clicks the yes button on the dialog, to call __doPostBack to get the SaveButtons serverside events to fire and to get the serverrside validation to run.
I've got
eval($("#<%= hdnBtnPostback.ClientID %>").val());
in the handler for the Yes button on the dialog.
The hdnPostBack field contains the result of:
Page.ClientScript.GetPostBackEventReference(mySaveCancelCustomControl, String.Empty)
Unsuprisingly this isn't working. The mySaveCancelCustomControl is the custom control mentioned above and it has two buttons that are rendered with two event handlers so the GetPostBackEventReference is doomed to fail.
Any ideas what I should do?
You can make the button a dialog button and put a asp.net button on the page with the ID of HiddenButton and wrap it in a div with a style of display:none; so the button is not visible. (Must not be Visible="false" so the button is rendered)
In the dialog javascript add a button that has the effect of clicking the hidden button
jQuery("#dialog").dialog({
buttons: {
'ButtonText': function() {
__doPostBack('<%# HiddenButton.ClientID %>', '')
jQuery(this).dialog('close');
}
}
});
and add a asp click handler to the hidden button
<div style="display:none;">
<asp:Button ID="HiddenButton" OnClick="HiddenButton_Click" ></Button>
<div>
Click event (HiddenButton_Click) on the serverside will fire when the dialog button is clicked
Hope this helps I use this pattern all the time
ps If ClientID does not work in the __doPostback() call user UniqueID I cant remember which it is.
When you are wiring up your new click on the client side, could you save the current click method into a temporary variable and then call the temporary variable from your Yes button?
Now I could be going about this the wrong way so if there is a better solution please post that as well. What I am trying to do is disable a button once it is clicked to prevent double clicks. In the past I have done my just disabling the button onclick but with webforms I am running into a little bit of a snag because there is validation on the page so I need that to fire and I need to post back.
So I have the following JQuery function to make a button disable itself on click. Here is the JQuery:
jQuery.fn.disableOnClick =
function()
{
return this.each(function()
{
$(this).click(function()
{
$(this).attr('disabled', 'disabled');
return true;
})
})
};
Intended usage would be:
$(document).ready(function()
{
$("#<%= btnSomeButton.ClientID %>").disableOnClick ();
});
This doesn't work... the button always disables, the validation is ignored and the postback doesn't even happen. I would assume because I am overwrittin the click handler. Suggestions?
UPDATE: I have tried just a basic function that is connected to the 'OnClientClick' of the button to do:
// In my Page_Load
btnSomeButton.OnClientClick = "return DisableButton('" + btnSomeButton.ClientID + "');";
// Javascript function
function DisableButton(id)
{
var bButton = $("#" + id);
if (Page_ClientValidate())
{
$("#" + id).attr('disabled', 'disabled');
__doPostBack(id, '');
}
}
This works as expected in a non master page setup but when I try to use it with a page that has a master page, the postback occurs and the Page_Load fires but the button click handler never gets called. It's like the __doPostBack is not sending which control event to fire correctly.
Any suggestions for changes or even a whole different approach?
One idea for a different approach (disclaimer: this is not a fully baked solution) is to go from the submit action of the form instead of the click handler of the button.
The validation all happens through the submit handler of the form. If everything checks out, the form is allowed to submit. If you could hook into that process, then when the form started to submit for real, you could find all buttons with the class DisableOnSubmit and disable them.
Validation could take some time, however, and some people (annoyingly) seem to like to double-click on web forms, so it might be best to blend the approaches. Disable the button immediately with a click handler, then if validation fails, re-enable the buttons that were disabled.
EDIT In response to comments
This description could be turned to be more like the signature in the question (where any button could be made to be click-once regardless of its CSS classes).
Create a jQuery extender where the buttons that fit the selector are given an onClick handler and (if not already done) the hook is added to the validation being complete. The onClick handler adds the clicked button to a collection of "currently in click evaluation" buttons. If validation succeeds, the form submits normally. If validation fails, the buttons in the collection are re-enabled and removed from the collection.
For the evil update panels, you might want to look into specifying these events with live bindings (used to be a plugin, but I think it's now part of the jQuery core depending on which version you're using) so that the event handlers are reregistered when the partial postbacks complete.
I get the feeling you can use GetPostBackEventReference to do the actual postback once you've done your validation dance.
Edit Oops, forgot the other half of the answer :-)
As for the double postback, I've used Postback Ritalin by Dave Ward in the past to curtail those pesky hyperactive users.
Add this to your startup code (ready event handler):
var elemButton = $('#<%= Button1.ClientID %>');
var fnExistingHandler = elemButton[0].onclick;
elemButton[0].onclick = function()
{
fnExistingHandler();
if (!Page_BlockSubmit)
{
$(this)
.hide()
.after('<input type="button" value="Please Wait..." disabled="disabled" />');
}
};
Basically you append new code to existing click handler. Note checking global variable Page_BlockSubmit.
Instead of disabling submit button you can hide it and immediately insert disabled button in its place. Because this happens very quickly it will look as button becoming disabled to the user. Details are at the blog of Josh Stodola.
Edit: fixed client validation.
Haven't tried it but what about something like this:
$("input[type=submit]").live("click", function() {
$(this).hide().clone().insertAfter(this).show().attr("disabled", "disabled").val("Please wait...");
return true;
});
This will ensure a submit button isn't disabled which ASP.NET doesn't like.
I have a table that is created in a DataList in ASP.Net. This table has three fields of text, then a field with an edit button, and a field with a delete button. When a person clicks the delete button, it posts back, deletes the items, and then binds the DataList again. The DataList is in an UpdatePanel so the item smoothly disappears after a half of a second or maybe a little more, but what I'd really like is for the row to slide out (up) as soon as they hit the delete button, and then have it delete the item on the post back.
I can make the row slide out with jQuery, but the postback gets in the way. How do you deal with that?
You can use page methods in asp.net to send a request to the server without doing a postback. They are very simple to use and you can do whatever effect you like when the ajax call is completed (you get a function called on success).
If you want to stick with the post back one solution is the following:
<asp:Button id="myButton" OnClientClick="return fadeThenAllowSubmit()" ... />
and in js something like:
var allowSubmit = false;
function fadeThenAllowSubmit() {
if (allowSubmit) return true
// do the jquery stuff that will be completed in, let's say, 1000ms
setTimeout(function() {
allowSubmit = true
$("input[id$=myButton]").click()
allowSubmit = false
}, 1000)
return false
}
It's a bit of a hack, the idea is to cancel the postback initially, do some stuff then set a timer where the postback will be enabled. The big problem with this approach is that the fade effect and the actual delete are independent (in case of an error you still get the fade effect).
have you tried looking at any of the Ajax control toolkit items? I believe there are some controls in there that will head with client side (java) code if your not extremely familiar
I would use client side Javascript to manually scale the "opacity" CSS property down to zero, then mark the element as "display: none" then submit the post-back.
I believe that in Internet Explorer, you need to use the "Filter" CSS property to do this as it does not support opacity.
You could just code up a routine to set both properties and that should cover all the major browsers.
Register the handler for form "submit" event.
$("form").submit(function() {
// if user initiated delete action
// do your thing with deleted row (effects, etc.)
// after you're done with it, submit the form from script
// (you can queue the submission after the effect)
// the submission from the script won't trigger this event handler
return false; // prevent submission
}
Preventing form submission is necessary to avoid interference with the effects you want to perform. After they are finished, you are free to proceed with submission.