I have a Google places auto completion search bar. The post data from the form is read in Symfony. The search bar works fine but the user has to click on a place in the list, so I made it that if the user hits enter it'd simulate a down arrow and select the first suggestion.
If a user clicks on a place in the list I do a jQuery form.append to add the lat/lng
If a user hits enter I can see the form.append happening in inspect elements but the fields are not showing up in the post data.
Below is the code that handles the auto completion and simulated down arrow
window.autocomplete = null;
const form = $('#search-form');
function initAutocomplete() {
var pac_input = document.getElementById('search-input');
(function pacSelectFirst(input) {
// store the original event binding function
var _addEventListener = (input.addEventListener) ? input.addEventListener : input.attachEvent;
function addEventListenerWrapper(type, listener) {
// Simulate a 'down arrow' keypress on hitting 'return' when no pac suggestion is selected,
// and then trigger the original listener.
if (type === "keydown") {
var orig_listener = listener;
listener = function (event) {
var suggestion_selected = $(".pac-item-selected").length > 0;
if (event.which === 13 && !suggestion_selected) {
var simulated_downarrow = $.Event("keydown", {
keyCode: 40,
which: 40
});
orig_listener.apply(input, [simulated_downarrow]);
}
orig_listener.apply(input, [event]);
};
}
_addEventListener.apply(input, [type, listener]);
}
input.addEventListener = addEventListenerWrapper;
input.attachEvent = addEventListenerWrapper;
// Create the autocomplete object, restricting the search to geographical location types.
autocomplete = new google.maps.places.Autocomplete(input,
{types: ['geocode']});
autocomplete.addListener('place_changed', fillInAddress);
})(pac_input);
}
Below is the function fillInAddress which adds the fields.
function fillInAddress() {
let place = autocomplete.getPlace();
console.log(place)
let lat = place.geometry.location.lat();
let lng = place.geometry.location.lng();
let searchplace = place.formatted_address;
let searchplaceElement = $('#searchplace');
if (!searchplaceElement.length) {
form.append("<input id='searchplace' name='searchplace' type='hidden' value='" + searchplace + "'>")
form.append("<input id='lat' name='lat' type='hidden' value='" + lat + "'>")
form.append("<input id='lng' name='lng' type='hidden' value='" + lng + "'>")
} else {
searchplaceElement.val(searchplace);
$('#lat').val(lat);
$('#lng').val(lng);
}
}
Below is the HTML form part.
<form action="/restaurants" id="search-form" method="post">
<div class="input-group input-group-lg">
<div class="input-group-prepend">
<span class="input-group-text"><i class="fa fa-map-marker"></i></span>
</div>
<input id="search-input" class="form-control shadow-none" type="text" placeholder="Zoeken op adres of postcode">
<div class="input-group-append">
<button type="submit" class="btn btn-dark">Zoeken</button>
</div>
</div>
</form>
I have to add I'm not a real good export on jQuery or Javascript.
The standard submit button only submits form fields that were initially loaded. Fields that were added after DOM loads, have to get submitted manually for example like this:
$('#search-form).on('submit', function(e) {
e.preventDefault();
$.post($(this).attr('action'), $(this).serialize());
});
Related
I'm designing a website and I need the below function to stop when one Input value is missing and display the error message.
My HTML code for the form:
<form action="http://localhost/qurantest/" method="get" target="_blank" id="my-form">
<input type="text" name="reference-number" id="reference-number" value="" class="6u 12u$(xsmall)" placeholder="enter chapter"/>
<input type="text" name="reference-number" id="reference-number2" value="" placeholder="enter verse"/>
<br>
<input type="submit" value="GO" class="button big special" />
</form>
The JavaScript function is;
<script type="text/javascript">
var form = document.querySelector('#my-form'),
text_field = document.querySelector('#reference-number');
text_field2 = document.querySelector('#reference-number2');
function submitHandler(){
// build the new url and open a new window
var url = form.action + text_field.value + '/' + text_field2.value;
window.open(url);
// prevent the form from being submitted because we already
// called the request in a new window
return false;
}
// attach custom submit handler
form.onsubmit = submitHandler;
</script>
What I want is: To stop the function and display an error message when 1 of the two "inputs" (text_fields) is empty. Also, I want to assign maximum values for each input. (In my case I want the 1st input field to contain only numbers between 1-114 and the 2nd input field to contain only numbers from 2-286), and this specific function opens in a new window as the above code suggests, I want the function to open in the current window itself. How can I do this is JavaScript?
I'm new to JS so any help would be appreciated. Thanks in Advance!!
Check this one.
<script type="text/javascript">
var form = document.querySelector('#my-form');
var text_field = document.querySelector('#reference-number');
var text_field2 = document.querySelector('#reference-number2');
function submitHandler(){
if(!text_field.value || !text_field2.value) {
console.log("error message here");
return;
}
var url = `${form.action}${text_field.value}/${text_field2.value}`;
window.open(url);
return;
}
form.onsubmit = submitHandler;
</script>
Try this
<script type="text/javascript">
var form = document.querySelector('#my-form'),
text_field = document.querySelector('#reference-number');
text_field2 = document.querySelector('#reference-number2');
function submitHandler(){
// checks values
if(text_field.value == "" || text_field2.value == "") {
alert("Message");
return false;
}
// build the new url and open a new window
var url = form.action + text_field.value + '/' + text_field2.value;
window.open(url);
// prevent the form from being submitted because we already
// called the request in a new window
return false;
}
// attach custom submit handler
form.onsubmit = submitHandler;
</script>
The HTML part contains a textarea with a label.The user has to enter text and the form should be submitted and refreshed for the user to enter text again for say 5 more times. How can I do this using Javascript?
This is the html code:
<form name="myform" method="post">
<div class="form-group col-sm-5">
<label for="ques"><p id="p1">Question:</p></label>
<textarea class="form-control" rows="5" id="ques"></textarea>
</div>
</form>
<button type="button" class="btn" id="sub" onclick="func()">Next</button>
The javascript code:
var x=1;
document.getElementById("p1").innerHTML="Question"+x;
function func()
{
var frm = document.getElementsByName('myform')[0];
frm.submit();
frm.reset();
return false;
}
Here are two methods you can use. Both of these require you to add a submit button to your form, like this:
<form name="myform" method="post">
<div class="form-group col-sm-5">
<label for="ques"><p id="p1">Question:</p></label>
<textarea class="form-control" rows="5" id="ques"></textarea>
</div>
<!-- add this button -->
<input type="submit" value="Submit" class="btn">
</form>
<!-- no need for a <button> out here! -->
Method 1: sessionStorage
sessionStorage allows you to store data that is persistent across page reloads.
For me info, see the MDN docs on sessionStorage. This method requires no external libraries.
Note that in this method, your page is reloaded on submit.
window.onload = function() {
var myForm = document.forms.myform;
myForm.onsubmit = function(e) {
// get the submit count from sessionStorage OR default to 0
var submitCount = sessionStorage.getItem('count') || 0;
if (submitCount == 5) {
// reset count to 0 for future submissions
} else {
// increment the count
sessionStorage.setItem('count', submitCount + 1);
}
return true; // let the submission continue as normal
}
// this code runs each time the pages loads
var submitCount = sessionStorage.getItem('count') || 0;
console.log('You have submited the form ' + submitCount + ' times');
if (submitCount == 4) {
console.log("This will be the final submit! This is the part where you change the submit button text to say \"Done\", etc.");
}
};
Method 2: AJAX with jQuery
If you don't mind using jQuery, you can easily make AJAX calls to submit your form multiple times without reloading.
Note that in this example your page is not reloaded after submit.
window.onload = function() {
var myForm = document.forms.myform;
var submitCount = 0;
myForm.onsubmit = function(e) {
$.post('/some/url', $(myForm).serialize()).done(function(data) {
submitCount++;
});
console.log('You have submited the form ' + submitCount + ' times');
if (submitCount == 4) {
console.log("This will be the final submit! This is the part where you change the submit button text to say \"Done\", etc.");
}
e.preventDefault();
return false;
};
};
Hope this helps!
You shuld create an array and push the value of the textbox to the array in func().
We can create a template using a <script type="text/template>, then append it to the form each time the button is clicked.
const btn = document.getElementById('sub');
const appendNewTextArea = function() {
const formEl = document.getElementById('form');
const textareaTemplate = document.getElementById('textarea-template').innerHTML;
const wrapper = document.createElement('div');
wrapper.innerHTML = textareaTemplate;
formEl.appendChild(wrapper);
}
// Call the function to create the first textarea
appendNewTextArea();
btn.addEventListener('click', appendNewTextArea);
<form name="myform" method="post" id="form">
</form>
<button type="button" class="btn" id="sub">Next</button>
<script id="textarea-template" type="text/template">
<div class="form-group col-sm-5">
<label for="ques"><p id="p1">Question:</p></label>
<textarea class="form-control" rows="5" id="ques"></textarea>
</div>
</script>
I want to check if a form has changed by using pure javascript.
My plan is to take all text including html tags between the form tag, hash the string and then when I need to check if any of the values has changed, I can just rehash the form and compare them.
So I have
<form action="/Building" method="post"> <div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-3"> Building Address </div>
<div class="col-md-2"> City </div>
<div class="col-md-1"> State </div>
<div class="col-md-2"> Zip </div>
</div>
<div class="row">
<div class="col-md-3">
<input id="bldgResult_bldg_mail_address" name="bldgResult.bldg_mail_address" type="text" value="">
</div>
<div> ...etc
<input type="submit" value="Save and Next Building ยป" name="action:SaveContinue" class="btn btn-info pull-right">
<input type="submit" value="Save" class="btn btn-primary pull-right" name="action:Save">
<input type="submit" value="Go To Next Building" class="btn btn-primary hash" name="action:Next">
</div>
</form>
The problem is "value" of the input fields doesn't update. I'm able to change every textbox field and the value or the inner HTML doesnt change.
Here is the code that actually hashes and gets the innerHTML
window.onload = function () {
var forms = document.getElementsByTagName("form");
var hashValue = forms[1].innerHTML.hashCode();
Array.prototype.map.call(document.getElementsByClassName("hash"), function (hObj) {
hObj.addEventListener("click", function (event) {
if (document.getElementsByTagName("form")[1].innerHTML.hashCode() == hashValue) {
return true;
}
else {
var conf = confirm("Continue to the next building WITHOUT saving? Pressing \"Okay\" will undo any pending changes." );
if(conf)
{
return true;
}
event.preventDefault();
return false;
}
});
});
};
The above block
if (document.getElementsByTagName("form")[1].innerHTML.hashCode() == hashValue) {
return true;
}
Is always returning true, because the innerHTML doesnt change, even after the textboxes have been typed in.
What can I do? Is there another way to get the text in the HTML with updated information?
You could assign an event handler to the 'input' event of each of your fields that changes a boolean flag. You then just check that flag and set it back to false after your check is complete.
For example
document.querySelectorAll("#yourForm input").forEach(input => {
input.addEventListener("input", () => {
changed = true;
});
}
/* ... */
function checkIfChanged() {
if(changed) {
// ...
}
changed = false;
}
If you also need to check for backspace you could use the keypress event instead.
You could loop though your form elements, get and concatenate the values, and then hash the values.
Update:
Here is an example using FormData (depends on browser target):
Hash Function from Here: Generate a Hash from string in Javascript/jQuery
String.prototype.hashCode = function() {
var hash = 0, i, chr;
if (this.length === 0) return hash;
for (i = 0; i < this.length; i++) {
chr = this.charCodeAt(i);
hash = ((hash << 5) - hash) + chr;
hash |= 0; // Convert to 32bit integer
}
return hash;
};
function GetFormHash() {
var hashes = [];
var forms = document.getElementsByTagName("form");
var _hash = ""
for(var i=0;i<forms.length;i++) {
var formData = new FormData(forms[i]);
for (var key of formData.keys()) {
console.log(key + "=" + formData.get(key));
_hash = _hash + key + "=" + formData.get(key);
}
hashes.push(_hash.hashCode());
console.log(_hash.hashCode());
}
return hashes;
}
There is also an onchange event for <form>. Depends on browser...
<form onchange="alert('changed')"></form>
If you use something like jQuery you could use that change() event: https://api.jquery.com/category/events/form-events/
Change will not tell you if they change the data back - so not 100% reliable. If you were open to a library like jQuery - you could possibly serialize the data https://api.jquery.com/serialize/ to keep track of changes,
One last incomplete example. You would need to update to get non "input" form elements like textarea etc. You would also have to do a bit of work to get the selected radios...
function GetFormHashOther() {
var hashes = [];
var forms = document.getElementsByTagName("form");
var _hash = ""
for(var i=0;i<forms.length;i++) {
var chill = forms[i].getElementsByTagName("input");
for (var c of chill) {
console.log(c.name + " = " + c.value);
_hash = _hash + c.name + " = " + c.value;
}
hashes.push(_hash.hashCode());
console.log(_hash.hashCode());
}
return hashes;
}
I have a question to you about JavaScript. I want to display form after clicking a button and then when I write something and click submit it must display the value of form on screen. And the problem is that when I click submit it display only for a second. Here is my JavaScript code:
window.onload = function () {
var dod = document.getElementById("dodaj")
dod.onclick = function () {
document.write("<form action='?' id='formualrz'><input id='f1' type='text' name='pole' value='Nazwa'><input id='f2' type='text' name='pole' value='Opis'><input type='submit' id='sub'></form>");
var f1 = document.getElementById("f1");
var f2 = document.getElementById("f2");
var submit = document.getElementById("sub");
submit.onclick = function () {
document.write(f1.value + "<br/>" + f2.value);
}
}
}
Your form is being submitted. Add the following to your form tag
<form onsubmit="return(false)" >
Or in your case on the event handler:
submit.onclick = function () {
document.write(f1.value + "<br/>" + f2.value);
return(false);
}
This topic explains what return false actually does.
We used to be able to enter a search field, address on search box, hit the ENTER key on the keyboard and get the search results.
I made several changes but can't pinpoint the change that resulted in the ENTER key misbehaving. Instead of submitting, it refreshes the page.
I have tried each of the following to stop the page refresh:
<form onSubmit="return false;">
<form onkeypress="return event.keyCode != 13">
Each works.
However, I can no longer hit the ENTER key and have results displayed.
What do I need to do to fix this?
Below is the js:
function getData()
{
dijit.byId("advanceSearchDialog").hide();
var form = document.getElementById("searchForm");
var form2 = document.getElementById("featuresForm")
var searchText = form.searchBox.value.replace(/-/g,"");
form.searchBox.value = searchText;
if (searchText != "")
{
// collect features to search for:
var features = [ ];
var featTypes = form2.featType;
for ( var f = 0; f < featTypes.length; ++f )
{
if ( featTypes[f].checked ) features.push( featTypes[f].value );
}
featureList = "'" + features.join("','") + "'";
searchMsg("Searching for '" + searchText + "' ...");
featureID = "";
var accord = dijit.byId("accordianContainer");
var resultsPane = dijit.byId("resultsPane");
accord.selectChild(resultsPane,true);
doGlobalSearch( searchText, featureList );
}
else
{
searchMsg("No search criteria entered, enter search text");
}
}
function searchKey(e){
// special case for IE to capture <enter> in the search box
var key = window.event ? e.keyCode : e.which;
var keychar = String.fromCharCode(key);
if (key == 13)
getData();
}
<form id="searchForm" class="search_field" method="get" action="">
<input name="searchBox" id="searchBox" value="" />
<button type="button" onclick="getData()"><img src="images/magnifying_glass.png" alt="Search" /></button>
</form>
Thanks
use just following simple jQuery
if(event.keyCode == 13){
event.preventDefault();
}
...bind it to you form
Remove the onkeypress and use onsubmit instead since it is automatically called when the enter key is pressed on an input field of a form.
<form onsubmit="return getData()">
<input name="searchBox" id="searchBox" value="" />
<button type="submit"><img src="images/magnifying_glass.png" alt="Search" /></button>
</form>
js
function getData() {
dijit.byId("advanceSearchDialog").hide();
var form = document.getElementById("searchForm");
var form2 = document.getElementById("featuresForm")
var searchText = form.searchBox.value.replace(/-/g,"");
form.searchBox.value = searchText;
if (searchText != "")
{
// collect features to search for:
var features = [ ];
var featTypes = form2.featType;
for ( var f = 0; f < featTypes.length; ++f )
{
if ( featTypes[f].checked ) features.push( featTypes[f].value );
}
featureList = "'" + features.join("','") + "'";
searchMsg("Searching for '" + searchText + "' ...");
featureID = "";
var accord = dijit.byId("accordianContainer");
var resultsPane = dijit.byId("resultsPane");
accord.selectChild(resultsPane,true);
doGlobalSearch( searchText, featureList );
}
else
{
searchMsg("No search criteria entered, enter search text");
}
return false;
}
Whatever function you are calling to display your search results needs to either
return false;
or
call event.preventDefault();
This will avoid the default form action from being executed (causing a full page refresh).