How would I go about integrating these two functions together so that when submitting the search form, it will first check the http get response, then depending on whether there was an error or not, either submit the form, or display an error message?
All that I've tried has either made the form not work at all, or not take into account the 'http.get function'.
var http = require("http");
var url = 'http://examplepage.com/';
search.submit(function (event) { // submit search query function
if (searchBox.val().length < 2) {
searchBox.focus();
event.preventDefault();
}
});
http.get(url, function (res) {
res.resume();
// successful - so submit search query
}).on('error', function () {
// unsuccessful - display error message
});
You should probably subscribe on click event for you button that triggers search, the go check the url and inside success handler do
Sample code of Click handler
http.get(url, function (res) {
// successful
if (searchBox.val().length < 2) {
$('your form selector').submit();
}
}).on('error', function () {
// unsuccessful - display error message
});
Related
Why isn't the form submitted the first time?
What have I done wrong?
If I click submit, the console will display the output (Event check # 0. Event check # 1.)
If I click on the submit button again, the console will display the output (Event check # 0. Event check # 1. Event check # 2.)
And after that the message will be sent to the mail.
".button-f" and "# send-btn-form" are the same button!
//#1grn --- Submitting the form without reloading the page
let sendBtn = document.querySelector(".button-f");
sendBtn.onclick = function(e) {
e.preventDefault(); // Cancels the default browser action
console.log("Event check №0.");
let formName = document.querySelector('#main-form'); // Find our shape
let formData = new FormData(formName); // Create a new FormData-object. We use all fields with the attribute name
let request = new XMLHttpRequest(); // Create a new XMLHttpRequest-object.
request.open('POST', "php/send.php"); // We configure it: POST-request for URL php/send.php
//#1grn --- Filtering characters such as: &<>"'
['name', 'socialname', 'numberfo', 'email', 'text'].forEach(name => {
let input = document.querySelector(`[name='${name}']`);
input.value = escape(input.value);
console.log("Event check №1.");
});
//#1grn --- Check ("real" event or generated by code)
let sendBttn = document.querySelector("#send-btn-form");
sendBttn.addEventListener('click', e => { // We accept the event object into our callback-function, call it "e".
if (e.isTrusted) { // CHECKING, if a e.isTrusted === true - then this is not a machine click.
request.send(formData); // We send HTTP request to the server and get a response.
console.log("Event check №2.");
} else {
console.log('blocked!');
}
});
// This code will work after we receive the server response
request.onload = function() {
if (request.status != 200) { // analyze HTTP-response status, if the status is not 200, then an error has occurred
} else { // if everything went smoothly, clear the form and display the result
formName.reset(formData); // Clearing the form
let on = document.querySelector(".message-good");
on.classList.add('ms-on');
}
};
};
If ".button-f" and "#send-btn-form" are the same button, you are adding an event listener every time you click the button. In that case, you are not executing the code inside that listener, it will be executed the next time you click it. So you could replace this
let sendBttn = document.querySelector("#send-btn-form");
sendBttn.addEventListener('click', e => {
if (e.isTrusted) {
request.send(formData);
} else {
console.log('blocked!');
}
});
with just this
if (e.isTrusted) {
request.send(formData);
} else {
console.log('blocked!');
}
I have a jQuery form-submission routine that has an input integrity check in ERROR_CHECK.PHP that relies on GET variables passed to it for inspection. If the values passed to it are malformed, then an alert box appears that explains the error and how the form data should be remedied. This alert box will need to pop up until the form data is no longer malformed, at which point that data is used for repopulating data on the page.
Thus, in the jQuery routine I'm at the mercy of our friend preventDefault(), and I have found a solution that does work, but not elegantly. The variable allowSubmit is initialized as FALSE and remains that way—with preventDefault() also in effect—until the form data passes the integrity check, at which point allowSubmit switches to TRUE...but that only happens with the submission of the correctly-formed input data. This means the user must submit the form a SECOND TIME in order for the form data to be used to replace data on the page...and that, of course, is not a solution (press the submit button twice?)
However, by dynamically submitting the form (here, with the $('#my_form').submit() statement) immediately after resetting allowSubmit to TRUE, I've submitted the form again, thereby allowing the user to submit correctly-formatted data ONCE, as it should be from the get-go.
This is obviously a band-aid solution and not elegant. Can anyone see a more elegant way to structure this? (I'm working with jQuery fashioned by another developer, and this occurs in the midst of a longer self-calling JQuery function, and I have to work with it on its own terms, lest I have to refashion all other parts of the larger function in which it occurs.
Here's a distillation of the code (with self-describing variables, etc.), which works as described, although not as elegantly as I'd like:
var allowSubmit = false;
$('#my_form').on('submit', function(e) {
if (!allowSubmit) {
e.preventDefault();
// Check to see if input data is malformed:
$.get('error_check.php', { new_element_name: $('#new_element_name').val() }, function(data) {
if (data != 0) {
alert("An Error Message that explains what's wrong with the form data");
} else {
allowSubmit = true;
// The line below--an auto-submit--is needed so we don't have to press the submit button TWICE.
// The variable allowSubmit is set to TRUE whenever the submitted form data is good,
// but the code suppressed by e.preventDefault() won't execute until the form is
// submitted a second time...hence the need for this programmatic form submission here.
// This allows the user to correct the errant form data, press the submit button ONCE and continue.
$('#my_form').submit();
}
});
}
$('#element_name').val($('#new_element_name').val());
});
What you are doing is okay, your other options might be to write a click handler for a generic button and submit the form through that event after validation, then you wont need to preventDefault as you won't be preventing any kind of submit action. Another solution might be to re-trigger the event after validation.
$("button").click(function() {
$("#my_form").submit();
});
...
allowSubmit = true;
// alternatively
jQuery( "body" ).trigger( e );
...
The callback solution you have doesn't seem unreasonable. I agree with #scott-g that a generic button click event handler would probably be your best bet. A more testable way to write what you have here may be:
var formView = {
$el: $('#my_form'),
$field: $('#element_name'),
$newField: $('#new_element_name'),
$submitBtn: $('#btn-submit')
}
var handleSubmit = function() {
var formData = formView.$field.val();
remoteVerify(formData)
.done(formView.$el.submit)
.done(updateForm)
.fail(handleVerificationError);
};
var remoteVerify = function(formData) {
var deferred = $.Deferred();
var url = 'error_check.php';
var data = { new_element_name: formData };
$.get(url, data)
.done(handleRequest(deferred))
.fail(handleRequestErr);
return deferred;
};
var handleRequest = function(deferred) {
return function (data, jqxhr) {
if (data != 0) {
deferred.reject(jqxhr, "An Error Message that explains what's wrong with the form data");
} else {
deferred.resolve(data);
}
}
};
var handleRequestErr = function() {
// error handling
}
var updateForm = function () {
formView.$field.val(formView.$newField.val());
}
var handleVerificationError = function (jqxhr, errMsg){
alert(errMsg);
}
formView.$submitBtn.on('click', handleSubmit)
You could try using an async: false setting using $.ajax (I don't know what your php is returning, so I am just "pretending" it's a json array/string like so echo json_encode(array("response"=>$trueorfalse));):
<script>
$('#my_form').on('submit', function(e) {
var valid_is = true;
// Check to see if input data is malformed:
$.ajax({
async: false,
url: 'error_check.php',
type: 'get',
data: { new_element_name: $('#new_element_name').val() },
success: function(response) {
var Valid = JSON.parse(response);
if(Valid.response != true) {
alert("An Error Message that explains what's wrong with the form data");
valid_is = false;
}
}
});
if(!valid_is)
e.preventDefault();
$('#element_name').val($('#new_element_name').val());
});
</script>
If you use async: false it runs the script in order and waits to execute the rest of the script until after it receives a response. Scott G. says you can do it with what you have with some slight modifications so I would try that first.
I'm submitting a form with an update() function in Angular, which then authenticates, returns a promise, and then submits a second form if successful.
The problem is, the second form won't submit with the document.getElementById(elementID).submit(); method. It will, however, submit with document.getElementById(elementID).click(); but only on non-touch devices of course.
Bottom line - why won't submit() work?
Here is a jsFiddle with a reduced and simplified version: http://jsfiddle.net/jimcamut/xos805gk/
Here is my function that handles the form submissions in its full version.
$scope.update = function(user) {
if ($scope.earlyUser.$valid) {
$scope.master = angular.copy(user);
console.log("Form submitted on front end");
// This integrates ParseJS and submits the data to a database - all good here, except after the promise
var parseUser = new Parse.Object("LaunchUser");
parseUser.setACL(new Parse.ACL());
parseUser.save({
name: $scope.master.name,
email: $scope.master.email,
zipcode: $scope.master.zipcode
},{
error: function(model, error) {
console.log("error is...");
console.log(error);
}
// Returns a promise
}).then(function(object) {
// Problem area here when attempting to submit second form...
document.getElementById('mc-embedded-subscribe').submit();
$scope.reset();
});
} else {
alert("Please correct the red form fields.");
}
};
element with id='mc-embedded-subscribe' is an input, but you need to "submit()" a form.
this line
document.getElementById('mc-embedded-subscribe').submit();
should be changed for
document.getElementById('mc-embedded-subscribe-form').submit();
Here you have a new fiddle with this changes, and it works!
http://jsfiddle.net/kx8dn8wc/
I have a series of buttons that execute different functions when clicked. The function checks whether the user is logged in, and if so proceeds, if not it displays an overlay with ability to log in/create account.
What I want to do is re-execute the button click after log-in, without the user having to reclick it.
I have it working at the moment, but I'm pretty sure that what I'm doing isn't best practice, so looking for advice on how I can improve...
Here's what I'm doing: setting a global variable "pending_request" that stores the function to be re-run and in the success part of the log-in ajax request calling "eval(pending_request)"
Example of one of the buttons:
jQuery('#maybe_button').click(function() {
pending_request = "jQuery('#maybe_button').click()"
var loggedin = get_login_status();
if (loggedin == true) {
rec_status("maybe");
}
});
.
success: function(data) {
if(data === "User not found"){
alert("Email or Password incorrect, please try again");
}else{
document.getElementById('loginscreen').style.display = 'none';
document.getElementById('locationover').style.display = 'none';
eval(pending_request);
pending_request = "";
}
}
Register a function to handle the click and then invoke that func directly without eval().
jQuery('#maybe_button').on('click', myFunction)
This executes myFunction when the button is clicked. Now you can "re-run" the function code every time you need it with myFunction().
And btw since you are using jQuery you can do $('#loginscreen').hide() where $ is an alias for jQuery that's auto defined.
EDIT
Please, take a look at the following code:
var pressedButton = null;
$('button1').on('click', function() {
if (!isLoggedIn()) {
pressedButton = $(this);
return;
}
// ...
});
And, in your success handler:
success: function() {
// ...
if (pressedButton) pressedButton.trigger('click');
// ...
}
I am attempting to test 4 usernames and password by using an array. The first username and password are successful, checked by fetching the "Howdy, (username)" in wordpress. My issue:
Once it runs the loop, it fails to reload the page where the username and password can be inputted; how can I re-load the page to continue to test the next usernames/passwords?:
CasperError: Cannot get informations from #log: element not found.
The element is not found, because it is attempting to find it in the now "logged in" page.
var casper = require('casper').create()
casper.userAgent('Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)');
casper.start('http://somesite.com')
casper.viewport(1024, 768).then(function() {
// new view port is now effective
});
//Usernames
var userNames = ['username1','username2','username3','username4'];
var userNamesIndex = 0;
//Passwords
var passWords = ['password1','password2','password3','password4'];
var passWordsIndex = 0;
function login () {
casper.then(function () {
this.sendKeys('#log', userNames[userNamesIndex]);
userNamesIndex++;
if (userNamesIndex >= userNames.length) {
userNamesIndex = 0;
}
this.sendKeys('#pwd', passWords[passWordsIndex]);
passWordsIndex++;
if (passWordsIndex >= passWords.length) {
passWordsIndex = 0;
}
console.log(userNames[userNamesIndex] + " account has been typed in.");
this.click('#wpmem_login > form > fieldset > div.button_div > input.buttons');
console.log("Log In button has been clicked!")
});
casper.wait(5000, function () {
this.echo(this.getTitle());
this.echo(this.fetchText('#wp-admin-bar-my-account > a'));
casper.capture('pic.png');
});
};
setInterval(login,2000);
casper.run();
There are functions for that. You can use casper.open, casper.thenOpen or casper.back to achieve that.
Also, you should not use setInterval or setTimeout to do some scheduling, because CasperJS is asynchronous on its own, but those functions are only useful when you want to execute a synchronous function later. CasperJS works by scheduling steps which you break by using setInterval or setTimeout. For another case where this breaks, see How do I remove the stack overflow from this casperjs code (phantomjs / javascript using setTimeout)?
Change login to use username and password directly and change the implementation accordingly (you don't need the counters):
function login (username, password) { /* your adjusted implementation */ }
After you logged into the page, you need to log out before using the next credentials. CasperJS uses cookies which are not cleared when using thenOpen.
So the script would look like this:
casper.start(); // empty page
userNames.forEach(function(username, index){
casper.thenOpen(url); // open the start page
login(username, passWords[index]); // schedule the steps
// you can also move the following steps inside the login function
casper.then(function(){
// do something
});
casper.then(function(){
// click logout button
});
});
casper.run(); // begin the execution
Here is the gist with the complete code.
If you want to track the successful and unsuccessful logins, you need a global variable:
var glob = {success: [], fail: []}; // before start for readability
In login you can then write into the variable:
casper.wait(5000, function () {
// use some indicator that the login worked, here the logout button
if (this.exists(logoutButtonSelector)) {
glob.success.push(username);
} else {
glob.fail.push(username);
}
this.echo(this.getTitle());
this.echo(this.fetchText('#wp-admin-bar-my-account > a'));
casper.capture('pic.png');
});
You can then print it like this:
casper.run(function(){
this.echo("success: " + glob.success.length + ", fail: " + glob.fail.length);
this.echo(JSON.stringify(glob));
});