FORM VALIDATION ISSUES - forms

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Assignment1</title>
<link rel="stylesheet" href="valid.css">
<script type="text/javascript" src="formValid.js"></script>
</head>
<body>
<h2>Info Grabber</h2>
<span class="required_fields">* Denotes Required Field</span>
<!--<form id = "contact_form" action="" >/-->
<form id="contact_form" action = "#" method="post" onSubmit="return validateForm(this)" >
<!-- <table> -->
<div class="name">
<div>
<label for='name'>Name<span class="red">*</span></label>
<input type='text' name='name' id='name' placeholder="First and last name" >
<div class="fixed" id="nameError">
Please enter your first and last name with a space between!</div>
</div>
</div>
<div class="address1">
<div>
<label for='address1'>Address Line 1<span class="red">*</span></label>
<input type='text' name='address1' id='address1' >
<div class="fixed" id="address1error">
Please enter your address!</div>
</div>
</div>
<div class="address2">
<div>
<label for='address2'>Address Line 2</label>
<input type='text' name='address2' id='address2'>
</div>
<div>
<label for="county">County<span class="red">*</span></label>
<select id="county" name="county">
<option value="" selected>Please select...</option>
<option value="01">Andivim
<option value="02">Armagh
<option value="03">Carlow
<option value="04">Cavan
<option value="05">Clare
<option value="06">Cork
<option value="07">Derry
<option value="08">Donegal
<option value="09">Down
<option value="10">Dublin
<option value="11">Fermanagh
<option value="12">Galway
<option value="13">Kerry
<option value="14">Kildare
<option value="15">Kilkenny
<option value="16">Laois
<option value="17">Leidivim
<option value="18">Limerick
<option value="19">Longford
<option value="20">Louth
<option value="21">Mayo
<option value="22">Meath
<option value="23">Monaghan
<option value="24">Offaly
<option value="25">Roscommon
<option value="26">Sligo
<option value="27">Tipperary
<option value="28">Tyrone
<option value="29">Waterford
<option value="30">Westmeath
<option value="31">Wexford
<option value="32">Wicklow
</select>
<div id="countyError" class="fixed">
Please select your county!</div>
</div>
</div>
<div class="gender">
<label>Gender<span class="red">*</span></label>
<input type="radio" name="gender" id="male" value="m">Male
<input type="radio" name="gender" id="female" value="f" >Female
<div id="genderError" class="fixed">
Please select your gender! </div>
</div>
<div class="preferences">
<label>Preferences<span class="red">*</span></label>
<input type="checkbox" name="color" id="red" value="r">Red
<input type="checkbox" name="color" id="green" value="g">Green
<input type="checkbox" name="color" id="blue" value="b">Blue
<div id="colorError" class="fixed">Please select a color! </div>
</div>
<div class="phone">
<label for="phone">Phone<span class="red">*</span></label>
<input type="text" id="phone" name="phone" placeholder="Eg. 0871234567">
<div id="phoneError" class="fixed">
Please enter a valid phone number with 10 digits in length! </div>
</div>
<div class="email">
<label for="email">Email<span class="red">*</span></label>
<input type="text" id="email" name="email" placeholder="example#domain.com">
<div id="emailError" class="fixed">
Please enter a valid email in the format "johndoe#domain.com"! </div>
</div>
<div class="password1">
<label for="password1">Password (6-8 characters)<span class="red">*</span></label>
<input type="password" id="password1" name="password1">
<div id="password1Error" class="fixed">
Please enter a valid password containing at least one uppercase letter and one number!</div>
</div>
<div class="password2">
<label for="password2">Verify password<span class="red">*</span></label>
<input type="password" id="password2" name="password2">
<div id="password2Error" class="fixed">
Passwords do not match, please re-enter! </div>
</div>
<div>
<label>
<input type="submit" value="SEND" id="submit">
</label>
</div>
<div>
<label>
<input type="reset" value="CLEAR" id="reset">
</label>
</div>
<!-- </table> -->
</form>
</body>
</html>
</form>
</body>
</html>
I'm newish to javascript css and HTML. I have to create a form that changes the input borders to red and display an error message when the wrong data is entered.
I have to use javascript for the validation as part of project so I can't use HTML5 'required'. When I run my program none of the errors show and when i click the submit button it clears all the fields.
I tried it in JSFiddle and got the following error which I don't understand
{"error": "Shell form does not validate{'html_initial_name': u'initial-js_lib', 'form': , 'html_name': 'js_lib', 'html_initial_id': u'initial-id_js_lib', 'label': u'Js lib', 'field': , 'help_text': '', 'name': 'js_lib'}{'html_initial_name': u'initial-js_wrap', 'form': , 'html_name': 'js_wrap', 'html_initial_id': u'initial-id_js_wrap', 'label': u'Js wrap', 'field': , 'help_text': '', 'name': 'js_wrap'}"}
I have tried and tried but I can't get this to work.
Any help would be greatly appreciated.
=====================================================================================
valid.css
.red {
color: red;
}
.input.error { /* for the error input text fields */
border: 1px red inset;
padding: 2px;
}
.error {
visibility: visible;
color: red;
display: inline-block;
}
/*
table {
border: 0;
}
td {
margin: 0;
padding: 3px 10px 3px 3px;
}
*/
label
{
display: inline-block;
width: 170px;
margin-top:10px;
margin-bottom:10px;
}
.colorLabel {
border: thin solid red;
}
.unColorLabel {
border: thin solid #3FE916;
}
.fixed {
visibility: hidden;
display: inline-block;
}
.required_fields {
color: red;
}
======================================================================================
formValid.js
function validateForm()
{
var name = document.getElementById("name");
if(name.length < 5 || !name.match(/[A-Za-z ]$/))
{
document.getElementById("name").className = "colorLabel";
document.getElementById("nameError").className = "error";
}
else
{
document.getElementById("name").className = "unColorLabel";
document.getElementById("nameError").className = "fixed";
}
var address1 = document.getElementById("address1");
if(address1.length === 0 || !address1.match(/[A-Za-z ]$/))
{
document.getElementById("address1").className = "colorLabel";
document.getElementById("address1Error").className = "error";
}
else
{
document.getElementById("address1").className = "unColorLabel";
document.getElementById("address1Error").className = "fixed";
}
// Return true if correct element is selected
var county= document.getElementById("county");
if(county == "-1")
{
document.getElementById("county").className = "colorLabel";
document.getElementById("countyError").className = "error";
}
else
{
document.getElementById("county").className = "unColorLabel";
document.getElementById("countyError").className = "fixed";
}
// Return true if the one of the radio buttons is checked
var gender = document.getElementsByName("gender");
var isChecked = false;
for (var i = 0; i < gender.length; i++)
{
if (gender[i].checked)
{
isChecked = true; // found one element checked
document.getElementById("genderError").className = "fixed";
break;
}
else
{
document.getElementById("genderError").className = "error";
}
}
var color = document.getElementsByName("color");
var isChecked2 = false;
for (var j = 0; j < color.length; j++)
{
if (color[j].checked)
{
isChecked2 = true; // found one element checked
document.getElementById("colorError").className = "fixed";
break;
}
else
{
document.getElementById("colorError").className = "error";
}
}
var phone = document.getElementById("phone");
if(inputValue.length != 10 || (inputValue.search(/^[0-9]+$/) == -1))
{
document.getElementById("phone").className = "colorLabel";
document.getElementById("phoneError").className = "error";
}
else
{
document.getElementById("phone").className = "unColorLabel";
document.getElementById("phoneError").className = "fixed";
}
var email = document.getElementById("email");
var atPos = email.indexOf("#");
var dotPos = email.lastIndexOf(".");
if((atPos < 1) && (dotPos < atPos + 1) && (inputValue.length < dotPos + 2))
{
document.getElementById("email").className = "colorLabel";
document.getElementById("emailError").className = "error";
}
else
{
document.getElementById("email").className = "unColorLabel";
document.getElementById("emailError").className = "fixed";
}
var password1 = document.getElementById("password1");
var allowed = /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{6,8}$/;
var inputValue = password1.value.trim();
if(!(inputValue.value.match(allowed)))
{
document.getElementById("password1").className = "colorLabel";
document.getElementById("password1Error").className = "error";
}
else
{
document.getElementById("password1").className = "unColorLabel";
document.getElementById("password1Error").className = "fixed";
}
var password2 = document.getElementById("password2");
if(password1.value != password2.value)
{
document.getElementById("password2").className = "colorLabel";
document.getElementById("password2Error").className = "error";
}
else
{
document.getElementById("password2").className = "unColorLabel";
document.getElementById("password2Error").className = "fixed";
}
}
enter code here

Related

Can't type in HTML form text/password/number input field (website with Unity WebGL build)

We are developing a site using Angular 9.
We have also integrated a Unity3D WebGL build in it.
When I try to type something in a text/password/number input field inside one of my forms, it doesn't write anything and the field doesn't seem to receive the input; also, the variable I bound the field to is not updated with the new value.
What makes it weirder is that:
I can select the input field (it gets highlighted as if I can start typing)
I can do CTRL+C on the field and what I copied somewhere else is pasted, as expected
I can use the type="number" arrow selectors to set the value of the field
I cannot type from the keyboard in the fields
I can interact as expected with other form tags, such as <select>
If I reload the page, it usually starts working as expected and I can type into the fields
Here is the code from my login form (component.ts above, template HTML below)
import { Component, OnInit } from '#angular/core';
import { AuthService } from '../auth.service'
import { first } from 'rxjs/operators';
import { Router, ActivatedRoute } from '#angular/router';
#Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit {
email: string = "";
password: string = "";
returnUrl: string = "home";
constructor(private router: Router, private route: ActivatedRoute, private authService: AuthService) { }
ngOnInit(): void {
let tmpReturnUrl = this.route.snapshot.queryParams["returnUrl"];
if (tmpReturnUrl != undefined)
{
console.log("true");
this.returnUrl = tmpReturnUrl;
}
else
console.log("false");
setInterval(() => {
console.log("EMAIL: " + this.email);
}, 1000);
}
onSubmit(){
this.authService.login(this.email, this.password)
.pipe(first())
.subscribe(
result => {
console.log("CAIOAOAOAOOA");
this.router.navigate([this.returnUrl]);
},
err => console.log(err)
);
}
}
<div class="card z-depth-5 w-50">
<div class="card-body">
<div class="card-title">Log in</div>
<div class="card-text">
<form #companyLoginForm="ngForm" (ngSubmit)="onSubmit()">
<mat-form-field>
<mat-label>Email: </mat-label>
<input matInput required type="text" name="email" id="email" [(ngModel)]="email">
</mat-form-field>
<mat-form-field>
<mat-label>Password: </mat-label>
<input matInput required type="password" name="password" id="password" [(ngModel)]="password">
</mat-form-field>
<button type="submit" [disabled]="!companyLoginForm.form.valid">Login</button>
</form>
<a routerLink="/company-register">
<button mdbBtn type="button" color="primary" class="relative waves-light">Sign Up</button>
</a>
</div>
</div>
</div>
And here, the code from another form where I also use type="number" and <select> (component.ts above, template HTML below)
import { Component, OnInit, Output } from '#angular/core';
import { BlockFormService } from '../block-form.service';
import { BlockData } from '../blockCardData';
import { BlockUtilsService } from '../block-utils.service';
import { ApiService } from '../../core/api.service'
import { NgForm } from '#angular/forms';
#Component({
selector: 'app-block-form',
templateUrl: './block-form.component.html',
styleUrls: ['./block-form.component.less']
})
export class BlockFormComponent implements OnInit {
updateComplete : Boolean = false;
materials : string[];
products : string[];
varieties : string[];
nations : string[];
// companies : {name: string, id: string}[] = [];
company : string = "";
colors : string[] = ["White", "Grey", "Black", "Brown", "Red", "Green", "Yellow", "Blue"];
blockData : BlockData = {_id : "", blockId: "", company: "", material: "", product: "",
variety: "", color: "", nation: "", modelName : "", imagePreview : "",
price: null, blockNumber: "",
length: null, height: null, width: null,
weight: null
};
imagePreview: File = null;
zipFile: File = null;
invalidUpload: boolean = false;
constructor( private blockFormService: BlockFormService, public blockUtils: BlockUtilsService, private companiesUtils: ApiService )
{ }
ngOnInit(): void {
this.materials = this.blockUtils.getMaterials();
this.colors = this.blockUtils.getColors();
this.companiesUtils.getLoggedCompany().subscribe(companiesResult => {
this.blockData.company = companiesResult._id;
this.company = companiesResult.name;
});
}
onImageSelected(event){
console.log(event.target.files[0]);
if (event.target.files[0].type === "image/png")
{
if (this.invalidUpload)
this.invalidUpload = false;
this.imagePreview = event.target.files[0];
}
else{
if (!this.invalidUpload)
this.invalidUpload = true;
event.target.value = null;
}
}
onMaterialSet(newMaterial): void{
console.log("Material set");
this.products = this.blockUtils.getProducts(newMaterial);
//console.log(this.products);
// if (this.products.length > 0)
// this.blockData.product = this.products[0];
// else
this.blockData.product = "";
this.onProductSet(this.blockData.product);
}
onProductSet(newProduct): void{
console.log("Product set");
this.varieties = this.blockUtils.getVarieties(this.blockData.material, newProduct);
// if (this.varieties.length > 0)
// this.blockData.variety = this.varieties[0];
// else
this.blockData.variety = "";
this.nations = this.blockUtils.getNations(this.blockData.material, this.blockData.product);
if (this.nations.length > 0)
this.blockData.nation = this.nations[0];
else
this.blockData.nation = "";
this.onVarietySet(this.blockData.variety);
}
onVarietySet(newVariety): void{
console.log("Variety set");
// this.nations = this.blockUtils.getNations(this.blockData.material, this.blockData.product);
// if (this.nations.length > 0)
// this.blockData.nation = this.nations[0];
// else
// this.blockData.nation = "";
}
onSubmit(blockForm : NgForm, imageField, zipField): void{
this.blockFormService.sendBlock(this.blockData, this.imagePreview, this.zipFile)
.subscribe(res => {
console.log("Sent!");
this.updateComplete = true;
});
this.blockData = {
_id: "", blockId: "", company: "", material: "", product: "",
variety: "", color: "", nation: "", modelName: "", imagePreview: "",
price: null, blockNumber: "",
length: null, height: null, width: null,
weight: null
};
blockForm.resetForm();
imageField.value = null;
zipField.value = null;
this.imagePreview = null;
this.zipFile = null;
}
}
<div class="form-group">
<div class="text-center" *ngIf='updateComplete'>
Block added successfuly
</div>
<form #blockForm="ngForm" (ngSubmit)="onSubmit(blockForm, imageField, zipField)">
<div class="container">
<div class="row">
<div class="col-3">
<mat-form-field>
<mat-label>Company: </mat-label>
<!-- <mat-select required [(ngModel)]="blockData.company" name="company-field"
id="company-field">
<mat-option selected [value]="company.id">{{company.name}}</mat-option>
</mat-select> -->
<input matInput disabled [value]="company" type="text" name="company-field" id="company-field">
</mat-form-field>
</div>
<div class="col-3">
<mat-form-field>
<mat-label>Material: </mat-label>
<mat-select #matField required [(ngModel)]="blockData.material" name="kind-field"
id="kind-field" (selectionChange)="onMaterialSet(blockData.material)">
<mat-option *ngFor="let mat of materials" [value]="mat">{{mat}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-3">
<mat-form-field>
<mat-label>Product: </mat-label>
<mat-select required [(ngModel)]="blockData.product" name="product-field"
id="product-field" (selectionChange)="onProductSet(blockData.product)">
<mat-option *ngFor="let prod of products" [value]="prod">{{prod}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-3">
<mat-form-field>
<mat-label>Block Number: </mat-label>
<input matInput required [(ngModel)]="blockData.blockNumber" type="text" name="blockNumber-field" id="blockNumber-field">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-3">
<mat-form-field>
<mat-label>Variety: </mat-label>
<mat-select required [(ngModel)]="blockData.variety" name="variety-field" id="variety-field"
placeholder="Variety" (selectionChange)="onVarietySet(blockData.variety)">
<mat-option *ngFor="let variety of varieties" [value]="variety">{{variety}}</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="col-3">
<!-- <label for="color-field">Color: </label> -->
<mat-form-field>
<mat-label>Color: </mat-label>
<mat-select required [(ngModel)]="blockData.color" name="color-field" id="color-field" placeholder="Color">
<mat-option *ngFor="let col of colors" [value]="col">{{col}}</mat-option>
</mat-select>
</mat-form-field>
<!-- <input #colField required [(ngModel)]="blockData.color" type="text" name="color-field" id="color-field" placeholder="Color"> -->
<!-- <color-circle #colorField [colors]='["#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#03a9f4", "#00bcd4", "#009688", "#4caf50", "#8bc34a", "#cddc39", "#ffeb3b", "#ffc107", "#ff9800", "#ff5722", "#795548", "#607d8b"]' name="color-field" id="color-field" (onChange)="blockData.color = $event.color.hex"></color-circle> -->
</div>
<div class="col-3">
<mat-form-field>
<mat-label>Nation: </mat-label>
<!-- <mat-select required [(ngModel)]="blockData.nation" name="nation-field"
id="nation-field">
<mat-option *ngFor="let nat of nations" [value]="nat">{{nat}}</mat-option>
</mat-select> -->
<input matInput disabled [(ngModel)]="blockData.nation" type="text" name="nation-field" id="nation-field">
</mat-form-field>
</div>
<div class="col-3">
<mat-form-field>
<mat-label>Price: </mat-label>
<input matInput required [(ngModel)]="blockData.price" type="number" name="price-field" id="price-field">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-3">
<mat-form-field>
<mat-label>Length: </mat-label>
<input matInput required [(ngModel)]="blockData.length" type="number" name="length-field" id="length-field">
</mat-form-field>
</div>
<div class="col-3">
<mat-form-field>
<mat-label>Width: </mat-label>
<input matInput required [(ngModel)]="blockData.width" type="number" name="width-field" id="width-field">
</mat-form-field>
</div>
<div class="col-3">
<mat-form-field>
<mat-label>Height: </mat-label>
<input matInput required [(ngModel)]="blockData.height" type="number" name="height-field" id="height-field">
</mat-form-field>
</div>
<div class="col-3">
<mat-form-field>
<mat-label>Weight: </mat-label>
<input matInput required [(ngModel)]="blockData.weight" type="number" name="weight-field" id="weight-field">
</mat-form-field>
</div>
</div>
<div class="row">
<div class="col-3">
<div class="file-field">
<div class="btn btn-primary btn-sm float-left">
<label for="image-field">Upload preview image: </label>
<input #imageField (change)="onImageSelected($event)" name="image-field" id="image-field" type="file" accept=".png, image/png" placeholder="Upload your file">
</div>
</div>
</div>
<div class="col-3">
<div class="file-field">
<div class="btn btn-primary btn-sm float-left">
<label for="zip-field">Upload models' zip: </label>
<input #zipField (change)="zipFile = $event.target.files[0];" name="zip-field" id="zip-field" type="file" placeholder="Upload your file">
</div>
</div>
</div>
</div>
<button type="submit" [disabled]="!blockForm.form.valid || imagePreview == null || zipFile == null || blockData.company === ''">Submit</button>
</div>
</form>
</div>
I hope I was clear enough, any help is appreciated :)
Finally I found the source of the problem. In our website we have integrated a Unity3D WebGL build and, if I moved from the web page with Unity to the login page, the Unity process was still running. Unity had the focus of every input of the keyboard, so it was catching all the inputs.
We resolved it by quitting the Unity application when we change page. This way, input fields can receive inputs from the keyboard again.
Another solution, maybe (I have not tested it), could be to not make Unity get the inputs, as discussed in this Unity forum's thread or by setting WebGLInput.captureAllKeyboardInput to false.

Form reset issue after get response via API in react js

I am submitting form via redux API call and getting response but on success response I am trying to reset form but that giving issue -
setState(...): Cannot update during an existing state transition (such as withinrenderor another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to 'componentWillMount'.
here is my from file -
=========================
import React from 'react';
import DefaultLayout from '../Layout/DefaultLayout';
//import $ from 'jquery';
import { connect } from 'react-redux';
import { contactRequest } from '../actions/signupActions';
import { bindActionCreators } from 'redux';
import validator from 'validator';
class Contactus extends React.Component {
constructor(props){
super(props);
document.title = "Contact Us";
this.errorMapping = {"100": "Your message has been submitted.",
"102": "Name cannot be empty.",
"104": "Email cannot be empty.",
"103": "Hotel cannot be empty.",
"105": "Incorrect email format.",
"106": "Phone cannot be empty."}
this.state = {name: '',email:'',message :''};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.baseState = this.state
}
handleInputChange(event) {
this.setState({ [event.target.name]: event.target.value});
}
handleSubmit(event) {
event.preventDefault();
this.props.contactRequest(this.state);
}
render(){
const style_1 = {height: '240px'};
const style_2 = {marginRight: '15px'};
const style_3 = {width: 'auto'};
return(
<DefaultLayout>
<section id="content">
<div className="content-wrap">
<div className="container clearfix">
<div className="col-md-6 bottommargin">
<section id="google-map" className="gmap" style={style_1} ></section>
</div>
<div className="col-md-6">
Click here to Send an Email
Send an Email
<div className="modal fade" id="contactFormModal" tabIndex="-1" role="dialog" aria-labelledby="contactFormModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-body">
<div className="contact-widget">
<div className="contact-form-result">
{this.props.resultMessage && this.props.resultMessage.status.map((msg, idx) => {
if(msg === 100) {
this.setState({name : "",email : ""});
return <span key={idx} id="succ_msg">{this.errorMapping[msg]}</span>
} else {
return <span key={idx} id="err_msg">{this.errorMapping[msg]}</span>
}
})
}
</div>
<form className="nobottommargin" id="r_contactform" name="r_contactform" method="post" onSubmit={this.handleSubmit} ref={(el) => this.myFormRef = el} >
<div className="form-process"></div>
<div className="col_half">
<label htmlFor="template-contactform-name">Name <small>*</small></label>
<input type="text" id="template-contactform-name" name="name" value={this.state.name} className="sm-form-control required" onChange={this.handleInputChange} />
</div>
<div className="col_half col_last">
<label htmlFor="template-contactform-email">Email <small>*</small></label>
<input type="email" id="template-contactform-email" name="email" value={this.state.email} className="required email sm-form-control" onChange={this.handleInputChange} />
</div>
<div className="clear"></div>
<div className="clear"></div>
<div className="col_half">
<label htmlFor="template-contactform-message">Message <small>*</small></label>
<textarea className="required sm-form-control" id="template-contactform-message" name="message" value={this.state.message} rows="6" cols="30" onChange={this.handleInputChange}></textarea>
<span className={this.state.messageError ? 'help-block error': '' }>{ this.state.messageError ? this.state.messageError: '' }</span>
</div>
<div className="col_full">
<button className="button button-3d nomargin" type="submit" id="contactform-submit" name="contactform-submit">Send Message</button>
</div>
</form>
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</DefaultLayout>
);
}
}
function mapStateToProps(state){
console.log("View data :"+JSON.stringify(state.Contactdata));
return {
resultMessage: state.Contactdata
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({contactRequest: contactRequest}, dispatch)
}
export default connect(mapStateToProps, mapDispatchToProps) (Contactus);
getting response in mapStateToProps function and trying to update state where I have applied condition if(msg === 100) .
Please let me know where I am doing wrong.
thanks
The right place to setState is not in the map function, since you are receiving props from redux, you can do it in the componentWillReceiveProps fucntion
class Contactus extends React.Component {
constructor(props){
super(props);
document.title = "Contact Us";
this.errorMapping = {"100": "Your message has been submitted.",
"102": "Name cannot be empty.",
"104": "Email cannot be empty.",
"103": "Hotel cannot be empty.",
"105": "Incorrect email format.",
"106": "Phone cannot be empty."}
this.state = {name: '',email:'',message :''};
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.baseState = this.state
}
componentWillReceiveProps(nextProps) {
nextProps.resultMessage.status.forEach((msg, idx) => {
if(msg === 100) {
this.setState({name : "",email : ""});
}
}
}
handleInputChange(event) {
this.setState({ [event.target.name]: event.target.value});
}
handleSubmit(event) {
event.preventDefault();
this.props.contactRequest(this.state);
}
render(){
const style_1 = {height: '240px'};
const style_2 = {marginRight: '15px'};
const style_3 = {width: 'auto'};
return(
<DefaultLayout>
<section id="content">
<div className="content-wrap">
<div className="container clearfix">
<div className="col-md-6 bottommargin">
<section id="google-map" className="gmap" style={style_1} ></section>
</div>
<div className="col-md-6">
Click here to Send an Email
Send an Email
<div className="modal fade" id="contactFormModal" tabIndex="-1" role="dialog" aria-labelledby="contactFormModalLabel" aria-hidden="true">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-body">
<div className="contact-widget">
<div className="contact-form-result">
{this.props.resultMessage && this.props.resultMessage.status.map((msg, idx) => {
if(msg === 100) {
return <span key={idx} id="succ_msg">{this.errorMapping[msg]}</span>
} else {
return <span key={idx} id="err_msg">{this.errorMapping[msg]}</span>
}
})
}
</div>
<form className="nobottommargin" id="r_contactform" name="r_contactform" method="post" onSubmit={this.handleSubmit} ref={(el) => this.myFormRef = el} >
<div className="form-process"></div>
<div className="col_half">
<label htmlFor="template-contactform-name">Name <small>*</small></label>
<input type="text" id="template-contactform-name" name="name" value={this.state.name} className="sm-form-control required" onChange={this.handleInputChange} />
</div>
<div className="col_half col_last">
<label htmlFor="template-contactform-email">Email <small>*</small></label>
<input type="email" id="template-contactform-email" name="email" value={this.state.email} className="required email sm-form-control" onChange={this.handleInputChange} />
</div>
<div className="clear"></div>
<div className="clear"></div>
<div className="col_half">
<label htmlFor="template-contactform-message">Message <small>*</small></label>
<textarea className="required sm-form-control" id="template-contactform-message" name="message" value={this.state.message} rows="6" cols="30" onChange={this.handleInputChange}></textarea>
<span className={this.state.messageError ? 'help-block error': '' }>{ this.state.messageError ? this.state.messageError: '' }</span>
</div>
<div className="col_full">
<button className="button button-3d nomargin" type="submit" id="contactform-submit" name="contactform-submit">Send Message</button>
</div>
</form>
</div>
</div>
<div className="modal-footer">
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
</DefaultLayout>
);
}
}
This is the reason, you are doing setState inside render method:
{this.props.resultMessage && this.props.resultMessage.status.map((msg, idx) => {
if(msg === 100) {
this.setState({name : "",email : ""});
.....
When msg==100 will be true, you are doing setState, again it will trigger re-rendering, again setState ....... infinite loop.
Remove that setState it will work.
Use componentWillReceiveProps lifecycle method, and do the setState inside that.
componentWillReceiveProps(newProps) {
newProps.resultMessage.status.forEach((msg, idx) => {
if(msg === 100) {
this.setState({
name : "",
email : ""
});
}
}
}

angular2 formArray conditional validation

I'm trying to impose validation based on a change of one field onto another field inside a formGroup which is inside a FormArray of multiple instances of this group. I'm using mydatepicker on one of the fields. For example, when the date is changed, I then want the Reason for change field in that group only to be validated to check to make sure the first option (value of 0) is not selected. I have 2 problems with this:
When I change the date, the Reason for change field does not get checked for validity right away. It only happens AFTER I change the value of the field to 1 and then to 0. It's default is set to 0 and it should immediately pick this up when I change the date.
When it does finally realize the form is invalid, it does it for ALL the update buttons rather than just the one in the FormGroup whose Date field I have changed.
ts file code:
subscribeDateChange(formGroup){
(<any>this.rfcActionTasksForm).controls.tasks.controls[0].controls['DueDate'];
const tasks = formGroup;
const changes$ = tasks.controls['DueDate'].valueChanges;
changes$.subscribe(dd => {
var arrayControl = this.rfcActionTasksForm.get('tasks') as FormArray;
var item = arrayControl.at(1);
console.log(item);
if(tasks.value['ReasonForChangeId'] == '0'){
tasks.controls['ReasonForChangeId'].setValidators(Validators.pattern(/([1-9])/));
}
});
}
ngOnInit() {
this.rfcActionTasksForm = this._fb.group({
tasks: this._fb.array([this.buildTask()])
});
}
buildTask(): FormGroup {
return this._fb.group({
Id: '',
Action: ['', Validators.required],
Step: '',
AssignedToId: ['', Validators.required],
AssignedToColour: '',
DueDate: ['', Validators.required],
ReasonForChangeId: '',
OriginalDueDate: '',
Completed: '',
OverDue: ''
},{
validator: (formGroup: FormGroup) => {
//return this.validateDays(formGroup);
//console.log(formGroup.controls['DueDate']);
//this.subscribeDateChange(formGroup.controls['DueDate'], formGroup.controls['ReasonForChangeId']);
return this.subscribeDateChange(formGroup);
}
});
}
html:
<form class="multi-col implementation" *ngIf="rfc.Plan [formGroup]="rfcActionTasksForm">
<div class="task-item" formArrayName="tasks" *ngFor="let task of tasks.controls; let i = index">
<div [formGroupName]="i">
<div class="row header-row">
<div class="col-md-12">
<h5 class="no-margin">Step {{i + 1}}</h5>
<input
[style.display]="'none'"
formControlName="Step">
<input
[style.display]="'none'"
formControlName="AssignedToColour">
<input
[style.display]="'none'"
formControlName="Id">
</div>
</div>
<div class="input-row row">
<div class="col-md-11">
<label for="{{'task' + i}}">Action:</label>
<div
[ngClass]="{'has-error': (tasks.get(i + '.Action').touched || tasks.get(i + '.Action').dirty) && !tasks.get(i + '.Action').valid }">
<textarea
rows="6"
id="{{'task' + i}}"
formControlName="Action"></textarea>
<span class="help-block" *ngIf="(tasks.get(i + '.Action').touched || tasks.get(i + '.Action').dirty) && tasks.get(i + '.Action').errors">
<span *ngIf="tasks.get(i + '.Action').errors.required">
Please enter a title.
</span>
</span>
</div>
</div>
<div class="col-md-1 text-center">
<label>Status</label>
<i *ngIf="tasks.get(i + '.Completed').value" class="glyphicon glyphicon-ok-sign ok" title="Completed"></i>
<i *ngIf="!tasks.get(i + '.Completed').value && !tasks.get(i + '.OverDue').value" class="glyphicon glyphicon-minus-sign pending" title="In progress"></i>
<i *ngIf="!tasks.get(i + '.Completed').value && tasks.get(i + '.OverDue').value" class="glyphicon glyphicon-exclamation-sign text-danger" title="Overdue!"></i>
</div>
</div>
<div class="input-row row">
<div class="col-md-3 assigned-to">
<div
[ngClass]="{'has-error': (tasks.get(i + '.AssignedToId').touched || tasks.get(i + '.AssignedToId').dirty) && !tasks.get(i + '.AssignedToId').valid }">
<label for="{{'assignedTo' + i}}">Assigned to:</label>
<div class="color-block" [style.background]="tasks.get(i + '.AssignedToColour').value"></div>
<label class="fa select">
<select
*ngIf="users"
id="{{'assignedTo' + i}}"
formControlName="AssignedToId">
<option
*ngFor="let user of users | trueValueFilter: 'IsActive'"
[value]="user.Id">{{user.Name}}</option>
</select>
</label>
<span class="help-block" *ngIf="(tasks.get(i + '.AssignedToId').touched || tasks.get(i + '.AssignedToId').dirty) && tasks.get(i + '.AssignedToId').errors">
<span *ngIf="tasks.get(i + '.AssignedToId').errors.required">
Please select a user.
</span>
</span>
</div>
</div>
<div class="col-md-3">
<div
[ngClass]="{'has-error': (tasks.get(i + '.DueDate').touched || tasks.get(i + '.DueDate').dirty) && !tasks.get(i + '.DueDate').valid }">
<label for="{{'dueDate' + i}}">Due date:</label>
<my-date-picker
class="datepicker"
type="text"
id="{{'dueDate' + i}}"
formControlName="DueDate"
[options]="myDatePickerOptions"></my-date-picker>
<span class="help-block" *ngIf="(tasks.get(i + '.DueDate').touched || tasks.get(i + '.DueDate').dirty) && tasks.get(i + '.DueDate').errors">
<span *ngIf="tasks.get(i + '.DueDate').errors.required">
Please set a due date.
</span>
</span>
</div>
</div>
<div class="col-md-2">
<label for="{{'reason' + i}}">Reason for change:</label>
<label class="fa select">
<select
class="reason-select"
*ngIf="reasons"
id="{{'reason' + i}}"
formControlName="ReasonForChangeId">
<option
*ngFor="let reason of reasons"
[value]="reason.Id">{{reason.Reason}}</option>
</select>
</label>
</div>
<div class="col-md-3">
<div class="text-center">
<label for="{{'OriginalDueDate' + i}}">Original due date:</label>
<span>{{tasks.get(i + '.OriginalDueDate').value | dateToStringFilter}}</span>
<input
readonly
type="text"
id="{{'OriginalDueDate' + i}}"
[style.display]="'none'"
formControlName="OriginalDueDate">
</div>
</div>
<div class="col-md-1">
<div class="text-center">
<label for="{{'completed' + i}}">Completed:</label>
<div class="checkbox-group">
<input type="checkbox"
type="checkbox"
id="{{'completed' + i}}"
formControlName="Completed">
<label class="checkbox" for="{{'completed' + i}}"></label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div>
<button
class="glyphicon glyphicon-plus-sign btn-icon add"
title="Insert task after this one"
(click)="insertTaskField(i)"></button>
<button
class="glyphicon glyphicon-remove-sign btn-icon delete"
title="Delete this task"
(click)="removeTaskField(i, tasks.get(i + '.Id')?.value)"></button>
<button
*ngIf="!tasks.get(i + '.Id').value"
(click)="saveNewTask(rfc.Id, i);"
[disabled]="!rfcActionTasksForm.valid"
class="pull-right">Save new</button>
<button
*ngIf="tasks.get(i + '.Id')?.value"
[disabled]="!rfcActionTasksForm.valid"
(click)="updateTask(i, tasks.get(i + '.Id')?.value)"
class="pull-right">Update</button>
</div>
</div>
</div>
</div>
</div>
<div class="row last">
<div class="col-md-12">
<button
class="pull-right"
[disabled]="enableUpdateAll === false"
(click)="reOrderTasks()">Update All</button>
</div>
</div>
</form>
I see multiple problems here:
A validator should be of the form:
(control: AbstractControl): {[key: string]: any} => {
if(isValid(control))
return null;
else
return {"myValidator":"invalid thing detected"};
}
You are returning undefined everytime so it can't work.
You cannot subscribe because it means everytime you make a change in your form, you resubscribe to the whole group's valuechanges, that's non-sense.
Forget about valueChanges, you need to do your control synchronously. Check if there is an error and use the setError() method of your children controls.
something like :
(group: FromGroup): {[key: string]: any} => {
if(!isValid(group)){
group.get("myChildControl").setErrors({"localError":"error detected !"});
return {"groupError":"error detected !"};
}
return null;
}
I'm not sure if you should use the second parameter of setError(errors,{emitEvent:false}) to avoid propagation or not.

App won't display all items (Ionic, Backand)

I want to make an app which displays some items, so I found the backand template (https://market.ionic.io/starters/backand-simple) and used it. I have about 40 items in my database, but the app only displays the first 20 items.
my controller.js
angular.module('SimpleRESTIonic.controllers', [])
.controller('LoginCtrl', function (Backand, $state, $rootScope, LoginService) {
var login = this;
function signin() {
LoginService.signin(login.email, login.password)
.then(function () {
onLogin();
}, function (error) {
console.log(error)
})
}
function onLogin(){
$rootScope.$broadcast('authorized');
login.email = '';
login.password = '';
$state.go('tab.dashboard');
}
function signout() {
LoginService.signout()
.then(function () {
//$state.go('tab.login');
login.email = '';
login.password = '';
$rootScope.$broadcast('logout');
$state.go($state.current, {}, {reload: true});
})
}
login.signin = signin;
login.signout = signout;
})
.controller('DashboardCtrl', function (ItemsModel, $rootScope) {
var vm = this;
function goToBackand() {
window.location = 'http://docs.backand.com';
}
function getAll() {
ItemsModel.all()
.then(function (result) {
vm.data = result.data.data;
});
}
function clearData(){
vm.data = null;
}
function create(object) {
ItemsModel.create(object)
.then(function (result) {
cancelCreate();
getAll();
});
}
function update(object) {
ItemsModel.update(object.id, object)
.then(function (result) {
cancelEditing();
getAll();
});
}
function deleteObject(id) {
ItemsModel.delete(id)
.then(function (result) {
cancelEditing();
getAll();
});
}
function initCreateForm() {
vm.newObject = {name: '', description: ''};
}
function setEdited(object) {
vm.edited = angular.copy(object);
vm.isEditing = true;
}
function isCurrent(id) {
return vm.edited !== null && vm.edited.id === id;
}
function cancelEditing() {
vm.edited = null;
vm.isEditing = false;
}
function cancelCreate() {
initCreateForm();
vm.isCreating = false;
}
vm.objects = [];
vm.edited = null;
vm.isEditing = false;
vm.isCreating = false;
vm.getAll = getAll;
vm.create = create;
vm.update = update;
vm.delete = deleteObject;
vm.setEdited = setEdited;
vm.isCurrent = isCurrent;
vm.cancelEditing = cancelEditing;
vm.cancelCreate = cancelCreate;
vm.goToBackand = goToBackand;
vm.isAuthorized = false;
$rootScope.$on('authorized', function () {
vm.isAuthorized = true;
getAll();
});
$rootScope.$on('logout', function () {
clearData();
});
if(!vm.isAuthorized){
$rootScope.$broadcast('logout');
}
initCreateForm();
getAll();
});
my services.js
angular.module('SimpleRESTIonic.services', [])
.service('APIInterceptor', function ($rootScope, $q) {
var service = this;
service.responseError = function (response) {
if (response.status === 401) {
$rootScope.$broadcast('unauthorized');
}
return $q.reject(response);
};
})
.service('ItemsModel', function ($http, Backand) {
var service = this,
baseUrl = '/1/objects/',
objectName = 'items/';
function getUrl() {
return Backand.getApiUrl() + baseUrl + objectName;
}
function getUrlForId(id) {
return getUrl() + id;
}
service.all = function () {
return $http.get(getUrl());
};
service.fetch = function (id) {
return $http.get(getUrlForId(id));
};
service.create = function (object) {
return $http.post(getUrl(), object);
};
service.update = function (id, object) {
return $http.put(getUrlForId(id), object);
};
service.delete = function (id) {
return $http.delete(getUrlForId(id));
};
})
.service('LoginService', function (Backand) {
var service = this;
service.signin = function (email, password, appName) {
//call Backand for sign in
return Backand.signin(email, password);
};
service.anonymousLogin= function(){
// don't have to do anything here,
// because we set app token att app.js
}
service.signout = function () {
return Backand.signout();
};
});
my dashboard-tab //which displays the items
<ion-view view-title="Produkte">
<div ng-if="!vm.isCreating && !vm.isEditing">
<ion-content class="padding has-header">
<!-- LIST -->
<div class="bar bar-header bar-balanced">
<span ng-click="vm.isCreating = true"><i class='icon ion-plus-round new-item'> Erstellen</i></span>
</div>
<div class="bar bar-subheader">
<div class="list card" ng-repeat="object in vm.data"
ng-class="{'active':vm.isCurrent(object.id)}">
<div class="item item-icon-right item-icon-left">
<i class="ion-compose icon" ng-click="vm.setEdited(object)"></i>
<h2 class="text-center"><b>{{object.name}}</b></h2>
<i class="icon ion-close-round" ng-click="vm.delete(object.id)"></i>
</div>
<div class="text-center">
{{object.description}}
</div>
<div class="item item-body">
<p style="text-align:center;"><img src="{{object.imgurl}}" style="max-width: 250px; max-height: 250px" /></p>
</div>
<div class="text-center">
{{object.price}} Euro
</div>
</div>
</div>
</ion-content>
</div>
<div ng-if="vm.isCreating">
<ion-content class="padding has-header">
<!-- Erstellen -->
<div class="bar bar-header">
<h2 class="title">Erstelle ein Produkt</h2>
<span ng-click="vm.cancelCreate()" class="cancel-create">Abbruch</span>
</div>
<div class="bar bar-subheader">
<form class="create-form" role="form"
ng-submit="vm.create(vm.newObject)" novalidate>
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">Name</span>
<input type="text" class="form-control"
ng-model="vm.newObject.name"
placeholder="Gib einen Namen ein">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Beschreibung</span>
<textarea placeholder="Beschreibung" class="form-control"
ng-model="vm.newObject.description"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Preis</span>
<textarea placeholder="Preis" class="form-control"
ng-model="vm.newObject.price"
typeof="float"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Bild</span>
<input type="text" class="form-control"
ng-model="vm.newObject.imgurl"
placeholder="Gib einen Bildlink ein">
</label>
</div>
<button class="button button-block button-balanced" type="submit">Fertig</button>
</form>
</div>
</ion-content>
</div>
<div ng-if="vm.isEditing && !vm.isCreating">
<ion-content class="padding has-header">
<!-- Bearbeiten -->
<div class="bar bar-header bar-secondary">
<h1 class="title">Bearbeiten</h1>
<span ng-click="vm.cancelEditing()" class="cancel-create">Abbrechen</span>
</div>
<div class="bar bar-subheader">
<form class="edit-form" role="form"
ng-submit="vm.update(vm.edited)" novalidate>
<div class="list">
<label class="item item-input item-stacked-label">
<span class="input-label">Name</span>
<input type="text" class="form-control"
ng-model="vm.edited.name"
placeholder="Gib einen Namen ein">
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Beschreibung</span>
<textarea class="form-control"
ng-model="vm.edited.description"
placeholder="Beschreibung"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Preis</span>
<textarea placeholder="Preis" class="form-control"
ng-model="vm.edited.price"
type="float"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Bild</span>
<textarea class="form-control"
ng-model="vm.edited.imgurl"
placeholder="Bildlink"></textarea>
</label>
<label class="item item-input item-stacked-label">
<span class="input-label">Auswählen</span>
<textarea class="form-control"
ng-model="vm.edited.check"
placeholder="true" type="boolean"></textarea>
</label>
</div>
<button class="button button-block button-balanced" type="submit">Speichern</button>
</form>
</div>
</ion-content>
</div>
thanks for using Backand! There is a default page size filter that you can modify in your getList() call. It is available in our new SDK - if you update to the latest version of the starter project you downloaded, it should already have the appropriate changes built-in. For reference, our new SDK can be found at https://github.com/backand/vanilla-sdk
Regarding resolving your issue, in order to adjust the page size, you can pass in an additional parameter to the getList function that dynamically changes the number of records you can retrieve. Here's some sample code that matches your use case:
service.all = function () {
params = { pageSize: 100 }; // Changes page size to 100
return Backand.object.getList('items', params);
};
Using the old SDK, you can do something similar by appending the parameters query param to the URL you use to drive your GET request.

PHP mail function has stopped working

I have created a contact form that sends an email to the website administrator and to the person who filled out the contact form. It was working fine and I have just come back to it to do some more testing and it has stopped sending. To my knowledge I've not changed any of the code. I can't figure out what is wrong with it. Can someone help? Below is the code for the three files I'm using.
This is the contact form file:
<div id="contact-form" class="contact-form">
<div class="rounded-box">
<div class="rounded-box-title">
<h3>Ask for a call back</h3>
<img src="<?php echo get_bloginfo('url') ?>/images-default/br_next.png"/>
</div><!-- .rounded-box-title -->
<?php
$cf = array();
if(isset($_SESSION['cf_returndata'])){
$cf = $_SESSION['cf_returndata'];
?>
<div id="success" class="success"><?php echo ($cf['success']); ?></div>
<script>
$("#success").delay(6000).slideUp();
</script>
<?php
}
?>
<div class="required-text-line">
<span class="required">*</span><span class="required-text">indicates required field</span>
</div>
<form name="contact-form" onsubmit="return validateForm()" action="<?php bloginfo('url'); ?>/wp-content/themes/example/contact-form-send.php" method="POST">
<fieldset>
<label for="fname"><span class="required">*</span>First name:</label></br>
<input type="text" name="fname" id="fname" onblur="return validateFirstName()" value="" />
<span class="error" id="fnameError" style="display: none;"></span>
<script>
$("#fname").blur(function(){
$("#fnameError").delay(6000).slideUp();
})
</script>
</fieldset>
<fieldset>
<label for="lname"><span class="required">*</span>Last name:</label></br>
<input type="text" name="lname" id="lname" onblur="return validateLastName()" value="" />
<span class="error" id="lnameError" style="display: none;"></span>
<script>
$("#lname").blur(function(){
$("#lnameError").delay(6000).slideUp();
})
</script>
</fieldset>
<fieldset>
<label for="email"><span class="required">*</span>Email:</label></br>
<input type="text" name="email" id="email" onblur="return validateEmail()" value="" />
<span class="error" id="emailError" style="display: none;"></span>
<script>
$("#email").blur(function(){
$("#emailError").delay(6000).slideUp();
})
</script>
</fieldset>
<fieldset>
<label for="tel"><span class="required">*</span>Telephone:</label></br>
<input type="text" name="tel" id="tel" onblur="return validateTel()" value="" />
<span class="error" id="telError" style="display: none;"></span>
<script>
$("#tel").blur(function(){
$("#telError").delay(6000).slideUp();
})
</script>
</fieldset>
<fieldset>
<label for="message"><span class="required">*</span>Message:</label></br>
<textarea name="message" id="message" onblur="return validateMessage()" ></textarea>
<span class="error" id="messageError" style="display: none;"></span>
<script>
$("#message").blur(function(){
$("#messageError").delay(6000).slideUp();
})
</script>
</fieldset>
<fieldset id="hiddenfield">
<label for="hidden"></label>
<textarea name="hidden" id="hidden" ></textarea>
</fieldset>
<input type="submit" value="Submit" id="submit" />
<script>
$("form").submit(function(){
$(".error").delay(6000).slideUp();
})
</script>
</form>
<?php unset($_SESSION['cf_returndata']); ?>
</div><!-- .rounded-box -->
</div><!-- .contact-form -->
This is the send PHP file:
<?php
if( isset($_POST) ){
if (empty($_POST ['hidden'])) {
$fname = htmlspecialchars($_POST ['fname']);
$lname = htmlspecialchars($_POST ['lname']);
$email = htmlspecialchars($_POST ['email']);
$tel = htmlspecialchars($_POST ['tel']);
$message = htmlspecialchars($_POST ['message']);
$to = "example#gmail.com";
$subject = "Callback request";
$body = "
<html>
<head>
</head>
<header style='padding:10px'>
<a href='http://example.com'>
<img src='http://example.com/images-default/example-logo.png' alt='example.com'>
</a>
</header>
<body style='border-top:2px solid #91448D;margin-top:15px'>
<p>You have recieved an message through the callback request form on the website.</p>
<p><strong>Name: </strong>{$fname} {$lname} </p>
<p><strong>Email: </strong>{$email} </p>
<p><strong>Telephone: </strong>{$tel} </p>
<p><strong>Message: </strong>{$message}</p>
</body>
</html>
";
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'From: example <info#example.com>' . "\r\n";
$headers .= 'Reply-To: info#example.com' . "\r\n";
mail ( //email to info#example.com
$to,
$subject,
$body,
$headers
);
$subject2 = "Thanks for your enqiry";
$body2 = "
<html>
<head>
</head>
<header style='padding:10px'>
<a href='http://example.com'>
<img src='http://example.com/images-default/example-logo.png' alt='example.com'>
</a>
</header>
<body style='border-top:2px solid #91448D;margin-top:15px'><br/>
<p style='margin-bottom:1em'>Hi {$fname},<br/><br/>
Thanks for enquiring about private maths tuition with <a href='http://example.com'>example.com</a>.<br/><br/>
We'll get back to you within 24 hours for a chat about your child's learning needs.<br/><br/>
Regards,<br/><br/>
<strong>Kathy</strong><br/>
<a href='http://example.com'>example.com</a> founder<br/>
tel: 01582 472060<br/>
email: <a href='mailto:info#example.com'>info#example.com</a></p>
</body>
</html>
";
mail ( //email to enquiror
$email,
$subject2,
$body2,
$headers
);
$success = "Thank you for your enquiry. We'll get back to you within 24 hours.";
$returndata = array (
'success' => $success
);
session_start();
$_SESSION['cf_returndata'] = $returndata;
header('location: ' . $_SERVER['HTTP_REFERER']);
}
}
?>
This is the javascript validation file:
function validateFirstName(){
if (
document.getElementById('fname').value == "") {
document.getElementById('fnameError').style.display = "block";
document.getElementById('fnameError').innerHTML = "Please enter your first name";
return false;
}
else {
document.getElementById('fnameError').style.display = "none";
return true;
}
}
function validateLastName(){
if (
document.getElementById('lname').value == "") {
document.getElementById('lnameError').style.display = "block";
document.getElementById('lnameError').innerHTML = "Please enter your last name";
return false;
}
else {
document.getElementById('lnameError').style.display = "none";
return true;
}
}
function validateEmail(){
var re = /^(([^<>()[\]\\.,;:\s#\"]+(\.[^<>()[\]\\.,;:\s#\"]+)*)|(\".+\"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
if (
re.test(document.getElementById('email').value)){
document.getElementById('emailError').style.display = "none";
return true;
}
else {
if (
document.getElementById('email').value == "") {
document.getElementById('emailError').style.display = "block";
document.getElementById('emailError').innerHTML = "Please enter your email address";
return false;
}
else {
document.getElementById('emailError').style.display = "block";
document.getElementById('emailError').innerHTML = "Please enter a valid email address";
return false;
}
}
}
function validateTel(){
var re = /(((\+44)? ?(\(0\))? ?)|(0))( ?[0-9]{3,4}){3}/;
if (
re.test(document.getElementById('tel').value)){
document.getElementById('telError').style.display = "none";
return true;
}
else {
if (
document.getElementById('tel').value == "") {
document.getElementById('telError').style.display = "block";
document.getElementById('telError').innerHTML = "Please enter your phone number";
return false;
}
else {
document.getElementById('telError').style.display = "block";
document.getElementById('telError').innerHTML = "Please enter a valid phone number";
return false;
}
}
}
function validateMessage(){
if (
document.getElementById('message').value == "") {
document.getElementById('messageError').style.display = "block";
document.getElementById('messageError').innerHTML = "Please enter a message";
return false;
}
else {
document.getElementById('messageError').style.display = "none";
return true;
}
}
function validateForm(){
// Set error catcher
var error = 0;
// Check first name
if(!validateFirstName(document.getElementById('fname').value)){
document.getElementById('fnameError').style.display = "block";
error++;
}
// Check last name
if(!validateLastName(document.getElementById('lname').value)){
document.getElementById('lnameError').style.display = "block";
error++;
}
// Validate email
if(!validateEmail(document.getElementById('email').value)){
document.getElementById('emailError').style.display = "block";
error++;
}
// Validate phone number
if(!validateTel(document.getElementById('tel').value)){
document.getElementById('telError').style.display = "block";
error++;
}
if(!validateMessage(document.getElementById('message').value)){
document.getElementById('messageError').style.display = "block";
error++;
}
if (
!document.getElementById('hidden').value == "") {
error++;
}
if(error > 0){
return false;
}
}