HTML5 constraint validation for custom check - javascript

I would like to check if username and email address is unique on client side.
Is there any way to add custom validation for constraint validation?
Or is there any other recommended way for this?
I assume I have to send async http request (I am using node js on server side) but would like to follow best practice for this one.

Yes you can use the setCustomValidity function from the constraint validation api, which is part of every form field (e.g., HTMLInputElement).
<input name="username">
<script>
const field = document.querySelector('[name="username"]');
field.addEventListener('change', () => {
fetch('https://example.com/myapiforcheckingusername' {
method:'POST',
body: JSON.stringify({username: field.value})
}).then((response) => {
const alreadyExists = // process response to check if username already exists
if (alreadyExists) {
field.setCustomValidity('The username already exists!');
}
});
});
</script>
The above code shows how to make an async validation on an input field. If the setCustomValidity is not the empty string it means it is a form error. If checkValidity is called on the accompanying form it returns false then.
You can check the MDN documentation for further examples on this matter.

you can make a request on input's blur to check if what user has written in input is unique or not and show result to user with check mark or red X
or you can show user after he clicked on signup button but i prefer the first solution

Related

email and password remember me for login after user logged in for the first time

when the user login to his account and click remember me how to make the login form auto-fill the user email and password when the user come to login again so he doesn't have to fill his email and password again in react and next
First of all, store user's credentials on front side (localStorage, lessionStorage and etc.) is not a good practice.
Usually "Remember me" checkboxes are used to create an auth-cookie with longer time life.
For example:
When user checked "Remember me", you will send post request with query params remember=1, server handle this, and send response with header:
Set-Cookie: {auth-cookie}={value}; Max-Age={one week, for example}
It will create a cookie in browser, which time life is one week.
In another case, if user didn't check "remember me", server responds with header like this:
Set-Cookie: {auth-cookie}={value}; Max-Age={one day, for example}
It means that user will be authorized during just one day, after it cookie will be expired, and user will logged out.
User can allow the browser to autocomplete input fields if click "Save password" after submitting the form in browser's popup.
It's browser behavior.
Best regards!
Answer
You can use localStorage, a built-in object in JavaScript for browsers.
localStorage is of type Storage, which means that you can use it via the methods setItem, getItem, and removeItem.
How to use
localStorage.getItem("item1"); // null
localStorage.setItem("item2", "EntityPlantt");
localStorage.getItem("item1"); // still null
localStorage.getItem("item2"); // "EntityPlant"
localStorage.item1; // "EntityPlantt"
location.reload(true); // Reloads page
localStorage is persistent, so you can call it on load to fill in the form.
Examples
onload = () => {
if (localStorage.getItem("data")) {
var data = JSON.parse(localStorage.data);
// fill out the form
}
}
And, when someone fills the form, you can save the form data in localStorage.
btn.onclick = () => {
localStorage.setItem("data", JSON.stringify({
// Form data
}));
submitForm(); // The submitting of the form; your code here
}
Note that localStorage can only store strings. So you can convert them to your type.
var number = parseFloat(localStorage.getItem("number"));
var string = localStorage.getItem("string");
var object = JSON.parse(localStorage.getItem("object"));
var array = localStorage.getItem("array").split(",");
var symbol = Symbol(localStorage.getItem("symbol"));
Reference
If you want to learn more about localStorage (and sessionStorage), go to the MDN docs.
You can use the localstorage of the browser (better encrypted). Then, if the user doesen't refresh the localstorage you will be able to use this information to fill the form.

Entering data into multiple form inputs in Puppeteer

I'm trying to fill out a form in Puppeteer with an email and password, and then hit submit.
Each time the tests are run either the email or password isn't fully entered before the submit button is pressed. This is a cut-down version of what I'm doing:
await page.type(selectorSlackInputEmail, email);
await page.type(selectorSlackInputPassword, password);
await page.click(selectorSlackButtonSignIn);
I think it might be because the test isn't properly awaiting the completion of page.type and therefore focus switches to the next input or the submit button is pressed before each input field is complete.
How do I get around this problem?
I would expect your await directives to cover the issue you're seeing - my best guess is that because the type method simply...
sends keydown, keypress/input and keyup events [1]
... that maybe some listeners are taking a little while to execute their hooked functions between the sending of those events and the calling of the click method.
How about a workaround that explicitly checks that those selectors have the expected data before clicking submit?
await page.type(selectorSlackInputEmail, email);
await page.type(selectorSlackInputPassword, password);
await page.waitFor(() => {
return document.querySelector(selectorSlackInputEmail).value = email) &&
document.querySelector(selectorSlackInputPassword).value = password);
});
// And only *then*
await page.click(selectorSlackButtonSignIn);
After trying other methods (including await page.type and await page.focus followed by await page.keyboard.type) this is the only thing that works for me to fill multiple form fields:
await signInPage.evaluate(
(email, password) => {
document.querySelector('input#email').value = email;
document.querySelector('input#password').value = password;
},
email,
password
);
This doesn't satisfy my original use case though. I want to properly simulate a user typing into forms but this method circumvents that and directly inserts values into the fields.
I'd welcome a 'proper' solution to this problem.
I had the same problem in my code and decided to just use a delay with the click function.
await page.click('input[value="SUBMIT"]', {delay: 100});

Can a Custom Validation Rule in Aurelia call other existing rules?

I want to create a custom validation rule for the Aurelia Validator plugin. Essentially, I have a semicolon-delimited string of email addresses (in a To) field and I'd like to split this string and run email validations on each individual email address. I have the following so far (there are null check issues, but ignore that for now)
ValidationRules.customRule('multiEmail', (value, obj) => {
var emails = value.split(';');
emails.forEach(() => {
// Call the existing email validation functionality rule for each value?
});
});
Is this possible?

How create a simple get form that will create a dynamic route, depending on the value of the search field (MONGODB and Node.js)

i want search throw the database for a value that the user puts in a get form.
The backend is very simple, i know how to search throw the database and render the result..
app.get('search/:id', function(req, res) {
var id = req.param("id");
mongoose.model('Something').find({
// the field that i want find. For example:
_id: id // This will search for the id field in the database, them will return a object if finds a match.
}, function(error, object){
if (error) {
res.send(error);
}
else {
res.send(object);
}
}
);
});
This script will work.
Now i'm having problems with the HTML.
I need a get form that will send a user to /search/SOMETHING THAT THE USER WANTS SEARCH, but i don't know exactly how to change the url dinamically..
Any help is very very welcome.
If you don't know how to achieve desired behaviour in the HTML, you could still do it in the backend - by setting a redirect. Your incoming request after form submission would be something like ?inputName=user search string.
You could then take the value of the query and perform an internal redirect to your route
app.get('search', function(req, res) {
res.redirect('/search/' + req.query["inputName"]);
});
to get a form to pass GET params in a nice express-like way, you need to hook on the onSubmit of the form and then trigger an XHR/ajax request instead of the form-post.
Or you can read the querystring via req.query.inputFieldName if you are okay having the url look like /search/?inputFieldName=AwesomeSearchString
I'd take the XHR/ajax way as it also prevents the page from reloading and thus improving user-experience.

MeteorJS email form validation

Total novice here.
I'm trying to do a client side form validation for a subscribe to newsletter form. My client side code is such.
Template.body.events({
"submit .new-subscriber": function (event) {
// This function is called when the new task form is submitted
var newEmail = event.target.newEmail.value;
if (newEmail is email?){
Meteor.call("addNewSubscriber", newEmail);
}
I'm not sure how to perform form validation here? Can I perform the same server side?
We currently use two different approaches for email validation at Edthena depending on the situation. Hopefully one or both of these will fit your needs.
Regex
Regular expressions can be used for quick and dirty email validation. They will catch any obviously bogus emails like x#y.z or foo#bar, but that's about the limit of their accuracy. We use these inside the app on the client when an existing user has no motivation to enter an invalid address. Here's an example:
var isEmailValid = function(address) {
return /^[A-Z0-9'.1234z_%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(address);
};
In your case, you could add a call to isEmailValid in the submit handler. If the function returns false you could display an error instead of calling addNewSubscriber.
You can read more about email regular expressions here.
Mailgun
In cases where you think users could intentionally input invalid addresses, you can bring out the big guns and call the mailgun email validation API. This trades speed (results can take a couple of seconds to come back) for dramatically improved accuracy (mailgun does things like check that an MX record exists on the target domain). We use this approach in our public-facing forms.
Meteor.methods({
isEmailValid: function(address) {
check(address, String);
// modify this with your key
var result = HTTP.get('https://api.mailgun.net/v2/address/validate', {
auth: 'api:pubkey-XXXXXXXXXXXXX',
params: {address: address.trim()}
});
if (result.statusCode === 200) {
// is_valid is the boolean we are looking for
return result.data.is_valid;
} else {
// the api request failed (maybe the service is down)
// consider giving the user the benefit of the doubt and return true
return true;
}
}
});
In this example, isEmailValid is implemented as a method and can be called either on the server or the client depending on your needs. Note that you will need to get an API key and add the http package to your app with meteor add http.
For more details, see the docs.

Categories