0

I am trying to call a c# function from JavaScript but the problem is, I need to pass a JS parameter for the function. How can I do this?

Here's my Js

 var categoryLists = <%= this.javaSerial.Serialize(this.categoryList) %>;
        function addInput(type, value, name, id, onclick, parentId) {
            var element = document.createElement("input");
            element.type = type;
            element.value = value;
            element.name = name;
            element.id = id;
            element.onclick = onclick;
            element.src = "trash.png";
            element.style.width = "25px";
            element.style.height = "25px";
            element.style.marginBottom = "3%";
            var parent = document.getElementById(parentId);
            
            parent.appendChild(element);
        }

        function addBreak(parentId) {
            var br = document.createElement("br");
            var parent = document.getElementById(parentId);
            parent.appendChild(br);
        }
         
        window.onload = function () {
            alert(this.categoryLists.length);
            for (var j = 0; j < this.categoryLists.length; j++) {
                var temp = "button" + j;
                addInput('image', '', temp, temp, <%=DeleteCategory(%>+categoryLists[j]), 'rightdiv');
                addBreak('rightdiv');
            }
        }

categoryLists[j] is my paramter

Here's the c# code

public void DeleteCategory(string category){
}

    public JavaScriptSerializer javaSerial = new JavaScriptSerializer();

Update- I call c# functions this way... <%= function()%> and they work fine. Thank you in advance

Update- with all the comments, I have tried using ajax or jquery - i am not sure what this is ... now my js looks like this and its broken... are there syntax issues?

 $(function () {
            function addInput(type, value, name, id, onclick, parentId) {
                var element = document.createElement("input");
                element.type = type;
                element.value = value;
                element.name = name;
                element.id = id;
                element.onclick = onclick;
                element.src = "trash.png";
                element.style.width = "25px";
                element.style.height = "28px";
                element.style.marginBottom = "3%";
                var parent = document.getElementById(parentId);

                parent.appendChild(element);
            }

            function addBreak(parentId) {
                var br = document.createElement("br");
                var parent = document.getElementById(parentId);
                parent.appendChild(br);
            }

             for (var j = 0; j < this.categoryLists.length; j++) {
                var temp = "button" + j;
                addInput('image', '', temp, temp, temp, 'rightdiv');
                addBreak('rightdiv');
            }
        });
  • Is there any specific reason that you don't use AJAX? See: https://stackoverflow.com/questions/3713/call-asp-net-function-from-javascript – Selim Yildiz Oct 23 '20 at 14:04
  • 2
    That's not how aspnet works. You need an ajax call or form post. – VDWWD Oct 23 '20 at 14:12
  • Does this answer your question? [Pass Javascript Variable To C# Code Behind](https://stackoverflow.com/questions/14977491/pass-javascript-variable-to-c-sharp-code-behind) – Pete Oct 23 '20 at 14:13
  • Sorry! I should update this question and give the whole thing out. I am calling other function this way and they work fine. It's just when I pass parameters, it doesn't work –  Oct 23 '20 at 14:34
  • You can generate the code in the asp.net view / control (including javascript code) using c# but what you can't do is call a c# function once the page is rendered in the browser. If you want to call a c# from the browser you will need to do it using ajax (which can take different forms depending on toolset). What you are showing above in your code is the construction of javascript code using your c# code which is created before it is sent to the browser, the javascript is not running at this point because it is not yet hosted in the browser. – Igor Oct 23 '20 at 14:41
  • The big takeaway for you here is to understand that you have browser side code execution and server side code execution. These 2 do *not* coexist in the same process. You can use ajax to call the server from a running browser session. The inverse, calling the running browser from the server, can only be done using a toolset like SignalR. – Igor Oct 23 '20 at 14:44
  • Mmmm Interesting.. I would use ajax but here I m calling a JS function as well. How would the syntax look for that ?? –  Oct 23 '20 at 14:57
  • About the second comment @Igor.. I am not so sure because you can always have onclick events in your browser page which can call the c# code –  Oct 23 '20 at 15:00
  • "you can always have onclick events in your browser page which can call the c# code" ← No, they wont at least not directly. What happens there is a postback occurs. The form is sent back (from the client) to the server as a postback. The server then processes that form and sends a new html form back to the client (browser). The other thing you might be referring to is client side onclick but this is executing javascript and not c# code (at least not without an ajax call). – Igor Oct 23 '20 at 15:05
  • There are some controls in toolkit add-ons that generate ajax for you with onclick events but I could not tell you which ones those are. That also might be what you are seeing. Regardless everything works on the premise of 2 processes (server and client) and these 2 are always separate and do not communicate *natively* with each other. – Igor Oct 23 '20 at 15:11
  • Oh wow! That's good to know. I have a ton to learn about .net then :) Can you help me with the syntax? –  Oct 23 '20 at 15:17

1 Answers1

0

You have quite a few ways to do this.

You can use the cheater approach. Drop in a text box, and a standard button (that will call server side code behind). (set clientID mode for this button and text box as static).

<asp:Button ID="btnHidden" runat="server" Text="hidden but"  />
<asp:TextBox ID="TextHiddenBox" runat="server" ClientIDMode="Static" ></asp:TextBox>

Ok, now in your js you can go:

<script>
   // set the value we want to pass in the hidden text box
   $('#txtHidden').value("abc");
   $('#hiddenButton').click;
<script>

Note: above is jQuery syntax. You could do this: (pure js no jQuery)

var myvaluetopass = "this is some text to pass as variable";
document.getElementById('<%= TextHiddenBox.ClientID %>').value = myvaluetopass;
document.getElementById('<%= btnHidden.ClientID %>').click();

so you don't have to introduce jQuery here - it can be some "time" and "hassle" to setup + get jQuery working.

So, the above will simple click on the hidden button, and the hidden text box will have the value that the code behind can work with. Once you wire up the above?

Then hide the button and the text box like this:

<asp:Button ID="btnHidden" runat="server" Text="hidden but"  style="display:none"/>
<asp:TextBox ID="TextHiddenBox" runat="server" ClientIDMode="Static" style="display:none" ></asp:TextBox>

Now, the above is certainly somewhat "klugey". But when you starting out, it can work quite well. So, you set the value of some text box (often hidden), and then with js you FIRE the click event of another button (again often hidden). This now gets you a easy way to run one particular code behind routine, and not have to wire up complex ajax code.

The next approach? Well, fire a post back command. This again like the above hidden button trick assumes you need/want a post back here in addition to calling that one routine. this approach is somewhat better in that you don't have to drop on the form two hidden controls.

You ALSO need to drop in the script manager for this to work (don't know why). But you can do this in your code:

     var myvaluetopass = "this is some text to pass as variable";
     __doPostBack("MyCoolEventName", myvaluetopass);

So, the above fires a page post back, and then in the load event, we have this:

 If Request("__EVENTTARGET") = "MyCoolEventName" Then

     Dim str As String = Request("__EVENTARGUMENT")

        Debug.Print("passed value = " & str)
 End If

or as C#

 if (Request("__EVENTTARGET") == "MyCoolEventName")
 {
    string str = Request("__EVENTARGUMENT");
    Debug.Print("passed value = " + str);
 }

So the above are some simple ways.

The ALL above ideas do cause a full page post-back to run. Now, if the routine you calling DOES need to set/get/change/deal with/see any control on the page, then of course one does need and want that all important page post back.

Last but not least? Well, you can do a ajax call, and that will call a specific routine on your page, pass values (if you want), and ONLY run that one routine. This can be VERY nice, it fast, and you do NOT get a full page post back. So, if the routine you need to run does not have to modify, or do much of anything on the web page, then ajax is certainly the best way to go (assuming that the routine you calling does NOT need to modify or change things on the page - since as noted, no page post-back will occur. And if you looking to use that value with code behind and modify things on the page, then you will need a post-back.

But, lets assume you do need to pass one, or do values.

Well, I suggest jQuery - it just makes the code a bit easier to write.

So, say in your web page, you have this simple sub, and want to pass two values:

<WebMethod()>
 Public Shared Sub MySimpleSub(MyCoolPassValue As String, Age As Integer)

    Debug.Print("passed string value = " & MyCoolPassValue & vbCrLf & "Age = " & Age.ToString)

 End Sub

or:

[WebMethod()]
public static void MySimpleSub(string MyCoolPassValue, int Age)
{
   Debug.Print("passed string value = " + MyCoolPassValue + Constants.vbCrLf + "Age = " + Age.ToString());
}

So in above, it just a public sub. (in the code behind for that web page). (note the Shared - it HAS to be Static sub - since we calling the page - but don't have the full class object model). We also need a

Imports System.Web.Services

Ok, now to call the above as ajax?

We get this:

            var myvaluetopass = "this is some text to pass as variable";
            var age = 23;

            $.ajax({
                type: "POST",
                async: true,
                url: 'OnePicture.aspx/MySimpleSub',
                data: JSON.stringify({MyCoolPassValue: myvaluetopass, Age: age}),
                contentType: "application/json; charset=utf-8",
                datatype: "json"
            }
            );
        }

So in above, we passed two values to the sub in the web form.

The above did assume jQuery. I can write it out as pure JavaScript, but the above thus gives;

How to pass values - hidden control idea. Or use __dopostback - this gets rid of the requirement to have a button + hidden text box (and use style="display:none" to hide the button and text box above (if you using that idea, and get it working).

As noted, I don't know why, but you have to drop a Scriptmanager into the page if you going to use dopostback. (or pass a valid control ref as the first parameter - it will just to your button code behind routine). But, my dopostback example simple gets/grabs the value in teh page load event (event args).

And then last but not least, we pass a value direction to a web method (sub) in that page - this is a ajax call, and just keep VERY much in mind that the code for this routine has to work without assuming that a page post-back occurred (compared to all previous examples that assumed you need a post back).

Albert D. Kallal
  • 42,205
  • 3
  • 34
  • 51
  • It took me a while to understand this but this actually worked out!! Thank you so much :D –  Oct 27 '20 at 17:45