What is wrong with this email RegExp? - regex

I'm trying to implement this (the one at the bottom of the page) RegExp to validate email addresses with jquery validation plugin.
This is my code:
$.validator.addMethod("email_address", function(value, element, param) {
var email_regexp = new RegExp("[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*#(?:a-z0-9?.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b", "g");
var result = value.match(email_regexp);
return result ? result.length >= param : false;
}, "Invalid email address");
No JS errors are shown, still it doesn't validate anything! Been playing with it for like an hour and can't get this working!
Is there something wrong?
EDIT: I tried also with // delimiters:
$.validator.addMethod("email_address", function(value, element, param) {
var result = value.match(/[a-z0-9!#$%&'*+/=?^_{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_{|}~-]+)*#(?:a-z0-9?.)+(?:[A-Z]{2}|com|org|net|edu|gov|mil|biz|info|mobi|name|aero|asia|jobs|museum)\b/g);
return result ? result.length >= param : false;
}, "Invalid email address");

~-]+(?:\.[a-z0-9!#$
// ^^
That \. will need escaping again for the Javascript string:
~-]+(?:\\.[a-z0-9!#$
// ^^^
Or, preferably, use // delimeters rather than constructing a RegExp object from a string.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/RegExp

Why are you writing a custom regex function for the jQuery Validate plugin when it already has an email rule built-in?
http://docs.jquery.com/Plugins/Validation/Methods/email
jQuery:
$(document).ready(function() {
$('#myform').validate({
rules: {
field: {
required: true,
email: true
}
}
});
});
HTML:
<form id="myform">
<input type="text" name="field" /> <br/>
<input type="submit" />
</form>
Working Demo:
http://jsfiddle.net/sRwHc/
The default regex function used within the .validate() plugin, FYI:
email: function(value, element) {
// contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))#((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
}

Related

Click event if element is checked and reload page

I would like a reload.location click-event only if a checkbox is checked. To me this seems to be basic conditions, but it's not working. Perhaps a different approach is needed? What I figured out, is when the checkbox is ticked, there is no html change in the <input type="checkbox"> element. Maybe this is the reason or is the combination of these conditions not possible? The else statement is a call back to the previous UI page. In below attempt, it's skipping the if-statement.
My attempt:
$(document.body).on("click", "#button", function(){
if (document.getElementById('checkbox').checked) {
location.reload(true);
} else {
return_to_page( this.dataset.return )
}
});
Above is working, however it's ignored due to the missing preventDefault:
$(document.body).on("click", "#button", function(e){
e.preventDefault();
//etc
});
checked is not a property of a jQuery object. You can use prop() to get the property instead:
$('#button').click( function() {
if ($('#checkbox').prop('checked')) {
location.reload(true);
}
// alternative #1 - use the 'checked' property of the Element in the jQuery object:
if ($('#checkbox')[0].checked) {
location.reload(true);
}
// alternative #2 - use the 'checked' property of the Element outside of jQuery:
if (document.getElementById('checkbox').checked) {
location.reload(true);
}
});
Here's a working example:
$('#button').click(function() {
if ($('#checkbox').prop('checked')) {
// location.reload(true);
console.log('Reload would happen now...');
} else {
console.log('Staying on the current page');
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<label>
<input type="checkbox" id="checkbox" />
Reload?
</label>
<button id="button">Go</button>
$('#button').click( function() {
if( $("input[id='checkbox']:checked") ) {
location.reload(true);
}
});
alternative
$('#button').click( function() {
if( $('#checkbox').is(':checked') ) {
location.reload(true);
}
});
All in a one plate methods:
$('#checkbox').is(":checked")
$('#checkbox').prop('checked')
$('#checkbox')[0].checked
$('#checkbox').get(0).checked

React - replace() not working to change symbol to letter

Based on other examples, my regex attempt to replace dashes (-) with letters should work. But it doesn't. I am using React.
I have followed this post (Replace multiple characters in one replace call) and other outside posts but I cannot get regex to replace dashes (-) with certain letters. The app only has one component, App.js. I have also tried writing the line targetNameDashes.replace(/'-'/gi, letter).toUpperCase(); but it hasn't worked either.
GitHub repo: https://github.com/irene-rojas/brooklyn-react
import React, { Component } from 'react';
import './App.css';
class App extends Component {
state = {
names: ['JAKE', 'AMY', 'GINA', 'ROSA', 'CHARLES', 'TERRY', 'HOLT'],
targetName: "",
targetNameDashes: "",
guessRemain: 10,
lettersGuessed: []
}
componentDidMount() {
let targetName = this.state.names[Math.floor(Math.random()*this.state.names.length)];
this.setState({
targetName: targetName,
targetNameDashes: targetName.replace(/[a-zA-Z]/gi , '-').toUpperCase(),
// The flags 'g' and 'i' are for global search and case insensitive search
});
console.log(targetName);
}
onKeyUp = (event) => {
event.preventDefault();
let letter = event.key.toUpperCase();
let targetName = this.state.targetName;
let guessRemain = this.state.guessRemain;
let lettersGuessed = this.state.lettersGuessed;
if (letter) {
this.setState({
guessRemain: guessRemain - 1,
lettersGuessed: lettersGuessed + letter
});
// if letter is in targetName, replace dash with letter
if (targetName.includes(letter)) {
console.log("yup");
let targetNameDashes = this.state.targetNameDashes;
// temporary variable that contains dashes and letters?
targetNameDashes.replace(/-/gi, letter).toUpperCase();
this.setState({
targetNameDashes: targetNameDashes
// does it need a callback to update?
});
}
}
if (guessRemain === 0) {
console.log("too bad");
this.setState({
guessRemain: 10,
lettersGuessed: []
});
this.componentDidMount();
}
console.log(`${letter} end of onKeyUp`);
}
render() {
return (
<div className="App">
<div>
You will be seen by:
<br></br>
{this.state.targetNameDashes}
</div>
<br></br>
<div>
Letters guessed:
<br></br>
<input onKeyUp={this.onKeyUp} />
<br></br>
Letters guessed in this round:
<br></br>
[ {this.state.lettersGuessed} ]
</div>
<br></br>
<div>
Guesses remaining:
<br></br>
{this.state.guessRemain}
</div>
</div>
);
}
}
export default App;
I noticed many issues that I should mention one by one:
Move some of the constants out of the state, for example names. Setting them in state makes no sense because they will not be changed and re-rendered in UI.
You manually called componentDidMount at the end of your key up event handler, which is not they way this should be done. Separate the logic that needs to be re-done in a separate utility function (i.e. gameReset() and call that instead).
The replace logic of the case when targetName.includes(letter) is not correct. It doesn't know which indices to replace.
Think of that this way: your targetName was "EVE", you are asking
a string that looks like "---" to change to wherever "E" is. How can
it know where "E" is without inspecting the original name? A loop
would be a better solution.
setState is asynchronous in nature. You should make use of prevState argument and callback method to ensure you are getting the correct states.
Here I have modified your codes and added comments where necessary, hope it helps:
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
// moved it outside state
const names = ["JAKE", "AMY", "GINA", "ROSA", "CHARLES", "TERRY", "HOLT"];
class App extends React.Component {
state = {
targetName: "",
targetNameDashes: "",
guessRemain: 10,
lettersGuessed: []
};
// utility extracted from componentDidMount
// so that it can be re-used later
resetGame = () => {
let targetName = names[Math.floor(Math.random() * names.length)];
this.setState({
guessRemain: 10,
lettersGuessed: [],
targetName: targetName,
targetNameDashes: new Array(targetName.length).fill("-").join("") // fill an array with hyphens
});
};
componentDidMount() {
// call the utility
this.resetGame();
}
onKeyUp = event => {
event.preventDefault();
let letter = event.key.toUpperCase();
// TODO: provide more logic to avoid bad key strokes
// for example backspace should not count
if (letter) {
this.setState(
prevState => {
let modifiedNameDashes = String(prevState.targetNameDashes);
// for each charecter of targetName
for (var i = 0; i < prevState.targetName.length; i++) {
// check if this charecter at index i matched the key
if (prevState.targetName[i] === letter) {
// if it does
// remove a hyphen from modifiedNameDashes at that exact index
modifiedNameDashes =
modifiedNameDashes.substr(0, i) +
letter +
modifiedNameDashes.substr(i + 1);
}
}
return {
targetNameDashes: modifiedNameDashes,
guessRemain: prevState.guessRemain - 1,
lettersGuessed: [...prevState.lettersGuessed, letter]
};
},
// callback after the state update is done
() => {
// won
if (this.state.targetNameDashes === this.state.targetName) {
console.log("Nice!");
}
// lost
if (this.state.guessRemain === 0) {
this.resetGame();
}
}
);
}
};
render() {
return (
<div className="App">
<div>
You will be seen by:
<br />
{this.state.targetNameDashes}
</div>
<br />
<div>
Letters guessed:
<br />
<input onKeyUp={this.onKeyUp} />
<br />
Letters guessed in this round:
<br />[ {this.state.lettersGuessed} ]
</div>
<br />
<div>
Guesses remaining:
<br />
{this.state.guessRemain}
</div>
<code>{JSON.stringify(this.state)}</code>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
targetNameDashes.replace(/-/gi, letter).toUpperCase();
this.setState({
targetNameDashes: targetNameDashes
// does it need a callback to update?
});
This is likely the source of your problem with nothing happening - String.prototype.replace returns a new version of the string, and doesn't modify the parameter string.
This would at least cause it to update so you can continue to work on the logic here.
this.setState({
targetNameDashes: targetNameDashes.replace(/-/gi, letter).toUpperCase()
});

How to show the error message when the textbox is empty when user click the submit button in ember.js?

I want to know when the textbox is empty and when user click the submit button the error message will need to show. Please help me.
This is my template register.hbs code
{{paper-input
label="E-mail"
type="email"
value=email
onChange=(action (mut email))
icon="email"
}}
{{#paper-button raised=true primary=true onClick=(action "register")}}Register{{/paper-button}}
and this is my controller register.js code
email: null,
actions: {
register() {
var data = {
email: this.get('email'),
};
var record = this.store.createRecord('register', data);
record.save().then((response) => {
this.set('email', null);
this.transitionToRoute('activation');
});
}
}
Just put something like:
if (!this.get('email').trim()){
//your code to show some error message
return
}
trim() removes possible whitespaces from the mail
and a empty or null string is falsy in javascript:
More on trim
More on what evaluates to True/False for strings

Algolia - Search with a condition to look into an array of string

I am using rails and algolia gem with mongoid datastore.
I am sending data to algolia for a model Question. One of the doc example in Algolia system is
objectID: 5691e056410213a381000000
text: "what is #cool about your name Mr. John? #name #cool"
asked_to: ["565571704102139759000000", "i7683yiq7r8998778346q686", "kjgusa67g87y8e7qtwe87qwe898989"]
asked_by: "564a9b804102132465000000"
created_at: "2016-01-10T04:38:46.201Z"
card_url: "http://localhost:3000/cards/5691e056410213a381000000"
answerers: []
has_answer: false
requestor_count: 0
status: "active"
popularity_point: 0
created_at_i: 1452400726
_tags: ["cool", "name"]
I want to find all those documents, where it meets these two conditions:
1) text contains your name
2) asked_to contains i7683yiq7r8998778346q686
I am using Twitter's typeahead javascript library. And my UI's javascript to implement algolia search is as follows:
<input class="typeahead ui-widget form-control input-md search-box tt-input" id="typeahead-algolia" placeholder="Search questions" spellcheck="false" type="text" autocomplete="off" dir="auto" style="position: relative; vertical-align: top;">
$(document).on('ready page:load', function () {
var client = algoliasearch("APPLICATION_ID", "SEARCH_KEY");
var index = client.initIndex('Question');
$('#typeahead-algolia').typeahead(
{
hint: false,
highlight: true,
minLength: 1
},
{
source: index.ttAdapter({hitsPerPage: 10}),
displayKey: 'text'
}
).on('keyup', this, function (event) {
if (event.keyCode == 13) {
$('#typeahead-algolia').typeahead('close');
window.location.href = "/?keyword="+encodeURIComponent($('#typeahead-algolia').val());
}
});
$('.typeahead').bind('typeahead:select', function(ev, suggestion) {
window.location.href = suggestion.card_url;
});
});
So my question is:
This code works perfectly. But how to add condition for asked_to contains i7683yiq7r8998778346q686 in above javascript to filter out result.
You can use a facet filter on the asked_to attribute in your query.
You first need to declare the attribute asked_to as an attribute for faceting in your index settings and then pass asked_to:i7683yiq7r8998778346q686 as a facet filter in your query via the facetFiltersquery parameter.
When your index settings are changed, you can change your source to add the facetFilters parameter:
$('#typeahead-algolia').typeahead(
{
hint: false,
highlight: true,
minLength: 1
},
{
source: index.ttAdapter({hitsPerPage: 10, facetFilters: "asked_to:i7683yiq7r8998778346q686"}),
displayKey: 'text'
}
).on('keyup', this, function (event) {
if (event.keyCode == 13) {
$('#typeahead-algolia').typeahead('close');
window.location.href = "/?keyword="+encodeURIComponent($('#typeahead-algolia').val());
}
});

check url without http and ".com"

I would like to check if the given url is valid.
It should accept:
www.gmail.com
and should reject:
www.gmail
I tried using this /((ftp|http|https):\/\/)?(\w+:{0,1}\w*#)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%#!\-\/]))?/
It works but if the given input is www.gmail it does accepts it.
Any Ideas?
UPDATE
http://jsfiddle.net/aabanaag/VktaX/
You could use Jquery Validate plugin for that.
$("#myform").validate({
rules: {
field: {
required: true,
url: true
}
}
});
You can find about it here
try this .It is working for me
<script type="text/javascript">
function validate() {
var url = document.getElementById("url").value;
var pattern = new RegExp("^(http:\/\/www.|https:\/\/www.|ftp:\/\/www.|www.){1}([0-9A-Za-z]+\.)");
if (pattern.test(url)) {
alert("Url is valid");
return true;
}
alert("Url is not valid!");
return false;
}
</script>
In jQuery
you can use url validation
<input type="text" class="url"/>
solved my problem:
found this while googling over the internet.
/^(http:\/\/www.|https:\/\/www.|ftp:\/\/www.|www.){1}[0-9A-Za-z\.\-]*\.[0-9A-Za-z\.\-]*$/
var pattern1 = /^(http:\/\/www.|https:\/\/www.|ftp:\/\/www.|www.){1}[0-9A-Za-z\.\-]*\.[0-9A-Za-z\.\-]*$/;
var result = "www.gmail";
if (pattern1.test(result)) {
console.log("test");
}else{
console.log("fail");
}
It works best.