Добавьте текстовое поле динамически и отправьте его на контроллер mvc - PullRequest
0 голосов
/ 06 июля 2019

Я новичок в mvc.Для моего приложения я имею в виду создание коллекции.Допустим, я должен отображать имя и адрес в первый раз.Если пользователь нажимает кнопку копирования, он должен клонировать div имени и адреса.Даже я клонирую его, используя Jquery, он отправляет текстовые поля.И я должен отправить все данные обратно в контроллер. Но он публикует только первую запись

I have created viewmodel and loop in view to display those in view. As index is 0 initially it is not displaying those text box. 

    public class Person
    {
        public string Name { get; set; }
        public string Address { get; set; }
    }
    public class PersonVM
    {
        public PersonVM()
        {
            Persons = new List<Person>();
        }
        public IList<Person> Persons { get; set; }
    }




    @model MvcApplication5.Models.PersonVM
@{
    ViewData["Title"] = "Index";
}

<h2>Index</h2>

<script src="~/Script/JavaScript.js"></script>
<div class="example-1">

    @using (Html.BeginForm("Create", "Person", FormMethod.Post, new { @id = "formpost", @class = "main-form" } ))
    {

        <div class="example-2">

            @for (int i = 0; i < Model.Persons.Count(); i++)
            {
                <p>Example one</p>
                <p>Example two</p>

                @Html.TextBoxFor(p => p.Persons[i].Name, null, new { @class = "form-control" })

                @Html.TextBoxFor(p => p.Persons[i].Address, null, new { @class = "form-control" })

            }

            <button type="button" class="btn-copy">Copy</button>

        </div>
        <input type="submit" id="submit" name="Submit" />

    }


</div>

<script>
    $(function () {
        $(".btn-copy").on('click', function () {
            var ele = $(this).closest('.example-2').clone(true);
            console.log(ele.find('input'));
            //var currentIndex = $(ele).split("[")[1][0];
            //var newIndex = Number(currentIndex) + 1;
            ele.find('input').each(function () {
                console.log($(ele));
                this.id = this.id.replace('0', '[' + 2 + ']');
                this.name = this.name.replace('[0]', '[' + 2 + ']');
                //$(ele).attr("name", $(ele).attr("name").replace(currentIndex, newIndex));
            });
            $(this).closest('.example-2').after(ele);
        });
        $(".main-form").on("submit", function () {
            //You might need to replace the selector here with something better and
            //repeat this for the name as well, or modify it to work with the whole div.
            //$.each($(".example-2"), function (index, inputContainer) {
            //    $.each($(inputContainer).children("div").children("input"), function (inputIndex, input) {
            //        var currentIndex = $(input).attr("name").split("[")[1][0];
            //        $(input).attr("name", $(input).attr("name").replace(currentIndex, index));
            //    });
            //});
            console.log($('.example-2').val);
        });
    });
</script>

1 Ответ

0 голосов
/ 06 июля 2019

Редактировать: - Я посмотрел на код более тщательно и заново его создал.Я внес некоторые незначительные изменения, но вот как это выглядит сейчас.

//My Controller action methods
    public IActionResult Index()
    {
        var emptyModel = new PersonVM() {
            Persons = new List<Person>()
        };
        emptyModel.Persons.Add(new Person());
        return View(emptyModel);
    }

    [HttpPost]
    public IActionResult Index(PersonVM people)
    {
        return View(people);
    }

Я не вносил никаких изменений в представление.Но я включил все это здесь

@model PersonVM

<div class="example-1">

    @using (Html.BeginForm("Create", "Person", FormMethod.Post, new { @class = "main-form"}))
    {


        <div class="example-2">


            <div>

                @for (int i = 0; i < Model.Persons.Count(); i++)
                {
                    <p>Example one</p>
                    <p>Example two</p>

                    @Html.TextBoxFor(p => p.Persons[i].Name, null, new { @class = "form-control" })

                    @Html.TextBoxFor(p => p.Persons[i].Address, null, new { @class = "form-control" })

                }

                <button type="button" class="btn-copy">Copy</button>
            </div>
        </div>
        <input type="submit" name="Submit" />


    }


</div>
<script>
    $(function () {
        $(".btn-copy").on('click', function () {
            var ele = $(this).closest('.example-2').clone(true);
            $(this).closest('.example-2').after(ele);
        });
        $(".main-form").on("submit", function () {
            //You might need to replace the selector here with something better and
            //repeat this for the name as well, or modify it to work with the whole div.
            $.each($(".example-2"), function (index, inputContainer) {
                $.each($(inputContainer).children("div").children("input"), function (inputIndex, input) {
                    var currentIndex = $(input).attr("name").split("[")[1][0];
                    $(input).attr("name", $(input).attr("name").replace(currentIndex, index));
                });
            });
        });
    });
</script>

Вот моя отправленная форма.enter image description here

Вот выходные данные отладки.enter image description here

Надеюсь, это решит вашу проблему.Одна хитрость заключается в необходимости очищать значение имени и поля Person каждый раз, когда вы клонируете, но этого легко достичь.

Вы видите это, потому что все отправляемые текстовые поля имеют одинаковый индекс,и каждое новое значение просто переопределяет существующее значение, когда происходит привязка модели.У вас есть два пути решения этого.Либо в вашем прослушивателе кликов назначьте новые индексы, либо дождитесь, пока пользователь отправит форму.Вот примеры кода.

Пример - 1: обновить индекс после перед добавлением нового текстового поля.

<script>
    //This assumes sequential indices.
    $(function () {
        $(".btn-copy").on('click', function () {
            var ele = $(this).closest('.example-2').clone(true);
            var currentIndex = $(ele).split("[")[1][0];
            var newIndex = Number(currentIndex) + 1;
            $(ele).attr("name", $(ele).attr("name").replace(currentIndex, newIndex);
            $(this).closest('.example-2').after(ele);
        })
    });
</script> 

Пример - 2: продолжить текущий метод и применить индексы при отправке.

<script>
    $(function () {
        $(".btn-copy").on('click', function () {
            var ele = $(this).closest('.example-2').clone(true);
            $(this).closest('.example-2').after(ele);
        });
        $("{selector for form}").on("submit", function() {
            //You might need to replace the selector here with something better and 
            //repeat this for the name as well, or modify it to work with the whole div.
            $.each("input[name='Persons[i].Address']", function(index, input){
                var currentIndex = $(input).split("[")[1][0];
                var newIndex = Number(currentIndex) + 1;
                $(input).attr("name", $(input).attr("name").replace(currentIndex, newIndex);                
            });
        });
    })


</script> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...