Allow submitting of react form

This commit is contained in:
benji 2017-01-14 22:45:51 +01:00
parent c160188af5
commit c5176aa479
5 changed files with 139 additions and 45 deletions

View file

@ -1,4 +1,4 @@
{ button, div, h3, input, option, select } = React.DOM { button, div, form, h3, input, option, select } = React.DOM
Action = React.createFactory React.createClass Action = React.createFactory React.createClass
buttonClass: (b) -> buttonClass: (b) ->
@ -22,23 +22,21 @@ Amount = React.createFactory React.createClass
@props.setAmount ref.target.value @props.setAmount ref.target.value
format: (ref) -> format: (ref) ->
t = ref.target t = ref.target
t.value = parseFloat(t.value).toFixed(2) t.value = parseFloat(t.value).toFixed(2) if t.value
render: -> render: ->
div className: 'row', div className: 'row',
div className: 'col-xs-4', div className: 'col-xs-4',
div className: 'input-group', div className: 'input-group',
div className: 'input-group-addon', '' div className: 'input-group-addon', ''
input { input {
type: 'number',
className: 'form-control input-lg', className: 'form-control input-lg',
placeholder: '0.00', name: 'transaction[euros]'
onBlur: @format,
onChange: @onChange, onChange: @onChange,
onBlur: @format placeholder: '0.00',
type: 'number',
} }
Suggestions = React.createFactory React.createClass
render: ->
Peer = React.createFactory React.createClass Peer = React.createFactory React.createClass
onChange: (ref) -> onChange: (ref) ->
@props.setPeer ref.target.value @props.setPeer ref.target.value
@ -62,7 +60,13 @@ Peer = React.createFactory React.createClass
div className: 'row', div className: 'row',
div className: 'col-xs-4', div className: 'col-xs-4',
div className: 'suggestions-wrapper', div className: 'suggestions-wrapper',
input type: 'text', className: @inputClass(options.length), onChange: @onChange, placeholder: 'Zeus member', value: (@props.peer || '') input {
className: @inputClass(options.length),
onChange: @onChange,
placeholder: 'Zeus member',
type: 'text',
value: (@props.peer || '')
}
if options.length != 0 if options.length != 0
div className: 'suggestions', div className: 'suggestions',
@options().map (s, i) => @options().map (s, i) =>
@ -75,53 +79,135 @@ Message = React.createFactory React.createClass
render: -> render: ->
div className: 'row', div className: 'row',
div className: 'col-xs-8', div className: 'col-xs-8',
input type: 'text', className: 'form-control input-lg', onChange: @onChange, placeholder: 'Message' input {
className: 'form-control input-lg',
name: 'transaction[message]',
onChange: @onChange,
placeholder: 'Message'
type: 'text',
}
Submit = React.createFactory React.createClass Submit = React.createFactory React.createClass
render: -> render: ->
{ onClick } = @props
div className: 'row', div className: 'row',
div className: 'col-xs-4 col-xs-offset-4', div className: 'col-xs-4 col-xs-offset-4',
button type: 'submit', onClick: @props.onClick, className: 'btn btn-default btn-lg form-control', 'Confirm' button {
className: 'btn btn-default btn-lg btn-block',
onClick: onClick,
type: 'submit',
}, 'Confirm'
Step = React.createFactory React.createClass Step = React.createFactory React.createClass
render: -> render: ->
{ error } = @props
div className: 'form-step', div className: 'form-step',
div className: 'form-step-counter', @props.step div className: 'form-step-counter', @props.step
div className: 'form-step-content', div className: 'form-step-content',
div className: 'form-step-title', @props.title div className: 'form-step-title',
@props.title,
div className: 'form-step-error',
error
div className: 'clear-both' div className: 'clear-both'
@props.children @props.children
div className: 'clear-both' div className: 'clear-both'
@TransactionForm = React.createClass @TransactionForm = React.createClass
getInitialState: -> getInitialState: ->
giving: null, amount: null, peer: null, message: null step: 1, giving: null, amount: null, peer: null, message: null
setAction: (b) -> setAction: (b) ->
@setState giving: b @setState giving: b
@setState step: 2 unless @state.step > 1
setAmount: (a) -> setAmount: (a) ->
@setState amount: a @setState amount: a
@setState step: 3 unless @state.step > 2
setPeer: (p) -> setPeer: (p) ->
@setState peer: p @setState peer: p
@setState step: 4 unless @state.step > 3
setMessage: (m) -> setMessage: (m) ->
@setState message: m @setState message: m
@setState step: 5 unless @state.step > 4
submit: (e) -> submit: (e) ->
console.log 'submit' e.preventDefault()
render: ->
{ giving, peer } = @state
{ user } = @props
errors = @errors()
if Object.keys(errors).length != 0
return
if giving
debtor = user.name
creditor = peer
else
debtor = peer
creditor = user.name
$('<input />')
.attr('name', 'transaction[debtor]')
.attr('value', debtor)
.attr('type', 'hidden')
.appendTo(@refs.form)
$('<input />')
.attr('name', 'transaction[creditor]')
.attr('value', creditor)
.attr('type', 'hidden')
.appendTo(@refs.form)
@refs.form.submit()
errors: ->
{ amount, giving, message, peer } = @state { amount, giving, message, peer } = @state
{ peers } = @props { peers, user } = @props
errors = {}
errors['giving'] = 'Please select an action.' unless giving != null
unless amount
errors['amount'] = 'Please fill in an amount.'
else if parseFloat(amount) <= 0
errors['amount'] = 'Please fill in a positive number.'
unless message && message != ""
errors['message'] = 'Please fill in a message.'
unless peer && peers.includes(peer) && peer != user
errors['peer'] = 'Please select a valid Zeus member.'
errors
render: ->
{ step, amount, giving, message, peer } = @state
{ peers } = @props
errors = @errors()
div id: 'transaction-form', div id: 'transaction-form',
h3 null, 'Transfer some money' h3 null, 'Transfer some money'
Step step: 1, title: 'What do you want to do?', form ref: 'form', action: '/transactions', acceptCharset: 'UTF-8', method: 'post',
Action giving: giving, setAction: @setAction Step step: 1, title: 'What do you want to do?',
if giving != null Action giving: giving, setAction: @setAction
Step step: 2, title: 'How much do you want to give?', if step >= 2
Amount setAmount: @setAmount Step {
if amount != null step: 2,
Step step: 3, title: 'Who do you want to give it to?', title: "How much do you want to #{if giving then 'give' else 'receive'}?",
Peer peer: peer, peers: peers, setPeer: @setPeer error: errors['amount'] if step > 2
if peer != null },
Step step: 4, title: 'Why do you want to give this?', Amount setAmount: @setAmount
Message setMessage: @setMessage if step >= 3
if message != null Step {
Submit null step: 3,
title: "Who do you want to #{if giving then 'give it to' else 'receive it from'}?",
error: errors['peer'] if step > 3
},
Peer peer: peer, peers: peers, setPeer: @setPeer
if step >= 4
Step {
step: 4,
title: "Why do you want to #{if giving then 'give' else 'receive'} this?",
error: errors['message'] if step > 4
},
Message setMessage: @setMessage
if step >= 5
Submit onClick: @submit
div className: 'clear-both' div className: 'clear-both'

View file

@ -31,7 +31,13 @@ $step-width: 26px;
.form-step-title { .form-step-title {
display: inline-block; display: inline-block;
font-weight: bold; font-weight: bold;
margin-bottom: 10px; margin-bottom: 5px;
}
.form-step-error {
color: red;
font-size: 11px;
height: 15px;
} }
.form-options { .form-options {

View file

@ -6,7 +6,7 @@ class TransactionsQuery
@transactions = Arel::Table.new(:transactions) @transactions = Arel::Table.new(:transactions)
@perspectived = Arel::Table.new(:perspectived_transactions) @perspectived = Arel::Table.new(:perspectived_transactions)
@peers = Arel::Table.new(:users).alias('peers') @peers = Arel::Table.new(:users).alias('peers')
@arel_table = Arel::Table.new(@user.name.concat('_transactions')) @arel_table = Arel::Table.new("#{@user.name}_transactions")
end end
def query def query

View file

@ -10,21 +10,21 @@ class TransactionsController < ApplicationController
@transaction = Transaction.new(transaction_params) @transaction = Transaction.new(transaction_params)
@transaction.reverse if @transaction.amount < 0 @transaction.reverse if @transaction.amount < 0
if can? :create, @transaction unless can? :create, @transaction
if @transaction.save @transaction = Request.new @transaction.info
render json: @transaction, status: :created authorize!(:create, @transaction)
else end
render json: @transaction.errors.full_messages,
status: :unprocessable_entity if @transaction.save
respond_to do |format|
format.html { redirect_to root_path }
format.json { render json: @transaction, status: :created }
end end
else else
request = Request.new @transaction.info respond_to do |format|
authorize!(:create, request) format.html { redirect_to root_path }
if request.save format.json { render json: @transaction.errors.full_messages,
render json: request, status: :created status: :unprocessable_entity }
else
render json: request.errors.full_messages,
status: :unprocessable_entity
end end
end end
end end

View file

@ -8,7 +8,9 @@ module BaseTransaction
belongs_to :creditor, class_name: 'User' belongs_to :creditor, class_name: 'User'
belongs_to :issuer, polymorphic: true belongs_to :issuer, polymorphic: true
validates :amount, numericality: { greater_than: 0 } validates :debtor, presence: true
validates :creditor, presence: true
validates :amount, numericality: { greater_than: 0 }
validate :different_debtor_creditor validate :different_debtor_creditor
end end