Dynamically addint input text boxs to Asp.Net core View C# + JS

Viewed 420

Im trying to add a function to add any amount of user requested textboxes my EventMembers input.

I have the functions working but the additional textbox inputs are not being added to my EventMembers List. I know if i just create multiple textboxes on my view by doing

EventMembers[0]
EventMembers[1]
EventMembers[2]

etc.. That works fine. How would i go about accomplishing the same thing with my javascript functions for dynamic textboxes? Code below with required info only.

Model:

public class Event
    {
        public List<string> EventMembers { get; set; }
    }

View:

<div class="form-group" id="firstdiv">
                <label asp-for="EventMembers" class="control-label">Event Members</label>
                <input asp-for="EventMembers" class="form-control" />
                    <input type="button" class="btn btn-primary" value="Add Member" 
                           onclick="DynamicText()" />
                <span asp-validation-for="EventMembers" class="text-danger"></span>
                <span style="color:red;">@TempData["MustEnterinput"]</span>
            </div>

Javascript:

function DynamicText() {
    var division = document.createElement('DIV');
    division.innerHTML = DynamicTextBox("");
    document.getElementById("firstdiv").appendChild(division);
}
function DynamicTextBox(value) {
    return '<div><input asp-for="EventMembers" class="form-control" /><input type="button" class="btn btn-primary" onclick="ReTextBox(this)" value="Remove" /></div>';
}
function ReTextBox(div) {
    document.getElementById("firstdiv").removeChild(div.parentNode.parentNode);
}
1 Answers

I changed some names for my setup.

Model;

public class EventMemberList
{
    public List<string> EventMembers { get; set; }
}

Controller, Get Action;

public IActionResult Index()
{
    EventMemberList model = new EventMemberList
    {
        EventMembers = new List<string>()
    };
    return View(model);
}

Controller, Post Action;

[HttpPost]
public IActionResult Index(EventMemberList model)
{
   //Do Something...
   return View(model);
}

Finaly View ;

@using (Html.BeginForm())
{
    <div class="form-group" id="firstdiv">
        <label class="control-label">Event Members</label>
        <div id="inputList"></div>
        <br />
        <a class="btn btn-primary" onclick="AddInput()">Add Member</a>
        <br />
        <button type="submit">Submit</button>
    </div>
}


<script type="text/javascript">
    function AddInput() {
        var inputList = document.getElementById("inputList");
        var inputCount = inputList.getElementsByTagName('input').length;
        var newInput = ` 
    <input class="form-control" id="EventMembers_${inputCount}" name="EventMembers[${inputCount}]" type="text" value=""> 
    <br/> 
`;
        var element = document.createElement("div");
        element.innerHTML = newInput ;
        inputList.appendChild(element);
    }
</script>

To append input, I created a div. You need to add id like EventMembers_${inputCount} and name like EventMembers[${inputCount}]. With doing this, you will be able to send data to controller.

If you want to some validation in model, you need to add to inputList some code ;

<div id="inputList">
    @for (int i = 0; i < Model.EventMembers.Count; i++)
    {
        @Html.EditorFor(_ => Model.EventMembers[i], new { htmlAttributes = new { @class = "form-control" } })
        <br />
    }
</div>

By doing this, when you submit list and model is not valid, you will be able to send invalid inputs to view back.

Related