0

Is it possible to pass an hidden field value from Razor View to Controller inside or tag? As the field is hidden, it is really a problem to pass its value to the Controller. On the other hand I think the only way to pass this hidden field is using input field inside hyperlink. How to create a code like below?

<a href="/Admin/Delete?ApplicantID=44">
<img class="myclass" src="../../Content/delete.png" title="Delete" />
<input type="hidden" value= "Delete" /></a>


Updates

View:

...
grid.Column("Actions", format: (item) =>
 new HtmlString(
      @Html.ActionImage("../../Content/detail.png", "Detail", "icon-link", "Detail", "Admin", new { applicantId = item.ApplicantID }).ToString() +
      @Html.ActionImage("../../Content/edit.png", "Edit", "icon-link", "Edit", "Admin", new { applicantId = item.ApplicantID }).ToString() +
      @Html.ActionImage("../../Content/delete.png", "Delete", "icon-link", "Delete", "Admin", new { applicantId = item.ApplicantID }).ToString()
 )
)
...


Controller:

[HttpPost]
public ActionResult Delete(int applicantId)
{
    Applicant deletedApplicant = repository.DeleteApplicant(applicantId);
    if (deletedApplicant != null)
    {
        TempData["message"] = string.Format("{0} was deleted",
        deletedApplicant.Name);
    }
        return RedirectToAction("Index");
    }
}


Helper Method:

public static MvcHtmlString ActionImage(this HtmlHelper html, string imagePath, string alt, string cssClass,
       string action, string controllerName, object routeValues)
{
    var currentUrl = new UrlHelper(html.ViewContext.RequestContext);
    var imgTagBuilder = new TagBuilder("img");
    imgTagBuilder.MergeAttribute("src", currentUrl.Content(imagePath));
    imgTagBuilder.MergeAttribute("title", alt);
    imgTagBuilder.MergeAttribute("class", cssClass);
    string imgHtml = imgTagBuilder.ToString(TagRenderMode.SelfClosing);
    var anchorTagBuilder = new TagBuilder("a"); 
    anchorTagBuilder.MergeAttribute("href", currentUrl.Action(action, controllerName, routeValues));
    anchorTagBuilder.InnerHtml = imgHtml; 
    string anchorHtml = anchorTagBuilder.ToString(TagRenderMode.Normal);
    return MvcHtmlString.Create(anchorHtml);
}
Jack
  • 1
  • 21
  • 118
  • 236

2 Answers2

1

<input>, <textarea>, <button> and <select> element values are only passed during a form submission. Moreover, they are only passed on when assigned a name attribute.

Clicking an anchor will not pass these values (unless you interject with some JavaScript and append it to the URL). The easiest method is to turn your link in to a mini form:

@using (Html.BeginForm("Delete", "Admin", FormMethod.POST,
                       new { ApplicantID = @Model.ApplicantID }))
{
    <!-- make sure to give this field a name -->
    <input type="hidden" name="???" value="Delete" />
    <input type="image" src="@Url.Content("~/Content/delete.png")" title="Delete" />
}

Otherwise, use javascript and bind to the anchor's click event and inject the hidden input's value before proceeding.

Brad Christie
  • 100,477
  • 16
  • 156
  • 200
  • Thanks for reply. Actually I had already used the same id value on both View and Controller as shown above. The problem is actually related to Delete action due to hidden field. Because I can easily open Edit form by pressing Edit icon on the View (in the GridView column), but I cannot call Delete Post method. On the other hand I have tried lot of time using "@using (Html.BeginForm("Delete", "Admin"))" and "@Html.Hidden("ApplicantID", item.ApplicantID)" properties on different places on the form. But it did not make any sense.>>> – Jack Nov 05 '13 at 16:00
  • >>> So, I would be happy that if you clarify me about how can I change my helper method and the action lines "@Html.ActionImage("../../Content/detail.png", "Detail", "icon-link", "Detail", "Admin", new { applicantId = item.ApplicantID }).ToString()" on the View. In addition to this I think I should use "@using (Html.BeginForm()" on the correct place. Could you also give an example with my code? Thank you very much for all of your consideration. – Jack Nov 05 '13 at 16:01
0

Based on discussion below, try this.

@Ajax.ActionLink("Delete",
                    "Delete", new { applicantid = item.applicantid },
                    new AjaxOptions
                    {
                        Confirm = "Delete?",
                        HttpMethod = "POST",
                    }, new { @class = "classname" })

a.classname
{
    background: url(~/Content/delete.png) no-repeat top left;
     display: block;
     width: 150px;
     height: 150px;
     text-indent: -9999px; /* hides the link text */
}

NOTE: this does not need to be inside a form.

tintyethan
  • 1,772
  • 3
  • 20
  • 44
  • 3
    Yup; just to add, because I'm not sure the OP understands this; "hidden" fields are no different than any other form fields when it comes to what is sent to the server. *One minor change* in the above: Technically, you are supposed to use the `name` attribute, rather than the `id` attribute for what the name of a value is the browser sends on form submit. The browser will *use* `id` if you don't include a `name`, but it's best to use name from the start. Also, there can be multiple input tags with the same name, but only one with each id. – Andrew Barber Nov 05 '13 at 14:18
  • @Ethan Pelton : Thanks for reply. Actually I had already used the same id value on both View and Controller as shown above. The problem is actually related to Delete action due to hidden field. Because I can easily open Edit form by pressing Edit icon on the View (in the GridView column), but I cannot call Delete Post method. On the other hand I have tried lot of time using "@using (Html.BeginForm("Delete", "Admin"))" and "@Html.Hidden("ApplicantID", item.ApplicantID)" properties on different places on the form. But it did not make any sense. >>> – Jack Nov 05 '13 at 16:00
  • >>> So, I would be happy that if you clarify me about how can I change my helper method and the action lines "@Html.ActionImage("../../Content/detail.png", "Detail", "icon-link", "Detail", "Admin", new { applicantId = item.ApplicantID }).ToString()" on the View. In addition to this I think I should use "@using (Html.BeginForm()" on the correct place. Could you also give an example with my code? Thank you very much for all of your consideration. – Jack Nov 05 '13 at 16:00
  • I'm afraid I don't understand what you're trying to accomplish. Maybe you can start over the beginning? It looks like you want to have the user click on a link and show detail for the the item they clicked. Is that right? – tintyethan Nov 05 '13 at 19:02
  • I just wanted to delete a records by clicking the image link near to the related record. In order to do that, I used a custom HTML Helper that let me use image as a link. But, although I can use the Edit link and open the Edit page by clicking the Edit link near to a record on the WebGrid, I cannot delete any record. The only thing I need to use Delete image button and delete record by pressing it. I think the real problem at here locating the "@using (Html.BeginForm()" on the View and the hidden property. Because the record id cannot be passed to the Controller. How can I provide this? Thanks – Jack Nov 05 '13 at 22:40
  • try this... In your controller, change the parameter that it accepts from applicantid to id. This is because the default routing, assuming you've left that alone, is looking for the 3rd part of the url to be "id" – tintyethan Nov 06 '13 at 00:27
  • @Ethan Pelton: It did not make any sense. On the other hand I realized that my form call GET instead of POST. I think that is due to that my ActionImage custom helper generates an image containing an anchor tag inside (). In HTML an anchor sends GET request and my controller action is decorated with the HttpPost request. For this reason I think the best way for me in this situation using Ajax for deleting records. – Jack Nov 06 '13 at 13:18
  • Ok, I just think you're going overboard with the custom helper. I don't think you need to do that. I'm going to edit my answer above with another suggestion. – tintyethan Nov 06 '13 at 13:41