ASP.NET MVC3 - Dynamically adding an item to array

2019-04-08 11:45发布

问题:

I'm working on a website where the user should be able to fill out a dynamic expanding form.

I would add a row with greyed out fields and when the user gives focus to one of those field the following javascript would add the line

<tr class="unSelected">
   <input name="id[]">
   <input name="blabla[]">
</tr>

$('.unSelected').focusin(function () {
  if ($(this).hasClass('unSelected')) {
    var row = $(this).clone(true);
    $(this).after(row);
    $(this).removeClass('unSelected');
  }
});

but how would one do this using razor and asp.net, as the objects wont be autogenerated then?

回答1:

In ASP.NET MVC, if you have a model class like:

public class PageModel
{
    public Collection<RowItem> RowItems { get; set; }
}

public class RowItem
{
    public int Id {get;set;}
    public string MoreFields { get; set; }
}

And your javascript adds rows like so:

<script type="text/javascript">
    var currentRowIndex = 0;

    $(document).ready(function () {
        SetFocusEventForInputs('unSelected0');
    });

    function SetFocusEventForInputs(className) {
        var inputSelector = '.' + className;

        $(inputSelector).focusin(function () {
            AddNewRowTo(this);
            $(inputSelector).unbind('focusin').removeClass(className);
        });
    }

    function AddNewRowTo(sendingInputField) {
        currentRowIndex++;
        var className = 'unSelected' + currentRowIndex;
        var collectionNamePrefix = 'RowItems[' + currentRowIndex + '].';

        var idField = $('<input/>').attr('name', collectionNamePrefix + 'Id').attr('type', 'text').attr('class', className);
        var moreFields = $('<input/>').attr('name', collectionNamePrefix + 'MoreFields').attr('type', 'text').attr('class', className);

        var cell = $('<td></td>').append(idField).append(moreFields);
        var row = $('<tr></tr>').append(cell);

        $(sendingInputField).parents("tr").after(row);

        SetFocusEventForInputs(className);
    }
</script>
<table>
    <tr>
        <td>
            <input name="RowItems[0].Id" type="text" class="unSelected0" />
            <input name="RowItems[0].MoreFields" type="text" class="unSelected0" />
        </td>
    </tr>
</table>

The default model binder in MVC should resolve it just fine when it gets posted

[HttpPost]
public ActionResult YourPostActionHere(PageModel model)
{
    var count = model.RowItems.Count();
    etc...
}


回答2:

You can do it the same way, because in the code example above, you are using jQuery which is also supported (of course) with ASP.NET MVC.

Perhaps I don't understand you, but I don't see any PHP code in the code example above.



回答3:

what you want to do is a client side script that is not depend on PHP or Asp.Net so it does not matter what your code is written by. this should work in Asp.Net mvc too.

if you want to collect the new control data to use it in server side you can collect it by JavaScript and assign it in a hidden field that can be accessed in server side. you can use one hidden field by save the values in one string and separated by any delimiter.



回答4:

Are you possibly just missing the script tags? Like the others said, javascript is platform independent.

<tr class="unSelected">
   <input name="id[]">
   <input name="blabla[]">
</tr>

<script src="/Scripts/jquery.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $().ready(function () {
        $('.unSelected').focusin(function () {
            if ($(this).hasClass('unSelected')) {
                var row = $(this).clone(true);
                $(this).after(row);
                $(this).removeClass('unSelected');
            }
        });
    });
</script>