3

I've look an found only a similar post and didn't really answer my question or maybe they did but I didn't understand. The post I read was this one: Why does this javascript variable I'm creating via C# only get updated once?

I'm using a paged gridview and every time it's object data source runs the SelectCountMethod, I use the returning value on javascript. But, I've noticed that even thought that same returned value changes, on the server side. On javascript this value doesn't update.

My program is quite long but I'll use a basic example and hopefully some of you will understand it.

Client side:

function SomeFuntion()
{
    alert("<%=num%>");
}

Server side:

//Global variable
Public Static int num = 0;

Public int SelectCountMethod()
{                  
    var num = SomeMethod(); //Returns int

    return num;
}

For example, on the server side num returns 60 and then this value updates to 7. On the server side num equals 7 but on the client side it's still 60. Is there a way to update the client sides value?

I apologies for my poor typing skills, English is not my native language. Some examples might be helpful and thanks in advance.

I noticed that it doesn't mater where I update this variable(on selectCount method or any other method), on the client side doesn't update.

Community
  • 1
  • 1
  • 4
    Where is your server side code at? You can't normally just "push" changes from the server to the client on demand, you'd need to use something like [SignalR](http://signalr.net/). – mason Apr 15 '15 at 20:50
  • I think we need a more realistic example. If that is using a PostBack, it should work fine. If you're doing something with AJAX, it's not going to update as that expression is evaluated on the server-side. – dmeglio Apr 15 '15 at 20:57
  • @mason Both my client and server side file are stored on the same local directory. How come I can't just makes those changes on demand? – José Corretjer-Gómez Apr 15 '15 at 21:01
  • 3
    Directory has nothing to do with it. You need to learn the page life cycle process. – mason Apr 15 '15 at 21:04
  • @dman2306 Everytime the selectCountMethod returning value updates it does post back but that's because the parameters on the table changed. That's irrelevant cause I don't utilize this on post back – José Corretjer-Gómez Apr 15 '15 at 21:06
  • But alert("**<%=num%>**"); is only evaluated on a postback – dmeglio Apr 15 '15 at 21:07
  • The client side function runs after `num` was updated on the server side. This happens every time the page loads but it's not placed on the Page_Load, not sure if that's what your asking – José Corretjer-Gómez Apr 15 '15 at 21:19
  • @dman2306 I'm not really considering if it's post back or not. But it does run on page load, on some occasions. – José Corretjer-Gómez Apr 15 '15 at 21:21

5 Answers5

2

Taking a look at your client-side code, the "<%=num%>" is actually run on the server. If you examined the source in your browser, what you'll see is:

function SomeFuntion()
{
    alert("60");
}

As you can see--there is no variable to update. In order to see that "60" change to "7", you'd have to refresh the client to pick up the new value that the server has for "num".

Russ
  • 4,091
  • 21
  • 32
  • I thought about that, but the client side function runs after `num` has been updated, do you think it's still necessary to refresh the client? – José Corretjer-Gómez Apr 15 '15 at 21:10
  • Then you can confirm that by viewing the source in your browser. If you see, 'alert("60")', then you are incorrect--it runs before the server changes it. If you see 'alert("7")', then it does run after. The "<%=num%>" code is server-side code and runs on the server. – Russ Apr 16 '15 at 12:59
0

Without your server side code, we won't be able to find the ideal solution. However, you could potentially do the following:

  • Use a Hidden Field to store the value.
  • Use a global variable for the page, to pass the value to global variable in your JavaScript.

The easiest would be the Hidden Field, the reason is you can easily modify the data on both Client and Server without any real issues. You'll want to ensure that you do not modify the state to often.

<input type="hidden" id="hdTimer" runat="server" />

Then you can do your JavaScript, such as:

$('#Example').on('change', function () {
     $('#hdTimer').val('60');
});

Now throughout the Client code you'll be able to modify the field with no issues, but when you need to submit a form, for a PostBack. You can use the field server side:

var content = hdTimer.value;

As I noted though, excessive cross manipulation may cause an issue at some point. Depending on the complexity. Your other approach would be the Global.

// Server Side
var example = 60;
protected void Page_Load(object sender, EventArgs e)
{

}

So this Global will hold the value, but when you reinitialize the value at Page Load it will hold be able to push an updated value to your JavaScript:

//Client Side:
var example = '<%= example %>';

The key though, will be to ensure you properly reinitialize the value.

When you do a PostBack your page is reinitialized, which can modify values on you if you aren't aware. This is incredibly important.

Greg
  • 11,302
  • 2
  • 48
  • 79
  • I am aware that if my variable is global, on post back this value could change and I did try using hiddenfields(forgot to mention that), but you can't access hiddenfields or any other control inside a method that it's called by the Object data source. Everytime I did, got null. – José Corretjer-Gómez Apr 15 '15 at 21:26
  • Are you sure, on any Server Side method if I call `hdTimer.value` I do obtain the proper value. You'll need more context then. – Greg Apr 15 '15 at 21:27
  • You're right, on any method you can use it but when you debug a controller that's been called inside a method used by the object data source, you'll get a null or at least I get null values – José Corretjer-Gómez Apr 15 '15 at 21:31
  • Are you using Web-Forms or Model View Controller? – Greg Apr 15 '15 at 21:32
  • I'm using web forms :/ – José Corretjer-Gómez Apr 15 '15 at 21:35
  • Define `controller` for me? If you could provide more context I'm certain I could help you. – Greg Apr 15 '15 at 21:36
  • A button, textbox, label, hiddenFields. Any of those tools are what I call controls, at least that's how my book calls them lol – José Corretjer-Gómez Apr 15 '15 at 21:39
  • They're `Controls`, but a `Controller` is different. That is why I asked. What exactly are you trying to accomplish? – Greg Apr 15 '15 at 21:41
  • Then apologize for the confusion. Like I mentioned, my program has a gridview and in every row there's a check box. I have a js function that when the top checkbox is clicked, it'll fill every check box(it works like a select all). I want to make a select all that applies to every page like gmail's select all pages. I only need the sum of every row to finish but it's been the most complicated part... – José Corretjer-Gómez Apr 15 '15 at 21:52
  • ... I've read many many posts on it. Tried many and none worked. So I tried this approach, I'm almost there I just need to get the right value – José Corretjer-Gómez Apr 15 '15 at 21:55
  • From your data source on the server, why not simply do `DataTable.Rows.Count` or something similar, then just keep track if that button is checked or not? – Greg Apr 15 '15 at 21:57
  • Cause I've tried using that line and I only get the count for the current row and not every row – José Corretjer-Gómez Apr 15 '15 at 22:01
  • Your using a data grid correct, your telling me that: `dataGridView1.RowCount.ToString();` won't return all the rows? – Greg Apr 15 '15 at 22:06
  • Remember my grid view allows paging an when I run that line, I get the rows of the current page and not of every page. By the way, I appreciate your help – José Corretjer-Gómez Apr 15 '15 at 22:20
  • Your misunderstanding, this is at the Server Side when you do the data bind. So your passing a physical instance of the Grid. – Greg Apr 15 '15 at 22:21
  • I tried running that line after the data binding for example on rowcommand, I get 10 cause that's how many rows there are on each page but the total amounts of rows on the grid are 63. – José Corretjer-Gómez Apr 15 '15 at 22:31
0

You could modify your JS method like this

var myMsg = <%=num%>;
function SomeFuntion()
{
    alert(myMsg);
}

and in the codebehind

public int num = 60;    
public int SelectCountMethod()
    {                  
        num = SomeMethod(); //Returns int
        ScriptManager.RegisterStartupScript(this,
                                                        this.GetType(),
                                                        "Funct",
                                                        "myMsg = " + num + ";",
                                                        true);
        return num;
    }

So every time your method SelectCountMethod() is called, your JS variable myMsg get a new value because of the line ScriptManager.RegisterStartupScript

Enrique Zavaleta
  • 2,098
  • 3
  • 21
  • 29
  • I would advise against `ScriptManager`. It will cause more harm than good. It would potentially resolve though. – Greg Apr 15 '15 at 21:28
  • Could you elaborate on the harm? I have used it for years and experienced no harm. – dmeglio Apr 15 '15 at 21:33
  • Why didn't work? It shows an error? The value doesn't change? – Enrique Zavaleta Apr 15 '15 at 22:37
  • No error was shown but if num is updated, on the client side, the value is stays the same. For example, if the initial value is 10 and then updates to 20, on the client side, it's still 10 but on the server side it's 20. By the way, the page does load every time num is updated, but I'm not evaluating post backs cause I don't need to. – José Corretjer-Gómez Apr 15 '15 at 23:06
0

Use an HttpHandler and jQuery. Google is your friend, there are several examples on SO as well.

sh1rts
  • 1,874
  • 1
  • 13
  • 14
0

I found a possible solution, inefficient, but it will have to do. I have a search textbox that every time the search button is clicked, updates the grid view with the retrieved data from a data base. When the Onclick is called it binds the data source with the gridView. What I did was call the SelectCountMethod again right below the binding and used the same parameters I had stored on the Object data source as paramaters for the selectCountMethod. Then the amount returned by the selectCount I stored it on a hiddenField and that's it.

//Global variables
string _param1 = string.Empty,
       _param2 = string.Empty;

//On click method for search btn
protected void OnSearch(object sender, EventArgs e)
{
    gv.DataBind();

    someHiddenField = SelectCountMethod(param1, param2); 
}

protected void OnSelecting(object sender, ObjectDataSourceSelectingEventArgs e)
    {
        try
        {
            e.InputParameters["Param1"] = param1;

            _param1 = param1                

            e.InputParameters["Param2"] = param2; 

            _param2 = param2;      
        }
        catch (Exception ex)
        {
            cvServerError.IsValid = false;
            cvServerError.ErrorMessage = ex.Message;
        }
    }