Click here to Skip to main content
15,884,099 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I'm just not getting it how to set columns collection dynamically in the controller. I have this sample code in my controller:

public ActionResult GenericGrid()
{
  var books = InitVars();


  WebGrid grid = new WebGrid(books, ajaxUpdateContainerId: "grid", ajaxUpdateCallback: "setArrows");
			
  WebGridColumn col1 = grid.Column("BookId", "", (item) => GetEditButtons(item), "col1", true);
  // ... 2-6 initialized also ...

  List<WebGridColumn> columnSet = new List<WebGridColumn>() {col1, col2, col3, col4, col5, col6};
  grid.Columns(columnSet.ToArray());

  ViewBag.Grid = grid;

  return View();
}

public object GetEditButtons(dynamic item)
{
  int bookID = item.BookId;

  return "<button class='delete-book display-mode' id='"+bookID+"'>Delete</button>" +
"<button class='edit-book display-mode' id='"+bookID+"'>Edit</button>" +
"<button class='save-book edit-mode edit-width' id='"+bookID+"'>Save</button>";
}


And I try to use it like this in the view:
<div id="grid">
  @grid.GetHtml(
    tableStyle : "table",
    alternatingRowStyle : "alternate",
    selectedRowStyle: "selected",
    headerStyle : "header"
    ) 
  )


All I get is a grid with all the fields (and BookId as the header and the book ID's as the fields.)

If I do this directly in the view:

@grid.GetHtml(
  tableStyle : "table",
  alternatingRowStyle : "alternate",
  selectedRowStyle: "selected",
  headerStyle : "header",
  columns : grid.Columns(
  grid.Column("", 
  style: "col1", 
  format: @<text>
    <button class="delete-book display-mode" id="@item.BookId">Delete</button>
    <button class="edit-book display-mode" id="@item.BookId">Edit</button>
    <button class="save-book edit-mode edit-width" id="@item.BookId">Save</button>
</text>)))
) 


lo and behold, it works.

But I don't want to do that!!! I want to create the columns dynamically in the controller.

One thing I note is that GetEditButtons is never called, even if I call grid.GetHtml() as a test in the controller.

Ideas?

Marc
Posted

1 solution

There is a timing issue here...You can do some work around but I have to ask, why?
Why not to put the formatting int the view? are you want to use dynamic models with the same view?
In any case - even with my solution you still will have the problem of the html content GetEditButtons returns - this content will be encoded and displayed as such and not as real html...
C#
List<webgridcolumn> columnSet = new List<webgridcolumn>() {col1, col2, col3, col4, col5, col6};
ViewBag.GridCols = columnSet;</webgridcolumn></webgridcolumn>

JavaScript
@grid.GetHtml(
  tableStyle : "table",
  alternatingRowStyle : "alternate",
  selectedRowStyle: "selected",
  headerStyle : "header",
  columns : ViewBag.GridCols
)

It will call your method, but the html content returned by it will not create real html, but will be encoded...
If you insist on creating column in the controller you better make an extension function instead of GetHtml and make you changes there
http://stackoverflow.com/questions/11698665/mvc3-web-grid-adding-action-links-at-the-begining-of-columns-list[^]
It is also better to use ActionLink helper method to create clickable links (like edit/delete) instead of creating html content like you did...
 
Share this answer
 
Comments
[no name] 9-Nov-14 10:12am    
Thanks for this, 5. Bruno
Kornfeld Eliyahu Peter 9-Nov-14 10:16am    
Thank you...
Marc Clifton 9-Nov-14 12:15pm    
That's what I ended up doing -- passing in the collection in the .cshtml file. Why I have to that there and not in with the grid.Columns method is beyond me. Personally, I'm finding Razor to be quite klunky. Ironically, it's making the same "klunk" sound that Ruby on Rails makes. Gee, I wonder why.
Kornfeld Eliyahu Peter 9-Nov-14 12:22pm    
Ever heard of 'Copy-Paste' :-)?
The official reason is separation of concerns...
As I told you can create your HTML helper or extend the one at hand, but if you do not mean to build a whole framework, you better go with what you have...

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900