简体   繁体   中英

Passing arguments to JS function with dynamically created content

I'm wrestling with something that has me pulling my hair out. Other solutions I have found on this site have got me close to an answer but I keep hitting a stumbling block. I'm working on an e-commerce portal using ASP.Net, C# and JS. I currently am populating the "Products" section by using a repeater to display product information from a DataTable (which itself is pulled from a SQL query).

My aspx script looks like this:

<div class="contentContainer">
       <asp:Repeater ID="productCatalog" runat="server">
            <ItemTemplate>
                <div class="productContainer <%#DataBinder.Eval(Container.DataItem, "pType")%>" data-category="<%#DataBinder.Eval(Container.DataItem, "pType")%>">
                    <img src="<%#DataBinder.Eval(Container.DataItem, "pImage")%>" class="productImage">
                    <h3 class="pName"><%#DataBinder.Eval(Container.DataItem, "pName")%></h3>
                    <p class="pDesc"><%#DataBinder.Eval(Container.DataItem, "pDesc")%></p>

                    <table class="productTable">
                        <tr>
                            <td class="price"><%#MoneyFormat((decimal)DataBinder.Eval(Container.DataItem, "price"))%></td>
                            <td><asp:Button class="btn btn-info" ID="Button1" runat="server" Text="Add to Cart" onClientClick='AddNewItem(<%#DataBinder.Eval(Container.DataItem, "pID")%>);return false;'/></td>
                        </tr>
                    </table>
                </div>
            </ItemTemplate>
        </asp:Repeater>
</div>

and my JS function:

<script type="text/javascript">
function AddNewItem(myPID) {

    PageMethods.AddToCart_Command(myPID);

    function onSucess(result) {
        alert(result);
    }

    function onError(result) {
        alert('Cannot process your request at the moment, please try later.');
    }
}

Code behind:

[WebMethod]
public static void AddToCart_Command(int myPID)
{
    //...stuff. Not where the problem is 
}

My problem stems from this line in the aspx file, specifically from the onClientClick section:

<asp:Button class="btn btn-info" ID="Button1" runat="server" Text="Add to Cart" onClientClick='AddNewItem(<%#DataBinder.Eval(Container.DataItem, "pID")%>);return false;'/>

"pID" is an integer value that corresponds to a key in a SQL database. I've tried just hardcoding an int as an argument to the AddNewItem() method and the function works correctly. The problem stems from when I try and pass the argument from the repeater data itself. If I use double quotes around the argument, I get a "The server tag is not well formed" error. If I use single quotes, the page builds without error but the function is not called when the button is clicked.

Please note that it's important that the page not reload after clicking the "Add To Cart" button. Its also important that the buttons are not hardcoded directly.

How can I pass this argument from the repeater data to my JS function?

Any and all help is greatly appreciated!


EDIT: As an alternative to passing the pID as an argument to the function, I have attempted to use jQuery to grab the pID as an attribute directly from an HTML element. Unfortunately, the method grabs the first instance of the element with the appropriate id and will only return that. In this case, the first product produced by the repeater.

I was able to solve this by simply changing the button type. This was the final line:

<button class="btn btn-info" id="Button2" onclick="AddNewItem( <%#DataBinder.Eval(Container.DataItem, "pID")%> ); return false;"/>Add to Cart</button>

I never needed the asp button in the first place; it was an over complication. I was able to call the JS method using this above. KISS I guess!

While your solution works, I bet there are some issues with the fact that you have a page web method that does not have access to anything instance specific of the page, since it is just a static method.

ASP.NET way of approaching it is:

  1. switch repeater to list view
  2. add button with the command
  3. add command argument on the button to be value of id
  4. in ItemCommand check if command is AddItemToCart and call corresponding method of the page.

UPDATE :

  1. if you need command to fire without reloading the page, put UpdatePanel on the page and put ListView inside UpdatePanel. that way PartialPostBack will happen when you click a button.

see example

  <asp:ListView runat="server" 
      ID="lvCatalog"
      OnItemCommand="OnItemCommand" DataMember='pID'
      >
      <LayoutTemplate>

          <div id="itemPlaceholder" runat="server"></div>

      </LayoutTemplate>
      <ItemTemplate>
        <div runat="server">
          <div>
            <asp:Label runat="server" ID="NameLabel" Text='<%#Eval("pName") %>' />
          </div>
          <div>
            <asp:LinkButton runat="server" 
              ID="lbAddToCart" 
              Text="Add To Cart" 
              CommandName="AddToCart" 
              CommandArgument='<%# Eval("pID") %>' />
          </div>
        </div>
      </ItemTemplate>
    </asp:ListView>

and

protected void OnItemCommand(object sender, ListViewCommandEventArgs e)
{
 if (String.Equals(e.CommandName, "AddToCart"))
 {

  ListViewDataItem dataItem = (ListViewDataItem)e.Item;
  string pID = 
    lvCatalog.DataKeys[dataItem.DisplayIndex].Value.ToString();

  AddItemToCart(e.CommandArgument.ToString())

  // or 
  AddItemToCart(pID);

  }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM