Adi Toma
Adi Toma

Reputation: 71

MVC 4 how to set row id for a WebGrid

In a partial Razor view I have this:

    @model IList<Stratent.ScanCloud.Shared.DeliveryOrderLineDto>

    <div id="gridDiv" style="width:100%; max-height:250px; overflow:auto; border:1px solid #d1d3d4">
@{

    var grid = new  WebGrid(Model, defaultSort: "Date",
                           selectionFieldName: "SelectedRow",
                      `enter code here`     fieldNamePrefix: "gridItem", ajaxUpdateContainerId: "grid");

}

  @if (Model.Count > 0)
  {
      @grid.GetHtml(

          tableStyle: "grid",
          alternatingRowStyle: "gridrow_alternate",
          //format:@<tr id= '@item.OrderId'> </tr>,
          selectedRowStyle: "highlight",
          rowStyle: "gridrow",
          htmlAttributes: new {id = "grid"},
          columns: grid.Columns(
              grid.Column("OrderId", header: "OrderId " + Html.SortDirection(ref grid, "Client"), style: "width:9%"),
              grid.Column("Client", header: "Client " + Html.SortDirection(ref grid, "Client"), style: "width:9%"),
              grid.Column("Date", header: "Date " + Html.SortDirection(ref grid, "Date"), style: "width:9%"),
              grid.Column("Time", header: "Time " + Html.SortDirection(ref grid, "Time"), style: "width:9%"),
              grid.Column("Reference", header: "Reference " + Html.SortDirection(ref grid, "Reference"), style: "width:9%"),
              grid.Column("Order", header: "Order " + Html.SortDirection(ref grid, "Order"), style: "width:15%"),
              grid.Column("Customer", header: "Customer " + Html.SortDirection(ref grid, "Customer"), style: "width:15%"),
              grid.Column("Street", header: "Street " + Html.SortDirection(ref grid, "Street"), style: "width:9%"),
              grid.Column("Number", header: "No " + Html.SortDirection(ref grid, "Number"), style: "width:9%"),
              grid.Column("Town", header: "Town " + Html.SortDirection(ref grid, "Town"), style: "width:9%"),
              grid.Column("Crs", header: "Crs " + Html.SortDirection(ref grid, "Crs"), style: "width:15%"),
              grid.Column("Document", header: "Document " + Html.SortDirection(ref grid, "Document"), style: "width:15%")
              )


           )
  }

 @if(Model.Count == 0)
    {
        <p>There are no OrderLines available.</p>
    }

</div>

In the main page I call

<%Html.RenderPartial("_orderLinesList", Model.Items); %>

and then I use this to pass the orderId to the controller:

<script type="text/javascript">
     $(function () {
        $("tbody tr").click(function () {
            var url = '<%=Url.Action("SelectOrderLine", "DeliveryOrderLines", new {id = "__id__"}) %>';
            url = url.replace('__id__', $(this).attr('id'));
            location.href = url;
        })
        .hover(function () { $(this).addClass('highlight'); }, function () { $(this).removeClass('highlight'); });
    });

</script>    

In the ActionResult from my Controller

 public ActionResult SelectOrderLine(int id)
    {
        return RedirectToAction("Index", "DeliveryOrderLine", new {id = id});
    }

I do not receive any id.

In the rendered html code I've seen that the does not have any Id to send in the ActionResult from Controller.

The grid rows does not contain any button like Edit, Delete ... this is not intended.

I want to define an id for each row and to use this id when a row is selected and then to send the id into the ActionResult method from my Controller.

Can you please tell me how I can solve this issue?

Thank you.

Upvotes: 7

Views: 7286

Answers (2)

James Joyce
James Joyce

Reputation: 1774

I know this is a bit of an old question, but I have been battling with this too.

I handled it by modifying the generated HTML from the webgrid before returning it to the view for rendering.

  1. Add "HtmlAgilityPack" using Package Manager - this is used to manipulate the HTML nodes. You can do it manually, but this makes it MUCH easier!
  2. Subclass the webgrid
  3. Override the GetHTML method
  4. Put this onto your view, and pass in a lambda to return the identifer value from the model item

    using HtmlAgilityPack;
    
    public class SmartGrid<T> : WebGrid
    {
    
         ...omitted for brevity...
    
        public IHtmlString GetHtml(string tableStyle = null, ...omitted for brevity..., Func<T, object> getRowId = null)
        {
            IHtmlString html =  base.GetHtml(tableStyle: tableStyle, ...omitted for brevity...);
    
            HtmlDocument doc = new HtmlDocument();
            doc.LoadHtml(html.ToString());
    
            for (int i = 0; i < this.Rows.Count; i++)
            { 
                HtmlNode node = _doc.DocumentNode.SelectSingleNode(String.Format("//table/tbody/tr[{0}]", i + 1));
                node.SetAttributeValue("id", getRowId(this.Rows[i].Value));
            }
    
            return new HtmlString(doc.DocumentNode.OuterHtml);
        }
    

This is a "denormalized" version to show the concept, in my production code I have moved the "SetRowIds" into a new function.

I am now using this interception of HTML to generate row edit templates, footers etc - it works nicely!

Upvotes: 0

Simon
Simon

Reputation: 6152

You can specify the format of each column when you set the grid up:

grid.Column("InvoiceID", header: "Invoice",
                format: @<text>@Html.ActionLink((string)item.InvoiceID.ToString(),
                "Invoice", "Invoice", new { invoiceID = item.InvoiceID }, null)</text>),

This will generate the appropriate link with an ID to pass back to your controller.

Upvotes: 2

Related Questions