added validation for delivery destination
This commit is contained in:
@@ -5,7 +5,8 @@ var React = require('react'),
|
|||||||
NavigationActions = require('../../actions/navigationActions'),
|
NavigationActions = require('../../actions/navigationActions'),
|
||||||
SingleItem = require('../items/singleItem'),
|
SingleItem = require('../items/singleItem'),
|
||||||
Globals = require('../../globals'),
|
Globals = require('../../globals'),
|
||||||
CartTotal = require('./cartTotal');
|
CartTotal = require('./cartTotal'),
|
||||||
|
RibicaFormError = require('../shared/ribicaFormError');
|
||||||
|
|
||||||
|
|
||||||
var Router = require('react-router');
|
var Router = require('react-router');
|
||||||
@@ -21,8 +22,10 @@ var CheckoutPage = React.createClass({
|
|||||||
<fieldset>
|
<fieldset>
|
||||||
<legend>Dostava</legend>
|
<legend>Dostava</legend>
|
||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
|
|
||||||
<label className="col-md-4 control-label" htmlFor="name">Prezime i Ime</label>
|
<label className="col-md-4 control-label" htmlFor="name">Prezime i Ime</label>
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
|
<RibicaFormError componentName="name" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||||
<input id="name" name="name" type="text" placeholder="Prezime Ime" className="form-control input-md" required="" value={this.state.deliveryDestination.get('name')} onChange={this._onFieldChange} />
|
<input id="name" name="name" type="text" placeholder="Prezime Ime" className="form-control input-md" required="" value={this.state.deliveryDestination.get('name')} onChange={this._onFieldChange} />
|
||||||
<span className="help-block">ime osobe koja prima pošiljku</span>
|
<span className="help-block">ime osobe koja prima pošiljku</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -30,6 +33,7 @@ var CheckoutPage = React.createClass({
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-md-4 control-label" htmlFor="name">Adresa</label>
|
<label className="col-md-4 control-label" htmlFor="name">Adresa</label>
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
|
<RibicaFormError componentName="address" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||||
<input id="address" name="address" type="text" placeholder="Ulica i broj" className="form-control input-md" required="" value={this.state.deliveryDestination.get('address')} onChange={this._onFieldChange} />
|
<input id="address" name="address" type="text" placeholder="Ulica i broj" className="form-control input-md" required="" value={this.state.deliveryDestination.get('address')} onChange={this._onFieldChange} />
|
||||||
<span className="help-block">adresa na koju će roba biti isporučena</span>
|
<span className="help-block">adresa na koju će roba biti isporučena</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -38,6 +42,7 @@ var CheckoutPage = React.createClass({
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-md-4 control-label" htmlFor="place">Mjesto</label>
|
<label className="col-md-4 control-label" htmlFor="place">Mjesto</label>
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
|
<RibicaFormError componentName="place" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||||
<select id="place" name="place" className="form-control" value={this.state.deliveryDestination.get('place')} onChange={this._onFieldChange} >
|
<select id="place" name="place" className="form-control" value={this.state.deliveryDestination.get('place')} onChange={this._onFieldChange} >
|
||||||
<option value=" 71000">Sarajevo</option>
|
<option value=" 71000">Sarajevo</option>
|
||||||
<option value=" 71103">Sarajevo, Centar</option>
|
<option value=" 71103">Sarajevo, Centar</option>
|
||||||
@@ -66,7 +71,7 @@ var CheckoutPage = React.createClass({
|
|||||||
<option value="76204">Bijela</option>
|
<option value="76204">Bijela</option>
|
||||||
<option value="76300">Bijeljina</option>
|
<option value="76300">Bijeljina</option>
|
||||||
<option value="73263">Bijelo Brdo</option>
|
<option value="73263">Bijelo Brdo</option>
|
||||||
<option value="89230">Bileca</option> ++++++++
|
<option value="89230">Bileca</option>
|
||||||
<option value="72248">Biljesevo</option>
|
<option value="72248">Biljesevo</option>
|
||||||
<option value="88407">Bjelimici</option>
|
<option value="88407">Bjelimici</option>
|
||||||
<option value="88201">Blagaj</option>
|
<option value="88201">Blagaj</option>
|
||||||
@@ -569,6 +574,7 @@ var CheckoutPage = React.createClass({
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-md-4 control-label" htmlFor="phone">Telefon</label>
|
<label className="col-md-4 control-label" htmlFor="phone">Telefon</label>
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
|
<RibicaFormError componentName="phone" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||||
<div className="input-group">
|
<div className="input-group">
|
||||||
<span className="input-group-addon">06</span>
|
<span className="input-group-addon">06</span>
|
||||||
<input id="phone" name="phone" className="form-control" placeholder="1 222 333" type="text" required="" value={this.state.deliveryDestination.get('phone')} onChange={this._onFieldChange} />
|
<input id="phone" name="phone" className="form-control" placeholder="1 222 333" type="text" required="" value={this.state.deliveryDestination.get('phone')} onChange={this._onFieldChange} />
|
||||||
@@ -579,6 +585,7 @@ var CheckoutPage = React.createClass({
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-md-4 control-label" htmlFor="email">E - mail</label>
|
<label className="col-md-4 control-label" htmlFor="email">E - mail</label>
|
||||||
<div className="col-md-4">
|
<div className="col-md-4">
|
||||||
|
<RibicaFormError componentName="email" errorMessagesObject={this.state.deliveryDestinationErrors} />
|
||||||
<input id="email" name="email" type="text" placeholder="ime@nekimail.com" className="form-control input-md" required="" value={this.state.deliveryDestination.get('email')} onChange={this._onFieldChange} />
|
<input id="email" name="email" type="text" placeholder="ime@nekimail.com" className="form-control input-md" required="" value={this.state.deliveryDestination.get('email')} onChange={this._onFieldChange} />
|
||||||
<span className="help-block">E - mail adresa na koju će vam biti poslano obavještenje o narudžbi</span>
|
<span className="help-block">E - mail adresa na koju će vam biti poslano obavještenje o narudžbi</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -592,7 +599,7 @@ var CheckoutPage = React.createClass({
|
|||||||
<div className="form-group">
|
<div className="form-group">
|
||||||
<label className="col-md-4 control-label" htmlFor="order"></label>
|
<label className="col-md-4 control-label" htmlFor="order"></label>
|
||||||
<div className="col-md-8">
|
<div className="col-md-8">
|
||||||
<CartTotal items={this.state.items} itemCounts={this.state.itemCounts} /> <button id="order" name="order" className="btn btn-success" onClick={this._onOrderClick}>Naruči</button>
|
<CartTotal items={this.state.items} itemCounts={this.state.itemCounts} /> <button id="order" name="order" className="btn btn-success" disabled={!this.state.isDeliveryDestinationValid} onClick={this._onOrderClick}>Naruči</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ var SingleItem = React.createClass({
|
|||||||
|
|
||||||
itemClick: function(e) {
|
itemClick: function(e) {
|
||||||
NavigationActions.goToItemDetails(this.props.item);
|
NavigationActions.goToItemDetails(this.props.item);
|
||||||
console.log(this.props.item)
|
console.log(this.props.item)
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,76 +0,0 @@
|
|||||||
var RibicaValidationMixin = {
|
|
||||||
_updateState: function(prop, value, callback) {
|
|
||||||
var newState = {};
|
|
||||||
newState[prop] = value;
|
|
||||||
this.setState(newState, function(){
|
|
||||||
if(callback) {
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
},
|
|
||||||
_validate: function(prop, value) {
|
|
||||||
if(this.validations && this.validations[prop]) {
|
|
||||||
var cb = function(err, revalidateFields) {
|
|
||||||
var errors = this.state.errors || {};
|
|
||||||
if (err !== undefined) {
|
|
||||||
if(err.length > 0) {
|
|
||||||
errors[prop] = err;
|
|
||||||
} else {
|
|
||||||
delete errors[prop];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
delete errors[prop];
|
|
||||||
}
|
|
||||||
this.setState({errors: errors});
|
|
||||||
if (revalidateFields) {
|
|
||||||
for(var i = 0; i < revalidateFields.length; i++) {
|
|
||||||
this.validateField(revalidateFields[i], this.state[revalidateFields[i]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.bind(this);
|
|
||||||
|
|
||||||
var immediateErrors = this.validations[prop](value, cb);
|
|
||||||
cb(immediateErrors);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
handleChange: function(prop) {
|
|
||||||
return function(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
var target = event.target;
|
|
||||||
this._updateState(prop, target.value, function(){
|
|
||||||
this._validate(prop, target.value);
|
|
||||||
}.bind(this));
|
|
||||||
}.bind(this);
|
|
||||||
|
|
||||||
},
|
|
||||||
getValidationMessages:function(prop) {
|
|
||||||
var errors = this.state.errors || {};
|
|
||||||
return (errors[prop] || []);
|
|
||||||
},
|
|
||||||
validateField: function(field) {
|
|
||||||
this._validate(field, this.state[field]);
|
|
||||||
},
|
|
||||||
validate: function() {
|
|
||||||
for (var key in this.state) {
|
|
||||||
if (this.state.hasOwnProperty(key)) {
|
|
||||||
this._validate(key, this.state[key]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this.isValid();
|
|
||||||
},
|
|
||||||
isValid: function() {
|
|
||||||
var errors = this.state.errors || {};
|
|
||||||
return Object.keys(errors).length === 0;
|
|
||||||
},
|
|
||||||
componentDidMount : function(){
|
|
||||||
this.setState({errors: {}});
|
|
||||||
if (this.validations) {
|
|
||||||
var self = this;
|
|
||||||
this.validations.getState = function() {
|
|
||||||
return self.state;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
module.exports = RibicaValidationMixin;
|
|
||||||
17
front-ui/app/components/shared/ribicaFormError.js
Normal file
17
front-ui/app/components/shared/ribicaFormError.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
var React = require('react');
|
||||||
|
|
||||||
|
|
||||||
|
var RibicaFormError = React.createClass({
|
||||||
|
render: function() {
|
||||||
|
var errorMessages = this.props.errorMessagesObject || {};
|
||||||
|
var componentName = this.props.componentName;
|
||||||
|
var message = errorMessages[componentName];
|
||||||
|
if (message !== undefined && message !== null && message !== "") {
|
||||||
|
return(<div className='error-message'>{message}</div>)
|
||||||
|
}
|
||||||
|
else return (<span></span>);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
module.exports = RibicaFormError;
|
||||||
@@ -17,6 +17,7 @@ var _itemsInCart = new ItemInCartCollection();
|
|||||||
var _itemsForDisplay = new ItemCollection();
|
var _itemsForDisplay = new ItemCollection();
|
||||||
_itemsForDisplay.setFromCart(true);
|
_itemsForDisplay.setFromCart(true);
|
||||||
var _deliveryDestination = new DeliveryDestination();
|
var _deliveryDestination = new DeliveryDestination();
|
||||||
|
var _deliveryDestinationErrors = {};
|
||||||
|
|
||||||
|
|
||||||
var loadCart = function() {
|
var loadCart = function() {
|
||||||
@@ -39,6 +40,7 @@ var loadCart = function() {
|
|||||||
if (!_deliveryDestination.get('id')) {
|
if (!_deliveryDestination.get('id')) {
|
||||||
_deliveryDestination.fetch({
|
_deliveryDestination.fetch({
|
||||||
success: function() {
|
success: function() {
|
||||||
|
validateDeliveryDestinationForm();
|
||||||
CartActions.dataLoaded();
|
CartActions.dataLoaded();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -82,6 +84,7 @@ var takeItemOut = function(itemId) {
|
|||||||
|
|
||||||
var changeDeliveryDestinationProperty = function(property, value) {
|
var changeDeliveryDestinationProperty = function(property, value) {
|
||||||
_deliveryDestination.set(property, value);
|
_deliveryDestination.set(property, value);
|
||||||
|
validateDeliveryDestinationForm();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -107,7 +110,49 @@ var saveDeliveryDestination = function() {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var validateDeliveryDestinationForm = function () {
|
||||||
|
_deliveryDestinationErrors = {};
|
||||||
|
|
||||||
|
var nameRegex = /.+\s+.+/i;
|
||||||
|
if(_deliveryDestination.get('name').search(nameRegex) < 0) {
|
||||||
|
_deliveryDestinationErrors['name'] = "I prezime i ime su obavezni";
|
||||||
|
}
|
||||||
|
|
||||||
|
var addressRegex = /.+\s+.+/i;
|
||||||
|
if(_deliveryDestination.get('address').search(addressRegex) < 0) {
|
||||||
|
_deliveryDestinationErrors['address'] = "Adresa mora biti ispravna";
|
||||||
|
}
|
||||||
|
|
||||||
|
var emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/i;
|
||||||
|
if(_deliveryDestination.get('email').search(emailRegex) < 0) {
|
||||||
|
_deliveryDestinationErrors['email'] = "Email mora biti ispravno upisan";
|
||||||
|
}
|
||||||
|
|
||||||
|
var phoneRegex = /[\d\s-]{7,8}/i;
|
||||||
|
if(_deliveryDestination.get('phone').search(phoneRegex) < 0) {
|
||||||
|
_deliveryDestinationErrors['phone'] = "Telefon mora biti ispravan";
|
||||||
|
}
|
||||||
|
|
||||||
|
var placeRegex = /^\s{0,1}\d{5}$/i;
|
||||||
|
if(_deliveryDestination.get('place').search(placeRegex) < 0) {
|
||||||
|
_deliveryDestinationErrors['place'] = "Mjesto mora biti izabrano";
|
||||||
|
}
|
||||||
|
|
||||||
|
var requiredFields = ["name", "email", "place", 'address', 'phone'];
|
||||||
|
for (var i in requiredFields) {
|
||||||
|
var value = _deliveryDestination.get(requiredFields[i]);
|
||||||
|
if (value === undefined || value === null || value === "") {
|
||||||
|
// if it's required there will be a star there
|
||||||
|
_deliveryDestinationErrors[requiredFields[i]] = "*";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
var isDeliveryDestinationValid = function () {
|
||||||
|
return Object.getOwnPropertyNames(_deliveryDestinationErrors).length === 0;
|
||||||
|
}
|
||||||
// Extend CartStore with EventEmitter to add eventing capabilities
|
// Extend CartStore with EventEmitter to add eventing capabilities
|
||||||
var CartStore = _.extend({}, EventEmitter.prototype, {
|
var CartStore = _.extend({}, EventEmitter.prototype, {
|
||||||
|
|
||||||
@@ -137,7 +182,10 @@ var CartStore = _.extend({}, EventEmitter.prototype, {
|
|||||||
count: numberOfItems,
|
count: numberOfItems,
|
||||||
items: _itemsForDisplay,
|
items: _itemsForDisplay,
|
||||||
itemCounts: states,
|
itemCounts: states,
|
||||||
deliveryDestination: _deliveryDestination
|
deliveryDestination: _deliveryDestination,
|
||||||
|
deliveryDestinationErrors: _deliveryDestinationErrors,
|
||||||
|
isDeliveryDestinationValid: isDeliveryDestinationValid()
|
||||||
|
|
||||||
};
|
};
|
||||||
return state;
|
return state;
|
||||||
},
|
},
|
||||||
@@ -156,7 +204,11 @@ var CartStore = _.extend({}, EventEmitter.prototype, {
|
|||||||
// Remove change listener
|
// Remove change listener
|
||||||
removeChangeListener: function(callback) {
|
removeChangeListener: function(callback) {
|
||||||
this.removeListener('change', callback);
|
this.removeListener('change', callback);
|
||||||
}
|
},
|
||||||
|
|
||||||
|
isDeliveryDestinationValid: isDeliveryDestinationValid
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user