web: stay in add form when there are errors
This commit is contained in:
parent
8bde2fd212
commit
e76cc6ee47
@ -25,6 +25,7 @@ import Settings (staticRoot, widgetFile, Extra (..))
|
|||||||
import Settings (staticDir)
|
import Settings (staticDir)
|
||||||
import Text.Jasmine (minifym)
|
import Text.Jasmine (minifym)
|
||||||
#endif
|
#endif
|
||||||
|
import Text.Blaze.Html.Renderer.String (renderHtml)
|
||||||
import Text.Hamlet (hamletFile)
|
import Text.Hamlet (hamletFile)
|
||||||
|
|
||||||
import Hledger.Web.Options
|
import Hledger.Web.Options
|
||||||
@ -104,7 +105,7 @@ instance Yesod App where
|
|||||||
|
|
||||||
defaultLayout widget = do
|
defaultLayout widget = do
|
||||||
master <- getYesod
|
master <- getYesod
|
||||||
mmsg <- getMessage
|
vd@VD{..} <- getViewData
|
||||||
|
|
||||||
-- We break up the default layout into two components:
|
-- We break up the default layout into two components:
|
||||||
-- default-layout is the contents of the body tag, and
|
-- default-layout is the contents of the body tag, and
|
||||||
@ -140,7 +141,6 @@ instance Yesod App where
|
|||||||
$(widgetFile "default-layout")
|
$(widgetFile "default-layout")
|
||||||
|
|
||||||
staticRootUrl <- (staticRoot . settings) <$> getYesod
|
staticRootUrl <- (staticRoot . settings) <$> getYesod
|
||||||
vd@VD{..} <- getViewData
|
|
||||||
withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")
|
withUrlRenderer $(hamletFile "templates/default-layout-wrapper.hamlet")
|
||||||
|
|
||||||
-- This is done to provide an optimization for serving static files from
|
-- This is done to provide an optimization for serving static files from
|
||||||
@ -232,8 +232,9 @@ getViewData :: Handler ViewData
|
|||||||
getViewData = do
|
getViewData = do
|
||||||
app <- getYesod
|
app <- getYesod
|
||||||
let opts@WebOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} = appOpts app
|
let opts@WebOpts{cliopts_=copts@CliOpts{reportopts_=ropts}} = appOpts app
|
||||||
(j, err) <- getCurrentJournal app copts{reportopts_=ropts{no_elide_=True}}
|
(j, merr) <- getCurrentJournal app copts{reportopts_=ropts{no_elide_=True}}
|
||||||
msg <- getMessageOr err
|
lastmsg <- getLastMessage
|
||||||
|
let msg = maybe lastmsg (Just . toHtml) merr
|
||||||
Just here <- getCurrentRoute
|
Just here <- getCurrentRoute
|
||||||
today <- liftIO getCurrentDay
|
today <- liftIO getCurrentDay
|
||||||
q <- getParameterOrNull "q"
|
q <- getParameterOrNull "q"
|
||||||
@ -275,11 +276,10 @@ getViewData = do
|
|||||||
getParameterOrNull :: String -> Handler String
|
getParameterOrNull :: String -> Handler String
|
||||||
getParameterOrNull p = unpack `fmap` fromMaybe "" <$> lookupGetParam (pack p)
|
getParameterOrNull p = unpack `fmap` fromMaybe "" <$> lookupGetParam (pack p)
|
||||||
|
|
||||||
-- | Get the message set by the last request, or the newer message provided, if any.
|
-- | Get the message that was set by the last request, in a
|
||||||
getMessageOr :: Maybe String -> Handler (Maybe Html)
|
-- referentially transparent manner (allowing multiple reads).
|
||||||
getMessageOr mnewmsg = do
|
getLastMessage :: Handler (Maybe Html)
|
||||||
oldmsg <- getMessage
|
getLastMessage = cached getMessage
|
||||||
return $ maybe oldmsg (Just . toHtml) mnewmsg
|
|
||||||
|
|
||||||
-- add form dialog, part of the default template
|
-- add form dialog, part of the default template
|
||||||
|
|
||||||
@ -334,7 +334,7 @@ addform _ vd@VD{..} = [hamlet|
|
|||||||
<table style="width:100%;">
|
<table style="width:100%;">
|
||||||
<tr#descriptionrow>
|
<tr#descriptionrow>
|
||||||
<td>
|
<td>
|
||||||
<input #date .typeahead .form-control .input-lg type=text size=15 name=date placeholder="Date" value=#{date}>
|
<input #date .typeahead .form-control .input-lg type=text size=15 name=date placeholder="Date" value=#{defdate}>
|
||||||
<td>
|
<td>
|
||||||
<input #description .typeahead .form-control .input-lg type=text size=40 name=description placeholder="Description">
|
<input #description .typeahead .form-control .input-lg type=text size=40 name=description placeholder="Description">
|
||||||
$forall n <- postingnums
|
$forall n <- postingnums
|
||||||
@ -344,7 +344,7 @@ addform _ vd@VD{..} = [hamlet|
|
|||||||
Tab in last field for <a .small href="#" onclick="addformAddPosting(); return false;">more</a> (or ctrl +, ctrl -)
|
Tab in last field for <a .small href="#" onclick="addformAddPosting(); return false;">more</a> (or ctrl +, ctrl -)
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
date = "today" :: String
|
defdate = "today" :: String
|
||||||
dates = ["today","yesterday","tomorrow"] :: [String]
|
dates = ["today","yesterday","tomorrow"] :: [String]
|
||||||
descriptions = sort $ nub $ map tdescription $ jtxns j
|
descriptions = sort $ nub $ map tdescription $ jtxns j
|
||||||
accts = sort $ journalAccountNamesUsed j
|
accts = sort $ journalAccountNamesUsed j
|
||||||
|
|||||||
@ -61,9 +61,9 @@ postAddForm = do
|
|||||||
<*> iopt textField "description"
|
<*> iopt textField "description"
|
||||||
<*> iopt (check validateJournalFile textField) "journal"
|
<*> iopt (check validateJournalFile textField) "journal"
|
||||||
|
|
||||||
case formresult of
|
ok <- case formresult of
|
||||||
FormMissing -> showErrors ["there is no form data"::String]
|
FormMissing -> showErrors ["there is no form data"::String] >> return False
|
||||||
FormFailure errs -> showErrors errs
|
FormFailure errs -> showErrors errs >> return False
|
||||||
FormSuccess dat -> do
|
FormSuccess dat -> do
|
||||||
let AddForm{
|
let AddForm{
|
||||||
addFormDate =date
|
addFormDate =date
|
||||||
@ -107,7 +107,7 @@ postAddForm = do
|
|||||||
,tpostings=[nullposting{paccount=acct, pamount=Mixed [amt]} | (acct,amt) <- zip accts amts]
|
,tpostings=[nullposting{paccount=acct, pamount=Mixed [amt]} | (acct,amt) <- zip accts amts]
|
||||||
})
|
})
|
||||||
case etxn of
|
case etxn of
|
||||||
Left errs -> showErrors errs
|
Left errs -> showErrors errs >> return False
|
||||||
Right t -> do
|
Right t -> do
|
||||||
-- 3. all fields look good and form a balanced transaction; append it to the file
|
-- 3. all fields look good and form a balanced transaction; append it to the file
|
||||||
liftIO $ do ensureJournalFileExists journalfile
|
liftIO $ do ensureJournalFileExists journalfile
|
||||||
@ -116,5 +116,6 @@ postAddForm = do
|
|||||||
txnTieKnot -- XXX move into balanceTransaction
|
txnTieKnot -- XXX move into balanceTransaction
|
||||||
t
|
t
|
||||||
setMessage [shamlet|<span>Transaction added.|]
|
setMessage [shamlet|<span>Transaction added.|]
|
||||||
|
return True
|
||||||
|
|
||||||
redirect (JournalR) -- , [("add","1")])
|
if ok then redirect JournalR else redirect (JournalR, [("add","1")])
|
||||||
|
|||||||
@ -55,8 +55,6 @@ topbar VD{..} = [hamlet|
|
|||||||
<nav class="navbar" role="navigation">
|
<nav class="navbar" role="navigation">
|
||||||
<div#topbar>
|
<div#topbar>
|
||||||
<h1>#{title}
|
<h1>#{title}
|
||||||
$maybe m' <- msg
|
|
||||||
<div#message>#{m'}
|
|
||||||
|]
|
|]
|
||||||
where
|
where
|
||||||
title = takeFileName $ journalFilePath j
|
title = takeFileName $ journalFilePath j
|
||||||
|
|||||||
@ -6,7 +6,7 @@
|
|||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
|
||||||
// show add form if ?add=1
|
// show add form if ?add=1
|
||||||
if ($.url.param('add')) { addformShow(); }
|
if ($.url.param('add')) { addformShow(showmsg=true); }
|
||||||
|
|
||||||
// sidebar account hover handlers
|
// sidebar account hover handlers
|
||||||
$('#sidebar td a').mouseenter(function(){ $(this).parent().addClass('mouseover'); });
|
$('#sidebar td a').mouseenter(function(){ $(this).parent().addClass('mouseover'); });
|
||||||
@ -126,8 +126,8 @@ function registerChartClick(ev, pos, item) {
|
|||||||
//----------------------------------------------------------------------
|
//----------------------------------------------------------------------
|
||||||
// ADD FORM
|
// ADD FORM
|
||||||
|
|
||||||
function addformShow() {
|
function addformShow(showmsg=false) {
|
||||||
addformReset();
|
addformReset(showmsg);
|
||||||
$('#addmodal')
|
$('#addmodal')
|
||||||
.on('shown.bs.modal', function (e) {
|
.on('shown.bs.modal', function (e) {
|
||||||
addformFocus();
|
addformFocus();
|
||||||
@ -136,13 +136,14 @@ function addformShow() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the add form is empty and clean for display.
|
// Make sure the add form is empty and clean for display.
|
||||||
function addformReset() {
|
function addformReset(showmsg=false) {
|
||||||
if ($('form#addform').length > 0) {
|
if ($('form#addform').length > 0) {
|
||||||
|
if (!showmsg) $('div#message').html('');
|
||||||
$('form#addform')[0].reset();
|
$('form#addform')[0].reset();
|
||||||
$('input#date').val('today');
|
|
||||||
// reset typehead state (though not fetched completions)
|
// reset typehead state (though not fetched completions)
|
||||||
$('.typeahead').typeahead('val', '');
|
$('.typeahead').typeahead('val', '');
|
||||||
$('.tt-dropdown-menu').hide();
|
$('.tt-dropdown-menu').hide();
|
||||||
|
$('input#date').val('today');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -100,4 +100,7 @@ $newline never
|
|||||||
<button type="button" .close data-dismiss="modal" aria-hidden="true">×
|
<button type="button" .close data-dismiss="modal" aria-hidden="true">×
|
||||||
<h3 .modal-title #addLabel>Add a transaction
|
<h3 .modal-title #addLabel>Add a transaction
|
||||||
<div .modal-body>
|
<div .modal-body>
|
||||||
|
$maybe m <- msg
|
||||||
|
$if isPrefixOf "Errors" (renderHtml m)
|
||||||
|
<div #message>#{m}
|
||||||
^{addform staticRootUrl vd}
|
^{addform staticRootUrl vd}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
$maybe msg <- mmsg
|
$maybe m <- msg
|
||||||
<div #message>#{msg}
|
$if not $ isPrefixOf "Errors" (renderHtml m)
|
||||||
|
<div #message>#{m}
|
||||||
^{widget}
|
^{widget}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user