ASP.NET MVC Razor Grid with editable foreign key dropdown column

7 posts, 1 answers
  1. Erwin
    Erwin avatar
    6 posts
    Member since:
    Aug 2010

    Posted 30 May 2012 Link to this post

    Hi all,

    I am trying to create an Ajax Telerik grid in Razor that has an updateable foreign key column that shows a dropdown list. I've copied my page pretty much like the example, and everything works. I can add new records, delete them and edit them. The only thing that doesn't work is that I get a textfield with the integer when I update a record in my grid, instead of a dropdown list with all the possibilities of the foreign key table.

    Anyone have any ideas on how I could fix this? See code below.

    Telerik grid:
    @(Html.Telerik().Grid<EditableAccount>()
        .Name("Grid")
        .ToolBar(commands => commands.Insert().ButtonType(GridButtonType.Text).ImageHtmlAttributes(new { style = "margin-left:0" }))
        .DataBinding(dataBinding => dataBinding.Ajax()
            .Insert("InsertAccount", "Administration")
            .Update("SaveAccount", "Administration")
            .Delete("DeleteAccount", "Administration"))
        .DataKeys(keys => { keys.Add(a => a.AccountId); })
        .Columns(columns =>
        {
            columns.ForeignKey(b => b.BankId, (IEnumerable)ViewData["Banks"], "ID", "Name").Width(50);
            columns.Bound(a => a.AccountNumber).Width(110);
            columns.Command(commands =>
            {
                commands.Edit().ButtonType(GridButtonType.Image);
                commands.Delete().ButtonType(GridButtonType.Image);
            }).Width(16);
        })
        .Editable(editing => editing.Mode(GridEditMode.InLine))
        .Pageable()
        .Scrollable()
        .Sortable()
    )

    Controller:
    [GridAction]
    public ActionResult Accounts()
    {
        ViewData["Banks"] = db.Banks.Select(b => new { Id = b.BankId, Name = b.Name });
        return View(new GridModel(accountRepository.All()));
    }
     
    [AcceptVerbs(HttpVerbs.Post)]
    [GridAction]
    public ActionResult InsertAccount()
    {
        //Create a new instance of the EditableProduct class.
        EditableAccount account = new EditableAccount();
     
        //Perform model binding (fill the product properties and validate it).
        if (TryUpdateModel(account))
        {
            //The model is valid - insert the product.
            accountRepository.Insert(account);
        }
     
        //Rebind the grid
        return View(new GridModel(accountRepository.All()));
    }
     
    [AcceptVerbs(HttpVerbs.Post)]
    [GridAction]
    public ActionResult SaveAccount(int id, int bankId)
    {
        EditableAccount account = new EditableAccount
        {
            AccountId = id,
            Bank = db.Banks
                       .Where(b => b.BankId == bankId)
                       .Select(b => b.Name).SingleOrDefault(),
            BankId = bankId
        };
     
        TryUpdateModel(account);
     
        accountRepository.Update(account);
     
        return View(new GridModel(accountRepository.All()));
    }
     
    [AcceptVerbs(HttpVerbs.Post)]
    [GridAction]
    public ActionResult DeleteAccount(int id)
    {
        //Find a customer with ProductID equal to the id action parameter
        EditableAccount account = accountRepository.One(a => a.AccountId == id);
     
        if (account != null)
        {
            //Delete the record
            accountRepository.Delete(account);
        }
     
        //Rebind the grid
        return View(new GridModel(accountRepository.All()));
    }

    Model:
    public class EditableAccount
    {
        [ScaffoldColumn(false)]
        public int AccountId { get; set; }
     
        [Required]
        [UIHint("GridForeignKey")]
        [DisplayName("Bank")]
        public int BankId { get; set; }
        public string Bank { get; set; }
     
        [Required]
        [DisplayName("AccountNumber")]
        public int AccountNumber { get; set; }
    }


    Repository:

    public IList<EditableAccount> All()
    {
        IList<EditableAccount> result =
                (from account in db.Accounts
                 select new EditableAccount
                 {
                     AccountId = account.AccountId,
                     Bank = account.Bank.Name,
                     BankId = account.BankId,
                     AccountNumber = account.AccountNr
                 }).ToList();
     
        return result;
    }
     
    /// <summary>
    /// Ones the specified predicate.
    /// </summary>
    /// <param name="predicate">The predicate.</param>
    /// <returns></returns>
    public EditableAccount One(Func<EditableAccount, bool> predicate)
    {
        return All().Where(predicate).FirstOrDefault();
    }
     
    /// <summary>
    /// Inserts the specified account.
    /// </summary>
    /// <param name="account">The account.</param>
    public void Insert(EditableAccount insertedAccount)
    {
        Account account = new Account();
        account.BankId = insertedAccount.BankId;
        account.AccountNr = insertedAccount.AccountNumber;
        db.Accounts.InsertOnSubmit(account);
        db.SubmitChanges();
    }
     
    /// <summary>
    /// Updates the specified account.
    /// </summary>
    /// <param name="account">The account.</param>
    public void Update(EditableAccount updatedAccount)
    {
        Account account = db.Accounts.SingleOrDefault(a => a.AccountId == updatedAccount.AccountId);
        account.BankId = updatedAccount.BankId;
        account.AccountNr = updatedAccount.AccountNumber;
        db.SubmitChanges();
    }
     
    /// <summary>
    /// Deletes the specified account.
    /// </summary>
    /// <param name="account">The account.</param>
    public void Delete(EditableAccount deletedAccount)
    {
        Account account = db.Accounts.SingleOrDefault(a => a.AccountId == deletedAccount.AccountId);
        db.Accounts.DeleteOnSubmit(account);
        db.SubmitChanges();
    }
  2. Joel
    Joel avatar
    2 posts
    Member since:
    May 2012

    Posted 31 May 2012 Link to this post

    +1 for this.   I'm having exact same problem with the same code structure. 
  3. Douglas
    Douglas avatar
    24 posts
    Member since:
    Apr 2012

    Posted 01 Jun 2012 Link to this post

    i'm having the same problem..

    did you figure this out?

    i don't think something this straightforward should be so difficult to implement..

    in webforms with a gridview it was a pretty easy thing to do..not so here.
  4. Answer
    Joel
    Joel avatar
    2 posts
    Member since:
    May 2012

    Posted 01 Jun 2012 Link to this post

    Solved the problem (at least for me):

    Just copy the GridForeignKey.cshmtl file (on my computer it is under "C:\Program Files (x86)\Telerik\Extensions for ASP.NET MVC Q1 2012\EditorTemplates-Razor") to your project. Put it under "Views\Shared\EditorTemplates" folder (create it if you have to).

    Apparently there are also currency, datetime, integer, etc. templates also, you can copy those as well to automatically use those formats.


  5. Douglas
    Douglas avatar
    24 posts
    Member since:
    Apr 2012

    Posted 01 Jun 2012 Link to this post

    That's IT!

    Thanks!!

  6. Erwin
    Erwin avatar
    6 posts
    Member since:
    Aug 2010

    Posted 04 Jun 2012 Link to this post

    Thanks a lot! That solved my problem! :D
  7. Phil
    Phil avatar
    1 posts
    Member since:
    Apr 2020

    Posted 28 May Link to this post

    I was having this issue for a few hours.

    I was going in circles following a few tutorials with no luck such as 

    https://docs.telerik.com/aspnet-mvc/html-helpers/data-management/grid/templates/editor-templates?_ga=2.10332085.162479736.1590480235-1736843189.1576230525

    I got to the stage where I could get it to render either a dropdown, but the data was not passed back, or the data passing as it was not a dropdown.

    Thought I would post here i to say thank you as creating the foreign key file seemed to fix it for me.

    I don't have the files on my local directory but if you create the file manually as the link below says

    https://demos.telerik.com/aspnet-mvc/grid/foreignkeycolumn

    @model object
    @(Html.Kendo().DropDownListFor(m => m)
        .BindTo((SelectList)ViewData[ViewData.TemplateInfo.GetFullHtmlFieldName("") + "_Data"])
    )
    it magically works.

    I created a partial view with no model within Razor.

    I'll have to grab the files or go looking for the other datatypes.

    Thanks

Back to Top