Call to ClientScript doesnot preserve value in Controls of Web Page - javascript

I have a small problem . If page is refreshed using F5 , TextBox should preserve its old value . In Page_Load() , if i keep // Loading(); then TextBox1 preserve its old value.
As soon as i remove comment , it loose value in TextBox1 .
Please tell me the reason behind it and What should be done to avoid it .
<script type="text/javascript">
function TextBox1_TextChanged() {
<%
Session["HitCount1"] = TextBox1.Text ;
%>
}
function getMyvalSession() {
var ff = "Loading Value";
return ff;
}
</script>
<body>
<form id="form1" runat="server">
<asp:TextBox ID="TextBox1" Name="TextBox1" runat="server"
AutoPostBack='true' onchange="TextBox1_TextChanged()"></asp:TextBox>
<%
string x = null;
x = Session["HitCount1"].ToString().Trim();
if ((x.Equals(null)) || (x.Equals("")))
{
// Session Variable is either empty or null .
}
else
{
TextBox1.Text = Session["HitCount1"].ToString();
}
%>
</form>
</body>
protected void Page_Load(object sender, EventArgs e)
{
// Loading();
}
void Loading()
{
String csname = "OnSubmitScript";
Type cstype = this.GetType();
// Get a ClientScriptManager reference from the Page class.
ClientScriptManager cs = Page.ClientScript;
// Check to see if the OnSubmit statement is already registered.
if (!cs.IsOnSubmitStatementRegistered(cstype, csname))
{
string cstext = " document.getElementById(\"TextBox1\").value = getMyvalSession() ; ";
cs.RegisterOnSubmitStatement(cstype, csname, cstext);
}
}

Combining inline server-side code and code-behind code is generally a bad idea. I would recommend just using the code-behind code.
This code:
function TextBox1_TextChanged() {
<%
Session["HitCount1"] = TextBox1.Text ;
%>
}
... is not going to have the effect of the (server-side) Session entry "HitCount1" getting set to Textbox1.Text, because TextBox1_TextChanged is a client-side function, and your assignment statement is going to happen on the server side. At run time, the chunk of server code will have been removed by the compiler, so TextBox1_TextChanged will be an empty function.
The rule of thumb: Things happen on the client, or they happen on the server on postback, or they happen on the server via Ajax calls. You can't mix client and server code together.
My recommendation: switch to doing everything in code-behind. When you have it working, if you have too many postbacks, investigate Ajax calls.

Related

Adding Hyperlinks to ValidationSummary using programatically added validators

I'm using the javascript from the answer in this question in a project of mine:
Adding Hyperlinks to ValidationSummary
It works really great. I've added it to the bottom of my masterpage (for some reason, even though it is inside $(document).ready, Page_Validators is null if i place it in the head section)
Anyway! I'm also adding some custom validators programatically on postback using this code:
public static CustomValidator ReturnErrorMessage(string message, string validationGroup, string controlToValidate = "")
{
CustomValidator control = new CustomValidator();
control.ID = "cv" + controlToValidate;
control.IsValid = false;
control.Text = " ";
control.ValidationGroup = validationGroup;
control.ErrorMessage = message;
control.ControlToValidate = controlToValidate;
return control;
}
However whenever I add a CustomValidator like that, in a button event, page_load or whatever, Page_Validators will be overridden and the errormessage will revert to the message without a anchor.
What gives? Am I doing something wrong or can someone explain what is happening?
I've tried debugging it and it does set the values correctly, but then it just reset afterwards.
I've tried for the heck of it and in $(document).ready set all validators as isvalid = false, and that gets overwritten too.
Im using asp.net 4.5 unobtrusive validation, but it does not make a difference if I turn it off.
Adding the javascript in code using Page.ClientScript.RegisterStartupScript at some point after the validator has been created does not work either.
If I don't add any validators in code everything works as expected.
I'm aware I can just add the anchor tags manually, but this is a lot of work to update existing validators instead of just tossing in a small script, so I'm hoping to get this to work.
You can use this code to test this:
using System;
using System.Web.UI.WebControls;
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
CustomValidator control = new CustomValidator();
control.ID = "cv" + txtName.ClientID;
control.IsValid = false;
control.Text = " ";
control.ValidationGroup = "errorGroup";
control.ErrorMessage = "Error message";
control.ControlToValidate = txtName.ClientID;
Form.Controls.Add(control);
}
}
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebForm1" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="jquery-3.3.1.min.js"></script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<asp:ValidationSummary ID="vsSummary" runat="server" ValidationGroup="errorGroup" ForeColor="Red" HeaderText="Error!" />
</div>
</form>
<script>
$(document).ready(function() {
var validators = Page_Validators; // returns collection of validators on page
$(validators).each(function() {
//get target control and current error validation message from each validator
//[0] is needed when using aspnet 4.5 unobtrusive validation
var validator = $(this)[0];
var errorMsg = validator.errormessage;
var targetControl = validator.controltovalidate;
//make link only if theres a control to target
if (targetControl) {
var errorMsgWithLink = "<a href='#" + targetControl + "' style='color: #FF3232;'> " + errorMsg + "</a>";
//update error message with anchor tag
validator.errormessage = errorMsgWithLink;
}
});
});
</script>
</body>
</html>
If you want you can try implementing your own 'CustomValidationSummary' control by following the same design pattern as mentioned at Reference Source by Microsoft, and modify the render method to include anchor tag to wrap error text, before it is passed into the writer method at line number 462.
I ended up using a extension method, adding the anchor tag in the method
public static void AddValidator(this Page p, string message, string validationGroup, string controlToValidate = "", bool addAnchorTags = true)
{
CustomValidator control = new CustomValidator();
control.ID = "cv" + controlToValidate;
control.IsValid = false;
control.Text = " ";
control.ValidationGroup = validationGroup;
control.ControlToValidate = controlToValidate;
if (addAnchorTags && !string.IsNullOrEmpty(controlToValidate))
{
control.ErrorMessage = "<a href='#" + controlToValidate + "' style='color: #FF3232;'> " + message + "</a>";
}
else
{
control.ErrorMessage = message;
}
p.Validators.Add(control);
}

How to get value of application variable in JavaScript from asp.net?

I want to access the value of an application variable in JavaScript. How can I do that?
Declare a public property in codebehind.
public string firstName = "Sanju";
Access this in JavaScript like this.
<script>
var myName;
function GetMyName()
{
myName = <%=this.firstName%>
}
</script>
To Access value in Session State, use this.
myName = '<%=Session["firstName"]%>'
To Access value in Application State, use this.
myName = '<%=Application["firstName"]%>'
You can make the variable public to access in javascript.
In code behind.
public string YourVar = "hello";
In javascript
alert("<%= YourVar %>");
Note the value of the server side variable is substituted in generated html / javascript once the response is sent. If you want to access it from javascript after page is loaded then you might need to use ajax call to fetch value from server.
The following gets the ClientID of the rendered control
//markup
<asp:TextBox ID="aTextBox" runat="server" />
<asp:TextBox ID="bTextBox" runat="server" />
<asp:TextBox ID="cTextBox" runat="server" />
//script
var Members =
{
aTextBox: $("#<%=aTextBox.ClientID %>"),
bTextBox: $("#<%=bTextBox.ClientID %>"),
cTextBox: $("#<%=cTextBox.ClientID %>")
}
Try the Sessions...
Make a session in your class (I assume you have a General class)and use its reference to access it on any page you want. But remember you have to assign a value before using it.
e.g,
below is a session of UserID.
public static int UserId
{
get
{
if (HttpContext.Current.Session["UserId"] != null)
return Convert.ToInt32(HttpContext.Current.Session["UserId"]);
else
return 0;
}
set
{
HttpContext.Current.Session["UserId"] = value;
}
}
First you have to store value in your session as soon as you application starts.
User user = new user(); // consider you have a User class
protected void btnLogin_OnClick(object sender, EventArgs e)
{
_user.Username = this.txtUserName.Text;
_user.Password = this.txtPassword.Text;
if (_user.Validate())
{
General.UserID = _user.UserID; // here you are storing the id of logged in user
Response.Redirect("~/HomePage.aspx");
}
else
{
this.labelNotice.Text = "Invalid Username or Password";
}
}
To access the value of this session on any page in javascript,
<%# Import Namespace="MyProject.Models" %>
<script type="text/javascript">
var myID;
function GetMyID() {
myID= '<%=General.UserId%>';
}
</script>
I imported my General class which is placed in the Models folder in MyProject solution.

Async Javascript callback not triggering the RaiseCallBackEvent function

In my asp.net application I used the async javascript callback.
The requirement is once the user enters the Postal code an async javascript callback function should be called. And the server side code must return me the city with respect to the postal code.
The coding I did is:
<asp:TextBox ID="txtPostCode" runat="server" CssClass="textbox" onchange="javascript: getCityAndStreet();" BorderStyle="Ridge" Height="20px" style="margin-left: 10px" Width="442px"></asp:TextBox>
This textbox onchange it will call the javascript function getCityAndStreet()
function getCityAndStreet()
{
var postalCode = document.getElementById('<%=txtPostCode.ClientID%>');
CallServer(postalCode.value, "");
}
function ReceiveCityAndStreet(rValue,context)
{
alert(rValue);
var city = document.getElementById('<%= txtCity.ClientID%>');
city.value = rValue;
}
Here the CallServer is the server side runtime javascript which is registered as below
protected void Page_Init(object sender, EventArgs e)
{
String cbReference = Page.ClientScript.GetCallbackEventReference(this, "arg", "ReceiveCityAndStreet", "context",true);
String callbackScript;
callbackScript = "function CallServer(arg, context)" + "{ " + "alert('Entered inside CallServer' + arg);" + cbReference + ";}";
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);
}
I implemented the ICallBackHandler and by this I got 2 methods:
string ICallbackEventHandler.GetCallbackResult()
{
return cityAndStreet;
}
void ICallbackEventHandler.RaiseCallbackEvent(string eventArgument)
{
txtStreet.Enabled = true;
txtCity.Enabled = true;
cityAndStreet = eventArgument;
}
in page_load function I just disabled the txtStreet.Enabled. txtCity.Enabled text boxes and on the raise callbackevent I am enabling it.
The issue here is the RaiseCallBackEvent is not working. I mean its not been triggered implicitly.
(This application is not accessed directly in the browser it is accessed through the SharePoint site)
I think the problem is that your button actually does postback when you click on it. You do not need postback because you are calling server using AJAX. Try changing onchage handler to this:
onchange="getCityAndStreet();return false;"
This will cause your button not to trigger postback.
EDIT: Also i want to mention that you cannot change controls in RaiseCallBackEvent method. It is not an actual postback. You need to enable text fields using javascript in onSuccess method.

Calling JS function from ASP.NET codebehind

I have two javascript functions in my aspx page. They use some fabric.js functions.
function saveCanvas() {
js = JSON.stringify(canvas.toDatalessJSON());
$get('<%= txtJSON.ClientID%>').value = js;
}
function loadCanvas() {
js = $get('<%= txtJSON.ClientID%>').value;
canvas.clear();
canvas.loadFromDatalessJSON(js);
canvas.renderAll();
}
And in the codebehind:
Protected Sub SaveJSON()
Dim scriptKey As String = "123"
Dim javaScript As String = "<script type='text/javascript'>saveCanvas();</script>"
ClientScript.RegisterStartupScript(Me.GetType(), scriptKey, javaScript)
End Sub
Protected Sub LoadJSON()
Dim scriptKey As String = "456"
Dim javaScript As String = "<script type='text/javascript'>loadCanvas();</script>"
ClientScript.RegisterStartupScript(Me.GetType(), scriptKey, javaScript)
End Sub
Now my question: Why does loadCanvas work while saveCanvas does not? txtJSON is not populated with the JSON-string.
Calling the saveCanvas function from the aspx page works fine.
The problem is that you call saveCanvas after the postback is done and at that point the canvas data is long gone.
If you have a button "Save" then you need to call saveCanvas when it is clicked so that the data is saved before the browser posts the page back to the server:
<asp:Button runat="server" Text="Save" OnClickClick="saveCanvas()" />

ASP.NET: HtmlGenericControl <DIV> - refresh

I have a DIV element:
<div runat="server" id="path">Nothing here... yet</div>
and JavaScript which changes its content dynamically. After some actions my element looks like this (tested with Firebug, JS is ok):
<div runat="server" id="path">FirstTest - SecondTest - ThirdTest</div>
Then I'd like to save it to text file (<asp:Button runat="server"...):
<script runat="server">
void Page_Load(Object sender, EventArgs e)
{
Button1.Click += new EventHandler(this.GreetingBtn_Click);
}
void GreetingBtn_Click(Object sender, EventArgs e)
{
HtmlGenericControl path = (HtmlGenericControl)Page.FindControl("path");
Response.AddHeader("content-disposition", "attachment;filename=download.txt");
Response.ContentType = "text/plain";
Response.Write(path.InnerText);
Response.Flush();
Response.Clear();
Response.End();
}
</script>
It also works OK (SaveDialog popups, user choose location), but... in output file there's only one line "Nothing here... yet". It looks like he doesn't react to changes made by JavaScript!
How can I force him to refresh DIV, so I can always save up-to-date content?
Thanks for any help!
You could update an asp:Hidden with the new value and use that value instead on the post back. The PlaceHolder control is not designed to be a two-way control.
E.g.
function UpdateText()
{
var text = ...;
document.getElementById("<%= path.ClientID %>").innerText = text;
document.getElementById("<%= pathHidden.ClientID %>").value = text;
}

Categories