skip to Main Content

I am quite new to JS and doing web apps and I am facing this problem:
I have JS code which creates me 6 gauges and function which updates gauge 1 value:

        <!-- Include the Gauge.js library -->
<!-- Raphael must be included before justgage -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.4/raphael-min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.9/justgage.min.js"></script>
        <!-- Initialize the gauge on page load -->
    <script>
        var gauge1;
        var gauge2;
        var gauge3;
        var gauge4;
        var gauge5;
        var gauge6;

        function updateGaugeValue(newValue, event) {
            event.preventDefault();
            gauge1.refresh(newValue);
        }

        window.onload = function () {

            gauge1 = new JustGage({
                id: "gauge1",
                value: 0,
                min: 0,
                max: 10,
                title: "My Gauge",
                label: "Value"
            });

            gauge2 = new JustGage({
                id: "gauge2",
                value: 0,
                min: 0,
                max: 10,
                title: "My Gauge",
                label: "Value"
            });

            gauge3 = new JustGage({
                id: "gauge3",
                value: 0,
                min: 0,
                max: 10,
                title: "My Gauge",
                label: "Value"
            });

            gauge4 = new JustGage({
                id: "gauge4",
                value: 0,
                min: 0,
                max: 10,
                title: "My Gauge",
                label: "Value"
            });

            gauge5 = new JustGage({
                id: "gauge5",
                value: 0,
                min: 0,
                max: 10,
                title: "My Gauge",
                label: "Value"
            });

            gauge6 = new JustGage({
                id: "gauge6",
                value: 0,
                min: 0,
                max: 10,
                title: "My Gauge",
                label: "Value"
            });

        };

    </script>

When I call update from button like this

                            <button onclick="updateGaugeValue(5, event)">Click me</button>

function normally works and change value of gauge 1 to 5.
But when I try to call this function from C# (using ASP.NET) via ClientScript like:

            
Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "updateGaugeValue(5, event)", true);

nothing happens. But if I try to test it and alert hello world like

            Page.ClientScript.RegisterStartupScript(this.GetType(), "CallMyFunction", "alert('Hello World')", true);

it normally works and alert. Any suggestions?

I expect that I am able to call this JS function from C# code.

2

Answers


  1. Apart from moving your scripts to the HEAD tag instead of having them at the end of BODY, you might want to delay the execution of the code coming from C# after the loading is done.

    Something like:

    window.onload = () => { const event = new Event("dummy"); setTimeout(() => { updateGaugeValue(5, event) }, 0) };
    

    Put that in the Page.ClientScript.RegisterStartupScript(... call.

    What it does:

    // appending to the queue of onload functions ensures any other variables and functions, that were declared in main template's scripts, will be defined already.
    window.onload = () => {
      const event = new Event("dummy"); // We want some event so that we can call .preventDefault() upon something.
      // There are better ways around it though.
    
      setTimeout(() => { 
        updateGaugeValue(5, event) 
      }, 0); // setting timeout to 0 effectively means, execute immediately after next round of UI updates
    };
    
    Login or Signup to reply.
  2. Ok, so the issue is much that we use a page onload/onready to setup, create and render the gauge.

    But, we want a plane jane asp.net button, say maybe a text box, and then some plain jane code behind to set the value.

    The issue is the on window load. If we "inject" a call to that routine, we can’t (very well) control when our registery start up script runs as opposed to the existing code to setup + create the gauges.

    So, what we need to do is "force" our startup script to wait. One great way is to use setTimeout, and that will in effect "push" our code to a routine on the javascript engine "execution stack" to wait, render page, run that gauge setup code, AND THEN run our desired code.

    Worse yet? Testing this a bit, the event.prevent seems to mess this up.

    so, here is a working proof of concept:

    markup:

    we put the script library code at top:

    eg:

    <title></title>
    <script src="../Scripts/jquery-1.12.4.js"></script>
    <link href="../Content/bootstrap.css" rel="stylesheet" />
    <script src="../Scripts/bootstrap.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.4/raphael-min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/justgage/1.2.9/justgage.min.js"></script>
    

    but, for OUR code, we want that stuff to be placed at bottom – after the dom been created, setup and rendered.

    So, now this code:

        <div style="padding:35px">
    
            <div style="border: solid 1px; float: left; padding: 8px">
                <legend>Client side buttons</legend>
                <button style="float: left" onclick="updateGaugeValue(4, event)">Click me</button>
                <button style="float: left; margin-left: 25px" onclick="updateGaugeValue2(6, event)">Click me</button>
    
            </div>
    
            <div style="float: left; margin-left: 30px; padding: 8px; border: solid 1px">
                    <legend>Server side buttons</legend>
    
                <div style="float:left">
                    Enter value 1-10 for gauage1:
                    <br />
                    <asp:TextBox ID="TextBox1" runat="server" Width="50px">
                    </asp:TextBox>
                    <asp:Button ID="cmdGauge1" runat="server"
                        Text="set guage 1"
                        CssClass="btn"
                        OnClick="cmdGauge1_Click" />
                </div>
    
                <div style="float: left; margin-left: 30px">
                    Enter value 1-10 for gauage2:
                    <br />
                    <asp:TextBox ID="TextBox2" runat="server" Width="50px">
                    </asp:TextBox>
                    <asp:Button ID="cmdGauge2" runat="server"
                        Text="set guage 2"
                        CssClass="btn"
                        OnClick="cmdGauge2_Click" />
                </div>
            </div>
    
            <div style="clear: both; height: 50px">
            </div>
    
            <div id="gauge1" style="float:left;width:250px;"></div>
    
            <div id="gauge2" style="width:200px;float:left; margin-left:40px; width: 250px"></div>
    
        </div>
    
    
    <script>
        var gauge1;
        var gauge2;
    
    
        window.onload = function () {
    
            gauge1 = new JustGage({
                id: "gauge1",
                value: 0,
                min: 0,
                max: 10,
                title: "Files Uploaded",
                label: "Zip Files Uploaded",
                showInnerShadow: true,
                shadowOpacity: 2,
                shadowSize: 5,
                textRenderer: function () {
                    return "144 / 400"
                }
            });
    
            gauge2 = new JustGage({
                id: "gauge2",
                value: 0,
                min: 0,
                max: 10,
                title: "My Gauge",
                label: "Pdf Files uploaded",
                showInnerShadow: true,
                shadowOpacity: 2,
                shadowSize: 5,
    
            });
        };
    
        function updateGaugeValue(newValue, event) {
            // event.preventDefault();
            // alert('START')
            gauge1.refresh(newValue);
        }
        function updateGaugeValue2(newValue, event) {
            // event.preventDefault();
            gauge2.refresh(newValue);
        }
    
    
    </script>
    

    So, we wrapped our startup script in a timeout function. Even with a dealy of "1", it works, since timeout pushed our code to the javaengine program stack, and thus it runs after everything else on that page.

    code behind:

        protected void cmdGauge1_Click(object sender, EventArgs e)
        {
            string jscode =
                $@"updateGaugeValue({TextBox1.Text},event)";
    
            jscode = "setTimeout(function () {" + jscode + "},1)"; 
            ClientScript.RegisterStartupScript(Page.GetType(), "myfunc", jscode, true);
        }
    
        protected void cmdGauge2_Click(object sender, EventArgs e)
        {
    
        }
    

    and result:

    enter image description here

    However, there really not much need to "call" that existing js routine you have, since the js object exists (or we assume it will).

    So, then this code :

        protected void cmdGauge1_Click(object sender, EventArgs e)
        {
            string jscode =
                $@"gauge1.refresh({TextBox1.Text})";
    
            jscode = "setTimeout(function () {" + jscode + "},1)"; 
            ClientScript.RegisterStartupScript(Page.GetType(), "myfunc", jscode, true);
        }
    

    So, now we don’t even call that js routine, but use the refresh method of the graph object.

    So, now, we can put back (un-comment) out the event.preventDefault();, and thus both client side, and server side buttons in above example will now "both" work.

    I should also point out that I used a delay of 1 (1 millisecond). This delay (amount) is not really required, but the FORCE of the routine to be pushed onto the java engine execution stack is the important part here.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search