How does one validate a dojo javascript form for Ajax? - javascript

I'm trying to validate a form written in Javascript/Dojo before posting it using Ajax. Here's the code:
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.6/dojo/dojo.xd.js" type="text/javascript" djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dijit.form.Form");
dojo.require("dijit.form.Button");
dojo.require("dijit.form.ValidationTextBox");
</script>
<script>
function send()
{
var mainForm = dojo.byId( "mainform" );
dojo.connect( mainForm , "onsubmit", function( event )
{
dojo.stopEvent(event);
if ( mainForm.validate() )
{
alert( "valid" );
var xhrArgs = {
form: dojo.byId( "mainform" ),
load: function( data )
{
// Success
alert( "Success" );
},
error: function( error )
{
// Error
alert( "Error" );
}
}
var deferred = dojo.xhrPost( xhrArgs );
}
else
{
alert( "not valid" );
}
});
}
dojo.addOnLoad( send );
</script>
<link rel="stylesheet" type="text/css" href="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/claro/claro.css"/>
</head>
<body class="claro">
<h2>Invitation:</h2>
<div dojoType="dijit.form.Form" id="mainform" jsId="mainform" encType="multipart/form-data" action="whatever.php" method="post">
<label for="name">Name: </label><input type="text" id="name" name="name" size="50"
dojoType="dijit.form.ValidationTextBox"
required="true"
propercase="true"/>
<br><br>
<button type="submit" dojoType="dijit.form.Button">Send Message</button>
</div>
</body>
Obviously I'm not using "alert"s in the production code; they help show me what's working and what's not working. The problem here is that the call to mainForm.validate() never returns. Commenting out the call to validate() "fixes" the problem (the form data is POSTed to the .php file), but now there's no validation at all.

Hello and welcome to StackOverflow.
Make sure that you are using dijit.byId to find dijits (as opposed to just their DOM nodes with dojo.byId), and that you are using properly cased event names. Try changing your send function like so:
function send()
{
var mainForm = dijit.byId( "mainform" );
dojo.connect( mainForm , "onSubmit", function( event )
....
When you use dojo.byId you get a regular DOM node (the regular HTML <form> tag), and not the actual dijit object (which has the validate function). This is also why improperly case on "onsubmit" works: a regular HTML form has an event called "onsubmit", but the dijit only has a method "onSubmit" (I agree this is a bit confusing).

Its a pie cake. do like this.
dijit.form.Form has a attr called state. if this state is empty string then the form widgets like dojo textbox are valid.
You can do like this.
1) Don't attach onsubmit for the form. Instead just attach click for the button and do the following code inside the button click handler.
var validForm = "";
dojo.connect( submitBtnDojoWidget, "onclick", function( event ){
if(mainform.state === validForm){
mainform.submit();
}
else {
// here mainform.state may be 'invalid' or 'incomplete'
console.log(mainform.state);
}
})

Related

JS - Collecting data from one function to run in another [duplicate]

There seems to be lots of info on how to submit a form using javascript, but I am looking for a solution to capture when a form has been submitted and intercept it in javascript.
HTML
<form>
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
When a user presses the submit button, I do not want the form to be submitted, but instead I would like a JavaScript function to be called.
function captureForm() {
// do some stuff with the values in the form
// stop form from being submitted
}
A quick hack would be to add an onclick function to the button but I do not like this solution... there are many ways to submit a form... e.g. pressing return while on an input, which this does not account for.
Ty
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
In JS:
function processForm(e) {
if (e.preventDefault) e.preventDefault();
/* do what you want with the form */
// You must return false to prevent the default form behavior
return false;
}
var form = document.getElementById('my-form');
if (form.attachEvent) {
form.attachEvent("submit", processForm);
} else {
form.addEventListener("submit", processForm);
}
Edit: in my opinion, this approach is better than setting the onSubmit attribute on the form since it maintains separation of mark-up and functionality. But that's just my two cents.
Edit2: Updated my example to include preventDefault()
You cannot attach events before the elements you attach them to has loaded
It is recommended to use eventListeners - here one when the page loads and another when the form is submitted
This works since IE9:
Plain/Vanilla JS
// Should only be triggered on first page load
console.log('ho');
window.addEventListener("DOMContentLoaded", function() {
document.getElementById('my-form').addEventListener("submit", function(e) {
e.preventDefault(); // before the code
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
})
});
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
jQuery
// Should only be triggered on first page load
console.log('ho');
$(function() {
$('#my-form').on("submit", function(e) {
e.preventDefault(); // cancel the actual submit
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
Not recommended but will work
If you do not need more than one event handler, you can use onload and onsubmit
// Should only be triggered on first page load
console.log('ho');
window.onload = function() {
document.getElementById('my-form').onsubmit = function() {
/* do what you want with the form */
// Should be triggered on form submit
console.log('hi');
// You must return false to prevent the default form behavior
return false;
}
}
<form id="my-form">
<input type="text" name="in" value="some data" />
<button type="submit">Go</button>
</form>
<form onSubmit="return captureForm()">
that should do. Make sure that your captureForm() method returns false.
Another option to handle all requests I used in my practice for cases when onload can't help is to handle javascript submit, html submit, ajax requests.
These code should be added in the top of body element to create listener before any form rendered and submitted.
In example I set hidden field to any form on page on its submission even if it happens before page load.
//Handles jquery, dojo, etc. ajax requests
(function (send) {
var token = $("meta[name='_csrf']").attr("content");
var header = $("meta[name='_csrf_header']").attr("content");
XMLHttpRequest.prototype.send = function (data) {
if (isNotEmptyString(token) && isNotEmptyString(header)) {
this.setRequestHeader(header, token);
}
send.call(this, data);
};
})(XMLHttpRequest.prototype.send);
//Handles javascript submit
(function (submit) {
HTMLFormElement.prototype.submit = function (data) {
var token = $("meta[name='_csrf']").attr("content");
var paramName = $("meta[name='_csrf_parameterName']").attr("content");
$('<input>').attr({
type: 'hidden',
name: paramName,
value: token
}).appendTo(this);
submit.call(this, data);
};
})(HTMLFormElement.prototype.submit);
//Handles html submit
document.body.addEventListener('submit', function (event) {
var token = $("meta[name='_csrf']").attr("content");
var paramName = $("meta[name='_csrf_parameterName']").attr("content");
$('<input>').attr({
type: 'hidden',
name: paramName,
value: token
}).appendTo(event.target);
}, false);
Use #Kristian Antonsen's answer, or you can use:
$('button').click(function() {
preventDefault();
captureForm();
});

Pass the value from a textarea to PHP

I want to pass the text I enter in to a textarea to a PHP function.
console.log($('#notes').val());
let report = {
notes: $('#notes').val()
};
//this.userData.addMediaReport(report)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<textarea id="notes" rows="4" cols="50">Lorem ipsum</textarea>
console.log returns undefined. Any ideas?
put the $('#notes').val() code inside the form submit event.
$(document).ready(function(){
$( "form" ).submit(function( event ) {
let report = {
notes: $('#notes').val()
};
});
});
Make sure the textarea exists and contains the required value before it is accessed.

Uncaught ReferenceError: (function) is not defined at HTMLButtonElement.onclick

I have a search form where I'm trying to have it output the results at the bottom of the page without reloading.
<form action='' method='post'>
<div id="search-form">
<input type="text" name="search" class="search-field" id="search" value="" />
<div class="submit-container">
<button type="button" value="" class="submit" id="searchbutton" onclick="searchoutput()" /></button>
</div>
</form>
<br><br>
<p>Type First Name</p>
I want the search results to show below when the button is clicked, using Ajax call to another script. I keep getting an error: "Uncaught ReferenceError: searchoutput is not defined at HTMLButtonElement.onclick
Here is my javascript (using jquery):
$( document ).ready(function() {
function searchoutput() {
if($(".search-field").val().length > 5) { //only shows results when more than 5 characters have been entered
var search = $(".search-field").val();
var update = $(".result");
var goal = 0;
$.get("query-include.php" , {search: search, goal: goal})
.done(function( data ) {
update.empty();
update.append(data);
$(this).remove();
});
};
}
$( ".search-field" ).keydown(function() {
var update =$(".results");
update.empty();
});
});
I have checked other posts and spent a long time trying to get the solution on my own. The odd thing is if I add an event listener for "keyup" in order to run the same function searchoutput as the user types:
var searchfield = document.getElementById("search");
searchfield.addEventListener("keyup", searchoutput);
Then I don't get the ReferenceError and the script runs fine.. I only get the function issue on button click.
It's a scoping issue - searchOutput is defined within the scope of the $(document).ready() function. What you could try is to declare a var for searchOutput before that code, then assign it to the function like this:
var searchOutput;
$( document ).ready(function() {
searchOutput = function () {
if($(".search-field").val().length > 5) {
//etc.
I add an eventListener in the place of searchoutput();
$( document ).ready(function() {
$('.submit').addEventListener('click', function(){
if($(".search-field").val().length > 5) { //only shows results when more than 5 characters have been entered
var search = $(".search-field").val();
var update = $(".result");
var goal = 0;
$.get("query-include.php" , {search: search, goal: goal})
.done(function( data ) {
update.empty();
update.append(data);
$(this).remove();
});
}
});
$( ".search-field" ).keydown(function() {
var update =$(".results");
update.empty();
});
});
In my case,
I was using modular code in my JS (i.e. import and export statements) so when I tried to use onclick, it wasn't calling my submit function. When I simply removed the import statement from my JS code and replaced dependent code with some default values, onclick called my function. Then I tried the addEventListener with import/export and finally it worked for me.

Is there a way to prevent a form from being submitted if it is not auto completed?

I'm learning jquery and its awesome! Its very easy to do complex stuff but I'm unsure how to prevent someone from submitting a form(or warning them) if a autocomplete fails.
I have a form on my site that gets autocompleted with existing data from my database and when they submit it provides info on that entry. If they add something thats not in the database then my server will bounce them back to the form page and let them know of the error but I want to do something to warn them while they are filling out the form(before they submit the form).
Long story short, I know how to detect changes in the field but how can I detect(and prevent submission of form) when they the field is not in the database? The two cases I'm thinking about is if there's a autocomplete for stock("ibm') and the user either types "ib"(before it fully completes) or "ibmm"(after it autocompleted).
Is there a jquery-ish easy way to detect if a field has not been fully resolved by autocomplete?
Any suggestions?
update:
As requested, here's my autocomplete code(basically just takes value in the search box and submits to a url called 'autocomplete'):
<script>
$(function() {
var cache = {},
lastXhr;
$( "#global-search-field" ).autocomplete({
minLength: 2,
source: function( request, response ) {
$(".message").empty()
var term = request.term;
if ( term in cache ) {
response( cache[ term ] );
return;
}
lastXhr = $.getJSON( "autocomplete", request, function( data, status, xhr ) {
cache[ term ] = data;
if ( xhr === lastXhr ) {
response( data );
if ( data == 'no results found'){
//alert(data);
//$(".message").empty().append("not found!");
}
}
});
}
});
});
</script>
Have the form loaded with the button as disabled. As you are filling up the form, you have a running tally of flags (class=validation) to notify when the form is ready, then you can enable the button.
There is no sense in having a workable button that will attempt to call the server if you already know that it should fail if not all the information is ready.
The example in the bottom will work if you fill up all three boxes with text. You can signify controls by having each textbox with a class append text "required" in red font using the appendTo() in jquery.
As long as there is a class validation on the html element, it will be required, so as we are entering data, it will remove those validation classes:
<html>
<head>
<script src="jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("input[name^='test']").blur(function(){
if ($(this).val() != "" && $(this).hasClass("validation")){
$(this).removeClass("validation");
}
var check = $(".validation"); //checks to see if there is any more validation
if (check.length == 0){
$("#nowSubmit").prop("disabled", false);
} else {
$("#nowSubmit").prop("disabled", true);
}
});
});
</script>
</head>
<body>
<form>
<input id="control1" name="test" type="textbox" class="validation" />
<input id="control2" name="test" type="textbox" class="validation" />
<input id="control3" name="test" type="textbox" class="validation" />
<input id="nowSubmit" type="submit" value="Click Here" disabled="true"/>
</form>
</body>
</html>
working example here: http://jsfiddle.net/hSatZ/
You can use ajax request put on "onchange" event on autocomplete fields which would check if specific value is in db and will notify user about error if needed without submitting the form

How to grab the onSubmit event for a form?

I want to know how to grab the onsubmit event from a form to do some form validation, because I don't have access to it directly. (I am writing a Wordpress plugin for comments, so don't have direct access to the form tag or the submit button.)
I got so frustrated trying to do this for my plugin that I have written a Hello World version below. I want it to show the 'Hello World' alert when I load the page, and the "form submitted" alert when I click on the submit button. Instead, it shows both pop ups when the page loads.
Here is my code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Hello World</title>
</head>
<body>
<h2>Test</h2>
<form action="#" method="post" id="commentform">
<p><input type="text" name="author" id="author" size="22" tabindex="1" />
<label for="author"><small>Name (required)</small></label></p>
<p><input name="submit" type="submit" id="submit" tabindex="5" value="Submit Comment" />
</form>
<script type="text/JavaScript">
<!--
alert("Hello world");
var formCheck = document.getElementById("commentform");
formCheck.onSubmit = doMapping();
function doMapping() {
alert("form submitted");
return false;
}
-->
</script>
</body>
</html>
Change this:
formCheck.onSubmit = doMapping()
to this:
formCheck.onSubmit = doMapping
When you add parenthesis to the end of a function you execute that function. When you assign a function (or pass it as a parameter to another function) you need to omit the parenthesis as that is the way to retrieve a function pointer in JavaScript.
Edit: You will also need to move the declaration of the doMapping function above the assignment of that function to the onsubmit event like this (good catch tvanfosson!):
function doMapping() {
alert("form submitted");
return false;
}
formCheck.onSubmit = doMapping();
However if the doMapping function is not used elsewhere you can declare the doMapping function as an anonymous function like this:
formCheck.onSubmit = function() {
alert("form submitted");
return false;
}
which seems a bit cleaner to me.
Using jQuery.
$(document).ready( function() {
$('#commentform').submit( function() {
alert('form submitted');
return false;
});
});
Thank you! Actually I solved it another way, using both Andrew's suggestion and the window.onload event - I think the problem was partly because the element hadn't actually loaded.
window.onload = function(){
if (document.getElementById("commentform")){
document.getElementById("commentform").onsubmit = doMapping;
}
}
function doMapping(){
alert("form submitted");
return false;
}

Categories