Twitter bootstrap set field from dropdown - javascript

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>

Related

Angular change detection on Template Reference Variables for property binding

I'm playing around with template reference variables. And thought of using its value to set the disabled property on a button. i.e disable a button unless the input field is non-empty. I expected the following code to work but the button stays disabled even after some value is entered in the input.
Why does Angular change detection not work in this case?
Is there another way to do achieve this using ONLY template reference variables?
The code is written in Angular 8 and node 12.16.2
<div class="form-group col-md-6">
<input #hello type="text" class="form-control" id="01">
</div>
<div class="form-group col-md-6">
<button class="btn btn-primary" [disabled]="hello.value.length === 0">Deactivate</button>
</div>
You can try ngForm combined with ngModel directive to achieve this,
<form #testForm="ngForm">
<div class="form-group col-md-6">
<input type="text" name="hello" ngModel class="form-control" id="01">
</div>
<div class="form-group col-md-6">
<button class="btn btn-primary" [disabled]="testForm.value.hello.length === 0">
Deactivate
</button>
</div>
</form>
{{testForm.value|json}}
Demo : https://stackblitz.com/edit/angular-ivy-xtdm4k?file=src/app/app.component.html
For more details, see this.

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>

Dynamic HTML form array only submitting last value to PHP

I'm trying to create a system for my organization that keeps track of points for our members. Part of that system is a page where the officers can create events for the members to sign up for in a form. Part of the event creation form is the "shift(s)" for that event, which looks like this:
<div id="shifts-div">
<div class="form-inline">
<div class="form-group">
<label for="start">Start Time: </label>
<input type="time" class="form-control" name="start[]" value="12:00:00">
</div>
<div class="form-group">
<label for="end">End Time: </label>
<input type="time" class="form-control" name="end[]" value="12:00:00">
</div>
<div class="form-group">
<label for="end">Spots Available: </label>
<input type="number" class="form-control" name="spots[]">
</div>
</div>
<br>
</div>
Since there can be any number of shifts for a given event I allow the officers to dynamically add or remove shifts using the following buttons:
<button type="button" class="btn btn-default" onclick="addShift()">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add Shift
</button>
<button type="button" class="btn btn-default" onclick="removeShift()">
<span class="glyphicon glyphicon-minus" aria-hidden="true"></span> Remove Shift
</button>
Which run these two javascript functions:
function addShift(){
var shift =
`<div class="form-inline">
<div class="form-group">
<label for="start">Start Time: </label>
<input type="time" class="form-control" name="start[]" value="12:00:00">
</div>
<div class="form-group">
<label for="end">End Time: </label>
<input type="time" class="form-control" name="end[]" value="12:00:00">
</div>
<div class="form-group">
<label for="end">Spots Available: </label>
<input type="number" class="form-control" name="spots[]">
</div>
</div>
<br>`;
document.getElementById("shifts-div").innerHTML += shift;
}
and
function removeShift() {
$('#shifts-div').children().last().remove();
$('#shifts-div').children().last().remove();
}
This works well as far as adding and removing shifts to the page, but when I submit the form to a php file start, end, and spots are not an array and only hold the values for the last shift. I check this by running this in the php:
foreach($_POST as $key => $value){
echo $key.' -> '.$value . ' ';
}
So, say I add 3 shifts with different values for each input and click submit, I would get this as the result (I took out the parts I don't think are relevant as they are just other non-array values for the event, like name and date, and are working properly):
start -> 14:00 end -> 17:00 spots -> 3
Where the start, end, and spots values are what I entered for the third shift that was added.
After some research I found that using innerHTML can cause some weird problems since it rewrites every node in the div, so I changed the addShift function to the following just to see if this was the problem (Not the prettiest way to do it, I know)
function addShift(){
$("#shifts-div").append("<div class='form-inline'><div class='form-group'><label for='start'>Start Time: </label><input type='time' class='form-control' name='start[]' value='12:00:00'></div><div class='form-group'><label for='end'>End Time: </label><input type='time' class='form-control' name='end[]' value='12:00:00'></div><div class='form-group'><label for='end'>Spots Available: </label><input type='number' class='form-control' name='spots[]'></div></div><br>");
}
The same problem persists with the same results. This is my first time doing this kind of web development and this is how I came up with to tackle this problem, but I recognize that there are probably better ways to do this that I am unaware of, so there are two parts to my question:
Why isn't my code running how I intend, and how do I fix that?
How would an experienced web developer implement the functionality I am after (assuming he was also just using basic javascript, html, and php)?
Like I said I am new, so feel free to critique any parts of my code, even if it doesn't directly solve the problem. There are so many different ways to do anything, it is hard to know which is the "correct" way for any given situation. Thanks in advance and let me know if more of the code needs to be given.
EDIT:
I submit the form with this button:
<button type="submit" class="btn btn-default btn-lg">Submit</button>
and this is what the form looks like:
<form action="../php/create-event.php" method="POST" name="event">
So, it turns out I had just messed up with uploading my changes to the server. Once I changed the innerHTML to jquery as described in the question and properly uploaded it the problem was fixed.
I'm going to leave this question up because even finding that solution took me a long time and I never found anyone directly addressing this problem. If you are having the problem I described above do the change from innerHTML to another DOM manipulation method. The problem has something to do with innerHTML rewriting the entire element and losing references to the elements that were already there.
I'll gladly accept a different answer if someone can come along and explain it better than I can.

How to clone form fields without their values?

How to clone following html without persisting the field values?
<form method=POST action="/url">
<div class="form-group" data-answer>
<div class="pull-left"><label><input type="checkbox" name="answer[1][is_correct]" value="true"> Correct Answer</label></div>
<div class="pull-right">
</span>
</div>
<input type="text" class="form-control" name="answer[1][body]" placeholder="Possible answer">
</div>
<div class="form-group" data-answer>
<div class="pull-left"><label><input type="checkbox" name="answer[2][is_correct]" value="true"> Correct Answer</label></div>
<div class="pull-right">
</span>
</div>
<input type="text" class="form-control" name="answer[2][body]" placeholder="Possible answer">
</div>
. . .
<button type="submit">Submit</button>
</form>
I can see only 3 possible choices here. However, all of them come with major flaws:
.clone() the .form-field normally and reset the field values.
Problem: resetting all the values one by one is cumbersome and is not a future-proof solution. For example, if more fields are added into the .form-group, their values will need to be cleared separately.
Include a hidden .form-group as a template on the page.
Problem: as you see, the input fields contain enumerated names like: answer[1][body]. It is convenient to clone the last .form-group and just increment the value by 1. Cloning the templated .form-group will be lacking this flexibility.
Read the fields as raw html and transform them into JQuery object
Problem: this seems to be a clear solution to me, however I couldn't get it working. The code $.parseHTML($('.form-group').html()) does not return a valid JQuery object, which I need to use .find() and other methods on.
What will be an effective and elegant solution to this problem?
Try this code:
$("button").click(function(){
var t = $("form").clone().appendTo("#clonedForm");
$(t).find("input[type=checkbox],input[type=text], textarea").removeAttr("checked").val('');
});

Dynamically add and remove form fields

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

Categories