简体   繁体   中英

Add textboxes dynamically in ASP.NET MVC

I work on an ASP.NET MVC project that I need some help with. I need to be able to create x number of textboxes when the user click "add textbox". When the user enter the page a viewmodel is loaded. This viewmodel need to handle the x number of textboxes that the user create when he is on the page so that when the page is posted these textboxes are part of the model. The model should look something like this..

public class PlanViewModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public List<EventViewModel> EventList { get; set; } // this should be the list of textboxes that the user "create" by clicking add new
}

public class EventViewModel
{
    public string Name { get; set; }
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public string Description { get; set; }
}

I'm kinda lost on how to do this so any help is appreciated.

UPDATE

I've added this javascript that add textboxes client side..

<script type="text/javascript">
function GetDynamicTextBox(value) {
    return('<input type="text" name="events[0].Key" value="box1" /><input type="text" name="events[0].Value.StartDate" value="box2"/><button type="button" class="btn btn-sm btn-primary" onclick="RemoveTextBox(this)"><i class="fa fa-angle-right"></i> Remove</button>');
}
function AddTextBox() {
    var div = document.createElement('DIV');
    div.innerHTML = GetDynamicTextBox("");
    document.getElementById("divcontent").appendChild(div);
}
function RemoveTextBox(div) {
    document.getElementById("divcontent").removeChild(div.parentNode);
}
</script>

            <div id="divcontent" class="form-group">
            <button type="button" class="btn btn-sm btn-primary" onclick="AddTextBox()"><i class="fa fa-angle-right"></i> Add</button>
        </div>

I think I only need to add unique id's for the textboxes like this...

events[0].Key
events[1].Key
events[2].Key

and so on..

But I don't know how. Anyone knows?

You can add a list of String, like this

public String[] MyTextFields

and then create HTML using Javascript, like this:

<input name="myTextFields[0]"></input>

<input name="myTextFields[1]"></input>

In Razor view:

@for (var i = 0; i < Model.EventList.Count; i++)
{
    @Html.EditorFor(x => Model.EventList[i].Name)
}

To set the name attribute of all edited elements in javascript, this is to be called on page load, and any time the collection changes (item is added or removed):

var children = document.getElementById("myDIV").children; // TODO: here supposing children are the input elements, may be different on your page (they may be nested in a different way)
for (i = 0; i < children.length; i++)
{
    var el = children[i];
    el.name = 'EventList[' + i + '].Name'; // TODO: look into source code of the generated page for the actual format of existing elements and then modify the mask accordingly
    el.id = 'EventList[' + i + '].Name';
}

If it is ok to have JS dependency than I suggest to use light Knockout library. It will help you to create/edit/delete your inputs. Check example in JS fiddle .

Use HTML to adjust your view. Tag data-bind lets you to bind to data and events

<button data-bind="click: addInput">Add</button>
<div data-bind="foreach: inputs">
  <input data-bind="value: text"/><br />
</div>
<button data-bind="click: proceed">Proceed</button>
<!-- Use Knockout JS library -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.5.0/knockout-min.js"></script>

Then small JS script which handles adding new input and processing data on click.

function InputData(text) {
  let self = this;
  self.text = text;
}
function InputViewModel() {
  let self = this;
  // Your array of HTML inputs
  self.inputs = ko.observableArray([new InputData("Default value")]);
  self.output = ko.observable();
  self.addInput = function() {
    // Dynamically adds new input on user click button "Add"
    self.inputs.push(new InputData(""));
  };
  self.proceed = function() {
    // Process all input with their values
    for (var i = 0; i < self.inputs().length; i++) {
        console.log(self.inputs()[i].text);
    }

  }
}
// Bind our JS to HTML view
ko.applyBindings(new InputViewModel());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM