So I've got this asp fileupload control which I'm using to select an image. The image is then saved in a temporary folder called "TempImages", then I'm pulling it from there and displaying it on the page, using the code shown below.
protected void Close_Click(object sender, EventArgs e)
{
Div1.Visible = false;
}
#endregion Submit button
protected void LogoToUpload_Click(object sender, EventArgs e)
{
if (upldLogo.HasFile)
{
upldLogo.SaveAs("C:\\TempImages\\" + upldLogo.FileName);
Response.ContentType = "image/jpeg";
string physicalFileName = #"C:\TempImages\" + upldLogo.FileName;
Response.WriteFile(physicalFileName);
}
My problem is that When the image is displayed, it gets rid of all the other controls, i.e. the dropdowns, the textboxs and the labels and all that jazz.
Anyone got any suggestions on how I can make the image just show either in a pop up or just display on the same page but with all the controls still there.
Cheers folks
Ok, so I managed to sort this out by using a little Javascript I put this into the head tag on the controls page.
<script type="text/javascript">
function previewFile() {
var preview = document.querySelector('#<%=imgLogo.ClientID %>');
var file = document.querySelector('#<%=upldLogo.ClientID %>').files[0];
var reader = new FileReader();
reader.onloadend = function () {
preview.src = reader.result;
}
if (file) {
reader.readAsDataURL(file);
} else {
preview.src = "";
}
}
</script>
aaaand this into the content.
This served to create a little preview of the picture next to the file upload control once you selected a file.
Cheers!
<input ID="upldLogo" type ="file" onchange="previewFile()" runat="server" />
Related
If i have method like this to Draw my side Menu Dynamically :
private void DrawSideMenu()
{
LinkButton x;
TaskDTO TaskList = new TaskDTO();
List<TaskDTO> List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
HtmlGenericControl myDIV = new HtmlGenericControl("div");
myDIV.ID = "menu8";
HtmlGenericControl myOrderedList = new HtmlGenericControl("ul");//css clss for <ul>
myOrderedList.ID = "orderedList";
myOrderedList.Attributes.Add("class", "task");
HtmlGenericControl listItem1;
string count = "";
foreach (TaskDTO i in List)
{
count = AdjustMenuCount1(i.TaskCode);
x = new LinkButton();
x.ID = i.TaskCode.ToString();
x.Text = i.TaskName + " " + count;
x.Click += new EventHandler(TaskC);
x.Style["FONT-FAMILY"] = "tahoma";
listItem1 = new HtmlGenericControl("li");
listItem1.Attributes.Add("class", "normal");
if (count != "0")
{
listItem1.Controls.Add(x);
myOrderedList.Controls.Add(listItem1);
}
}
myDIV.Controls.Add(myOrderedList);
MenuTD.Controls.Add(myDIV);
Session["SideMenu"] = myDIV;//Save to redraw when page postbacks
}
This Method takes long time to draw my menu.so i call it one time in (!IsPostBack) and save it in session so that i could redraw it like that :
MenuTD.Controls.Add( ((System.Web.UI.Control)(Session["SideMenu"])));
It redraws it successfully but when i click on any link it doesn't hit the event because i thought it's not possible to save the x.Click += new EventHandler(TaskC); in the session ,so i want to know how to loop through my session content to resetting the delegate of my link ?
That idea won't work because if you're not wiring up the Event Handler every time the page is loaded, it won't run.
If we come back to the original issue, you said it's slow. Creating controls at runtime cannot be slow and it's most likely the way you create your list of items:
List<TaskDTO> List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
Instead of storing complete menu, try to store in the Session only List and create all controls as usual. If menu is required on one page only, then use ViewState instead of Session.
Also it makes sense to change the entire code as currently you hardcode all style and layout settings in the code. Create all layout (div, ul, li) in aspx, move all styles in css (for example, you use "task" class but still set "tahoma" in the code). This would simplify the code and bring more flexibility.
List<TaskDTO> List = null;
void Page_Load(object sender, EventArgs e)
{
if (ViewState["List"] != null) {
List = (List<TaskDTO>)ViewState["List"];
} else {
// ArrayList isn't in view state, so we need to load it from scratch.
List = TaskList.DrawMenu(int.Parse(Session["emp"].ToString()));
}
// Code to create menu, e.g.
if (!Page.IsPosBack) {
Repeater1.DataSource = List;
Repeater1.DataBind();
}
}
void Page_PreRender(object sender, EventArgs e)
{
// Save PageArrayList before the page is rendered.
ViewState.Add("List", List);
}
...
<ul id="orderedList">
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<li><%# Eval("TaskName") %></li>
</ItemTemplate>
</asp:Repeater>
</ul>
Maybe save it in application level so it only gets built once, then just put the menu into an object and loop through it to re-add the clicks.
I'm afraid that in order for it to work you are going to have to rebind the Click handler on every Page_Load.
Based on your code, and assuming your TaskC is available, you can make this method:
private void RebindMenuHandlers() {
if(Session["SideMenu"] == null)
return; // Your menu has not been built yet
var menu = ((System.Web.UI.Control)(Session["SideMenu"]));
var orderedList = menu.Controls[0];
foreach(var listItem in orderedList){
foreach(var control in listItem){
var linkButton = control as LinkButton;
if(linkButton != null){
linkButton.Click += new EventHandler(TaskC);
}
}
}
}
Then call it on your Page_Load event:
void Page_Load(object sender, EventArgs e)
{
RebindMenuHandlers();
// .... etc
}
I just typed this directly here, so please forgive any silly compilation mistakes, this should be enough to give you the general idea. Hope that helps.
I'm trying to make simple webpage here is my body in HTML code
<body runat="server" id="BodyTag" style="height: 1171px; width: 1148px;">
<form id="form1" runat="server">
On Page_Load in my Form.aspx.cs file i want to generate random number from 1 to X
where X is the number of files in a specific folder(folder containing images) then i want the body background image to be this random generated number as long as the image names in the folder are 1,2, ... , ... Here is my code
protected void Page_Load(object sender, EventArgs e)
{
string path = "C:/Users/FluksikartoN/documents/visual studio 2012/Projects/FLUKSIKARTON/FLUKSIKARTON/WebPhotos/BackGroundPhotos";
int countF = Directory.GetFiles(path, "*.*", SearchOption.AllDirectories).Length;
Random rand = new Random((int)DateTime.Now.Ticks);
int n = rand.Next(1, countF);
BodyTag.Style["background-image"] = "C:/Users/FluksikartoN/documents/visual studio 2012/Projects/FLUKSIKARTON/FLUKSIKARTON/WebPhotos/BackGroundPhotos/" + n.ToString() + ".jpg";
}
body background image does not change, it stays white and i dont understand why.Please do not hesitate to ask more information if you need
This is better achieved with css. Since you need a way to do it from code, the easiest option that comes to my mind is do it with generated Javascript
Javascript
<script type="text/javascript">
document.body.style.background = "url('http://localhost:53942/images/_65209699_fanbase_bbc.jpg')";
document.body.style.backgroundRepeat = 'no-repeat';
</script>
Applying it to your code
protected void Page_Load(object sender, EventArgs e)
{
string script = "<script type=\"text/javascript\">
document.body.style.background = \"url('http://localhost:53942/images/_65209699_fanbase_bbc.jpg')";
document.body.style.backgroundRepeat = 'no-repeat';
</script>\";
ClientScript.RegisterClientScriptBlock(this.GetType(), "background-changer-script", script);
}
This will just spill the Javascript to the bottom of your page and will be executed by the browser, changing the background as expected. Check the intellisense for Javascript and CSS for other background properties that can be set
You likely need to use a web relative URL:
BodyTag.Style["background-image"] = "http://localhost/FLUKSIKARTON/WebPhotos/BackGroundPhotos/" + n.ToString() + ".jpg";
Another approach would be to provide 1 CSS class per image and then switch which is being used:
CSS
.image1 {
background-image: url('/FLUKSIKARTON/WebPhotos/BackGroundPhotos/1.jpeg');
}
C#
BodyTag.CssClass = string.Format("image{0}.jpeg", n);
Fairly straightforward. I'm just looking for users to be able to add a title to the file before uploading. (Yes, I encourage proper filenames, but that's not the point.)
<asp:TextBox runat="server" ID="txtDocumentTitle" />
<ajaxToolkit:AjaxFileUpload runat="server" ID="ajxUploadNDA" OnUploadComplete="ajxUpload_Complete" Width="400px" /><br />
protected void ajxUpload_Complete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
{
MyFile f = new MyFile();
f.DocumentType = e.ContentType;
f.FileBytes = e.GetContents();
f.FileName = e.FileName;
f.DocumentCategory = "Package Files";
f.FileUploaded = DateTime.Now;
f.DocumentTitle = txtDocumentTitle.Text;
f.Save();
DataBind();
}
However when setting a breakpoint, txtDocumentTitle.Text is always blank. I can't seem to force a full postback or find any other way to get the current value of that textbox. I can allow the user to edit those properties after the file is uploaded, but that is not the design I'd prefer for a few reasons. (It encourages leaving values at default.)
I've tried:
protected void Page_Init(object sender, EventArgs e)
{
ScriptManager.GetCurrent(Page).RegisterPostBackControl(ajxUploadNDA);
ScriptManager.GetCurrent(Page).SupportsPartialRendering = false;
ScriptManager.GetCurrent(Page).EnablePartialRendering = false;
}
and I've tried
<ajaxToolkit:AjaxFileUpload runat="server" ID="ajxUploadNDA" OnUploadComplete="ajxUpload_Complete" Width="400px" onchange="if (confirm('Upload ' + this.value + '?')) this.form.submit();" />
Any suggestions would be more than welcome.
I've sort of solved it by adding a button to "Set Document Title" which adds the value of the textbox to session. The ajxUpload_Complete function then uses this Session variable to set the title to that session value on upload.
It's sloppy for a couple reasons, but it's the best I could do.
On Page_Load:
if (!Page.IsPostBack && !ajxUploadNDA.IsInFileUploadPostBack)
{
Session.Remove("DefaultDocumentCategory");
lblDocumentCategory.Text = "Data Package Files";
Session.Remove("DefaultDocumentTitle");
lblDocumentTitle.Text = "Data Package File";
}
protected void btnChangeDocumentAttributes_Click(object sender, EventArgs e)
{
lblDocumentCategory.Text = cboDocumentCategory.SelectedValue;
lblDocumentTitle.Text = txtDocumentTitle.Text;
Session["DefaultDocumentCategory"] = lblDocumentCategory.Text;
Session["DefaultDocumentTitle"] = lblDocumentTitle.Text;
}
I also added a dummy button to the page to force a postback refreshing my gridview that shows all the files uploaded.
<asp:Button ID="btnForcePostBack" runat="server" Text="" Style="background-color: Transparent; color: inherit; border-style: none;" />
protected void ajxUpload_Complete(object sender, AjaxControlToolkit.AjaxFileUploadEventArgs e)
{
MyFile f = new MyFile();
f.DocumentType = e.ContentType;
f.FileBytes = e.GetContents();
f.FileName = e.FileName;
f.FileUploaded = DateTime.Now;
if (Session["DefaultDocumentCategory"] == null || Session["DefaultDocumentCategory"].ToString() == string.Empty) f.DocumentCategory = "Data Package Files";
else f.DocumentCategory = Session["DefaultDocumentCategory"].ToString();
if (Session["DefaultDocumentTitle"] == null || Session["DefaultDocumentTitle"].ToString() == string.Empty) f.DocumentTitle = "Data Package File";
else f.DocumentTitle = Session["DefaultDocumentTitle"].ToString();
f.Save();
ajxUploadNDA.Page.ClientScript.RegisterStartupScript(this.GetType(), "RefreshParent", "<script type='text/javascript'>var btn = window.parent.document.getElementById('btnForcePostBack');if (btn) btn.click();</script>");
}
I couldn't get any of these other answers to work. I ended up putting the textbox on an ajax update panel. Then I created an event for the textbox OnTextboxChanged that stored the value in the session. Then I could grab the value in the UploadComplete right from the session.
When using ajax upload, you can only save right away, then second step would be to have separate call to get file from saved location and operate on it. I was having same issue with multiple asynchronous upload using Uploadify and Uploadifive. My first step when uploading multiple files is to save to temp location, then have second call to retrieve it, resize it and save it to cloud (Azure Storage). Its impossible to put a break point, since the threads are all over the place. Its a strange behavior, specially when uploading a single file, but that's the best solution to first save then retrieve using separate call.
The problem is that AjaxFleUpload control use hidden frame for submitting file content. You may use script below to pass textbox value to server:
Sys.Application.add_load(applicationLoadHandler);
function applicationLoadHandler() {
var originalCreateForm = Sys.Extended.UI.AjaxFileUpload.prototype._createVForm;
Sys.Extended.UI.AjaxFileUpload.prototype._createVForm = function () {
originalCreateForm.call(this);
var textBox = document.createElement("INPUT");
textBox.setAttribute("type", "text");
textBox.setAttribute("name", "<%= txtDocumentTitle.UniqueID %>");
textBox.setAttribute("value", document.getElementById("<%= txtDocumentTitle.ClientID %>").value);
this._vForm.appendChild(textBox);
}
}
On server you can get user input from Request.Form collection:
var title = Request.Form[txtDocumentTitle.UniqueID];
I have added the Gridview control on a webPage.
I am deleting any row (one row at a time) by calling PageMethod as follow:
<script type="text/javascript">
function Delete_Row(){
PageMethods.DeleteRow(row_id, GetTimeCallback, ErrorHandler, TimeOutHandler);
}
GetTimeCallback = function (result)
{
if (result) {
alert('Row is deleted');
// I want to refresh the Gridview here
}
}
<script type="text/javascript">
where "row_id" is primery key of the row.
It shows the alert perfectly but does not refresh the Gridview with one less deleted row.
what code should i write to Update the gridview?
NOTE: I dont want to refresh entire page.
Write CallBack Function to acheive this...You can find the Callback Functionality at http://msdn.microsoft.com/en-us/library/ms178208 and http://msdn.microsoft.com/en-us/library/ms178210
Edit:-
protected void Page_Load(object sender, EventArgs e)
{
String cbReference =Page.ClientScript.GetCallbackEventReference(this,
"arg", "ReceiveServerData", "context");
String callbackScript;
callbackScript = "function CallServer(arg, context)" +
"{ " + cbReference + ";}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(),
"CallServer", callbackScript, true);
}
System.IO.StringWriter strDataGridHtml= new System.IO.StringWriter();
public void RaiseCallbackEvent(String eventArgument)
{
string idToBeDeleted=eventArgument;
//Write deleteCode
//DataBind the Grid
HtmlTextWriter htwObject = new HtmlTextWriter(strDataGridHtml);
GridViewControl.RenderControl(htwObject);
}
public String GetCallbackResult()
{
return strDataGridHtml.ToString();
}
Now as you see this strDataGridHtml will be sent to Javascript Function ReceiveServerData...
<script type="text/ecmascript">
function ReceiveServerData(rValue)
{
document.getElementById("divIDWhichEncapsulategridView").innerHTML = rValue;
}
</script>
Hope this Will Help you..As i don't i have your full code i can't write the exact one...but this should give you some idea on how to proceed...And also please go through the "CallBack" Functionality in order to understand this functionality to the fullest..
I have a class that defines a Hierarchical RadGrid that I will be using application wide. This grid has many column so this is the best implementation for me, as I will be overriding specific characteristics of the grid based om implementation.
The grid will function in a different manner based on the access level of the user. On a 'basic user level' they will have a Add New Item/Edit Item on the parent grid and Edit, Reject(delete), Approve(Update) on the Child Grid
The next level will be a 'Approver' role. They will NOT have Add New Item/Edit Item on the parent grid and will only have Reject(Edit) on the child. The edit action that the user will take in this role when rejecting an item is that they will be required to enter a comment through a user control that will be launched when the click the reject button. The problem that I am having is that the custom user control is not displaying for a DetailTableView.EditFormSettings when using a GridButtonColumn as the firing event. Any thoughts? TIA
private void SubmittedBatchesRadGrid_ItemDataBound(object sender, GridItemEventArgs e)
{
GridDataItem _dataItem = e.Item as GridDataItem;
if (_dataItem == null) return;
if (e.Item.OwnerTableView.Name == "SubmittedBatchesRadGrid_ChildGrid")
{
SetChildGridCommandColumns(sender, e);
return;
}
if (_dataItem.KeyValues == "{}") { return; }
SetMasterGridCommandColumns(sender, e, _dataItem);
}
private static void SetChildGridCommandColumns(object sender, GridItemEventArgs e)
{
const string _jqueryCode = "if(!$find('{0}').confirm('{1}', event, '{2}'))return false;";
const string _confirmText = "<p>Rejecting this adjustment will mean that you will have to also reject the batch when you are done processing these items.</p><p>Are you sure you want to reject this adjustment?</p>";
((ImageButton)(((GridEditableItem)e.Item)["PolicyEditRecord"].Controls[0])).ImageUrl = "/controls/styles/images/editpencil.png";
ImageButton _btnReject = (ImageButton)((GridDataItem)e.Item)["DeleteTransaction"].Controls[0];
_btnReject.CommandName = "Update";
_btnReject.ImageUrl = "/controls/styles/images/decline.png";
_btnReject.ToolTip = "Reject this item";
//_btnReject.Attributes["onclick"] = string.Format(_jqueryCode, ((Control)sender).ClientID, _confirmText, "Reject Adjustment");
}
private void SubmittedBatchesRadGrid_DetailTableDataBind(object sender, GridDetailTableDataBindEventArgs e)
{
e.DetailTableView.EditFormSettings.EditFormType = GridEditFormType.WebUserControl;
e.DetailTableView.EditFormSettings.UserControlName = "/Controls/RejectedAdjustmentComment.ascx";
e.DetailTableView.EditMode = GridEditMode.PopUp;
e.DetailTableView.CommandItemSettings.ShowAddNewRecordButton = false;
GridDataItem _dataItem = e.DetailTableView.ParentItem;
e.DetailTableView.DataSource = AdjustmentAPI.GetAdjustmentsByBatch(Convert.ToInt32(_dataItem.GetDataKeyValue("BatchID").ToString()), PolicyClaimManualAdjustmentCode);
}
It looks like you just need to use OnClientClick instead, and return the value of the confirm dialog.
_btnReject.OnClientClick = "return confirm(\"Are you sure you?\");"
RadAjax has a little quirk when it comes to confirm dialogs, so you may need to use this instead:
_btnReject.OnClientClick = "if (!confirm(\"Are you sure?\")) return false;"
So I thought I would share my solution in case anyone else needs it.
I was barking up the wrong tree with the edit control. Even though a comment is part of the dataset in the RadGrid I don't want to edit the existing record. I decided to create a usercontrol to handle the process. The RadWindow does not take .ascx pages directly so I started with a .aspx wrapper page and inserted the control there. Then I changed the OnClientClick event to launch the RadWindow loading the new aspx file passing the parameters I needed to the usercontrol. The usercontrol saves the comment to the database and updates the record status and then closes.
I modified this section from above:
private static void SetChildGridCommandColumns(object sender, GridItemEventArgs e)
{
((ImageButton)(((GridEditableItem)e.Item)["PolicyEditRecord"].Controls[0])).ImageUrl = "/controls/styles/images/editpencil.png";
ImageButton _btnReject = (ImageButton)((GridDataItem)e.Item)["DeleteTransaction"].Controls[0];
int _manualAdjustmentId = Convert.ToInt32(((GridDataItem)e.Item)["ManualAdjustmentId"].Text);
int _manualAdjustmentBatchId = Convert.ToInt32(((GridDataItem)e.Item)["ManualAdjustmentBatchId"].Text);
_btnReject.ImageUrl = "/controls/styles/images/decline.png";
_btnReject.ToolTip = "Reject this item";
_btnReject.OnClientClick = String.Format("OpenRadWindow('/controls/RejectedAdjustmentComment.aspx?manualAdjustmentId={0}&manualAdjustmentBatchId={1}', 'CommentDialog');return false;", _manualAdjustmentId, _manualAdjustmentBatchId);
}
private void SubmittedBatchesRadGrid_DetailTableDataBind(object sender, GridDetailTableDataBindEventArgs e)
{
//I deleted this section
e.DetailTableView.EditFormSettings.EditFormType = GridEditFormType.WebUserControl;
e.DetailTableView.EditFormSettings.UserControlName = "/Controls/RejectedAdjustmentComment.ascx";
e.DetailTableView.EditMode = GridEditMode.PopUp;
//
e.DetailTableView.CommandItemSettings.ShowAddNewRecordButton = false;
GridDataItem _dataItem = e.DetailTableView.ParentItem;
e.DetailTableView.DataSource = AdjustmentAPI.GetAdjustmentsByBatch(Convert.ToInt32(_dataItem.GetDataKeyValue("BatchID").ToString()), PolicyClaimManualAdjustmentCode);
}
I added this to the page with the datagrid:
<telerik:RadWindowManager ID="SubmittedBatchesWindow" runat="server">
<windows>
<telerik:RadWindow ID="CommentDialog" runat="server" Title="Rejected Agjustment Comment Dialog"
Height="350px" Width="440" Left="250px" ReloadOnShow="false" ShowContentDuringLoad="false"
Modal="true" VisibleStatusbar="false" />
</windows>
</telerik:RadWindowManager>
I created a new aspx file and inserted the new ascx control inside
<form id="form1" runat="server">
<telerik:RadScriptManager ID="RadScriptManager1" runat="server">
</telerik:RadScriptManager>
<uc:RejectedComment id="RejectionComment1" runat="server" />
</form>
I added my code behind for the update in the ascx file, the javascript for the front end
<script language ="javascript" type ="text/javascript" >
//<![CDATA[
function GetRadWindow() {
var oWindow = null;
if (window.radWindow) oWindow = window.radWindow; //Will work in Moz in all cases, including clasic dialog
else if (window.frameElement.radWindow) oWindow = window.frameElement.radWindow; //IE (and Moz as well)
return oWindow;
}
function CancelEdit() {
GetRadWindow().close();
}
//]]>
</script>
and last but not least closing the window after a successful update in the button click event;
Page.ClientScript.RegisterStartupScript(Page.GetType(), "", "CancelEdit();", true);
I hope someone else finds this useful. It took me several hours hunting the telerik site to find this piece by piece.