Form validation not working with progressButton js - javascript

I've been working on this website with an animated submit button with a 3d built-in proggress bar:
http://add.digital/contato.php
For the submit button, I used this plugin:
http://tympanus.net/codrops/2013/12/12/progress-button-styles/
Everything works beautifully, the loading bar runs smoothly and there are no problems with the form submission. The problem is the validation, which doesn't seem to work. The submit button ("Enviar") is a button tag. When I change it for an input tag, validation works, but the proggress bar doesnt, and vice-versa. I've tried reproducing the effect with an input tag, but it didn't work. So I tried to work on the form validation, which seemed more approachable. I've run quite a few solutions I found here on SO and on other websites regarding form validation with button tags, but I got pretty much the same result from all of them: when hitting the submit button, the error messages for empty fields are shown, but noe of them stops the progress bar animation and the form submission. I've also searched for queries related to Ladda.js, which is a similar plugin, but I can't find a way to validate the form and stop the animation and submission when necessary. I've checked the entire code (as a newbie), and tried many different solutions, but wasn't able to sort this matter, which is quite annoying. Any help or guidance on how to gou about with this would be much appreciated.
Below is the form:
<form action="envia_mail_a2.php" method="POST">
<div class="input-group">
<label for="nome" class="hidden"></label>
<input class="input-custom" type="text" placeholder="Nome" name="edtNome" id="edtNome" required>
</div>
<div class="input-group">
<label for="email" class="hidden"></label>
<input class="input-custom" type="text" placeholder="E-mail" id="edtEmail" name="edtEmail" required>
</div>
<div class="input-group">
<label for="telefone" class="hidden"></label><input class="input- custom" type="text" placeholder="Fone" id="edtTelefone" name="edtTelefone" required>
</div>
<div class="input-group">
<label for="mensagem" class="hidden"></label>
<textarea class="input-custom expanding" placeholder="Mensagem" rows="1" name="edtMensagem" id="edtMensagem"></textarea>
</div>
<div class="input-group text-right">
<button type="submit" id="btnEnviar" name="btnEnviar" class="submit progress-button" data-style="rotate-angle-bottom" data-perspective data-horizontal>Enviar</button>
</div>
</form>
And here the validation (original code, as it was when I took over the project, without my attempts):
<script>
$(document).ready(function(e) {
$("button#btnEnviar").click(function(e) {
var nome = $("#edtNome").val();
var mail = $("#edtEmail").val();
var fone = $("#edtTelefone").val();
var mensagem = $("#edtMensagem").val();
$.ajax({
type: 'POST',
url: "envia_mail_a2.php",
//context: document.body,
//dataType: 'text',
data: "nome="+nome+"&mail="+mail+"&fone="+fone+"&mensagem="+mensagem,
success: function(){
//alert('Enviado com sucesso')
setInterval(function(){
$("#edtNome").val('');
$("#edtEmail").val('');
$("#edtTelefone").val('');
$("#edtMensagem").val('');
}, 3000);
},
error: function () {
alert('Erro ao enviar');
}
});
});
});
</script>
Once again, thanks for all the attention

After looking at the code on the page, when calling new ProgressButton, there are two parameters passed to the constructor ... the button HTMLElement that will be turned into a progress button via the plugin, and a callback function that will determine what happens when the newly created progress button is clicked. Right now you have two click handlers on the progress button. One that is being passed into the new ProgressButton() call, and another one that you've pasted above that is created when the document is ready. The one being passed into the ProgressButton constructor is handling the animation of the button, and the additional click handler you've pasted above is taking care of validation. You need to move the validation code into the click handler that is being passed to the ProgressButton constructor so that the animation happens in-sync with validation. For instance, you could trigger the animation as the result of a success return from the validation service, or you could do something else to the button if there is an error. But all this should happen from a single handler since the validation is happening asynchronously, and right now, since the animation and validation are happening from two different handlers that are both triggered by clicks on the button, you're not able to sync those two processes up.
So I'm thinking something like this:
new ProgressButton( bttn, {
callback : function( instance ) {
var nome = $("#edtNome").val();
var mail = $("#edtEmail").val();
var fone = $("#edtTelefone").val();
var mensagem = $("#edtMensagem").val();
var animation = function() {
var progress = 0,
interval = setInterval( function() {
progress = Math.min( progress + Math.random() * 0.1, 1 );
instance._setProgress( progress );
if( progress === 1 ) {
instance._stop(1);
clearInterval( interval );
}
}, 200 );
}
$.ajax({
type: 'POST',
url: "envia_mail_a2.php",
//context: document.body,
//dataType: 'text',
data:"nome="+nome+"&mail="+mail+"&fone="+fone+"&mensagem="+mensagem,
success: function(){
//alert('Enviado com sucesso')
//call the animation
animation();
},
error: function () {
alert('Erro ao enviar');
//do another animation if there is an error
}
});
});
}
} );
To be honest, progress bars aren't great for AJAX calls when you're not able to really tell what the "progress" of the call is ... I guess you could do something that worked off the readyState of the XHR object using onreadystatechange events, but often times most AJAX progress indicators like this are some type of looping animation.

Related

Jquery keyup event firing more than once

I'm trying to display some content from my database in a div, every time a user types a value into an input box. I'm using jquery to do this. But whenever I type something, once into the input box... the call-back function repeats, four times.
getProducts(){
$('.search-products').on('keyup', function(){
const searchProducts = new SearchProducts();
let search = $.trim($(this).val()); // get search text
if(search!==""){
// let data = {search: search};
let url = '/search-for-products/' + search;
$.ajax({
type: "GET",
url: url,
data: {},
success: function(response){
if(response.success){
searchProducts.showSearchProducts(response.products);
}
}
});
}
});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" class="form-control search-products" placeholder="What are you searching for ?" aria-label="Username" aria-describedby="basic-addon1" style="color: light grey;">
I'd like your honest opinions on what could be wrong, with my code. Cos, I'm now confused about what to do.
If you've not found why it's added twice, a simple fix is you can remove the listener before adding it again:
$('.search-products').off('keyup').on('keyup', ...)
You can also use namespace events, to not remove other keyup events:
$('.search-products').off('keyup.search').on('keyup.search', ...)
Not many people know that jQuery supports namespace events.

Submit button is refreshing the page

I have a form inside of an mvc project and sending the inputs with post method to the controller. Everything is good if I use a "button", but it keeps refreshing the page if I change it to "submit".
html:
<form role="form" id="login">
<div class="form-group">
<input type="text" class="form-control border-purple" id="postCode" placeholder="Postcode" value="3208SC">
</div>
<div class="form-group">
<input type="text" class="form-control border-purple" id="huisNummer" placeholder="Huisnummer" value="20">
</div>
<div class="form-group">
<input type="email" class="form-control border-purple" id="eMail" placeholder="EMail" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-zoeken" id="btnZoeken">#ReinisResource.SidebarButton</button>
</div>
</form>
and this is my js code:
$("#login").submit(function() {
$("#mapStuff").empty();
$("#items").empty();
$("#historie").empty();
var selectedEmp = $(".drpDown :selected").text();
var postCodex = $("#postCode").val();
var huisNummerx = $("#huisNummer").val();
var eMailx = $("#eMail").val();
$("#empName").html(selectedEmp);
$.post("/Home/GetAddressCount", { postCode: postCodex, huisNumber: huisNummerx, eMail: eMailx }, function (response) {
if (response.Count === 0) {
$("#pers-info").hide();
$("#btn-section").hide();
$("#multipleAdd").hide();
document.getElementById('inCorrectInfo').click();
} else {
$("#employeesList").hide();
$("#pers-info").show();
var houseInfo1 = response.Straat + " " + huisNummerx;
var houseInfo2 = postCodex + " " + response.Woonplaats;
$("#perceelInfo").html(houseInfo1 + "<br>" + houseInfo2);
$("#meldingMaken-btn").addClass("active");
$("#historie-btn").removeClass("active");
if (response.Count === 1) {
$("#multipleAdd").hide();
reinis.ShowMapStuff();
reinis.ShowItemStuff();
} else {
reinis.ShowMultipleAddress();
}
}
});
});
If you ask me why I need to change it to "submit" from "button" I wanted to add Jquery validation. And I think submit is better to use it for good coding.
Thanks in advance
Since it is a submit event, it will submit unless you do preventDefault or return false, as i can see you need to '$.post` .
So it would be like this.
$("#login").submit(function(event){
event.preventDefault();
// followed by your code for $.ajax
});
More info- http://www.w3schools.com/jquery/event_preventdefault.asp
The event.preventDefault() method stops the default action of an element from happening.
For example: Prevent a submit button from submitting a form ( this is your case).
The default behavior of the <submit> and <button> element is to submit the form and redirect to another location. In order to prevent the page from being reloaded, make sure to prevent that behavior:
$("#login").submit(function(e) {
e.preventDefault();
// Your code here
});
A slightly less convenient method is to use return false, but you have to be careful because it is simply the shorthand of e.stopPropagation() and e.preventDefault(). It will prevent events from bubbling up, so if you are sniffing for events higher up in the DOM tree that originate from the #login element they will be lost.
Also, return false;, unlike e.preventDefault() has to be placed on the last line of the function so that it doesn't stop the function from being executed midway, i.e.:
$("#login").submit(function(e) {
// Your code here
// Last line
return false;
});
Well, that's what a submit button does :)
You can override this behavior by preventing the default behavior of the event when handling the submit event of the form:
$("#login").submit(function(e) {
e.preventDefault();
// the rest of the code
});
Ideally, in order to achieve graceful degradation, the submit button (and the form in general) should still perform the necessary actions for the application by way of posting the form and reloading the page. So the form should have an action which invokes the server-side operation being invoked.
Then the JavaScript code would override that behavior (using the above method) and provide a more UX-friendly AJAX approach to the operation being invoked.
Both should work, so that JavaScript isn't required in order to use the application.

Login without clicking submit

so I'm working on this project in which I made an admin area.
While I was working on the login functionality, I wanted a feature like this :-
As soon as the user fills all the entries (Username and Password), the system automatically logs him in.
He doesn't need to hit the submit button.
Similarly, he should be given an error message if the password was incorrect.
How can I achieve this functionality ?
I guess it could be done via jQuery and Ajax, and I have nil knowledge in both of them.
If anybody could guide me in the correct direction, it would be great.
Admin_login.php
<form class="form-horizontal" action="****" method="post" id="login">
<fieldset>
<div class="input-prepend" title="Username" data-rel="tooltip">
<span class="add-on"><i class="icon-user"></i></span><input autofocus class="validate[required] text-input, input-large span10" name="username" id="username" type="text" placeholder="Username"/>
</div>
<div class="clearfix"></div>
<div class="input-prepend" title="Password" data-rel="tooltip">
<span class="add-on"><i class="icon-lock"></i></span><input class="validate[required] text-input, input-large span10" name="password" id="password" type="password" placeholder="password"/>
</div>
<div class="clearfix"></div>
<div class="clearfix"></div>
<p class="center span5">
<button type="submit" class="btn btn-primary">Login</button>
</p>
</fieldset>
</form>
Database Table
Column Name Type
Username VARCHAR
Password VARCHAR
I wrote a git.
This is the link:
https://github.com/FabioSorre/HTML-PHP-AJAX-JQUERY-JS
The steps are these:
Html: No form action (action="") and specify method (Client-side)
Javascript/Jquery: onSubmit function call (Client-side)
Setup JSON callback (Client-side)
Php file (set json_encode, the operations and response(s)) (Server-side)
Show the results (Client-side)
Try using setInterval() that executes a function that checks if both fields are filled every 100MS. Please not this is a dirty hack. I would suggest using better validation methods. Google can help u with that
<script>
function checkCompleteness(){
if($('#username').val()!=='' || $('#password').val()!==''){
//POST DATA HERE MAYBE WITH AJAX OR TRIGER SUBMIT(GOOGLE HOW)
$.post(
'my/endpoint',
{
username:$('#username').val(),
password: $('#password').val()
}, function(response){
// ACT ON RESPONSE STATUS
});
}
//CHECK BOTH FIELDS EVERY 100 MS
setInterval(checkCompleteness(), 100);
</script>
Ok so I'm thinking a little out loud but I hope this guides you to the right direction.
Let's assume that when you are logging in you type a character at maybe 1 sec delay. Let's assume that when the user finishes typing the Password, 2 or 3 seconds will pass. You can make a listener that waits for 2 seconds to pass after the password is typed and then trigger the submit file. Of course you should check that the username is also typed (min characters and not empty exception).
You can make the 2 second listener like this:
Javascript code:
// Trigger a callback function after a given time
var wait = (function(){
var timer = 0;
return function(callback, ms){
clearTimeout (timer);
timer = setTimeout(callback, ms);
};
})();
// Trigger the submit via AJAX
wait(function(){
// form validation
$.ajax({
url: '/Admin_login.php',
type: 'POST',
dataType: 'default: Intelligent Guess (Other values: xml, json, script, or html)',
data: {
username: $('#username').val(),
password: $('#password').val()
},
})
.done(function() {
console.log("success");
})
.fail(function() {
console.log("error");
})
.always(function() {
console.log("complete");
});
}, 2000); // It submits the form via AJAX after 2 seconds have passed since
// the user typed something in the password field
Admin_login.php
The PHP part is more of a sketch but I hope you understand the idea behind it
<?php
$username = $_POST['username'];
$password = $_PSOT['password'];
//some more forom validation
$loggedin = login($username, $password);
if ($loggedin) {
// Loggedin
}
else {
// renegerate form
}
?>
P.S. Don't forget to avoid SQL injection and escape any special characters, some more information about this topic here: How can I prevent SQL injection in PHP?
Keep me posted and good luck! :)

How can I run a jquery function to update progress bar when file is uploading?

Hello, I am trying to implement some code I got at http://elfga.com/. I want to integrate it with the file upload scripts from AspUpload. I have it working separately but not together.
If I wrap the jquery in
$(document).ready(function(){
...
});
the jquery runs, polls the script that reports the upload status, and writes to the console as expected. If I bind it to the form submission by using
$(document).ready(function(){
$("#addForm").submit(function() {
...
});
});
the file uploads, but the jquery does not poll the script and write the data to the console.
I'm fairly new to jquery. What have I got wrong here? Thanks
html
<form name="addForm" id="addForm" method="post" enctype="multipart/form-data" action="moduleMaterialUpd.asp?PID=368337C0351A5DE6" onSubmit="getProgress()">
<fieldset>
<div>
<label for="title">Material: </label>
<input name="filename" type="file" required/>
</div>
<div>
<input class="button big primary" name="button" type="submit" value="Add Material"/>
<a class="button big primary" href="module.asp?id=456283123">Done</a>
</div>
</fieldset>
</form>
<div class="progress progress-striped active" id="progressouter" style="width:500px; margin:10px auto;">
<div class="bar" id="progress"></div>
</div>
jquery
<script type="text/javascript">
$(document).ready(function(){
//$("#addForm").submit(function() {
var request;
var thispid = "<%=mypid%>";
console.log(thispid);
var progresspump = setInterval(function(){
/* query the completion percentage from the server */
request = $.ajax({
type: "GET",
url: "progress_ajax_update.asp?pid=<%=mypid%>",
dataType: "xml"
});
// callback handler that will be called on success
request.done(function (xml){
$(xml).find('Progress').each(function(){
var elap = $(this).find('ElapsedTime').text();
var rem = $(this).find('RemainingTime').text();
var perc = $(this).find('PercentComplete').text();
var tot = $(this).find('TotalBytes').text();
var upl = $(this).find('UploadedBytes').text();
var rem = $(this).find('RemainingBytes').text();
var spd = $(this).find('TransferSpeed').text();
// log a message to the console
console.log(elap);
console.log(perc);
console.log("progress_ajax_update.asp?pid=<%=mypid%>")
/* update the progress bar width */
$("#progress").css('width',perc+'%');
/* and display the numeric value */
$("#progress").html(perc+'%');
/* test to see if the job has completed */
if(test > 99.999) {
clearInterval(progresspump);
$("#progressouter").removeClass("active");
$("#progressouter").removeClass("progress-striped");
$("#progress").html("Done");
}
});
});
}, 2000);
//});
});
</script>
You get this behavior, because when you submit form (by clicking submit button) you actually reload the page or even direct the form submission to another script which in both cases stops javascript interpretation. So to achieve what you want you need to prevent the submission of form before the point you need. Just try to use in your .submit(event):
return false;
or for latest Chromes I guess (maybe even combine both)
event.returnValue=false;
You can then check the progress of upload and do something with javascript or when you are happy with upload, then only submit your form in javascript:
$('#form-id').submit()
But in latter case don't forget to use .on('click') handler first on submit button to do what you need, because $(form).submit() will simply call again your submit() function and which don't return true and continue the event.

JQuery Ajax call stop refresing the page

I have the following html code:
<div>
<form id="ChartsForm">
<div id="optionsheader">
<p>Choose your page:</p>
<div id="dateoptions">
<p>Until date: <input type="date" name="until_date" value="Until date"></p>
<p>Since date: <input type="date" name="since_date" value="Since date"></p>
</div>
</div>
<select name="accmenu" id="accmenu" style="width:300px; float:left; clear:both;">
<?php
$user_accounts = $facebook->api('/me/accounts','GET');
foreach($user_accounts['data'] as $account) {
?>
<option data-description="<?php echo $account['category'] ?>" data-image="https://graph.facebook.com/<?php echo $account['id']; ?>/picture" value="<?php echo $account['id'] ?>"><?php echo $account['name'] ?></options>
<?php
}
?>
</select>
<div class="insightsoptions">
<p>Choose your insights:</p>
<input id="newLikes" class="insightsbuttons" type="submit" name="submit" value="Daily new likes">
<input id="unlikes" class="insightsbuttons" type="submit" name="submit" value="Daily unlikes">
</div>
<div class="insightsgraphs">
<div id="dailyNewLikes"></div>
<div id="dailyUnlikes"></div>
</div>
</form>
</div>
which has a form with the id=ChartForm that contain two date inputs until_date and since_date, one select accmenu and two submit inputs with the values Daily new likes and Daily unlikes. I use the following Jquery function:
$(function () {
$('#accmenu').change(function() {
$(".insightsgraphs div").hide();
$(".insightsoptions input").attr("class","insightsbuttons");
});
$("#newLikes").one('click', function () {
$.ajax({type:'GET', url: 'newLikes.php', data:$('#ChartsForm').serialize(), success:
function(response) {
var json = response.replace(/"/g,'');
json = "[" + json + "]";
json = json.replace(/'/g,'"');
var myData = JSON.parse(json);
var myChart = new JSChart('dailyNewLikes', 'line');
myChart.setDataArray(myData);
myChart.setSize(960, 320);
myChart.setAxisNameX('');
myChart.setAxisValuesColorX('#FFFFFF');
myChart.setAxisNameY('');
myChart.setTitle('Daily New Likes');
myChart.draw();
}});
return false;
});
$("#newLikes").on('click', function(){
$(this).toggleClass('green');
$('#dailyNewLikes').toggle();
});
$("#unlikes").one('click', function () {
$.ajax({type:'GET', url: 'unlikes.php', data:$('#ChartsForm').serialize(), success:
function(response) {
alert(response);
$("#dailyUnlikes").html(response);
}});
return false;
});
$("#unlikes").on('click', function(){
$(this).toggleClass('green');
$('#dailyUnlikes').toggle();
});
});
for the application flow in the following manner: every time I click on one of the input submit buttons the script will make only one Ajax GET request to a specific php file that send me back a response with which I create a Chart in a hidden div with the id=dailyNewLikes or id=dailyUnlikes by case (for testing purposes I work for the moment only on the first button). The button it will change his background color into green and the div it will be shown. I use $("#newLikes").on('click', function(){ for change back and forth the background color and the display time of the div. (from green and display:block to red and display:none, you get the point I hope :D). Also I use $('#accmenu').change(function() { to change all buttons to red and hide the respective div in case an option from the select is changed. My problem is that after I refresh the page (Ctrl+R) choose since and until date, click on the first button (it change to green and the div is shown, also the toggle is working fine) and then click on the second button which works fine on the first click (is becoming green and div is shown) but on the second click I have an issue: the script is making another Ajax GET request (a wrong URL one) and the page is refreshed. Ex. of a good reguest URL:
http://localhost/smd/unlikes.php?until_date=2013-05-01&since_date=2013-04-01&accmenu=497232410336701
and an ex. of a wrong request URL:
http://localhost/smd/?until_date=2013-05-01&since_date=2013-04-01&accmenu=497232410336701&submit=Daily+unlikes#_=_
Like it can be seen (it doesn't need in the first to make this extra request) the php file is not present and also a new submit parameters is added. This also happen if I change from the select with another option. What am I do wrong? I really need to know, not just to have my code "fixed". It bugging me for a little while. Any feedback is more than welcomed. P.S. Also, how can I start the .one function only if both date inputs has been choosen? Something like how could help me?
var until = $('#dateoptions input[name="until_date"]').val();
var since = $('#dateoptions input[name="since_date"]').val();
if (until == "" || since == "") {
alert('Until date or Since date missing!');
return;
}
it will work that way? Sorry for the long question...
i think you should make your question a little shorter and just point what you need and what errors are you getting ..anyways...going through your code i see you have two click event for same button at the end for $("#unlikes").one and $("#unlikes").on(..and no return false in other function.
try adding return false
$("#newLikes").on('click', function(){
$(this).toggleClass('green');
$('#dailyNewLikes').toggle();
return false;
});
$("#unlikes").on('click', function(){
$(this).toggleClass('green');
$('#dailyUnlikes').toggle();
return false;
});
my guess is that , since you have two click event..when it gets clicked ..these event will fire and since you are missing return false in second click function...the form gets submitted hence refreshing the form.
however its better if put your codes in single click function than creating two seperate click event.

Categories

Resources