Dynamically Add Field to a Form

Dynamically creating a specific number of input form elements

You could use an onclick event handler in order to get the input value for the text field. Make sure you give the field an unique id attribute so you can refer to it safely through document.getElementById():

If you want to dynamically add elements, you should have a container where to place them. For instance, a <div id="container">. Create new elements by means of document.createElement(), and use appendChild() to append each of them to the container. You might be interested in outputting a meaningful name attribute (e.g. name="member"+i for each of the dynamically generated <input>s if they are to be submitted in a form.

Notice you could also create <br/> elements with document.createElement('br'). If you want to just output some text, you can use document.createTextNode() instead.

Also, if you want to clear the container every time it is about to be populated, you could use hasChildNodes() and removeChild() together.

<html>
<head>
<script type='text/javascript'>
function addFields(){
// Generate a dynamic number of inputs
var number = document.getElementById("member").value;
// Get the element where the inputs will be added to
var container = document.getElementById("container");
// Remove every children it had before
while (container.hasChildNodes()) {
container.removeChild(container.lastChild);
}
for (i=0;i<number;i++){
// Append a node with a random text
container.appendChild(document.createTextNode("Member " + (i+1)));
// Create an <input> element, set its type and name attributes
var input = document.createElement("input");
input.type = "text";
input.name = "member" + i;
container.appendChild(input);
// Append a line break
container.appendChild(document.createElement("br"));
}
}
</script>
</head>
<body>
<input type="text" id="member" name="member" value="">Number of members: (max. 10)<br />
<a href="#" id="filldetails" onclick="addFields()">Fill Details</a>
<div id="container"/>
</body>
</html>

Dynamically add field to a form python django

Okey using formset factory i very straight forward and simple to render multiple fields for user to fill in their information. First of all you would need to create forms.py in your project and then import django's formset_factory in forms. We would do something like so:

from django.forms import formset_factory
from .models import SupplyChainStops

# Here we are creating a formset to handle the maniplations of our form to
# have extra field by using the extra parameter to formset_factory
# and also we can add a delete function to allow users to be able to delete

Formset = formset_factory(SupplyChainStops, fields=[' stop_name',' stop_longitude','stop_latitude'], extra=4, can_delete=True)
# I have set the formset to give us an extra field of four and enable users
# to delete

Now we are going to work on the view to handle our formset.

from django.views.generic.edit import FormView
from .forms import Formset

class formsetView( FormView):
template_name = 'formset.html'
form_class = Formset
success_url = '/'


In our template we will do something like this .


<form method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Add">
</form>

Doing this in a function base view

from .forms import Formset

def formset_view(request):
if request.method == 'POST':
formset = Formset(request.POST,)
if formset.is_valid():
formset.save()
else:
formset = ()
return render (request, 'formset.html',{'formset':formset})

In your HTML Template

<form method="post">{% csrf_token %}
{{ formset.as_p }}
<input type="submit" value="Add">
</form>

How to create dynamic form input fields in React with ANTd

If you're using antd version 4.9.0+, you can take advantage of the initialValue property on the Form.List. This allows you set intial values on the form items of the array. Alternatively, you can set the initialValues property on the Form. Here's a minimum viable example using the former method.

import { Form, Input, Button, Space } from "antd";
import { MinusCircleOutlined, PlusOutlined } from "@ant-design/icons";
import React from "react";

//Basic Idea
/*
I want the user to be able to edit some details of a purchase order that already exists in the database,
then resubmit the order with a form.
The details of the purchase order should be orginally displayed in the form input fields,
and the user can change them directly via those fields.
*/

//This is the order that already exists
const order = {
po_number: "123abc",
carrier: "Fastway",
items: [
{
item_code: "dnh75n",
quantity: "10",
special_requirements: "Add picture of happy dog"
},
{
item_code: "456def",
quantity: "4",
special_requirements: "Do not include lids"
}
]
};

const GroupForm = () => {
const onFinish = (values) => {
console.log(values);
};

//Create form fields based off how many items are in the order
const itemInputs = order.items.map((item) => {
return {
item_code: item.item_code,
quantity: item.quantity,
special_requirements: item.special_requirements
};
});

return (
<div>
<Form onFinish={onFinish}>
<b>{"Order " + order.po_number}</b>

<Form.Item name="carrier" label="carrier" initialValue={order.carrier}>
<Input style={{ width: "500px" }} />
</Form.Item>
<Form.Item
name="po_number"
label="PO number"
initialValue={order.po_number}
hidden
>
<Input />
</Form.Item>

<b>Order Items</b>

<Form.List name="items" initialValue={itemInputs}>
{(fields, { add, remove }) => (
<>
{fields.map((field) => (
<Space
key={field.key}
style={{ display: "flex", marginBottom: 8 }}
align="baseline"
>
<Form.Item
{...field}
name={[field.name, "item_code"]}
fieldKey={[field.fieldKey, "item_code"]}
>
<Input placeholder="Item Code" />
</Form.Item>
<Form.Item
{...field}
name={[field.name, "quantity"]}
fieldKey={[field.fieldKey, "quantity"]}
>
<Input placeholder="Quantity" />
</Form.Item>
<Form.Item
{...field}
name={[field.name, "special_requirements"]}
fieldKey={[field.fieldKey, "special_requirements"]}
>
<Input placeholder="Quantity" />
</Form.Item>
<MinusCircleOutlined onClick={() => remove(field.name)} />
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => add()}
block
icon={<PlusOutlined />}
>
Add item
</Button>
</Form.Item>
</>
)}
</Form.List>

<Form.Item>
<Button type="primary" htmlType="submit">
{" "}
Change Details{" "}
</Button>
</Form.Item>
</Form>
</div>
);
};

export default GroupForm;

// I want to submit a form object that looks like this. E.g.
// This is what 'onFinish' should display in the console
/*

{
po_number:"123abc",
carrier:"Fastway",
items: [{
item_code:"dnh75n",
quantity:"10",
special_requirements:"Add picture of happy dog"
},
{
item_code:"456def",
quantity:"4",
special_requirements:"Do not include lids"
}
]
}

*/

DEMO

angular 7 reactive forms: dynamically add / remove input fields for each input field in the form

I think what will work best for your situation is to use FormArray. With FormArray you can push and remove items just like you would do with a normal array

  myForm = this.fb.group({
documents: this.fb.array([])
});

get documentsControl(): FormArray {
return this.myForm.get("documents") as FormArray;
}
documents = [
{ id: 1, service_item_id: 311101, name: "document 1" },
{ id: 2, service_item_id: 311102, name: "document 2" },
{ id: 3, service_item_id: 311103, name: "document 3" },
{ id: 4, service_item_id: 311104, name: "document 4" }
];
ngOnInit() {
this.documents.forEach(document =>
this.documentsControl.push(
this.fb.group({
id: [document.id],
name: [document.name],
service_item_id: [document.service_item_id]
})
)
);
}
constructor(private fb: FormBuilder) {}
submitForm() {}
add() {
this.documentsControl.push(
this.fb.group({
id: [null],
name: [null],
service_item_id: [null]
})
);
}
remove(index) {
this.documentsControl.removeAt(index);
}

to add items we use push while to remove items we use removeAt

Below is the html

<form [formGroup]="myForm" (ngSubmit)="submitForm()">
<ng-container formArrayName='documents'>
<div *ngFor="let c of documentsControl.controls; let index = index" [formGroupName]='index'>
<label>
{{ c.value.name}}
</label>
<input type="number" formControlName="service_item_id" placeholder="name" />
<button class="btn btn-primary btn-sm" (click)="add()">Add</button>
<button class="btn btn-primary btn-sm" (click)="remove(index)">Remove</button>
</div>
</ng-container>
<button type="submit" class="btn btn-primary btn-small">Submit</button>
</form>

Edit

To add items below there clicked button we can implement insert()

  insert(index) {
const serviceItenId = this.documentsControl.controls[index].get('service_item_id').value
this.documentsControl.insert(
index + 1,
this.fb.group({
id: [null],
name: [null],
service_item_id: [serviceItenId]
})
);
}

I have updated the below Demo to reflect this

See Demo



Related Topics



Leave a reply



Submit