so basically im in a process of creating my unit project which is an eCommerce website. one of the feature that important is a watch list (ex: watch list in ebay)
now i already finish in designing and succeed in adding/removing db record but what bothers me is that the page is the delay/ page posting back for each item saved/clicked. i tried adding an update panel but there is a still delay when we click the button.
below is my copy of the code
Design
<listview>
<itemTemplate>
......
<asp:UpdatePanel ID="UpdatePanel2" runat="server">
<ContentTemplate>
<asp:LinkButton ID="lnkSaved" class="btn-icon btn-white btn-star btn-radius" runat="server" CausesValidation="false" CommandName="ToggleSave">
<span></span>
<asp:Label ID="lblSaved" runat="server" Text="Save Activity" AssociatedControlID="lnkSaved"></asp:Label>
</asp:LinkButton>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="lnkSaved" />
</Triggers>
</asp:UpdatePanel>
.......
</itemtemplate>
</listview>
CodeBehind
protected void ListViewActivities_ItemCommand(object sender, ListViewCommandEventArgs e)
{
HiddenField hdnisSaved = e.Item.FindControl("hdnisSaved") as HiddenField;
HiddenField hdnActivityID = e.Item.FindControl("hdnActivityID") as HiddenField;
LinkButton lnkSaved = e.Item.FindControl("lnkSaved") as LinkButton;
Label lblSaved= e.Item.FindControl("lblSaved") as Label;
Guid userID = new MembershipHelper().GetProviderUserKey(WebSecurity.CurrentUserId);
if (Convert.ToBoolean(hdnisSaved.Value))
{
lnkSaved.Attributes.CssStyle.Clear();
if(Convert.toboolean(hdnisSaved.Value))
{
lnkSaved.Attributes.Add("Class", "btn-icon btn-white btn-radius btn-star");
lblSaved.Text ="Save";
}
else
{
lnkSaved.Attributes.Add("Class", "btn-icon btn-white btn-radius btn-starred");
lblSaved.Text ="Saved";
}
new CustomerDAC().ToggleSave(userID, Convert.ToInt32(hdnActivityID.Value,hdnisSaved.Value));
}
}
could you guys give me a direction, what should i do so a user will have a smooth experience(async prefered) when clicking this button.
You probably want to perform the action on the client side (browser side) in javascript/jquery and then sync the changes in the background, so that the user's perception is immediate but the slow part (http roundtrip to the server and persisting the data to DB) happens in the "background".
Related
I have asp.net FileUpload control inside an update panel. When I click upload button, I am reading the file for some code, if code not found then I am showing ModalPopup for selecting a user from dropdown, otherwise uploading and emailing the file to user of that Code(this code is saved in Database).
If code not found,its displaying ModalPopup and removing the selected file, I want to persist the selected file after post back.
This is my code
<asp:UpdatePanel ID="UpdatePanel3" runat="server" >
<ContentTemplate>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:RequiredFieldValidator ID="rfvFileupload" ValidationGroup="validate" runat="server" ErrorMessage="* required" ControlToValidate="FileUpload1"></asp:RequiredFieldValidator>
</ContentTemplate>
</asp:UpdatePanel>
and on Button Click
protected void btnupload_Click(object sender, EventArgs e)
{
//Reading the file and Checking from Database
if(codefound)
{
//Sending email to the user of the Code
}
else
{
ModalPopupExtender1.Show();
}
}
How can I persists the value of Upload control on post back?
Background::
When a file is selected using FileUpload Control ,then on postback, PostedFile property gets initialized with HttpPostedFile object for the file. Since http request cannot maintain state, so it looses it's state.
NOTE: FileUpload control will not work with asynchronous postback.So a postback is needed to get the file. One way is to set the triggers for your Upload button, i.e. <asp:PostBackTrigger > & NOT <asp:AsyncPostBackTrigger>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:FileUpload ID="fileUploadImage" runat="server"></asp:FileUpload>
<asp:Button ID="btnUpload" runat="server" Text="Upload Image"
OnClick="btnUpload_Click" />
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnUpload" />
</Triggers>
</asp:UpdatePanel>
And your Upload button code:
protected void btnUpload_Click(object sender, EventArgs e)
{
if (fileUpload1.HasFile)
{
fileName = fileupload1.FileName;
fileUpload1.SaveAs("~/UploadedContent/" + fileName);
}
}
TO PERSIST THE VALUE OF FILEUPLOAD CONTROL, you can store the fileupload object altogether in session and after postback retrieve the values you require from session.
protected void Page_Load(object sender, EventArgs e)
{
// store the FileUpload object in Session.
// "FileUpload1" is the ID of your FileUpload control
// This condition occurs for first time you upload a file
if (Session["FileUpload1"] == null && FileUpload1.HasFile)
{
Session["FileUpload1"] = FileUpload1;
Label1.Text = FileUpload1.FileName; // get the name
}
// This condition will occur on next postbacks
else if (Session["FileUpload1"] != null && (! FileUpload1.HasFile))
{
FileUpload1 = (FileUpload) Session["FileUpload1"];
Label1.Text = FileUpload1.FileName;
}
// when Session will have File but user want to change the file
// i.e. wants to upload a new file using same FileUpload control
// so update the session to have the newly uploaded file
else if (FileUpload1.HasFile)
{
Session["FileUpload1"] = FileUpload1;
Label1.Text = FileUpload1.FileName;
}
}
This problem is somewhat well documented, the update panel is listed as not working with certain controls.
File upload, and tree view being 2 of the biggies.
To make it work you should use Triggers/PostbackTrigger
<asp:UpdatePanel ID="UpdatePanel3" runat="server" >
<ContentTemplate>
<asp:FileUpload ID="FileUpload1" runat="server" />
<asp:RequiredFieldValidator ID="rfvFileupload" ValidationGroup="validate" runat="server" ErrorMessage="* required" ControlToValidate="FileUpload1" />
<asp:Buton ID="btnupload" runat="server" Text="Upload" onclick="btnupload_Click"></asp:Button>
</ContentTemplate>
<Triggers>
<asp:PostBackTrigger ControlID="btnupload"/>
</Triggers>
</asp:UpdatePanel>
try add
$('form').attr('enctype', 'multipart/form-data');
I have this AJAX button that I want to update some CSS. The problem is that the controls I want it to update are in a different file and can't be moved out of that file.
This is the panel whose CSS I want to update, which is located in the Site.master file:
<asp:ScriptManager ID="ScriptManager" runat="server" />
<asp:UpdatePanel ID="Panel2" runat="server" updatemode="Always">
<ContentTemplate>
<div id="updateThis" runat="server"><p>Test text</p></div>
</ContentTemplate>
</asp:UpdatePanel>
This is the button, located in the Items.ascx file:
<asp:UpdateProgress runat="server" ID="PageUpdateProgress">
<ProgressTemplate>
<img class="ajax-loader" src="/Images/ajax-loader.gif" alt="Loading..." />
</ProgressTemplate>
</asp:UpdateProgress>
<asp:UpdatePanel ID="Panel3" runat="server" updatemode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger controlid="UpdateButton" eventname="Click" />
</Triggers>
<ContentTemplate>
<asp:Button runat="server" OnClick="UpdateButton"
OnClientClick="hideButton()" Text="Update"
class="update" ID="UpdateButton" name="UpdateButton"
type="submit" ></asp:Button>
</ContentTemplate>
</asp:UpdatePanel>
This is the Items.ascx.cs method that is UpdateButton
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.Controls[0].FindControl("updateThis");
div.Style.Add("color", "#ff0000");
}
When I click the button it doesn't end up working correctly. As of right now, with the AJAX UpdateProgress template, it shows the loading GIF and then the GIF disappears and the text never changes color.
EDIT
Hopefully this will give a better idea of where things might be going wrong:
THIS WORKS
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.FindControl("updateThis");
div.Style.Add("color", "#ff0000");
UpdateButton.Text = "Done!";
}
I had #updateThis in the FindControl() method. Don't be like me!
You should add the runat="server" attribute to the div control, to make it visible in code-behind:
<div id="updateThis" runat="server"><p>Test text</p></div>
You can also remove Controls[0] in the event handler (but it works if you keep it, according to my tests):
protected void UpdateButton(object sender, EventArgs e)
{
var masterPage = this.Page.Master;
var updatePanel = masterPage.FindControl("Panel2");
var div = (HtmlGenericControl)updatePanel.FindControl("updateThis");
div.Style.Add("color", "#ff0000");
}
In this example I want when the button with ID "PostCommentsButton" is pressed this ContentTemplate to be triggered and to iterate all again in ListView with ID "CommentListView". But this didn't work here. What I miss ?
In this example I take the new text from textfield and in code behind I put this new content from textfield with ado.net and I save this new content in database. The problem is that when the button in UpdatePanel is pressed the new information didn't come in the list with the other content. It comes only if I restart the page. I want ListView in UpdatePanel to be iterated again to take this new content from the textfield with AJAX when the button is pressed. What should I do ?
aspx code:
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="PostCommentsButton" />
</Triggers>
<ContentTemplate>
<asp:ListView ID="CommentListView" runat="server" DataSource= '<%# Eval("Comments") %>'>
<ItemTemplate>
<div class="postComments">
<span class="authorComment"><%# Eval("Author") %></span>
:
<span class="commentContent"><%# Eval("Message") %></span>
</div>
</ItemTemplate>
</asp:ListView>
</ContentTemplate>
</asp:UpdatePanel>
code behind :
protected void PostsListView_ItemCommand(object sender, ListViewCommandEventArgs e)
{
//commandName is for recognize the clicked button
if (e.CommandName == "postComment")
{
//get the comment from textbox from current listview iteration
BlogProfileEntities blogProfile = new BlogProfileEntities();
var commentBox = e.Item.FindControl("AddCommentTextbox") as TextBox;
var hiddenFieldPostID = e.Item.FindControl("CurrentPostIDHiddenField") as HiddenField;
string text = commentBox.Text;
var postID = hiddenFieldPostID.Value;
Comment newComment = new Comment()
{
Message = text,
PostID = int.Parse(postID),
Author = Membership.GetUser().UserName
};
blogProfile.Comments.Add(newComment);
blogProfile.SaveChanges();
I dont see a text box in your example. If the text box is not in the update panel that gets called when the list view post back fires, I dont think you'll get the current value. I would suspect that if you put a break point on your commentBox variable, you would see it comes back as Nothing. If this isn't your full code, post everything.
I have an ASPxPopupControl and an ASPxGridView.
Inside this PopupControl i have my own usercontrol which contains a form for editing person information.
Inside the GridView is a list with different persons.
When i select a different person in the gridview i want the content of the popupcontrol to update for the to the person information of the selected user so i can edit it.
My problem is; i can't get this to work, i have tried placing update panels with all sorts of triggers or forcing the updatepanel to update. But it still doesn't work.
PopupControl:
<dx:ASPxPopupControl ID="pcVolgnummerToevoegen" runat="server" AllowDragging="True" ClientInstanceName="popup_toevoegen" CloseAction="CloseButton" LoadingPanelText="Laden…" Height="700" Width="700" Modal="True" PopupHorizontalAlign="WindowCenter" PopupVerticalAlign="WindowCenter">
<ContentCollection>
<dx:PopupControlContentControl ID="pcVolgnummerToevoegenContent" runat="server">
<asp:UpdatePanel ID="upnlToevoegen" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<uc:GegevensControl ID="ucGegevensControl_Toevoegen" runat="server" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="KlantVolgnummerGrid" />
</Triggers>
</asp:UpdatePanel>
</dx:PopupControlContentControl>
</ContentCollection>
</dx:ASPxPopupControl>
DataView Selection_Changed:
protected void KlantVolgnummerGrid_SelectionChanged(object sender, EventArgs e)
{
Session["Person_Id"] = KlantVolgnummerGrid.GetSelectedFieldValues("ID");
}
Page_Load of the usercontrol inside the popup
protected void Page_Load(object sender, EventArgs e)
{
Person varPerson = PersonControllerClient.GetPerson(Session["Person_Id"]);
....Code that fills the form
}
I have checked the SelectionChanged event of the GridView, it triggers. But the update panel doesn't update.
After i refresh the page the person i have selected is shown inside the popup.
Is there anyway i can update the popup for showing the right person without having to refresh the page everytime i select a different person?
Disable a ASPxGridView callback mode to force grid using UpdatePanel callbacks.
Just set the ASPxGridView.EnableCallBack http://documentation.devexpress.com/#AspNet/DevExpressWebASPxGridViewASPxGridView_EnableCallBackstopic property to “false”.
Remove the trigger and add ChildrenAsTriggers="false" on your updatepanel
<asp:UpdatePanel ID="upnlToevoegen" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="false">
<ContentTemplate>
<uc:GegevensControl ID="ucGegevensControl_Toevoegen" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
code-behind:
protected void KlantVolgnummerGrid_SelectionChanged(object sender, EventArgs e)
{
int id = KlantVolgnummerGrid.GetSelectedFieldValues("ID");
Person varPerson = PersonControllerClient.GetPerson(id);
....Code that fills the form
upnlToevoegen.Update();
}
I am firing an event from an ascx control in order to update some controls in the container to which the ascx control belongs.
The ascx control is displayed via a modal popup extender. When I click a button inside the ascx, I fire an event to which the container containing the ascx control is subscribes.
The event delegate is fired and the expected logic is run in the container's code behind, the problem is that any changes made to controls inside not the container aren't updated despite the event logic having been processed. The expected changes are not reflected on the page when the results of the postback is rendered.
Are there any pitfalls I should know of?
The markup for the container
<asp:Panel ID="panelTreeViewAttributesTitle" runat="server">
<asp:Label ID="someLabel" runat="server" Text="Hello Governor" />
<asp:LinkButton ID="LinkButtonEdit" runat="server" Text="(Edit)" />
<ajax:ModalPopupExtender BackgroundCssClass="modalBackground" Enabled="True"
ID="btnEdit_ModalPopupExtender" PopupControlID="modalPanel" runat="server"
TargetControlID="LinkButtonEdit" />
</asp:Panel>
<asp:Panel ID="modalPanel" runat="server" CssClass="modalPopUp" Style="display: none">
<xxx:customControl runat="server" ID="myCustomControl" />
</asp:Panel>
The code behind for the container
protected void Page_Load(object sender, EventArgs e)
{
myCustomControl.Updated += eventCaptured;
if (IsPostBack) return;
...
}
void eventCaptured(object sender, EventArgs e)
{
someLabel.Text = "Goodbye Governor";
}
The custom control
<script type="text/javascript">
function Update() {
var ajaxManager = $find("<%= RadAjaxManager.GetCurrent(Page).ClientID %>");
if (ajaxManager != null)
ajaxManager.ajaxRequest("");
}
</script>
<asp:Panel ID="panelEditPanel" runat="server">
<asp:Label ID="lblCMA" runat="server" Text="Call me Arnooold." />
</asp:Panel>
<asp:Button ID="btnUpdate" runat="server" Text="Update" OnClientClick="Update()" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel" />
The custom control's code behind
public event EventHandler Updated;
protected void AjaxManager_AjaxRequest(object sender, AjaxRequestEventArgs e)
{
//Some DB backend logic
UpdateFinished();
}
private void UpdateFinished()
{
if (Updated == null) return;
Updated(this, null);
}
Maybe the button click is causing a partial post back instead of a normal, full-page post back. If this is the case, the entire life cycle would run on the server side (including your event handler) but only part of the HTML would be updated on the client side when the response comes back to the browser. "someLabel" could be outside the region that gets updated on the client side.