Problem Registering onsubmit statement for Extended button control - asp.net

Hi I recently fell in love with an extended upload button control I found here that when used together with an aspnet file upload control, can perform uploads in a gmail-like manner. The only problem is that when the control is placed on a page any button on that page will trigger the click event of the extended control.
I had no idea why this was happening until I looked at the source code.
/// Basic registration of events
protected override void OnInit(EventArgs e)
{
this.Page.LoadComplete += new EventHandler(Page_LoadComplete);
base.OnInit(e);
this.Page.ClientScript.RegisterClientScriptInclude(this.GetType(), "ScriptBlock", this.Page.ClientScript.GetWebResourceUrl(this.GetType(), "WebControls.JScripts.AIMScript.js"));
string cid = this.ClientID;
string onsubmitstatement = "return AIM.submit( document.forms[0], {'onStart' : " + OnStartScript + ", 'onComplete' : " + OnCompleteScript + "})";
this.Page.ClientScript.RegisterOnSubmitStatement(this.GetType(), "OnSubmitScript", onsubmitstatement);
}
From what I can gather the problem lies in the control registering the 'onsubmitstatement' for all controls
on pages form i.e 'document.forms[0]'. Now I have very limited experience in authoring custom controls so all my efforts to register the 'onsubmitstatement' for only the upload control has failed e.g
string ctrlid = this.ClientID
string onsubmitstatement = "return AIM.submit( document.getElementById('" + ctrlid + "'), {'onStart' : " + OnStartScript + ", 'onComplete' : " + OnCompleteScript + "})";
can any one help me? Is there a way to register the onsubmit function for only this control ?

We'd need to know what exactly AIMScript.js is actually doing to really answer the question.
The basic idea though is that you need to change the javascript so it does it's thing on the click event for a particular button, rather than intercepting the submit event for the entire form. But it could be that this particular javascript might be dependent on a form element in some other ways too.
It could be as simple as changing the registrations to just register a javascript DoClick function like this:
string onsubmitstatement = "function DoClick() {return AIM.submit( document.forms[0], {'onStart' : " + OnStartScript + ", 'onComplete' : " + OnCompleteScript + "})}";
this.Page.ClientScript. RegisterClientScriptBlock(this.GetType(), "OnSubmitScript", onsubmitstatement);
Then in on the actual button control, wire it up to call the new DoClick() javascript function you registered above --like this:
<input type="button" value="ClickMe" onclick="DoClick()" />

Related

WebForm: Update textbox from another thread

In WebForm, How Update textbox from another thread
lock (tbConsole)
{
tbConsole.Text += "\r\n server:" + text;
}
You usually don't.
Code Behind is executed on the server, then the resulting Page is sent to the client/browser. At that point, the life cycle of your C# Code Behind is over.
You need to use the Invoke method of the control to run the code on the UI thread:
tbConsole.Invoke(new Action(() => tbConsole.Text += "\r\n server:" + text));

Is it possible to handle events from an activeX object in Classic ASP

From another question I recently posted, it seems that Classic ASP might not be able to deal with events that an activeX object might throw.
Can anybody verify this or if it can, how do I do it?
Is it possible to handle events from an activeX object in Classic ASP
No, if you are speaking about COM events.
But, Depending on what you mean by the word "event" the answer is "Maybe."
See Create COM/ActiveXObject in C#, use from JScript, with simple event
It's possible to create a COM class / ActiveX thing, instantiate it in JScript/Classic ASP, and have the COM class invoke a callback that is defined in the ASP page. This is not done via COM events, but it may satisfy your requirement.
The ASP code might look like:
<script language="Javascript" runat="server">
var greet = Server.CreateObject("Ionic.Greet");
greet.onHello = function(arg, num) {
Response.Write("onHello (ASP) invoked.<br/>\n");
Response.Write(" num = " + num + " stat=" + arg.status + "<br/>\n");
};
response = greet.Hello("ASP");
Response.Write("response: " + response + "<br/>\n");
Response.Write("status: " + greet.status + "<br/>\n");
</script>
This works only if the COM class being created exposes a property that can be set, and then invokes the "Default method" on that property. Like this:
public partial class Greet : IGreet
{
public Object onHello { get; set; }
public String Hello(string name)
{
var r = FireEvent();
return "Why, Hello, " + name + "!!!" + r;
}
}
...where FireEvent is like this:
private string FireEvent()
{
if (onHello == null) return " (N/A)";
onHello
.GetType()
.InvokeMember
("",
BindingFlags.InvokeMethod,
null,
onHello,
new object [] {});
return "ok";
}
Obviously if you have a COM class that cannot be changed, and it uses COM events, then this approach will not apply.
You are correct ASP cannot handle events. It does not have the either the CreateObject signature needed to wire up script functions to events nor does it support the <script FOR syntax that you might use client-side.

HiddenField Cannot be Referenced in CodeBehind file

I have the following HiddenField in my ASP.NET 2.0 webform:
<asp:HiddenField ID="HiddenModel" runat="server"
OnValueChanged="HiddenModel_ValueChanged" />
My codebehind references HiddenModel in this if..else statement:
if (serial.Text.ToString() != "0")
{
CarpetMultiView.ActiveViewIndex = 1;
HiddenModel.Value = model.SelectedItem.Text.ToString();
LabelCurrent.Text = "Your Current Selection is :
Make-" + make.SelectedItem.Text.ToString() + " Model-" +
model.SelectedItem.Text.ToString() + " S/N-" + serial.SelectedItem.Text.ToString();
Page.Title = make.SelectedItem.ToString() + " " + model.SelectedItem.ToString() + " " +
serial.SelectedItem.ToString() + " " + "Carpet";
}
When I debug the solution using VWD 2005, I receive the following error:
The name 'HiddenModel' does not exist in the current context
My #Page directive inherits carpet_template which matches the codebehind class:
public partial class carpet_template : System.Web.UI.Page
How can I resolve these and other similar errors?
From the link below:
"If you are testing in IIS, you should go to the website menu in VWD, click start options, click "build" on the tree in the left pane, and on the dropdown list labelled "Before running startup page" select "No Build".
Full story HERE.
Its difficult to be sure when the code is out of context of the page life cycle, but it sounds like asp.net simply doesn't accept that the field currently exists.
The most logical reason is that the hidden field doesn't yet exist in the page life cycle (see page lifecycle) - is the code run before the page has been loaded or before the control has been rendered?
Alternatively if there is a problem with the form you could get this behaviour (eg if the hidden field is not within the form tags).
Delete all the backup copies of the same files. I had a backup copy of the same file in same folder, after deleting those backup files - solution is compiling without any errors.
Got this solution from link below: [slash84]
http://forums.asp.net/post/3060379.aspx

Button clicked twice before postback

This is really driving me crazy having been on it for hours.
I have a url whose query strings are concatenated based on selected items on a form, I need to do a post to this url, but an imagebutton control has to be clicked for the post to occur. I put the PostBackUrl property of the imagebutton inside the event of the image button, hence causing it to be clicked twice before eventually posting the url... but i really need to click once but this aint working. I know why its clicking twice, tried calling the url with javascript but it wasnt working.
Below is the code. Please help me with code samples cos am still a newbie, kinda. Thanks
protected void searchImageButton_Click(object sender, ImageClickEventArgs e)
{
returntype = tidRadioButtonList.SelectedItem.Value;
dateDlabel = selddate1TextBox.Text.Trim();
dateAlabel = seladate1TextBox.Text.Trim();
depart = seldcity1DropDownList.SelectedItem.Value;
arrive = selacity1DropDownList.SelectedItem.Value;
flightclass = selcabinclassDropDownList.SelectedItem.Value;
adult = seladultsDropDownList.SelectedItem.Text;
child = selchildrenDropDownList.SelectedItem.Text;
infant = selinfantsDropDownList.SelectedItem.Text;
result = resultbyRadioButtonList.SelectedItem.Value;
promos = promocodeTextBox.Text.Trim();
string theURL = "http://yyy.xxx.com/CAB/SessionHandler.aspx?target=%2fCAB%2fIBE.aspx&pub=%2fng%2fEnglish&Tab=1&s=&h=?tid=" + returntype +
"&seldcity1=" + depart.Trim() + "&selddate1=" + dateDlabel + "&selacity1=" + arrive.Trim() + "&seladate1=" + dateAlabel + "&selcabinclass=" + flightclass
+ "&seladults=" + adult + "&selchildren=" + child + "&selinfants=" + infant + "&resultby=" + result + "&promocode=" + promos;
searchImageButton.PostBackUrl = theURL;
}
But you are saying ASP.NET to cause postback twice. PostBackUrl is special property for cross page postback but if you set it to the same page you will get the postback twice. First postback is common processing which occures because user clicks ImageButton. Second is initiated because you set up PostBackUrl. For your scenario you can't use ImageButton. Use HyperLink and place img inside the link. Btw. what are you trying to achieve with that code?
Since you need to postback to another url, why not use
Response.Redirect(theURL);

Generating an action URL in JavaScript for ASP.NET MVC

I'm trying to redirect to another page by calling an action in controller with a specific parameter. I'm trying to use this line:
window.open('<%= Url.Action("Report", "Survey",
new { id = ' + selectedRow + ' } ) %>');
But I couldn't make it work; it gives the following error:
CS1012: Too many characters in character literal.
Can't I generate the action URL this was on the client side? Or do I have to make an Ajax call by supplying the parameter and get back the needed URL? This doesn't seem right, but I want to if it's the only way.
Is there an easier solution?
Remember that everything between <% and %> is interpreted as C# code, so what you're actually doing is trying to evaluate the following line of C#:
Url.Action("Report", "Survey", new { id = ' + selectedRow + ' } )
C# thinks the single-quotes are surrounding a character literal, hence the error message you're getting (character literals can only contain a single character in C#)
Perhaps you could generate the URL once in your page script - somewhere in your page HEAD, do this:
var actionUrl =
'<%= Url.Action("Report", "Survey", new { id = "PLACEHOLDER" } ) %>';
That'll give you a Javascript string containing the URL you need, but with PLACEHOLDER instead of the number. Then set up your click handlers as:
window.open(actionUrl.replace('PLACEHOLDER', selectedRow));
i.e. when the handler runs, you find the PLACEHOLDER value in your pre-calculated URL, and replace it with the selected row.
I usually declare a javascript variable in the section to hold the root of my website.
<%="<script type=\"text/javascript\">var rootPath = '"
+ Url.Content("~/") + "';</script>" %>
To solve your problem I would simply do
window.open(rootPath + "report/survey/" + selectedRow);
Could you do
window.open('/report/survey/' + selectedRow);
instead where selected row I assume is the id? The routing should pick this up fine.
or use getJSON
Perhaps you could use JSONResult instead. Wherever the window.open should be call a method instead i.e. OpenSurveyWindow(id);
then add some jquery similar to below
function OpenSurveyWindow(id){
$.getJSON("/report/survey/" + id, null, function(data) {
window.open(data);
});
}
now in your controller
public JsonResult Survey(int id)
{
return Json(GetMyUrlMethod(id));
}
That code isnt syntactically perfect but something along those lines should work
Just if someone is still looking for this. The controller action can have normal parameters or a model object with these fields. MVC will bind the valus automatically.
var url = '#Url.Action("Action", "Controller")';
$.post(url, {
YearId: $("#YearId").val(),
LeaveTypeId: $("#LeaveTypeId").val()
}, function (data) {
//Do what u like with result
});
You wont be able to do this, the URL.Action is a server side process so will parse before the clientside selectedRow is available. Israfel has the answer I would suggest.
If selectedRow is a client-side variable, it won't work. You have to use #Israfel implementation to link. This is because the server-side runs before the client-side variable even exists.
If selectedRow is a server-side variable within the view, change to this:
window.open('<%= Url.Action("Report", "Survey", new { id = selectedRow } ) %>');
This is because the id will infer the selectedRow variable type, or you could convert to string with ToString() method (as long as it's not null).
A way to do this that might be considered cleaner involves using the T4MVC T4 templates. You could then write the JavaScript inside your view like this:
var reportUrl = '<%= Url.JavaScriptReplacableUrl(MVC.Survey.Report())%>';
reportUrl = myUrl.replace('{' + MVC.Survey.ReportParams.id + '}', selectedRow);
window.open(reportUrl);
The advantage of this is that you get compile-time checking for the controller, action, and action parameter.
One more thing that can be done, no so clean i guess:
var url = "#Url.RouteUrl(new { area = string.Empty, controller = "Survey", action = "Report" })";
var fullUrl = url + '?id=' + selectedRow;
The easiest way is to declare a javascript variable than concate your parameter value to the link.
var url = '#Url.Action("Action","Controller")' + "/" + yourjavascriptvariable;
<a href='" + url + "'>

Resources