Daleman
Daleman

Reputation: 874

Select Tag Helper get value and text

I just read this Select Tag Helper, how to use tag helper and previously I asked about onchange for select tag helper.

But this time, I need to get the text of the select tag helper. This is my model:

public class Paid__Period {
    [Key]
    public Int16 ID_Period { get; set; }
    public string Period { get; set; }
}

This is my view:

<select asp-for="Period" class="form-control input-sm"                        
    asp-items="@(new SelectList (@ViewBag.Period, "ID_Period", "Period"))" onchange="this.form.submit()">
</select>

When it rendered into HTML, it becomes

<select class="form-control input-sm" onchange="this.form.submit()" id="Period" name="Period">
   <option value="0">- Choose Period -</option>
   <option value="1">2016 - 1 (Jan - Jun)</option>
   <option value="2">2017 - 1 (Jan - Jun)</option>
   <option value="3">2017 - 2 (Jul - Dec)</option>
   <option value="4">2018 - 1 (Jan - Jun)</option>
   <option value="5">2018 - 2 (Jul - Dec)</option>
   <option value="6">2019 - 1 (Jan - Jun)</option>
   <option value="7">2019 - 2 (Jul - Dec)</option>
   <option value="8">2020 - 1 (Jan - Jun)</option>
</select>

Till here, everything works well. But I need return value from view to action controller every time selected are ID_Period and Period: '2020 - 1 (Jan - Jun)'. How to do this?

I just prepare my action like this:

[HttpPost]
public IActionResult Paid_Tuition (Paid_Period period) {
}

but Paid_Period is always null. Any suggestion to solve my problem above?

Upvotes: 2

Views: 6847

Answers (2)

itminus
itminus

Reputation: 25360

but Paid_Period is always null.

That's because your're posting an int and try to bind that int value to an instance Paid__Period.

Let's inspect your rendered HTML :

<form ... >
    ...

    <select class="form-control input-sm" onchange="this.form.submit()" id="Period" name="Period">
       <option value="0">- Choose Period -</option>
       <option value="1">2016 - 1 (Jan - Jun)</option>
       <option value="2">2017 - 1 (Jan - Jun)</option>
       <option value="3">2017 - 2 (Jul - Dec)</option>
       <option value="4">2018 - 1 (Jan - Jun)</option>
       <option value="5">2018 - 2 (Jul - Dec)</option>
       <option value="6">2019 - 1 (Jan - Jun)</option>
       <option value="7">2019 - 2 (Jul - Dec)</option>
       <option value="8">2020 - 1 (Jan - Jun)</option>
    </select>

</form>

When you select the "2020 -1 (Jan - Jun)", the payload sent to server is (assuming you're using a content-type of application/x-www-form-urlencoded ):

...&Period=7&...

But your action method is treating period as an instance of Paid_Period instead of an int :

[HttpPost]
public IActionResult Paid_Tuition (Paid_Period period) 
{
}

How to solve

change your action method to accept an int period, and construct an instance of Paid_Period according to the int period Id.

Upvotes: 0

Tetsuya Yamamoto
Tetsuya Yamamoto

Reputation: 24957

You need another tag helper (e.g. hidden field) bound to string property of your viewmodel to pass text option from selected value together with the <select> element itself:

<select asp-for="ID_Period" class="form-control input-sm"                        
    asp-items="@(new SelectList (@ViewBag.Period, "ID_Period", "Period"))" onchange="onSelectedIndexChanged(this)">
</select>
<input asp-for="Period" type="hidden" />

Then you can retrieve selected text option using JS function bound to onchange event:

function onSelectedIndexChanged(value)
{
    var textValue = value.options[value.selectedIndex].text;
    document.getElementById('Period').value = textValue;

    // if you want to submit the form, uncomment this line below
    // document.getElementById('yourformId').submit();
}

Or if you're using jQuery then you could remove onchange event attribute and handle change event instead to assign value into hidden field:

$('#ID_Period').change(function () {
    var textValue = $('#ID_Period option:selected').text();
    $('#Period').val(textValue);

    // if you want to submit the form, uncomment this line below
    // $('form').submit();
});

Note:

It's more recommended to trigger form submit using a button rather than <select> element's change event.

Upvotes: 3

Related Questions