Display jquery dialog on postback in ASP.NET after saving a new record - asp.net

What I would like to do is have the user add a new record to the database and popup a JQuery dialog confirming that the new record was saved. I thought this would be a simple exercise. I have a gridview bound to a LINQDataSource to allow the user to view and edit existing records and a textbox and a button to add new codes.
In the head of the document, I have the following:
$('#dialog').dialog({
autoOpen: false,
width: 400,
buttons: {
"Ok": function () {
$(this).dialog("close");
}
}
});
and futher down in the markup I have:
<div id="dialog" title="New Code Added">
<p>"<asp:Literal runat="server" ID="LiteralNewCode"></asp:Literal>" was successfully added.</p>
</div>
So when the user enters a new description and it passes all the validation, it's added to the database and the gridview is rebound to display the new record.
protected void ButtonSave_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
CCRCode.Add( <long list of paramters> );
GridCode.DataBind();
IsNewCode = true;
NewDescription = <new description saved to database>;
}
}
Now, here's where (I thought) I'd set a boolean property to indicate that a new description had been added as well as the text of the new description. See below:
protected bool IsNewCode
{
get { return ViewState["IsNewCode"] != null ? (bool)ViewState["IsNewCode"] : false; }
set { ViewState["IsNewCode"] = value; }
}
private string NewDescription
{
get { return ViewState["NewDescription"] != null ? ViewState["NewDescription"].ToString() : string.Empty; }
set { ViewState["NewDescription"] = value; }
}
Here's where I loose my way. My guess is I want to add functionality to include code similar to:
$('#dialog').dialog('open');
I've added a registerscriptblock method in the page_load event but that didn't work. Any ideas? Or am I just going about this entirely wrong?
Thanks.

Not really get what you want to do. But, i use jquery alot with .NET in my projects. here is how i do, probably could give you a hint.
foo.aspx.cs
public String ScriptToRun = "$('#dialog').dialog('open');";
change the value of ScriptToRun in your C# code
foo.aspx
$(document).ready(function() {<%=ScriptToRun %>});
Remember that whatever you done in backend is going to generate HTML, Css& javascript to browser.

Two ways: one, write the javascript in your server-side code. Or, define a JS method to show the dialog (say named showDialog), and call it via:
Page.ClientScript.RegisterStartupScript(... "showDialog();" ..);
RegisterStartupScript puts the method call at the end, ensure your script is above it to work. You can also wrap it with document.ready call too, to ensure JQuery is properly loaded.

I think that the only think that you have miss is the creation of the dialog when the Dom is ready.
$(document).ready(function() {$('#dialog').dialog('open');});

I posted code in a different question for a custom "MessageBox" class I wrote:
ASP.NET Jquery C# MessageBox.Show dialog uh...issue
the code by default uses the javascript alert() function, but you can define your callback so that it calls your custom javascript method to display the messages.

Related

How to avoid duplicate entry from asp.net on Postback?

I have a dropdown list that pulls data from template table. I have an Add button to insert new template. Add button will brings up jQuery popup to insert new values. There will be a save button to save the new data. On_Save_Click I enter the new data and close the popup.
Here is the proplem:
When I refresh the page, the page entering the values again. So, I get duplicate entries!
Question:
How can I avoid this issue? I check out Satckoverflow and Google, both they suggest to redirect to another page. I don't want to redirect the user to another page. How can I use the same form to avoid this issue? Please help.
You can use viewstate or session to indicate if data already inserted (button pressed).
Something like this:
private void OnbuttonAdd_click()
{
if(ViewState["DataInserted"] != "1")
{
...
// Add new entry...
...
if(data inserted successfully)
{
ViewState["DataInserted"] = "1";
}
}
}
Edit:
public bool DataInserted
{
get
{
if (HttpContext.Current.Session["DataInserted"] == null)
{
HttpContext.Current.Session["DataInserted"] = false;
}
bool? dataInserted = HttpContext.Current.Session["DataInserted"] as bool?;
return dataInserted.Value;
}
set
{
HttpContext.Current.Session["DataInserted"] = value;
}
}
...
private void OnbuttonAdd_click()
{
if(!DataInserted)
{
...
// Add new entry...
...
if(data inserted successfully)
{
DataInserted = true;
}
}
}
The simplest way is to use a post/redirect/get pattern.
Basically, the refresh action for page build with post requires to repost the data. Using this pattern, you will reload the whole page.
With ASP.Net, you have a simple alternative, use an UpdatePanel. This will refresh only part of the page using AJAX. As the page itself is still the result of a GET request, you can refresh the page. And as you use ASP.Net, it's quite easy to integrate.
Finally, you can use a home made AJAX refresh. A combination of jQuery, KnockOut and rest services (for example), can help you to avoid refreshing the full page in benefits of an ajax call.
There is some experience:
Disable Submit button on click (in client side by JavaScript).
change Session['issaved'] = true on save operation at server side and change it on new action to false.
use view state for pass parameters like RecordId (instead of QueryString) to clear on refresh page. i always pass parameter's with Session to new page, then at page load set
ViewState['aaa']=Session['aaa'] and clear Sessions.
...I hope be useful...
Do this it is very easy and effective
Intead of giving IsPostBack in the page load(),please provide inside the button click (To send or insert data)
Call the same page again after reseting all input values
protected void Btn_Reg_Click1(object sender, EventArgs e)
{
try
{
if (IsPostBack)
{
Registration_Save();
Send_Mail();
txtEmail.Text = "";
txtname.Text = "";
Response.Redirect("~/index.aspx");
}
}
catch (Exception) { }
}
You won't see any server messages after refreshing the page..

How to dynamically and incrementally add controls to a container

I thought this was straight forward, but i have a link button, and I do this in the click event:
myContainer.Controls.Add( new FileUpload());
I expect 1 new file control upload to be spawned in the container for each click, however, I always get 1. What do I need to do to have multiple file upload controls?
Since the control was added dynamically, it does not survive the postback. This means that you have to add the file upload (or any other dynamically added control) again in the preinit event to be able to have its values populated and to use it later on in the page life cycle.
Sounds like you are trying to be able to upload multiple files. You may want to add the file uploads with jQuery and use the Request.Files property to get them on the back-end.
I agree with Becuzz's answer. Try this, there are better ways to do it, but this might help as well:
Add this to the "Load" event of your page
if (!IsPostBack) {
Session["UploadControls"] = null;
}
if (Session["UploadControls"] != null) {
if (((List<Control>)Session["UploadControls"]).Count > 0) {
foreach ( ctrl in (List<Control>)Session["UploadControls"]) {
files.Controls.Add(ctrl);
}
}
}
And also add this to the PreInit portion of your page:
string ButtonID = Request.Form("__EVENTTARGET");
if (ButtonID == "Button1") {
FileUpload NewlyAdded = new FileUpload();
List<Control> allControls = new List<Control>();
if (Session["UploadControls"] != null) {
if (((List<Control>)Session["UploadControls"]).Count > 0) {
foreach ( ctrl in (List<Control>)Session["UploadControls"]) {
allControls.Add(ctrl);
//Add existing controls
}
}
}
if (!allControls.Contains(NewlyAdded)) {
allControls.Add(NewlyAdded);
}
Session["UploadControls"] = allControls;
}
And add this to your HTML. This can be anything of course:
<div id="files" runat="server">
</div>
I use the "__EVENTTARGET" value to know what caused the postback, so that you don't get unwanted Upload controls.
Good luck, and hopefully this helps.
Hanlet

ASP.NET Custom Button Control - How to Override OnClientClick But Preserve Existing Behaviour?

So i have a ASP.NET 4 Custom Control called "SafeClickButton" which is designed to override the default behaviour of the client-side click (OnClientClick).
Essentially i'm trying to disable the button on click, then do any existing functionality (validation, postback, etc).
It looks to be correctly rendering the HTML (onclick="this.disabled=true;__doPostback...), and it is disabling correctly, but the problem is with the page validation. If any validation on the page has failed, its posting back and THEN showing the validation errors (where it should be done on client side without requiring a postback).
Here's the code for the custom control.
public class SafeClickButton : Button
{
public override string OnClientClick
{
get
{
return string.Format("this.disabled=true;{0}", Page.ClientScript.GetPostBackEventReference(this, string.Empty));
}
set
{
base.OnClientClick = value;
}
}
protected override PostBackOptions GetPostBackOptions()
{
PostBackOptions options = new PostBackOptions(this, string.Empty) {ClientSubmit = true};
if (Page != null)
{
if (CausesValidation && (Page.GetValidators(ValidationGroup).Count > 0))
{
options.PerformValidation = true;
options.ValidationGroup = ValidationGroup;
}
if (!string.IsNullOrEmpty(PostBackUrl))
{
options.ActionUrl = HttpUtility.UrlPathEncode(ResolveClientUrl(PostBackUrl));
}
}
return options;
}
}
What am i doing wrong?
EDIT
Okay so i found part of the problem:
return string.Format("this.disabled=true;{0}", Page.ClientScript.GetPostBackEventReference(this, string.Empty));
Will not apply the dervied behaviour of the postbackoptions.
So i changed it to this:
return string.Format("this.disabled=true;{0}", Page.ClientScript.GetPostBackEventReference(GetPostBackOptions()));
Now the validation is getting fired properly on the client side, but the button isn't re-enabled, FML =)
I think i need to be even smarted now, and say "If validation fails, re-enable button".
Any ideas?
You should be able to just add the Page_ClientValidate method inline. I have never tried this so it might not work:
return string.Format("if (Page_ClientValidate()) { this.disabled=true; {0} } else return false;",
Page.ClientScript.GetPostBackEventReference(this, string.Empty));
You might have to mess with it or add some checks to support GroupValidation but I think this will get you on the right path.
EDIT: I have updated the answer and moved you disable into the if so it only gets disabled when Page_ClientValidate fails.
Check out this link as it is doing what you are looking for I think and illustrates what I was meaning with the Page_ClientValidate:
http://msmvps.com/blogs/anguslogan/archive/2004/12/22/27223.aspx

Best practice for modal window in Web Forms application

On a list page, clicking on one of the items brings up the details in a modal popup window which will have its own functionality (like validation, updating etc). What's the best practice to implement this (not looking for a hack). I see two options here:
Hide the details markup until a list item is clicked at which time, do a ajax request to get the details and populate and show the details section.
Have the details section as a separate page by itself. On a list item click, show this page in a modal window (is this even possible?) This is similar to the IFrame approach and sounds like an old school approach.
What are the pros of cons of these approaches or are there other ways of doing this? There should not be a postback on list item click.
Edit: Any more opinions are appreciated.
I'm doing option 1 currently, it's very lightweight and all you need is an ajax post (jQuery or UpdatePanel) and some modal (I'm using jQery UI). It's easier than a full page post, plus you have the added benefit of being able to manipulate the page you're in as part of the result.
For example I have grids in the page, the editor is modal, usually with more detail, when you hit save, the grid is updated. I've put this in a generic template solution and it's very easy to work with, and is as light as webforms can be in that situation, so I'm all in favor of option 1.
Here's an example approach, having your modal control inherit from UpdatePanel (code condensed for brevity):
public class Modal : UpdatePanel
{
private bool? _show;
public string Title
{
get { return ViewState.Get("Title", string.Empty); }
set { ViewState.Set("Title", value); }
}
public string SaveButtonText
{
get { return ViewState.Get("SaveButtonText", "Save"); }
set { ViewState.Set("SaveButtonText", value); }
}
protected override void OnPreRender(EventArgs e)
{
if (_show.HasValue) RegScript(_show.Value);
base.OnPreRender(e);
}
public new Modal Update() { base.Update();return this;}
public Modal Show() { _show = true; return this; }
public Modal Hide() { _show = false; return this; }
private void RegScript(bool show)
{
const string scriptShow = "$(function() {{ modal('{0}','{1}','{2}'); }});";
ScriptManager.RegisterStartupScript(this, typeof (Modal),
ClientID + (show ? "s" : "h"),
string.Format(scriptShow, ClientID, Title, SaveButtonText), true);
}
}
In javascript:
function modal(id, mTitle, saveText) {
var btns = {};
btns[saveText || "Save"] = function() {
$(this).find("input[id$=MySaveButton]").click();
};
btns.Close = function() {
$(this).dialog("close");
};
return $("#" + id).dialog('destroy').dialog({
title: mTitle,
modal: true,
width: (width || '650') + 'px',
resizable: false,
buttons: btns
}).parent().appendTo($("form:first"));
}
Then in your markup (Can't think of a better name than MyControls right now, sorry!):
<MyControls:Modal ID="MyPanel" runat="server" UpdateMode="Conditional" Title="Details">
//Any Controls here, ListView, whatever
<asp:Button ID="MySaveButton" runat="server" OnClick="DoSomething" />
</MyControls:Modal>
In you pages codebehind you can do:
MyPanel.Update().Show();
Fr your approach, I'd have a jQuery action that sets an input field and clicks a button in the modal, triggering the update panel to postback, and in that code that loads the details into whatever control is in the modal, just call MyPanel.Update.Show(); and it'll be on the screen when the update panel ajax request comes back.
The example above, using jQuery UI will have 2 buttons on the modal, one to close and do nothing, one to save, clicking that MySaveButton inside the modal, and you can do whatever you want on then server, calling MyPanel.Hide() if successful, or put an error message in the panel if validation fails, just don't call MyModal.Hide() and it'll stay up for the user after the postback.

C# .NET and Javascript Confirm

I have a C# ASP.NET web page with an xml file upload form. When the user clicks 'upload', a javascript confirm alert will pop up asking the user, "is this file correct?". The confirm alert will only activate if the file name does not contain a value from one of the other form fields.
What is the best way to combine the use of a C# ASP.NET form and a javascript confirm alert that is activated if the name of a file being uploaded does not meet certain criteria?
There's not much you need to do with C# for this page, it sounds like most of this will be done on the client side.
Add the fileupload control and a button to your .aspx form. Set the Button's OnClientClick property to something like
OnClientClick = "return myFunction()"
and then write a javascript function like:
function myFunction()
{
// Check other text values here
if (needToConfirm){
return confirm('Are you sure you want to upload?');
}
else return true;
}
Make sure "myFunction()" returns false if you wish to cancel the postback (i.e. the user clicked "no" in the confirm dialog). This will cancel the postback if they click "No".
I suppose you are putting value of valid string in a hidden field (you haven't mentioned). Implement OnClientClick for Upload button:
<asp:button .... OnClientClick="return confirmFileName();"/>
<script type="text/javascript">
function confirmFileName()
{
var f = $("#<%= file1.ClientID %>").val();
var s=$("#<%= hidden1.ClientID %>").attr("value");
if (f.indexOf(s) == -1) {
if (!confirm("Is this correct file?")) {
$("#<%=file1.ClientID %>").focus();
return false;
}
}
return true;
}
</script>
EDIT:- Regarding <%= file1.ClientID %>.
This will be replaced by the client side ID of the file upload control like ctl00$ctl00$cphContentPanel$file1. It puts the script on steroids with respect to using something like $("input[id$='file1']"). For more information please see Dave Wards' post.
window.onload = function() {
document.forms[0].onsubmit = function() {
var el = document.getElementById("FileUpload1");
var fileName = el.value;
if(fileName.indexOf("WHATEVER_VALUE") == -1) {
if(!confirm("Is the file correct?")) {
el.focus();
return false;
}
}
return true;
}
}
I had problems implementing this kind of thing to work in both IE and FireFox because of the way events work in those browsers. When I got it to work in one of them, the other would still cause a postback even if I cancelled out.
Here's what we have in our code (the browser test was stolen from elsewhere).
if (!window.confirm("Are you sure?"))
{
if (/MSIE (\d+\.\d+);/.test(navigator.userAgent))
window.event.returnValue = false;
else
e.preventDefault();
}
In addition to using client side validation, you should also add a CustomValidator to provide validation on the server side. You cannot trust that the user has Javascript turned on, or that the user has not bypassed your Javascript checks.

Resources