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.
Related
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.
I currently have a listbox (part of a search criteria) that represents a list of strings that are retrieved one at a time via a pop-up window. However when the pop-up window closes the selected String is never added to the listbox. (I have confirmed that the hidden variable is updated and if you navigate away from the page after a search is performed and navigate back, the list box correctly shows Strings I had selected from the pop up previously). Any help would be greatly appreciated!
<script type="text/javascript">
function selectBook(bookId, extendedBookName) {
var idInput = jQuery("#myForm\\:bookNames");
if (idInput.val() == "") {
idInput.val(extendedBookName);
} else {
idInput.val(idInput.val() + '###' + extendedBookName);
}
}
</script>
...
<h:form id="myForm">
...
<ui:define name="form-fields">
<h:selectOneListbox id="booksListBox" size="3" style="width:470px">
<s:selectItems var="_var" value="#{bean.searchCriteria.bookNames}" label="#{_var}" noSelectionLabel="" />
</h:selectOneListbox>
<h:outputLink onclick="return openNewWindow('#{bean.booksLookupUrl}?#{bean.bookLookupParameters}', 'book');"
target="_blank">
<h:inputHidden id="bookNames" value="#{bean.searchCriteria.bookNames}" converter="StringListConverter"/>
<h:outputText value="Add"/>
</h:outputLink>
</ui:define>
...
</h:form>
This is javaScript that belongs to the lookup window. This calls the selectBook function
function selectBook(bookId, extendedBookName) {
var extendedName = unescape(extendedBookName);
window.opener.selectBook(bookId, extendedName);
window.close();
}
And for my Java code...
public class BookSearchCriteria implements Serializable {
...
private List<String> bookNames = new ArrayList<String>();
public List<String> getBookNames() {
return bookNames;
}
public void setBookNames(List<String> bookNames) {
this.bookNames = bookNames;
}
The StringListConverter code...
#FacesConverter("myStringListConverter")
public class StringListConverter implements Converter {
// this is used as a regex, so choose other separator carefully
private static final String MY_SEPARATOR = "###";
#Override
public Object getAsObject(FacesContext context, UIComponent component,
String value) {
if (value == null) {
return new ArrayList<String>();
}
return new ArrayList<String>(Arrays.asList(value.split(MY_SEPARATOR)));
}
#Override
public String getAsString(FacesContext context, UIComponent component,
Object value) {
if (value == null) {
return "";
}
return join((List<String>) value, MY_SEPARATOR);
}
/**
* Joins a String list, src: http://stackoverflow.com/q/1751844/149872
*
* #param list
* #param conjunction
* #return
*/
public static String join(List<String> list, String conjunction) {
StringBuilder sb = new StringBuilder();
boolean first = true;
for (String item : list) {
if (first) {
first = false;
} else {
sb.append(conjunction);
}
sb.append(item);
}
return sb.toString();
}
}
I don't really understand why you want to populate your listBox using a popup.
But if you modify the underlying bean values, you need to rerender the <h:selectOneListbox/> to reflect these changes. If you are using (or can use) the richfaces framework it can be done quite easily through an ajax call.
The ajax4jsf component called <a4j:jsFunction/> can do the job. For example in your parent page add :
<a4j:jsFunction name="refreshListbox" reRender="booksListBox" limitToList="true"/>
and in your popup just call this js function when a new book value is selected :
<script type="text/javascript">
window.opener.refreshListbox();
</script>
You could also use a <rich:modalPanel> instead of a popup to stay in the same page and interact more easily with your jsf components.
The page in the popup window is running some server-side Java code that creates new options for the dropdown menu. This has no absolutely no effect on the parent page until the parent page is reloaded and regenerated by the server. To avoid reloading the page, you need to create and select the new option using client-side JavaScript/jQuery code.
Assuming that the HTML code for the resulting option should look something like <option value="bookId">extendedBookName</option>, you can use this:
<script>
function addBook(bookId, extendedBookName) {
var newOption = jQuery('<option>').val(bookId).text(extendedBookName);
var idInput = jQuery('#myForm\\:bookNames');
idInput.append(newOption).val(bookId);
}
</script>
Demo: http://jsfiddle.net/5Cwjk/
Or, if the selection from the popup window is not guaranteed to be new, then you'll want to dynamically determine whether creating an option is necessary before doing so to avoid duplicates:
<script>
function addBook(bookId, extendedBookName) {
var idInput = jQuery('#myForm\\:bookNames');
if (idInput.val(bookId).val() != bookId) {
var newOption = jQuery('<option>').val(bookId).text(extendedBookName);
idInput.append(newOption).val(bookId);
}
}
</script>
Demo: http://jsfiddle.net/nTtY9/1/
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.
I am having a wizardcontrol, where in one step the user can input his name, emailaddress, phonenumber etc.
When the user press the "Next" button of the wizard, I'm checking the database to see if there is an excisting account with the specified phonenumber.
If that is the case, the system is supposed to ask the user if he will bind the new information to that number, or if he will enter a new phonenumber.
If he says that he will bind the information, the information is binded and wizard proceeds to step2, and if he will enter a new phonenumber the wizard stays at step1.
The code looks something like this:
protected void Wizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
{
if (Wizard1.ActiveStepIndex == 0)
{
Page.Validate();
if (Page.IsValid)
{
if (!Mobile_ValidateForExistingUsers(((TextBox)WizardStep1.ContentTemplateContainer.FindControl("txtPhone")).Text))
{
//JavaScript popup or something, which prompts the user?
}
}
}
}
where the validater is:
protected bool Mobile_ValidateForExistingUsers(string usrPhone)
{
bool IsValid = false;
using (SqlConnection conn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand("spCheckMobile", conn))
{
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#Mobile", usrPhone));
cmd.Connection.Open();
object result = cmd.ExecuteScalar();
if (result == null)
{
IsValid = true;
}
}
return IsValid;
}
How to ask the user this question, and either proceed or let him enter some new information in a wizard?
I think the most effective way to handle this would be to make the Mobile_ValidateForExistingUsers(phoneNumber) function a WebMethod for an AJAX call. Once you write the AJAX code, attach the AJAX call to a <asp:CustomValidator> for its client-side validation function and if it returns false, follow up with your window.alert('use new number').
Alternatively, you can handle most of this through server-side code by using a <asp:CustomValidator>, although there's no need to set a client-side validation function if you're handling the validation server-side. Simply set the CustomValidator1.IsValid property to the results of the Mobile_ValidateForExistingUsers(phoneNumber) function and then call Page.Validate() to see if the page is still valid. If not, flag a runat="server" hidden input and have some client-side code prompt the user on window.onload and if they want to use the new number, store that in a second hidden field. Example follows:
protected void Wizard1_NextButtonClick(object sender, WizardNavigationEventArgs e)
{
if (Wizard1.ActiveStepIndex == 0)
{
Page.Validate();
if (Page.IsValid)
{
if (HiddenField2.Value == '') //Client-side Flag not set
{
if (!Mobile_ValidateForExistingUsers(((TextBox)WizardStep1.ContentTemplateContainer.FindControl("txtPhone")).Text))
{
CustomValidator1.IsValid = false; // Invalidate the page so the Next Step fails.
HiddenField1.Value = false; // Page will get re-rendered to client to fix errors and stay on the same step.
}
}
else
{
if (HiddenField2.Value == 'true')
{
// Use new binding logic.
}
else
{
//User does not want to use new number, so logic to handle goes here.
}
}
}
}
}
And then somewhere in the client-side markup:
/*
* Crude example
*/
<script type="text/javascript">
window.onload = function () {
'use strict';
var hf1 = document.getElementById('<%=HiddenField1.ClientID %>');
var hf2 = document.getElementById('<%=HiddenField2.ClientID %>');
var myForm = document.getElementById('<%=Form1.ClientID %>');
if (hf1.value === 'false') { // or if (hf1.value) if you just want the truthiness of the value's existence (depending on how you flag stuff)
hf2.value = window.confirm('Wanna use this number?').toString().toLowerCase();
}
myForm.submit();
}
</script>
Hope this helps,
Pete
I have made a web user control (.ascx) which consists of the two html textbox and two input buttons, when I try to do document.getElementById('<%=ControlID.ClientID%>') it returns null. what could i have done wrong ?
source code:
<script language="javascript" type="text/javascript">
function intilize() {
var x = document.getElementById('<%=JSNumeric_Control.ClientID%>');
}
</script>
<table class="style1">
<tr>
<td >
<My:UserInfoBoxControl ID="JSNumeric_Control" runat="server" />
</td>
<td>
</td>
</tr>
<tr>
<td colspan="2" style="text-align: center">
<input id="Button1" type="button" value="button" onclick="intilize()" /><br />
</td>
</tr>
</table>
Here is the code for the Numbric.cs, the following are the property used and in page load i am using JavaScript to assign all the events for the HTML inputs:
public partial class NumricCounter : System.Web.UI.UserControl
{
public string defualtValue = "0";
public double defaultIncrementValue = 1;
public int defaultPrecsionValue = 0;
public string Button_Add_ClientID
{
get { return Button_Add.ClientID; }
}
public string Button_Subtract_ClientID
{
get { return Button_Subtract.ClientID; }
}
//Set and Get for all these properties. (Code Omitted)
public string Text;
public double IncrementValue;
public int PrecsionValue;
public void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Text_Output.Value = this.Text;
Button_Add.Attributes.Add("onclick", "Add(" + IncrementValue.ToString() + "," + PrecsionValue.ToString() + ");");
Button_Subtract.Attributes.Add("onclick", "Subtract(" + this.IncrementValue.ToString() + "," + this.PrecsionValue.ToString() + ")");
Text_Output.Attributes.Add("onkeyup", "check(" + this.PrecsionValue.ToString() + ");");
}
}
}
Try replacing your function:
function intilize() {
var x = document.getElementById('<%=JSNumeric_Control.ClientID%>');
}
with this:
function intilize() {
var x = document.getElementById('JSNumeric_Control');
}
The getElementById should read the ID of the element from the rendored html.
JSNumeric_Control.ClientID will return the ClientID of the control if it were rendered to the page. It's existance doesn't necessarily mean that there will be HTML on the final page that has that ID.
For example if you create a control that just outputs two buttons you will give each of those buttons different IDs that are not the same as the control that they live in. Often you might create a container div that you will put around all other content which you will give the ID of the Control to for easy finding but there is no reason for this to exist.
What you should do is either make sure that your control does create this HTML container with the ID of your control or you should refer specifically to the client ID of the items inside your control.
var button1 = document.getElementById('<%=JSNumeric_Control.Button1.ClientID%>');
The problem is that in the DOM there's no element with Id = ClientID of your UserInfoBoxControl. The controls inside your user control will have other Ids, like 'JSNumeric_Control_Button1', 'JSNumeric_Control_TextBox1' etc. If you need to get both of the input buttons, you can do one of the following:
Use jquery selector to find all inputs with type = button and id starting with <%=JSNumeric_Control.ClientID%>
Add two new properties to your control - FirstButtonClientID and SecondButtonClientID that will provide you with clientIDs of your buttons. Then you can use it in javascript.
Create custom javascript object which will represent your usercontrol and provide necessary functionality.
You are most likely trying to search the DOM before it's been loaded. Try putting your code inside an onload handler:
document.onload = function () {
alert(document.getElementById('<%=ControlID.ClientID%>'));
}
This makes sure that the code isn't executed before you actually have all of the DOM loaded.
//Button_Add is the control id inside the user control
var x = document.getElementByID(JSNumeric_Control.FindControl("Button_Add").ClientID);