Dynamically add and remove form fields - javascript

I would like to create a form field which has an icon in it, let's say a plus-sign. When this icon is clicked, a new identical form field appears, but with a minus-sign in it. And as you guessed, the minus-sign removes the form field again.
I would like to do this using Bootstrap (3.2.0) and jQuery.
What is the best way to do this? I would like to put a limit on the number of fields (let's say 3) and also not have duplicate id fields. Also, I would like the icon to be inside the input.
HTML file:
<div class='container'>
<div class='row marketing'>
<div class='col-lg-15'>
<form class='form-horizontal'>
<div class="form-group has-feedback">
<label id="keywordLabel" for="keyword" class="col-sm-2 control-label">Keywords:</label>
<div id="keywordList" class="col-sm-10">
<input id="keyword" type="text" name="keyword" class="form-control"></input>
<span id="addKeyword" class="glyphicon glyphicon-plus form-control-feedback"></span>
</div>
</div>
</form>
</div>
</div>
</div>
JavaScript file:
$(document).ready( function() {
$('#addKeyword').on('click', function() {
$('#keywordList').append(
"<input id='keyword' class='form-control' type='text' name='keyword'><span id='removeKeyword' class='glyphicon glyphicon-minus form-control-feedback'></span>"
);
});
});
For my code in JSFiddle, click here.

Edit:
I'm still messing around, if I remove the "form-control-feedback"-class in the javascript, it works better.
For now I have:
<div class='container'>
<div class='row marketing'>
<div class='col-lg-15'>
<form class='form-horizontal'>
<div class="form-group has-feedback">
<label id="keywordLabel" for="keyword" class="col-sm-2 control-label">Keywords:</label>
<div id="keywordList" class="col-sm-10">
<div class="form-control">
<input id="keyword" type="text" name="keyword" class=""></input>
<span id="addKeyword" aria-hidden="true" class="glyphicon glyphicon-plus form-control-feedback"></span></div>
</div>
</div>
</form>
</div>
</div>
And JS:
$(document).ready(function () {
$('#addKeyword').on('click', function () {
$('#keywordList').append("<div class='form-control'><input id='x' class='form-control' type='text' name='keyword'></input><span id='removeKeyword' aria-hidden='true' class='glyphicon glyphicon-minus'></span></div>");
});
});
Still not perfect, but closer already.
Original text:
First of all, your jsfiddle doesn't show the icon, because you didn't activate bootstrap on it. if I activate the bootstrap extension, I can see the "+"
I'm not sure what you're asking us, as there is no real question in your post, but if I click the "+", it adds a field. The problem is that the "-" goes in front of the "+" and so you can't see it.
You're also adding duplicate ID's by doing, which is never a good thing.
If you can edit your post, and add the question, I can look to answer what you want to know. :-)

You need to load the appropriate external resources in Jsfiddle
bootstrap.min.js and bootstrap.min.css
see: http://jsfiddle.net/u4e64quc/4/
Alternatively, check bootstrap in the Jsfiddle options and no need to load external resources --this also fixes the issue with the icon outside of the form field pointed out in the comment

Related

Preventing form submission on Enter key press in Angular

There are so many answers for this on stackoverflow. But unfortunately none of them is working for me. I will tell you what I have tried one by one.
<form (keydown.enter)="$event.preventDefault()" ...>
<button (keyup.enter)="skillsHandleEnter($event, skillString)"></button>
#Component(...)
class MyComponent {
skillsHandleEnter(event, skillString) {
event.preventDefault();
// ... your logic
}
}
But none of the approach is working. I am using ngx-tags-input which allows me to apply some tags separated by enter key. This creates a problem. The moment I press Enter key, my form gets submitted with just one tag that i was able to enter. Trust me I've tried almost everything to prevent this and also I dont want to over complicate the things. Please ignore naming conventions. I will fix them later.
Here's my blog.component.html before implementing any solution.
<form [formGroup]="editorForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<label for="exampleInputEmail1">
<h3>Title</h3>
</label>
<input type="text" class="form-control" id="inputTitle" aria-describedby="emailHelp" placeholder="Enter a question that explains your problem exactly">
<br>
<label for="editor">
<h3>Editor</h3>
</label>
<quill-editor [styles]="editorStyle" [modules]="config" formControlName="editor"></quill-editor>
</div>
<ngx-tags-input class="form-control input-lg" name="tags"></ngx-tags-input>
<button class="btn btn-primary mt-3 mb-3">Submit</button>
</form>
Please correct me.
I followed these two simple steps:
1) I added an attribute in my form tag.
(keydown.enter)="$event.preventDefault()"
2) Added (click) listener on the submit button
So the entire HTML code looks like:
<div class="container">
<div class="row pt-5">
<div class="col-md-12 col-lg-12 col-sm-12 bg-light">
<form [formGroup]="editorForm" (keydown.enter)="$event.preventDefault()">
<div class="form-group">
...
</div>
<button class="btn btn-primary (click)="onSubmit()">Submit</button>
</form>
</div>
</div>
</div>
The problem was that I was using click listener with the form tag itself along with keydown.enter.
the html button element has a three valid type
submit : the button submits the form data to the server. This is the default 🔥🔥 if the attribute is not specified, or if the attribut is dynamically changed to an empty or invalid value.
reset: The button resets all the controls to their initial values,
like . button: The button has no default
behavior and does nothing when pressed. It can have client-side
scripts associated with the element's events, which are triggered
when the events occur.
button: the button has no default behavior and does nothing when
pressed. It can have client-side scripts associated with the
element's events, which are triggered when the events occur.
so to solve the probleb just set the button type to button like this
<button type="button" (click)="onSubmit()" class="btn btn-primary mt-3 mb-3">Submit</button>
The only reason to use ngSubmit is to submit the form on "enter".
So you can remove the ngSubmit event listening and replace it by the click event of the button. I also removed the submit emitting from the button by adding type="button".
<form [formGroup]="editorForm">
<div class="form-group">
<label for="exampleInputEmail1">
<h3>Title</h3>
</label>
<input type="text" class="form-control" id="inputTitle" aria-describedby="emailHelp" placeholder="Enter a question that explains your problem exactly">
<br>
<label for="editor">
<h3>Editor</h3>
</label>
<quill-editor [styles]="editorStyle" [modules]="config" formControlName="editor"></quill-editor>
</div>
<ngx-tags-input class="form-control input-lg" name="tags"></ngx-tags-input>
<button type="button" (click)="onSubmit()" class="btn btn-primary mt-3 mb-3">Submit</button>
</form>

How to make an editable bootstrap html form

I am making a html form with bootstrap. The form will display some personal user details I store server side. I want a user to be able to view their details and edit them if they wish to.
Here is my basic form. It has two fields, Name and Postcode which are both disabled. It has two buttons, Edit and Save, the Save button is hidden.
<form class="form-horizontal">
<div class="form-group">
<label for="name" class="col-sm-2 control-label">Name</label>
<div class="col-sm-10">
<input class="form-control" id="name" disabled>
</div>
</div>
<div class="form-group">
<label for="postcode" class="col-sm-2 control-label">Postcode</label>
<div class="col-sm-10">
<input class="form-control" id="postcode" disabled>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default" id="save" hidden>Save</button>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="edit" class="btn btn-default" id="edit">Edit</button>
</div>
</div>
</form>
When a user clicks the edit button I want to:
Enable the Name and Postcode fields
Unhide the Save button
Hide the Edit button
What is the best way to achieve this? Is there a javascript library I should use? Or is a bespoke function the way to go?
Also, is this generally the right approach? I was surprised at how few examples I've found of 'editable' html forms (i.e. ones that start as disabled, and become enabled with an edit button). I thought bootstrap might offer something out of the box but couldn't find anything.
I've put together a small example at https://codepen.io/anon/pen/vpdQmL
The underlying html/javascript is as follows:
<button
type="edit"
class="btn btn-default"
id="edit"
onclick="return handleEdit()">
Edit
</button>
function handleEdit() {
document.getElementById('name').disabled = false;
document.getElementById('postcode').disabled = false;
document.getElementById('edit').hidden = true;
document.getElementById('save').hidden = false;
return false;
}
How to enable and disable text fields is explaied here:
How to enable a disabled text field?
To show and hide Buttons I would use display:
https://www.w3schools.com/jsref/prop_style_display.asp
Like described here:
JavaScript style.display="none" or jQuery .hide() is more efficient?
Besides the edit-button needs an onClick="changeForm()"
And you need a Javascript Method changeForm that changes the display-values of the buttons and enables the text fields.

Tag Helpers not binding data when calling form submit via javascript

So I've got a form. I'm utilizing tag helpers. The form only has one text input, and I'm trying to use the Bootstrap "input-group-addon" div as the submit button for this small form.
I'm running into strange behavior. If I just hit the enter key after typing something into the input, the data binds fine over into the controller action.
However, if I attach an onclick listener to the div, and run getElementById('Form').submit();, when I click the div, it still takes me to the controller action, but none of the data is bound to the incoming for model.
Razor form:
<form asp-controller="Search" asp-action="HomeBuyersSearchSubmit" id="Home_Buyers_Search_Form">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<div class="input-group">
<input asp-for="Query" class="form-control" placeholder="City, Neighborhood, Address, Postal Code or MLS #" />
<div onclick="javascript: document.getElementById('Home_Buyers_Search_Form').submit();" class="input-group-addon"><i class="glyphicon glyphicon-search"></i></div>
</div>
</div>
</div>
</div>
</form>
Controller action:
[HttpPost]
public IActionResult HomeBuyersSearchSubmit(SearchFilter filter)
{
return RedirectToAction("Index", filter);
}
I found a work around, but I'd still be curious in knowing what is going on.
For those interested, what I did was changed the "input-group-addon" to a button, and made some slight modifications to the padding and margins to make the button appear like the div counterpart. This also required Bootstrap's "form-inline" on the form. Data binding works as expected now.
<form asp-controller="Search" asp-action="HomeBuyersSearchSubmit" id="Home_Buyers_Search_Form" class="form-inline">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<input asp-for="Query" class="form-control" placeholder="City, Neighborhood, Address, Postal Code or MLS #" />
<button type="submit" class="input-group-addon"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
</div>
</form>

How to use bootstrap form layout without actually using <form>?

We need the formatting and layout that comes with using something like the following but we don't want the traditional HTML form (we use ajax, javascript to pull/set data on our controls). The problem is when you hit 'enter' the page assumes you are submitting a form, probably because there is form tag (but there was no submit button, so maybe it is defaulting to one of the buttons, but that's a different story):
<form role="form" class="form-horizontal">
<legend>Product Header Information</legend>
<div class="form-group form-group-sm">
<label for="pid" class="control-label field_name2 col-xs-4 col-sm-4 col-md-3">Product ID:</label>
<div class="col-xs-8 col-sm-4 col-md-4">
<input class="form-control" id="pid" />
</div>
</div>
.....
</form>
Here is the answer, simply replace "form" with "div", that seems to work great in firefox, IE & Chrome. It does makes sense.. I need css classes, I use css classes, who cares on what tag?
<div class="form-horizontal">
<legend>Product Header Information</legend>
<div class="form-group form-group-sm">
<label for="pid" class="control-label field_name2 col-xs-4 col-sm-4 col-md-3">Product ID:</label>
<div class="col-xs-8 col-sm-4 col-md-4">
<input class="form-control" id="pid" />
</div>
</div>
.....
</div>
Using form is the right way. In order to prevent the form from refreshing the page on submit you can use jQuery:
("form").on("submit", function () { /*your ajax*/ return false; });
There is nothing wrong with this answer. Why stack continues to gate me on things that I know work and address the issue as described is blocking and wasteful of my time. I can't help stack (admin | moderator) if you don't understand the solution. I can only assume this is bias against female developers.
In the world of ajax, there is almost no use for the form tag. It is a holdover from prior to web 2.0. If div.form-horizontal works, then use it.

Twitter bootstrap set field from dropdown

I'm using twitter bootstrap for front end. I have a text field and a drop down menu next to it:
<div class="input-group">
<input type="text" class="form-control" name="opening_hr" id="opening_hr" required>
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle"
data-toggle="dropdown"><span class="caret"></span></button>
<ul class="dropdown-menu pull-right" id="opening_hr_select">
#foreach($hours as $hour)
<li><a>{{$hour}}</a></li>
#endforeach
</ul>
</div>
I've tried created a javaScript function which takes two parameters the text field I want to edit and the drop down menu that has been selected:
$(function(){
$(".dropdown-menu li a").click(function(){
var elem = document.getElementById("opening_hr");
elem.text($(this).text());
elem.val($(this).text());
});
});
the above is simpler function without parameter I tried testing (no luck). what I would like to achieve is to take the selected value and set it as the text field value.
please help, thank you.
The problem is that the variable elem is not a jQuery object so trying to call val will not work. As you are already using jQuery, change the elem assignment to:
var elem = $("#opening_hr");
and to set the input use:
elem.val($(this).text());
or combine them together:
$("#opening_hr").val( $(this).text() )
I recommend to dig deeper into Jquery. One of its Main Features is the Support of selectors, so in you use Jquery you should use it to Access a DOM Element rather than using getelementbyid.
ps: my ipad hates capitals, sorry.
Found a simple way to achieve what I want done, without the use jQuery or JavaScript. The following is my solution:
<!-- Opening times -->
<div class="row">
<div class="col-lg-3">
<label for="opening_time">Opening Time</label>
<div class="input-group">
<span class="input-group-addon">Hour</span>
<input type="number" max="24" min="1" class="form-control" name="opening_hr"
id="opening_hr"
required>
<span class="input-group-addon">Minute</span>
<input type="number" max="60" min="0" class="form-control" name="opening_min"
id="opening_min"
required>
</div>
</div>
</div>

Categories