Vini
Vini

Reputation: 2134

Calling an Action Method based on the value of DropDownList and the model

I have a dropdownlist in my View. I need to enable the user to select a value from the dropdownlist and click a button/ActionLink to call another action method in the same controller. The values that needs to be passed to the new ActionMethod are the ID of the selected Value from the dropdownlist and also the ID of the model which is being passed into the View. The model and the Dropdownlist are not linked together by any means.

I have tried onchnage = document.location.href to set the path of the action method and pass a single value to the action method. But the issue with document.location.href is that it appends the url to the existing url which is not appreciated; i.e, the final url turns out be localhost:port/controller1/action1/controller1/action2 which should have been simply localhost:port/controller1/action2

I am looking for a way where it could be done without using javascript as I have already tried it.

Code in the View

@using (Html.BeginForm("Copy","SetValues",FormMethod.Post))
{
    <p>
        @Html.DropDownList("OptionValueID", null, "Select")
        <input type="submit" value="Copy" />

        //This is the preferable method though
        @*@Html.ActionLink("Copy", "Copy", "SetValues", new { @OptionValueID = @ViewBag.id,@CopyID = CopyDDL.SelectedValue},null)*@
    </p>
}

The copy function is going to take two arguments: Id of the selected item and ID that is being passed through ViewBag.id

The View that is being returned by View would a different View

JavaScript that I have tried

<script language="javascript" type="text/javascript">
    function copy(_OptionValueID)
    {
        var url = "/SetValues/Copy";
        $.ajax({
            url: url,
            data: { copyid: _OptionValueID},
            type: "POST",
            success: function (data) { }


        });
        response();
    }
</script>

It doesn't evaluate at all.

Action Method that calls this View

public ActionResult Index(int id)
{
        var ov = db.OptionValue.Include(x => x.Option).FirstOrDefault(x => x.OptionValueID == id);
        var opid = ov.OptionID;
        var op = db.Option.Include(x => x.TechnicalCharacteristic).FirstOrDefault(x => x.OptionID == opid);
        var tcid = op.TechnicalCharacteristicID;
        var tc = db.TechnicalCharacteristic.Include(x => x.TcSets).FirstOrDefault(x => x.TechnicalCharacteristicID == tcid);
        var tcset = tc.TcSets;
        var opv = db.OptionValue.FirstOrDefault(x => x.OptionValueID == id);
        ViewBag.OptionValue = opv.OptionVal;
        ViewBag.Option = opv.Option.OptionName;
        ViewBag.Lsystem = opv.Option.Lsystem.LsystemName;
        ViewBag.FamilyName = opv.Option.Lsystem.LsystemFamily.FamilyName;
        ViewBag.OptionValID = id;
        ViewBag.OptionID = opv.OptionID;
        var setValue = db.SetValue.Where(x=>x.OptionValueID==id).OrderBy(x=>x.TcSet.SetName);
        ViewBag.OptionValueID = new SelectList(db.OptionValue.Where(x=>x.OptionID==opid), "OptionValueID", "OptionVal");
        return View(setValue.ToList());
}

I ahve checked most question relating to this, but none had the overhead of passing two parameters without using a model.

UPDATE: making it more clear

 public ActionResult copy(int OptionValueID,int CopyID)
 {
     //do Something
     return View("Error");
 }

Above is the Copy Method

OptionValueID = ViewBag.OptionValID //Got from the Action Method Index of SetValues
CopyID = Value from the DropDownlist

Edit Based on Answer

@using (Html.BeginForm("Copy","SetValues",FormMethod.Post))
{
    <p>
        @Html.DropDownList("CopyID", null, "Select")
        <button type="submit" id="Copy" data-id="@ViewBag.OptionValID"> Copy </button>
    </p>
}

now the page is being redirected but the no parameters are being passed. Should I be adding routevalues?

Upvotes: 0

Views: 69

Answers (1)

user3559349
user3559349

Reputation:

You cannot do it without javascript. Your ActionLink() method is parsed on the server before its sent to the client, so any route values are the initial values in the controller, not any edited values the user makes in the view. In order to respond to client side events you need javascript.

You can use ajax to post the values to the server method.

Include a button and handle its click event

<button type="button" id="Copy" data-id="@ViewBag.id">Copy</button>

Script

var url = '@Url.Action("Copy", "SetValues")';
$('#Copy").click(function() {
  var optionID = $(this).data('id');
  var copyID = $('#OptionValueID').val();
  $.get(url, { OptionValueID: optionID, copyID : CopyID }, function(response) {
    // do something with the response
  });
});

or alternatively if you wanting to redirect, then replace the $.get() with

location.href = url + '?OptionValueID=' + optionID + '&CopyID=' + copyID;

Edit

Based on revised question and comments, if you wanting to post and redirect, there is no need for any javascript or the link. The dropdownlist needs to be @Html.DropDownList("CopyID", null, "Select") so that its selected value is bound to method parameter int CopyID and since the OptionValueID is not edited, then either add its value as a route parameter in the form

@using (Html.BeginForm("Copy", "SetValues", new { OptionValueID = ViewBag.OptionID }, FormMethod.Post))

or add a hidden input for the value

<input type="hidden" name="OptionValueID" value="@ViewBag.OptionID" />

Upvotes: 1

Related Questions