Getting Javascript values from client on page load - c#

I'm trying to determine the client window size on pageload, to use in creating a bitmap using c#. From reading on SO and elsewhere, I know that one method would be to:
Write a Javascript function to get the relevant values;
Store these in hidden fields;
Read the value using the code behind (c#) and then do stuff with it.
However, I'm getting tripped up by the execution sequence that runs code behind BEFORE any Javascript, even though I've set <body onload... to get and set the relevant values. (see below)
I know the rest of my code works, because, when I execute, the page shows the word "by" and the button. Then, after I have clicked the button and the page reloads, it can now suddenly read the two hidden values.
My question is, how can I get my c# Page_Load code to get those two hidden values from the client side, before it executes the rest of my code, and without the need for user action like clicking a button?
My page:
<body onload="getScreenSize()">
<form id="form1" runat="server">
<input type="hidden" name="hiddenW" ID="hiddenW" runat="server" />
<input type="hidden" name="hiddenH" ID="hiddenH" runat="server" />
<script>
function getScreenSize() {
var myW = document.getElementById("hiddenW");
myW.value = window.innerWidth;
var myH = document.getElementById("hiddenH");
myH.value = window.innerHeight;
}
</script>
<asp:Button ID="Button1" runat="server" Text="Button" />
</form>
</body>
Code behind:
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(hiddenW.Value+" by " +hiddenH.Value);
}
}
On first run (when I need those values), it shows
and after I click the button, it proves the Javascript works:
The question then, is how do I get those values before the rest of my Page_Load code runs, so that I can go straight into generating and displaying my image?

You cannot get the client window size before the C# Page_Load() executes because the page is rendered to the client after the C# code execution is complete.
The window size may change during page load, hence you have to get the window size only after page load is complete.
Solution:
You can use ajax to send the values to the back-end, after the page has loaded completely.
OR
You can cause a post-back using java-script after you get the correct value, this way:
JQuery:
$(function() {
var width = window.innerWidth ||
document.documentElement.clientWidth ||
document.body.clientWidth;
var height = window.innerHeight ||
document.documentElement.clientHeight ||
document.body.clientHeight;
$('#hdn_width').val(width);
$('#hdn_height').val(height);
$('#your_form').submit();
});
C#:
protected void Page_Load(object sender, EventArgs e)
{
try
{
if (IsPostBack)
{
// Use hdn_width and hdn_height here
}
}
catch (Exception ex)
{
}
}

Use the IsPostBack property
This would solve your problem
For Example
if(!Page.IsPostBack)
{
//Control Initialization
//Your code goes here
}

I used a timer to postback once and two none-displayed textboxes to store the window-values width and height. the textboxes are filled with a javascript:
document.getElementById('<%=TxWd.ClientID %>').value = window.innerWidth;
document.getElementById('<%=TxHt.ClientID %>').value = window.innerHeight;
In code behind (VB.NET):
Protected Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Session("seswidth") = Val(TxWd.Text)
Session("sesheigth") = Val(TxHt.Text)
Timer1.Enabled = False
End Sub

Related

How to access the value attribute of a progress tag from backend code

I'm trying to make a progress bar to display during some "modifying" we are doing to 200,000+ rows from an excel document. I just wanted to try something simple, but I can't seem to get the value attribute from the progress tag.
For example if I had something simple like:
<asp:UpdatePanel ID="upnlPercent" runat="server">
<progress id="progressPercent" runat="server"></progress>
</asp:UpdatePanel>
And:
public static void CleanExcelSheet()
{
for(int i = 0; i < rows.Count; i++)
{
... // Clean whatever
progressPercent.Value = i / rows.Count;
upnlPercent.Update();
}
}
Is anyone aware of a simple way I could handle something like this? I'm open to other suggestions also if this doesn't really seem like a viable solution.
Thanks a bunch!
what you would want to do, is store the percent in a session var Session["percent"], and set a Load handler to your update panel where you would update the progress from the session var.
on client side, you would use javascript to make the update panel post back and update each certain amount of miliseconds.
an important thing to remember, is to run your cleaning function on a separate thread so it would not block your app, and allow the app to listen to post backs from the update panel.
here is an example of how to do it:
aspx:
this is our update panel with an element inside which we will update
<asp:UpdatePanel ID="UpdatePanel1" runat="server" OnLoad="UpdatePanel1_Load">
<ContentTemplate>
<label id="Label_For_Server_Time" runat="server"></label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="Button1" runat="server" Text="Click Me" OnClick="Button1_Click" />
in your aspx header, add the following code:
this code calls the built-in asp.net postback function on the update panel, it will fire the Load handler of the update panel without refreshing the whole page
<script type="text/javascript">
window.onload = function () {
setInterval("__doPostBack('<%=UpdatePanel1.ClientID%>', '');", 1000);
}
</script>
code behind:
this is the load handler for the update panel, it fires everytime the panel is posting back from the aspx page, we are checking if the session var exists, and setting the label text:
protected void UpdatePanel1_Load(object sender, EventArgs e)
{
if (Session["percent"] != null)
{
Label_For_Server_Time.InnerText = Session["percent"].ToString();
}
}
this is your function, we are running it on a separate thread to not block the app and setting the session var accordingly.
public void CleanExcelSheet()
{
new Thread(delegate()
{
for (int i = 0; i < 100000000; i++)
{
//... your cleaning here
float _f = (float)i / 100000000;
Session["percent"] = _f;
}
}).Start();
}
protected void Button1_Click(object sender, EventArgs e)
{
CleanExcelSheet();
}
On the server side, the type of progressPercent is HtmlGenericControl, which allows you to get/set properties like this:
progressPercent.Attributes["value"] = (i / rows.Count).ToString();
Or if the attribute is not already present, you may have to do the following:
progressPercent.Attributes.Add("value", (i / rows.Count).ToString());

Fire Serverside event from javascript

i have hiddentfield whose value is changing on javascript.
I just wanted to fire serverside event valuechanged event of hiddenfield when its value changed from javascript.
I tried with :
__doPostBack('hfLatitude', 'ValueChanged');
But giving me error :
Microsoft JScript runtime error: '__doPostBack' is undefined
Is there any other alternative for this?
Please help me.
In javascript, changes in value to hidden elements don't automatically fire the "onchange" event. So you have to manually trigger your code that is already executing on postback using "GetPostBackEventReference".
So, with a classic javascript approach, your code should look something like in the example below.
In your aspx/ascx file:
<asp:HiddenField runat="server" ID="hID" OnValueChanged="hID_ValueChanged" Value="Old Value" />
<asp:Literal runat="server" ID="litMessage"></asp:Literal>
<asp:Button runat="server" ID="btnClientChage" Text="Change hidden value" OnClientClick="ChangeValue(); return false;" />
<script language="javascript" type="text/javascript">
function ChangeValue()
{
document.getElementById("<%=hID.ClientID%>").value = "New Value";
// you have to add the line below, because the last line of the js code at the bottom doesn't work
fValueChanged();
}
function fValueChanged()
{
<%=this.Page.GetPostBackEventReference(hID, "")%>;
}
// the line below doesn't work, this is why you need to manually trigger the fValueChanged methiod
// document.getElementById("<%=hID.ClientID%>").onchange = fValueChanged;
</script>
In your cs file:
protected void hID_ValueChanged(object sender, EventArgs e)
{
litMessage.Text = #"Changed to '" + hID.Value + #"'";
}
Quick and Dirty:
Simply put a asp button on form. Set it display:none.
<asp:Button id="xyx" runat="server" style="display:none" OnClick="xyx_Click" />
On its click event call any server side event.
protected void xyx_Click(o,e)
{
//you server side statements
}
To call its from JS use as below:
<script>
function myserverside_call()
{
var o = document.getElementById('<%=xyx.ClientID%>');
o.click();
}
function anyotherjsfunc()
{
//some statements
myserverside_call();
}
</script>
First way is to use HiddenField.ValueChanged Event.
If you want to also watch this varible in Client Side just use this:
$('#hidden_input').change(function() {
alert('value changed');
});
Second way is to assign value to Varible:
$('#hidden_input').val('new_value').trigger('change');

How to set focus at the end of textbox while typing?

I have a textbox with a live search function. It is working all good except one problem. If I type any characters on it, it just loses its focus. If I set textbox.Focus(), the cursor goes at the beginning of the textbox.
I have tried most of solutions on the internet. Please check my codes below.
asp:TextBox ID="searchCompany" runat="server" Text="" CssClass="searchCompany" AutoPostBack="true" Width="190px" OnTextChanged="searchCompany_TextChanged"></asp:TextBox>
In page_Load
protected void Page_Load(object sender, EventArgs e)
{
//ScriptManager1.RegisterAsyncPostBackControl(Menu1);
menuDisplay();
searchCompany.Attributes.Add("onkeyup", "setTimeout('__doPostBack(\\'" + searchCompany.UniqueID + "\\',\\'\\')', 0);");
//searchCompany.Attributes.Add("onfocus", "javascript:setSelectionRange('" + "','')");
//searchCompany.Focus();
}
and I have tried javascript as below
<script type="text/javascript">
function setSelectionRange() {
var inputField = document.getElementById('searchCompany');
if (inputField != null && inputField.value.length > 0) {
if (inputField.createTextRange) {
var FieldRange = inputField.createTextRange();
FieldRange.moveStart('character',inputField.value.length);
FieldRange.collapse();
FieldRange.select();
}
}
}
</script>
I have tried to put codes on a method "searchCompany_TextChanged" which is calling if user type any characters on a textbox everytime however it is not working as well.
I saw other solutions with using Textbox.Select() but System.Windows.Control is not working in asp.net i guess.
Any idea??
There's a very simple trick that's worked for me. Basically, set the text value of the of input to itself to its own text value, and that will move the cursor to the end of the text. Then just focus it. This code uses jQuery to demonstrate that, but you should be able to do that in straight JS as well.
HTML
<input type="text" id="focusText"></input>
<button id="focusButton">Set Focus</button>
JavaScript
$("#focusButton").click(function() {
var text = $("#focusText").val();
$("#focusText").val(text).focus();
})
Here's a non jQuery example of the JavaScript, HTML should be the same:
document.getElementById("focusButton").onclick = function() {
var inputElement = document.getElementById("focusText");
var text = inputElement.value;
inputElement.value = text;
inputElement.focus();
}
Here's a fiddle demonstrating the non-jQuery version of the code: http://jsfiddle.net/C3gCa/

Page.Unload Event inside a Update Panel

I have a Image Button declared as,
<div>
<asp:ImageButton ID="btnDoWork" runat="server" ImageUrl="/_LAYOUTS/1033/IMAGES/row.png" ValidationGroup="Page" />
</div>
<div>
<asp:RequiredFieldValidator runat="server" ID="reqName" ControlToValidate="txtEmail" ValidationGroup="Page" ErrorMessage="enter a email" />
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ValidationExpression="^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$" ControlToValidate="txtEmail" ValidationGroup="Page" ErrorMessage="enter a email" />
</div>
within a update panel,
now in code behind I am doing something like this,
btnDoWork = (ImageButton)this.control.FindControl("btnDoWork"); //this code is in childcontrols method
btnDoWork.Click += new ImageClickEventHandler(btnDoWork_Click);
then
protected void btnDoWork_Click(object sender, ImageClickEventArgs e)
{
//Process a bit of code and at end,
this.Page.Unload += new EventHandler(Page_Unload_MessageBox);
and then in button click event,
public static void Page_Unload_Page_Unload_MessageBox(object sender, EventArgs e)
{
System.Globalization.CultureInfo _culture = Thread.CurrentThread.CurrentUICulture;
StringBuilder sb = new StringBuilder();
sb.Append("<script language=\"javascript\">");
sb.Append("$('body').append(\"<div id='M'><span id='text'>" +
SPUtility.GetLocalizedString("$Resources:abc", "def", (uint)_culture.LCID) +
"</span><br/><div id='BB' onclick='return BB();'><a href='' onclick='return BB();'>" +
SPUtility.GetLocalizedString("$Resources:OK", "def", (uint)_culture.LCID) +
"</a></div></div>\");");
sb.Append("function BB() { $('#M').remove(); $('#E').remove(); return false; }");
sb.Append("function dM(){ var browser = navigator.appName; if (browser == 'Netscape') { $('#M').css({ 'top': '5%' }, 500); } }");
sb.Append("</script>");
// Write the JavaScript to the end of the response stream.
HttpContext.Current.Response.Write(sb.ToString());
Now if I put email address I get error while when it tries to Response.Write I think, I wonder what alternative is there, e.g. can I use triggers in update panel or any other event or something..
here's the error I am getting now,
Note: I changed all variable names so don't get confused if something doesn't match
The message is very clear, you can not add this command HttpContext.Current.Response.Write on update panel, and that because can not know how to handle it, because the update panel is return a struct that is used by the javascript to redraw some part of the page.
The solution is to add a literal control inside the UpdatePanel, in the place you wish to add the extra html code, and write that control the render as:
txtLiteralID.Text = sb.ToString();
How ever, here you have a diferent situation than the normal, you won to render and run a script.
The main problem is how to trigger the script to run. The only way is to use the UpdatePanel handler that is this standard code:
<script type="text/javascript">
// if you use jQuery, you can load them when dom is read.
$(document).ready(function () {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(InitializeRequest);
prm.add_endRequest(EndRequest);
});
function InitializeRequest(sender, args) {
}
function EndRequest(sender, args) {
// after update occur on UpdatePanel run the code.
UnloadMsgBox();
}
</script>
Now on the EndRequest you need to call your script, where it may all read exist in your code as:
function UnloadMsgBox()
{
// render your code of the javascript.
$('body').append(\"<div id='M'><span id='text'></span><br/><div id='BB' onclick='return BB();'><a href='' onclick='return BB();'></a></div></div>\");
function BB() { $('#M').remove(); $('#E').remove(); return false; }"
function dM(){ var browser = navigator.appName; if (browser == 'Netscape') { $('#M').css({ 'top': '5%' }, 500); } }"
}
and not need to render it on UpdatePanel.
To summarize:
On the update panel you can not use the Response.Write to render something but a literal control, that renders inside him.
On the update panel you can not render javascript code and expect to run, to run a javascript code you need to use the EndRequest handler that comes with the UpdatePanel.
MS Ajax calls perform full page rendering, calculate the diff from the original, send the diff to the client, and magically merge the diff in the browser.
If you just send javascript as response, it's something the framework does not expect and it throws the message.
See a previous answer on how to invoke javascript from an UpdatePanel.

Get variable & keep changes after postback

This question is related to: Hide div on clientside click
The issue I am having is that after postback event from asp.net happens onClick any clientside changes made reset how can I keep the client side changes I am making.
Second question how can I get a variable from code behind and pass it into my javascript to perform a comparison.
Html:
<div runat="server" id="someDiv1" enableviewstate="true" >
<asp:LinkButton OnClientClick="Show_Hide_Display()"
ID="lbtnDiv1"
runat="server"
CausesValidation="true"
OnClick="lbtn_onClickServer">
</asp:LinkButton>
</div>
<div runat="server" class="tick" id="div2" style="display:none;" enableviewstate="true">
</div>
Javascript:
<script type="text/javascript">
function Show_Hide_Display() {
var div1 = document.getElementById("<%=someDiv1.ClientID%>");
var div2 = document.getElementById("<%=div2.ClientID %>");
if (div1.style.display == "" || div1.style.display == "block") {
div1.style.display = "none";
div2.style.display = "block";
}
else {
div1.style.display = "block";
div2.style.display = "none";
}
}
</script>
The OnClick event causes a postback like it should, on this occassion it checks if users, chosen username is available.
If it is available show a tick, if it isn't error.
I got the error working and am trying to program the tick on client side.
So OnClientClick I am able to toggle between some text and a tick. So I need to:
Get the bool result from code behind
After postback keep tick (if username is available)
I am almost there but can't quite figure the last two points out.
If you are using an UpdatePanel in your page, and assuming that div which you are trying to toggle is outside the control, you can always inject javascript on a partial postback:
Like for e.g. on your button's click event which executes on a partial postback make a call to ScriptManager.RegisterClientScriptBlock() --> How to retain script block on a partial postback?
Alternatively, you can append an end request handler. This is some javascript which should run after the partial postback. --> ASP.NET Register Script After Partial Page Postback (UpdatePanel)
The answer for the both questions lies of checking the boolean value send from the code behind.
1-----.in code-behind c#
protected void Page_Load(object sender, System.EventArgs e)
{
var linkbtn = (Button)Page.FindControl("lbtnDiv1");
linkbtn .Attributes.Add("onClick", "Show_Hide_Display('" + parameter+ "')");
}
2------- change your javascript
function Show_Hide_Display(parameter)
{
if( paramater=='true')
{
----your logic---
}
else
{
----your logic
}
}

Categories

Resources