0

I have a table template and table as below in MVC view

Template for dynamic row

<table id="Newrelation" style="display:none">
    <tr>
        <td>
            <select id="relation-%" style="width:100px" class="relation_type" name="survey_detail[#].relation" value></select>
        </td>
        <td>
            <select id="agegroup-%" style="width:100px" class="age_group" name="survey_detail[#].age_group" value></select>
        </td>
        <td>
            <select id="nodependent-%" style="width:100px" class="no_dependent" name="survey_detail[#].no_dependent" value></select>
            <input type="hidden" id="new_relation" name="survey_detail.Index" value="%" />
        </td>
        <td><input id="delete" class="delete" value="X" type="button"></td>
    </tr>
</table>

Actual table

<table id="relation" class="table table-striped table-hover table-bordered">
    <tbody>
        <tr>
            <th style="width:100px">
                Relation
            </th>
            <th style="width:150px">
                Age Group
            </th>
            <th style="width:150px">
                No: Dependent
            </th>
        </tr>
        @if (Model != null)
        {
            for (int i = 0; i < Model.survey_detail.Count; i++)
            {
                <tr>
                    <td>
                        @Html.DropDownListFor(m => m.survey_detail[i].relation, (SelectList)@ViewBag.Relation,"--", new { @class = "m-wrap" })
                    </td>
                    <td>
                        @Html.DropDownListFor(m => m.survey_detail[i].age_group, (SelectList)@ViewBag.Agegroup,"--", new { @class = "m-wrap" })
                    </td>
                    <td>
                        @Html.DropDownListFor(m => m.survey_detail[i].no_dependent, (SelectList)@ViewBag.Number, "--", new { @class = "m-wrap" })
                        <input type="hidden" name="survey_detail.Index" value="@i" />
                    </td>
                    <td><input id="delete" class="delete" value="X" type="button"></td>
                </tr>
            }
        }
    </tbody>
<table>

Jquery to attach new row on button click

$('#add_rel').click(function (e) {
    var body = $('#relation').children('tbody').first();
    var index = (new Date()).getTime();
    var clone = $('#Newrelation').clone();
    clone.html($(clone).html().replace(/\[#\]/g, '[' + index + ']'));
    clone.html($(clone).html().replace(/"%"/g, '"' + index + '"'));
    clone.html($(clone).html().replace(/"relation-%"/g, 'relation-' + index));
    clone.html($(clone).html().replace(/"agegroup-%"/g, 'agegroup-' + index));
    clone.html($(clone).html().replace(/"nodependent-%"/g, 'nodependent-' + index));
    var newrow1 = clone.find('tr');
    body.append(newrow1);
});

And it attach new row to the table but all the select list comes blank eventhough the @ViewBag.Relation,@ViewBag.agegroup,@ViewBag.Number has data.

Please guide me to get values on the select list

4
  • The <select> elements in the template that your cloning do not have any <option> elements so there is nothing to display. You will need to generate and append the options elements to the new row based on values in the ViewBag properties. Commented Jun 1, 2016 at 11:20
  • @StephenMuecke can i give option property in template with the viewbag? Commented Jun 1, 2016 at 11:21
  • As a side note, your use of DropDownListFor() inside a loop will not work correctly - the first option will always be selected when the page is initially displayed Commented Jun 1, 2016 at 11:22
  • @StephenMuecke can u pls show one eg? Commented Jun 1, 2016 at 11:23

1 Answer 1

1

Firstly, your use of DropDownListFor() will not work correctly (the first option will always be selected no mater what the value of the property is) as explained in this answer (note in your case you will not be able to use the EditorTemplate option).

To solve this and the main issue in your question, change your ViewBag properties from IEnumerable<SelectListItem> to IEnumerable<T> where T is an object containing just 2 properties, for example

public class OptionVM
{
    public int ID { get; set; }
    public string Name { get; set; }
}

and then the code in the GET method would be something like

ViewBag.Relation = db.Relations.Select(x => new OptionVM
{
    ID = x.RelationId,
    Name = x.SomeOtherPropertyToDisplay
});

In the view, for the generating the existing items, use

for (int i = 0; i < Model.survey_detail.Count; i++)
{
    ....
    @Html.DropDownListFor(m => m.survey_detail[i].relation, 
        new SelectList(ViewBag.Relation, "ID", "Name", Modelsurvey_detail[i].relation), 
        "--", 
        new { @class = "m-wrap" })
    ....
}

which will ensure the correct options is selected.

Now you can use those same ViewBag properties to add the <option> elements to your template when the page is first loaded.

// Get the first select element in the template
var relationSelect = $('#Newrelation').find('select').eq(0);
// Create a javascript array of the options
var relationOptions = @Html.Raw(Json.Encode(ViewBag.Relations));
// Create and append option elements
relationSelect.append($('<option></option>').val('').text('--'));
$.each(relationOptions, function(index, item) {
    relationSelect.append($('<option></option>').val(item.ID).text(item.Name));
});

and repeat for the 2nd and 3rd <select> elements in the template.

Side notes:

  1. It is not necessary to add id attributes to the <select> and <input type="hidden"> elements in the template and you should not be adding one to the <input type="button"> because that is generating invalid html (duplicate id attributes).
  2. Your creating a null ("--") option which suggest you will be validating that a selection has been made, in which case you should also be adding @Html.ValidationMessageFor() for each property (and adding the html that it generates to your template (refer this answer for more detail). If that is the case, you will also need to reparse the validator each time a new item is added (as shown in the previous link).
  3. Finally, I recommend you use a view model containing properties for the collections used to generate the options rather than using ViewBag.
Sign up to request clarification or add additional context in comments.

8 Comments

var relationOptions = '@Html.Raw(Json.Encode(ViewBag.Relation)'; giving error Unterminated string literal. Strings that start with a quotation mark (") must be terminated before the end of the line. However, strings that start with @ and a quotation mark (@") can span multiple lines
Oops - just noticed I was missing a closing ) - should be var relationOptions = '@Html.Raw(Json.Encode(ViewBag.Relation))'; - see edit - but let me check there are no other typos by creating the fiddle.
Found another as well (there should be no quotes). See this DotNetFiddle for a working example (note I'll delete the fiddle in a few hours so fork it if you want to keep it)
thanks for your help..but still the select list is getting empty..the fiddle also when i run the select list don't have any value
The fiddle works fine so not sure what your saying - the html is just <select></select> and has no options - and its the script which is adding the 4 options to it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.