web: cleanup, enable jquery, use auto-completing combo fields on add form
This commit is contained in:
		
							parent
							
								
									f3ffef2d8a
								
							
						
					
					
						commit
						8c8395778c
					
				| @ -12,6 +12,7 @@ import System.FilePath ((</>), takeFileName) | |||||||
| import System.IO.Storage (withStore, putValue, getValue) | import System.IO.Storage (withStore, putValue, getValue) | ||||||
| import Text.ParserCombinators.Parsec (parse) | import Text.ParserCombinators.Parsec (parse) | ||||||
| import Yesod | import Yesod | ||||||
|  | import Yesod.Helpers.Static | ||||||
| 
 | 
 | ||||||
| import Hledger.Cli.Commands.Add (journalAddTransaction) | import Hledger.Cli.Commands.Add (journalAddTransaction) | ||||||
| import Hledger.Cli.Commands.Balance | import Hledger.Cli.Commands.Balance | ||||||
| @ -28,36 +29,43 @@ import Paths_hledger_make (getDataFileName) | |||||||
| #else | #else | ||||||
| import Paths_hledger (getDataFileName) | import Paths_hledger (getDataFileName) | ||||||
| #endif | #endif | ||||||
|  | -- import Hledger.Cli.Commands.Web.Templates | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| defhost = "localhost" | defhost           = "localhost" | ||||||
| defport = 5000 | defport           = 5000 | ||||||
| defbaseurl = printf "http://%s:%d" defhost defport :: String |  | ||||||
| browserstartdelay = 100000 -- microseconds | browserstartdelay = 100000 -- microseconds | ||||||
| hledgerurl = "http://hledger.org" | hledgerorgurl     = "http://hledger.org" | ||||||
| manualurl = hledgerurl++"/MANUAL.html" | manualurl         = hledgerorgurl++"/MANUAL.html" | ||||||
| 
 | 
 | ||||||
| data HledgerWebApp = HledgerWebApp { | data HledgerWebApp = HledgerWebApp { | ||||||
|       appRoot    :: String |       appRoot    :: String | ||||||
|      ,appWebdir  :: FilePath |      ,appDir     :: FilePath | ||||||
|      ,appOpts    :: [Opt] |      ,appOpts    :: [Opt] | ||||||
|      ,appArgs    :: [String] |      ,appArgs    :: [String] | ||||||
|      ,appJournal :: Journal |      ,appJournal :: Journal | ||||||
|  |      ,appStatic  :: Static | ||||||
|      } |      } | ||||||
| 
 | 
 | ||||||
| mkYesod "HledgerWebApp" [$parseRoutes| | mkYesod "HledgerWebApp" [$parseRoutes| | ||||||
| /             IndexPage            GET | /static          StaticR           Static appStatic | ||||||
| /style.css    StyleCss             GET | /                IndexR            GET | ||||||
| /journalonly  JournalOnlyPage      GET POST | /journalonly     JournalOnlyR      GET POST | ||||||
| /registeronly RegisterOnlyPage     GET | /registeronly    RegisterOnlyR     GET | ||||||
| /accounts     AccountsPage         GET | /accounts        AccountsOnlyR     GET | ||||||
| /journal      AccountsJournalPage  GET POST | /journal         JournalR          GET POST | ||||||
| /register     AccountsRegisterPage GET POST | /register        RegisterR         GET POST | ||||||
| |] | |] | ||||||
| 
 | 
 | ||||||
|  | style_css       = StaticRoute ["style.css"] | ||||||
|  | hledger_js      = StaticRoute ["hledger.js"] | ||||||
|  | jquery_js       = StaticRoute ["jquery.js"] | ||||||
|  | dhtmlxcommon_js = StaticRoute ["dhtmlxcommon.js"] | ||||||
|  | dhtmlxcombo_js  = StaticRoute ["dhtmlxcombo.js"] | ||||||
|  | 
 | ||||||
| instance Yesod HledgerWebApp where approot = appRoot | instance Yesod HledgerWebApp where approot = appRoot | ||||||
| 
 | 
 | ||||||
| defaultpage = AccountsJournalPage | defaultroute = JournalR | ||||||
| 
 | 
 | ||||||
| -- | A bundle of useful data passed to templates. | -- | A bundle of useful data passed to templates. | ||||||
| data TemplateData = TD { | data TemplateData = TD { | ||||||
| @ -71,7 +79,7 @@ data TemplateData = TD { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| mktd = TD { | mktd = TD { | ||||||
|       here = IndexPage |       here = IndexR | ||||||
|      ,title = "hledger" |      ,title = "hledger" | ||||||
|      ,msg = Nothing |      ,msg = Nothing | ||||||
|      ,a = "" |      ,a = "" | ||||||
| @ -83,8 +91,9 @@ mktd = TD { | |||||||
| -- | The web command. | -- | The web command. | ||||||
| web :: [Opt] -> [String] -> Journal -> IO () | web :: [Opt] -> [String] -> Journal -> IO () | ||||||
| web opts args j = do | web opts args j = do | ||||||
|   let baseurl = fromMaybe defbaseurl $ baseUrlFromOpts opts |   let host    = defhost | ||||||
|       port = fromMaybe defport $ portFromOpts opts |       port    = fromMaybe defport $ portFromOpts opts | ||||||
|  |       baseurl = fromMaybe (printf "http://%s:%d" host port) $ baseUrlFromOpts opts | ||||||
|   unless (Debug `elem` opts) $ forkIO (browser baseurl) >> return () |   unless (Debug `elem` opts) $ forkIO (browser baseurl) >> return () | ||||||
|   server baseurl port opts args j |   server baseurl port opts args j | ||||||
| 
 | 
 | ||||||
| @ -98,10 +107,11 @@ browser baseurl = do | |||||||
| server :: String -> Int -> [Opt] -> [String] -> Journal -> IO () | server :: String -> Int -> [Opt] -> [String] -> Journal -> IO () | ||||||
| server baseurl port opts args j = do | server baseurl port opts args j = do | ||||||
|     printf "starting web server on port %d with base url %s\n" port baseurl |     printf "starting web server on port %d with base url %s\n" port baseurl | ||||||
|     fp <- getDataFileName "web" |     dir <- getDataFileName "web" | ||||||
|     let app = HledgerWebApp{ |     let app = HledgerWebApp{ | ||||||
|                appRoot=baseurl |                appRoot=baseurl | ||||||
|               ,appWebdir=fp |               ,appDir=dir | ||||||
|  |               ,appStatic=fileLookupDir (dir </> "static") $ typeByExt -- ++[("hamlet","text/plain")] | ||||||
|               ,appOpts=opts |               ,appOpts=opts | ||||||
|               ,appArgs=args |               ,appArgs=args | ||||||
|               ,appJournal=j |               ,appJournal=j | ||||||
| @ -156,22 +166,14 @@ getHandlerParameters = do | |||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| -- handlers & templates | -- handlers & templates | ||||||
| 
 | 
 | ||||||
| getStyleCss :: Handler HledgerWebApp () | getIndexR :: Handler HledgerWebApp () | ||||||
| getStyleCss = do | getIndexR = redirect RedirectTemporary defaultroute | ||||||
|     app <- getYesod |  | ||||||
|     let dir = appWebdir app |  | ||||||
|     sendFile "text/css" $ dir </> "style.css" |  | ||||||
| 
 |  | ||||||
| ---------------------------------------------------------------------- |  | ||||||
| 
 |  | ||||||
| getIndexPage :: Handler HledgerWebApp () |  | ||||||
| getIndexPage = redirect RedirectTemporary defaultpage |  | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| -- | A combined accounts and journal view. | -- | A combined accounts and journal view. | ||||||
| getAccountsJournalPage :: Handler HledgerWebApp RepHtml | getJournalR :: Handler HledgerWebApp RepHtml | ||||||
| getAccountsJournalPage = do | getJournalR = do | ||||||
|   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters |   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters | ||||||
|   today <- liftIO getCurrentDay |   today <- liftIO getCurrentDay | ||||||
|   -- app <- getYesod |   -- app <- getYesod | ||||||
| @ -183,11 +185,10 @@ getAccountsJournalPage = do | |||||||
|       td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} |       td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} | ||||||
|       editform' = editform td $ jtext j |       editform' = editform td $ jtext j | ||||||
|   hamletToRepHtml $ pageLayout td [$hamlet| |   hamletToRepHtml $ pageLayout td [$hamlet| | ||||||
| ^scripts^ |  | ||||||
| %div.ledger | %div.ledger | ||||||
|  %div.accounts!style=float:left;  ^br^ |  %div.accounts!style=float:left;  ^br^ | ||||||
|  ^navlinks.td^ |  ^navlinks.td^ | ||||||
|  ^addform^ |  ^addform.td^ | ||||||
|  ^editform'^ |  ^editform'^ | ||||||
|  ^importform^ |  ^importform^ | ||||||
|  %div#transactions.journal |  %div#transactions.journal | ||||||
| @ -195,14 +196,14 @@ getAccountsJournalPage = do | |||||||
|   ^jr^ |   ^jr^ | ||||||
| |] | |] | ||||||
| 
 | 
 | ||||||
| postAccountsJournalPage :: Handler HledgerWebApp RepPlain | postJournalR :: Handler HledgerWebApp RepPlain | ||||||
| postAccountsJournalPage = postJournalOnlyPage | postJournalR = postJournalOnlyR | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| -- | A combined accounts and register view. | -- | A combined accounts and register view. | ||||||
| getAccountsRegisterPage :: Handler HledgerWebApp RepHtml | getRegisterR :: Handler HledgerWebApp RepHtml | ||||||
| getAccountsRegisterPage = do | getRegisterR = do | ||||||
|   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters |   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters | ||||||
|   today <- liftIO getCurrentDay |   today <- liftIO getCurrentDay | ||||||
|   -- app <- getYesod |   -- app <- getYesod | ||||||
| @ -215,11 +216,10 @@ getAccountsRegisterPage = do | |||||||
|       td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} |       td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} | ||||||
|       editform' = editform td $ jtext j |       editform' = editform td $ jtext j | ||||||
|   hamletToRepHtml $ pageLayout td [$hamlet| |   hamletToRepHtml $ pageLayout td [$hamlet| | ||||||
| ^scripts^ |  | ||||||
| %div.ledger | %div.ledger | ||||||
|  %div.accounts!style=float:left;  ^br^ |  %div.accounts!style=float:left;  ^br^ | ||||||
|  ^navlinks.td^ |  ^navlinks.td^ | ||||||
|  ^addform^ |  ^addform.td^ | ||||||
|  ^editform'^ |  ^editform'^ | ||||||
|  ^importform^ |  ^importform^ | ||||||
|  %div#transactions.register |  %div#transactions.register | ||||||
| @ -227,14 +227,14 @@ getAccountsRegisterPage = do | |||||||
|   ^rr^ |   ^rr^ | ||||||
| |] | |] | ||||||
| 
 | 
 | ||||||
| postAccountsRegisterPage :: Handler HledgerWebApp RepPlain | postRegisterR :: Handler HledgerWebApp RepPlain | ||||||
| postAccountsRegisterPage = postJournalOnlyPage | postRegisterR = postJournalOnlyR | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| -- | A simple accounts and balances view like hledger balance. | -- | A simple accounts and balances view like hledger balance. | ||||||
| getAccountsPage :: Handler HledgerWebApp RepHtml | getAccountsOnlyR :: Handler HledgerWebApp RepHtml | ||||||
| getAccountsPage = do | getAccountsOnlyR = do | ||||||
|   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters |   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters | ||||||
|   today <- liftIO getCurrentDay |   today <- liftIO getCurrentDay | ||||||
|   let td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} |   let td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} | ||||||
| @ -308,8 +308,8 @@ isAccountRegex s = take 1 s == "^" && (take 5 $ reverse s) == ")$|:(" | |||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| -- | A basic journal view, like hledger print, with editing. | -- | A basic journal view, like hledger print, with editing. | ||||||
| getJournalOnlyPage :: Handler HledgerWebApp RepHtml | getJournalOnlyR :: Handler HledgerWebApp RepHtml | ||||||
| getJournalOnlyPage = do | getJournalOnlyR = do | ||||||
|   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters |   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters | ||||||
|   today <- liftIO getCurrentDay |   today <- liftIO getCurrentDay | ||||||
|   let td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} |   let td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} | ||||||
| @ -317,12 +317,11 @@ getJournalOnlyPage = do | |||||||
|       txns = journalReportAsHtml opts td $ journalReport opts fspec j |       txns = journalReportAsHtml opts td $ journalReport opts fspec j | ||||||
|   hamletToRepHtml $ pageLayout td [$hamlet| |   hamletToRepHtml $ pageLayout td [$hamlet| | ||||||
| %div.journal | %div.journal | ||||||
|  ^scripts^ |  | ||||||
|  %div.nav2 |  %div.nav2 | ||||||
|   %a#addformlink!href!onclick="return addformToggle()" add one transaction |   %a#addformlink!href!onclick="return addformToggle()" add one transaction | ||||||
|   \ | $ |   \ | $ | ||||||
|   %a#editformlink!href!onclick="return editformToggle()" edit the whole journal |   %a#editformlink!href!onclick="return editformToggle()" edit the whole journal | ||||||
|  ^addform^ |  ^addform.td^ | ||||||
|  ^editform'^ |  ^editform'^ | ||||||
|  #transactions ^txns^ |  #transactions ^txns^ | ||||||
| |] | |] | ||||||
| @ -346,9 +345,25 @@ journalReportAsHtml _ td items = [$hamlet| | |||||||
|        evenodd = if even n then "even" else "odd" |        evenodd = if even n then "even" else "odd" | ||||||
|        txn = trimnl $ showTransaction t where trimnl = reverse . dropWhile (=='\n') . reverse |        txn = trimnl $ showTransaction t where trimnl = reverse . dropWhile (=='\n') . reverse | ||||||
| 
 | 
 | ||||||
| addform :: Hamlet HledgerWebAppRoute | addform :: TemplateData -> Hamlet HledgerWebAppRoute | ||||||
| addform = [$hamlet| | addform td = [$hamlet| | ||||||
|  %form#addform!method=POST!style=display:none; | %script!type=text/javascript | ||||||
|  |  $$(document).ready(function() { | ||||||
|  |     /* dhtmlxcombo setup */ | ||||||
|  |     window.dhx_globalImgPath="../static/images/"; | ||||||
|  |     var desccombo  = new dhtmlXCombo("description"); | ||||||
|  |     var acct1combo = new dhtmlXCombo("account1"); | ||||||
|  |     var acct2combo = new dhtmlXCombo("account2"); | ||||||
|  |     desccombo.enableFilteringMode(true); | ||||||
|  |     acct1combo.enableFilteringMode(true); | ||||||
|  |     acct2combo.enableFilteringMode(true); | ||||||
|  |     desccombo.setSize(300); | ||||||
|  |     acct1combo.setSize(300); | ||||||
|  |     acct2combo.setSize(300); | ||||||
|  |     /* desccombo.enableOptionAutoHeight(true, 20); */ | ||||||
|  |     /* desccombo.setOptionHeight(200); */ | ||||||
|  |  }); | ||||||
|  | %form#addform!method=POST!style=display:none; | ||||||
|   %table.form |   %table.form | ||||||
|    %tr |    %tr | ||||||
|     %td!colspan=4 |     %td!colspan=4 | ||||||
| @ -361,7 +376,10 @@ addform = [$hamlet| | |||||||
|        %td!style=padding-left:1em; |        %td!style=padding-left:1em; | ||||||
|         Description: |         Description: | ||||||
|        %td |        %td | ||||||
|         %input.textinput!size=35!name=description!value=$desc$ |         %select!id=description!name=description | ||||||
|  |          %option | ||||||
|  |          $forall descriptions d | ||||||
|  |           %option!value=$d$ $d$ | ||||||
|       %tr.helprow |       %tr.helprow | ||||||
|        %td |        %td | ||||||
|        %td |        %td | ||||||
| @ -369,8 +387,7 @@ addform = [$hamlet| | |||||||
|        %td |        %td | ||||||
|        %td |        %td | ||||||
|         .help $deschelp$ |         .help $deschelp$ | ||||||
|    ^transactionfields1^ |    ^postingsfields.td^ | ||||||
|    ^transactionfields2^ |  | ||||||
|    %tr#addbuttonrow |    %tr#addbuttonrow | ||||||
|     %td!colspan=4 |     %td!colspan=4 | ||||||
|      %input!type=hidden!name=action!value=add |      %input!type=hidden!name=action!value=add | ||||||
| @ -378,20 +395,29 @@ addform = [$hamlet| | |||||||
| |] | |] | ||||||
|  where |  where | ||||||
|   -- datehelplink = helplink "dates" "..." |   -- datehelplink = helplink "dates" "..." | ||||||
|   datehelp = "eg: 7/20, 2010/1/1, " |   datehelp = "eg: 2010/7/20" | ||||||
|   deschelp = "eg: supermarket (optional)" |   deschelp = "eg: supermarket (optional)" | ||||||
|   date = "today" |   date = "today" | ||||||
|   desc = "" |   descriptions = sort $ nub $ map tdescription $ jtxns $ j td | ||||||
|   transactionfields1 = transactionfields 1 |  | ||||||
|   transactionfields2 = transactionfields 2 |  | ||||||
| 
 | 
 | ||||||
| transactionfields :: Int -> Hamlet HledgerWebAppRoute | postingsfields :: TemplateData -> Hamlet HledgerWebAppRoute | ||||||
| transactionfields n = [$hamlet| | postingsfields td = [$hamlet| | ||||||
|  |  ^p1^ | ||||||
|  |  ^p2^ | ||||||
|  | |] | ||||||
|  |   where | ||||||
|  |     p1 = postingfields td 1 | ||||||
|  |     p2 = postingfields td 2 | ||||||
|  | 
 | ||||||
|  | postingfields :: TemplateData -> Int -> Hamlet HledgerWebAppRoute | ||||||
|  | postingfields td n = [$hamlet| | ||||||
|  %tr#postingrow |  %tr#postingrow | ||||||
|   %td!align=right |   %td!align=right $acctlabel$: | ||||||
|    $label$: |  | ||||||
|   %td |   %td | ||||||
|    %input.textinput!size=35!name=$acctvar$!value=$acct$ |    %select!id=$acctvar$!name=$acctvar$ | ||||||
|  |     %option | ||||||
|  |     $forall acctnames a | ||||||
|  |      %option!value=$a$ $a$ | ||||||
|   ^amtfield^ |   ^amtfield^ | ||||||
|  %tr.helprow |  %tr.helprow | ||||||
|   %td |   %td | ||||||
| @ -402,24 +428,26 @@ transactionfields n = [$hamlet| | |||||||
|    .help $amthelp$ |    .help $amthelp$ | ||||||
| |] | |] | ||||||
|  where |  where | ||||||
|   label | n == 1    = "To account" |   numbered = (++ show n) | ||||||
|         | otherwise = "From account" |   acctvar = numbered "account" | ||||||
|   accthelp | n == 1    = "eg: expenses:food" |   amtvar = numbered "amount" | ||||||
|            | otherwise = "eg: assets:bank:checking" |   acctnames = sort $ journalAccountNamesUsed $ j td | ||||||
|   amtfield | n == 1 = [$hamlet| |   (acctlabel, accthelp, amtfield, amthelp) | ||||||
|  |        | n == 1     = ("To account" | ||||||
|  |                      ,"eg: expenses:food" | ||||||
|  |                      ,[$hamlet| | ||||||
|                        %td!style=padding-left:1em; |                        %td!style=padding-left:1em; | ||||||
|                         Amount: |                         Amount: | ||||||
|                        %td |                        %td | ||||||
|                         %input.textinput!size=15!name=$amtvar$!value=$amt$ |                         %input.textinput!size=15!name=$amtvar$!value="" | ||||||
|                        |] |                        |] | ||||||
|            | otherwise = nulltemplate |                      ,"eg: $6" | ||||||
|   amthelp | n == 1    = "eg: 5, $6, €7.01" |                      ) | ||||||
|           | otherwise = "" |        | otherwise = ("From account" | ||||||
|   acct = "" |                      ,"eg: assets:bank:checking" | ||||||
|   amt = "" |                      ,nulltemplate | ||||||
|   numbered = (++ show n) |                      ,"" | ||||||
|   acctvar = numbered "accountname" |                      ) | ||||||
|   amtvar = numbered "amount" |  | ||||||
| 
 | 
 | ||||||
| editform :: TemplateData -> String -> Hamlet HledgerWebAppRoute | editform :: TemplateData -> String -> Hamlet HledgerWebAppRoute | ||||||
| editform _ content = [$hamlet| | editform _ content = [$hamlet| | ||||||
| @ -455,142 +483,8 @@ importform = [$hamlet| | |||||||
|      %a!href!onclick="return importformToggle()" cancel |      %a!href!onclick="return importformToggle()" cancel | ||||||
| |] | |] | ||||||
| 
 | 
 | ||||||
| scripts = [$hamlet| | postJournalOnlyR :: Handler HledgerWebApp RepPlain | ||||||
| <script type="text/javascript"> | postJournalOnlyR = do | ||||||
| 
 |  | ||||||
|  function filterformToggle() { |  | ||||||
|  var a = document.getElementById('addform'); |  | ||||||
|  var e = document.getElementById('editform'); |  | ||||||
|  var f = document.getElementById('filterform'); |  | ||||||
|  var i = document.getElementById('importform'); |  | ||||||
|  var t = document.getElementById('transactions'); |  | ||||||
|  var alink = document.getElementById('addformlink'); |  | ||||||
|  var elink = document.getElementById('editformlink'); |  | ||||||
|  var flink = document.getElementById('filterformlink'); |  | ||||||
|  var ilink = document.getElementById('importformlink'); |  | ||||||
|  var jlink = document.getElementById('journallink'); |  | ||||||
|  var rlink = document.getElementById('registerlink'); |  | ||||||
| 
 |  | ||||||
|   if (f.style.display == 'none') { |  | ||||||
|    flink.style['font-weight'] = 'bold'; |  | ||||||
|    f.style.display = 'block'; |  | ||||||
|   } else { |  | ||||||
|    flink.style['font-weight'] = 'normal'; |  | ||||||
|    f.style.display = 'none'; |  | ||||||
|   } |  | ||||||
|   return false; |  | ||||||
|  } |  | ||||||
| 
 |  | ||||||
|  function addformToggle() { |  | ||||||
|  var a = document.getElementById('addform'); |  | ||||||
|  var e = document.getElementById('editform'); |  | ||||||
|  var f = document.getElementById('filterform'); |  | ||||||
|  var i = document.getElementById('importform'); |  | ||||||
|  var t = document.getElementById('transactions'); |  | ||||||
|  var alink = document.getElementById('addformlink'); |  | ||||||
|  var elink = document.getElementById('editformlink'); |  | ||||||
|  var flink = document.getElementById('filterformlink'); |  | ||||||
|  var ilink = document.getElementById('importformlink'); |  | ||||||
|  var jlink = document.getElementById('journallink'); |  | ||||||
|  var rlink = document.getElementById('registerlink'); |  | ||||||
| 
 |  | ||||||
|   if (a.style.display == 'none') { |  | ||||||
|    alink.style['font-weight'] = 'bold'; |  | ||||||
|    elink.style['font-weight'] = 'normal'; |  | ||||||
|    ilink.style['font-weight'] = 'normal'; |  | ||||||
|    jlink.style['font-weight'] = 'normal'; |  | ||||||
|    rlink.style['font-weight'] = 'normal'; |  | ||||||
|    a.style.display = 'block'; |  | ||||||
|    e.style.display = 'none'; |  | ||||||
|    i.style.display = 'none'; |  | ||||||
|    t.style.display = 'none'; |  | ||||||
|   } else { |  | ||||||
|    alink.style['font-weight'] = 'normal'; |  | ||||||
|    elink.style['font-weight'] = 'normal'; |  | ||||||
|    ilink.style['font-weight'] = 'normal'; |  | ||||||
|    a.style.display = 'none'; |  | ||||||
|    e.style.display = 'none'; |  | ||||||
|    i.style.display = 'none'; |  | ||||||
|    t.style.display = 'block'; |  | ||||||
|   } |  | ||||||
|   return false; |  | ||||||
|  } |  | ||||||
| 
 |  | ||||||
|  function editformToggle() { |  | ||||||
|  var a = document.getElementById('addform'); |  | ||||||
|  var e = document.getElementById('editform'); |  | ||||||
|  var f = document.getElementById('filterform'); |  | ||||||
|  var i = document.getElementById('importform'); |  | ||||||
|  var t = document.getElementById('transactions'); |  | ||||||
|  var alink = document.getElementById('addformlink'); |  | ||||||
|  var elink = document.getElementById('editformlink'); |  | ||||||
|  var flink = document.getElementById('filterformlink'); |  | ||||||
|  var ilink = document.getElementById('importformlink'); |  | ||||||
|  var jlink = document.getElementById('journallink'); |  | ||||||
|  var rlink = document.getElementById('registerlink'); |  | ||||||
| 
 |  | ||||||
|   if (e.style.display == 'none') { |  | ||||||
|    alink.style['font-weight'] = 'normal'; |  | ||||||
|    elink.style['font-weight'] = 'bold'; |  | ||||||
|    ilink.style['font-weight'] = 'normal'; |  | ||||||
|    jlink.style['font-weight'] = 'normal'; |  | ||||||
|    rlink.style['font-weight'] = 'normal'; |  | ||||||
|    a.style.display = 'none'; |  | ||||||
|    e.style.display = 'block'; |  | ||||||
|    i.style.display = 'none'; |  | ||||||
|    t.style.display = 'none'; |  | ||||||
|   } else { |  | ||||||
|    alink.style['font-weight'] = 'normal'; |  | ||||||
|    elink.style['font-weight'] = 'normal'; |  | ||||||
|    ilink.style['font-weight'] = 'normal'; |  | ||||||
|    a.style.display = 'none'; |  | ||||||
|    e.style.display = 'none'; |  | ||||||
|    i.style.display = 'none'; |  | ||||||
|    t.style.display = 'block'; |  | ||||||
|   } |  | ||||||
|   return false; |  | ||||||
|  } |  | ||||||
| 
 |  | ||||||
|  function importformToggle() { |  | ||||||
|  var a = document.getElementById('addform'); |  | ||||||
|  var e = document.getElementById('editform'); |  | ||||||
|  var f = document.getElementById('filterform'); |  | ||||||
|  var i = document.getElementById('importform'); |  | ||||||
|  var t = document.getElementById('transactions'); |  | ||||||
|  var alink = document.getElementById('addformlink'); |  | ||||||
|  var elink = document.getElementById('editformlink'); |  | ||||||
|  var flink = document.getElementById('filterformlink'); |  | ||||||
|  var ilink = document.getElementById('importformlink'); |  | ||||||
|  var jlink = document.getElementById('journallink'); |  | ||||||
|  var rlink = document.getElementById('registerlink'); |  | ||||||
| 
 |  | ||||||
|   if (i.style.display == 'none') { |  | ||||||
|    alink.style['font-weight'] = 'normal'; |  | ||||||
|    elink.style['font-weight'] = 'normal'; |  | ||||||
|    ilink.style['font-weight'] = 'bold'; |  | ||||||
|    jlink.style['font-weight'] = 'normal'; |  | ||||||
|    rlink.style['font-weight'] = 'normal'; |  | ||||||
|    a.style.display = 'none'; |  | ||||||
|    e.style.display = 'none'; |  | ||||||
|    i.style.display = 'block'; |  | ||||||
|    t.style.display = 'none'; |  | ||||||
|   } else { |  | ||||||
|    alink.style['font-weight'] = 'normal'; |  | ||||||
|    elink.style['font-weight'] = 'normal'; |  | ||||||
|    ilink.style['font-weight'] = 'normal'; |  | ||||||
|    a.style.display = 'none'; |  | ||||||
|    e.style.display = 'none'; |  | ||||||
|    i.style.display = 'none'; |  | ||||||
|    t.style.display = 'block'; |  | ||||||
|   } |  | ||||||
|   return false; |  | ||||||
|  } |  | ||||||
| 
 |  | ||||||
| </script> |  | ||||||
| |] |  | ||||||
| 
 |  | ||||||
| postJournalOnlyPage :: Handler HledgerWebApp RepPlain |  | ||||||
| postJournalOnlyPage = do |  | ||||||
|   action <- runFormPost' $ maybeStringInput "action" |   action <- runFormPost' $ maybeStringInput "action" | ||||||
|   case action of Just "edit"   -> postEditForm |   case action of Just "edit"   -> postEditForm | ||||||
|                  Just "import" -> postImportForm |                  Just "import" -> postImportForm | ||||||
| @ -606,9 +500,9 @@ postAddForm = do | |||||||
|     $ (,,,,,) |     $ (,,,,,) | ||||||
|     <$> maybeStringInput "date" |     <$> maybeStringInput "date" | ||||||
|     <*> maybeStringInput "description" |     <*> maybeStringInput "description" | ||||||
|     <*> maybeStringInput "accountname1" |     <*> maybeStringInput "account1" | ||||||
|     <*> maybeStringInput "amount1" |     <*> maybeStringInput "amount1" | ||||||
|     <*> maybeStringInput "accountname2" |     <*> maybeStringInput "account2" | ||||||
|     <*> maybeStringInput "amount2" |     <*> maybeStringInput "amount2" | ||||||
|   -- supply defaults and parse date and amounts, or get errors. |   -- supply defaults and parse date and amounts, or get errors. | ||||||
|   let dateE = maybe (Left "date required") (either (\e -> Left $ showDateParseError e) Right . fixSmartDateStrEither today) dateM |   let dateE = maybe (Left "date required") (either (\e -> Left $ showDateParseError e) Right . fixSmartDateStrEither today) dateM | ||||||
| @ -643,14 +537,14 @@ postAddForm = do | |||||||
|    Left errs -> do |    Left errs -> do | ||||||
|     -- save current form values in session |     -- save current form values in session | ||||||
|     setMessage $ string $ intercalate "; " errs |     setMessage $ string $ intercalate "; " errs | ||||||
|     redirect RedirectTemporary AccountsRegisterPage |     redirect RedirectTemporary RegisterR | ||||||
| 
 | 
 | ||||||
|    Right t -> do |    Right t -> do | ||||||
|     let t' = txnTieKnot t -- XXX move into balanceTransaction |     let t' = txnTieKnot t -- XXX move into balanceTransaction | ||||||
|     j <- liftIO $ fromJust `fmap` getValue "hledger" "journal" |     j <- liftIO $ fromJust `fmap` getValue "hledger" "journal" | ||||||
|     liftIO $ journalAddTransaction j opts t' |     liftIO $ journalAddTransaction j opts t' | ||||||
|     setMessage $ string $ printf "Added transaction:\n%s" (show t') |     setMessage $ string $ printf "Added transaction:\n%s" (show t') | ||||||
|     redirect RedirectTemporary AccountsRegisterPage |     redirect RedirectTemporary RegisterR | ||||||
| 
 | 
 | ||||||
| -- | Handle a journal edit form post. | -- | Handle a journal edit form post. | ||||||
| postEditForm :: Handler HledgerWebApp RepPlain | postEditForm :: Handler HledgerWebApp RepPlain | ||||||
| @ -663,7 +557,7 @@ postEditForm = do | |||||||
|    Left errs -> do |    Left errs -> do | ||||||
|     -- XXX should save current form values in session |     -- XXX should save current form values in session | ||||||
|     setMessage $ string errs |     setMessage $ string errs | ||||||
|     redirect RedirectTemporary AccountsJournalPage |     redirect RedirectTemporary JournalR | ||||||
| 
 | 
 | ||||||
|    Right t' -> do |    Right t' -> do | ||||||
|     -- try to avoid unnecessary backups or saving invalid data |     -- try to avoid unnecessary backups or saving invalid data | ||||||
| @ -677,24 +571,24 @@ postEditForm = do | |||||||
|     if not changed |     if not changed | ||||||
|      then do |      then do | ||||||
|        setMessage $ string $ "No change" |        setMessage $ string $ "No change" | ||||||
|        redirect RedirectTemporary AccountsJournalPage |        redirect RedirectTemporary JournalR | ||||||
|      else do |      else do | ||||||
|       jE <- liftIO $ journalFromPathAndString Nothing f tnew |       jE <- liftIO $ journalFromPathAndString Nothing f tnew | ||||||
|       either |       either | ||||||
|        (\e -> do |        (\e -> do | ||||||
|           setMessage $ string e |           setMessage $ string e | ||||||
|           redirect RedirectTemporary AccountsJournalPage) |           redirect RedirectTemporary JournalR) | ||||||
|        (const $ do |        (const $ do | ||||||
|           liftIO $ writeFileWithBackup f tnew |           liftIO $ writeFileWithBackup f tnew | ||||||
|           setMessage $ string $ printf "Saved journal %s\n" (show f) |           setMessage $ string $ printf "Saved journal %s\n" (show f) | ||||||
|           redirect RedirectTemporary AccountsJournalPage) |           redirect RedirectTemporary JournalR) | ||||||
|        jE |        jE | ||||||
| 
 | 
 | ||||||
| -- | Handle an import page post. | -- | Handle an import page post. | ||||||
| postImportForm :: Handler HledgerWebApp RepPlain | postImportForm :: Handler HledgerWebApp RepPlain | ||||||
| postImportForm = do | postImportForm = do | ||||||
|   setMessage $ string $ "can't handle file upload yet" |   setMessage $ string $ "can't handle file upload yet" | ||||||
|   redirect RedirectTemporary AccountsJournalPage |   redirect RedirectTemporary JournalR | ||||||
|   -- -- get form input values, or basic validation errors. E means an Either value. |   -- -- get form input values, or basic validation errors. E means an Either value. | ||||||
|   -- fileM <- runFormPost' $ maybeFileInput "file" |   -- fileM <- runFormPost' $ maybeFileInput "file" | ||||||
|   -- let fileE = maybe (Left "No file provided") Right fileM |   -- let fileE = maybe (Left "No file provided") Right fileM | ||||||
| @ -702,17 +596,17 @@ postImportForm = do | |||||||
|   -- case fileE of |   -- case fileE of | ||||||
|   --  Left errs -> do |   --  Left errs -> do | ||||||
|   --   setMessage $ string errs |   --   setMessage $ string errs | ||||||
|   --   redirect RedirectTemporary AccountsJournalPage |   --   redirect RedirectTemporary JournalR | ||||||
| 
 | 
 | ||||||
|   --  Right s -> do |   --  Right s -> do | ||||||
|   --    setMessage $ string $ s |   --    setMessage $ string $ s | ||||||
|   --    redirect RedirectTemporary AccountsJournalPage |   --    redirect RedirectTemporary JournalR | ||||||
| 
 | 
 | ||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| -- | A simple postings view like hledger register. | -- | A simple postings view like hledger register. | ||||||
| getRegisterOnlyPage :: Handler HledgerWebApp RepHtml | getRegisterOnlyR :: Handler HledgerWebApp RepHtml | ||||||
| getRegisterOnlyPage = do | getRegisterOnlyR = do | ||||||
|   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters |   (a, p, opts, fspec, j, msg, here) <- getHandlerParameters | ||||||
|   today <- liftIO getCurrentDay |   today <- liftIO getCurrentDay | ||||||
|   let td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} |   let td = mktd{here=here, title="hledger", msg=msg, a=a, p=p, j=j, today=today} | ||||||
| @ -753,8 +647,8 @@ mixedAmountAsHtml b = preEscapedString $ addclass $ intercalate "<br>" $ lines $ | |||||||
| ---------------------------------------------------------------------- | ---------------------------------------------------------------------- | ||||||
| 
 | 
 | ||||||
| -- | A standalone journal edit form page. | -- | A standalone journal edit form page. | ||||||
| getEditPage :: Handler HledgerWebApp RepHtml | getEditR :: Handler HledgerWebApp RepHtml | ||||||
| getEditPage = do | getEditR = do | ||||||
|   (a, p, _, _, _, msg, here) <- getHandlerParameters |   (a, p, _, _, _, msg, here) <- getHandlerParameters | ||||||
|   today <- liftIO getCurrentDay |   today <- liftIO getCurrentDay | ||||||
|   -- reload journal's text without parsing, if changed     -- XXX are we doing this right ? |   -- reload journal's text without parsing, if changed     -- XXX are we doing this right ? | ||||||
| @ -774,7 +668,11 @@ pageLayout td@TD{title=title, msg=msg} content = [$hamlet| | |||||||
|  %head |  %head | ||||||
|   %title $title$ |   %title $title$ | ||||||
|   %meta!http-equiv=Content-Type!content=$metacontent$ |   %meta!http-equiv=Content-Type!content=$metacontent$ | ||||||
|   %link!rel=stylesheet!type=text/css!href=@StyleCss@!media=all |   %script!type=text/javascript!src=@StaticR.jquery_js@ | ||||||
|  |   %script!type=text/javascript!src=@StaticR.dhtmlxcommon_js@ | ||||||
|  |   %script!type=text/javascript!src=@StaticR.dhtmlxcombo_js@ | ||||||
|  |   %script!type=text/javascript!src=@StaticR.hledger_js@ | ||||||
|  |   %link!rel=stylesheet!type=text/css!media=all!href=@StaticR.style_css@ | ||||||
|  %body |  %body | ||||||
|   ^navbar.td^ |   ^navbar.td^ | ||||||
|   #messages $m$ |   #messages $m$ | ||||||
| @ -787,7 +685,7 @@ pageLayout td@TD{title=title, msg=msg} content = [$hamlet| | |||||||
| navbar :: TemplateData -> Hamlet HledgerWebAppRoute | navbar :: TemplateData -> Hamlet HledgerWebAppRoute | ||||||
| navbar TD{p=p,j=j,today=today} = [$hamlet| | navbar TD{p=p,j=j,today=today} = [$hamlet| | ||||||
|  #navbar |  #navbar | ||||||
|   %a.topleftlink!href=$hledgerurl$ |   %a.topleftlink!href=$hledgerorgurl$ | ||||||
|    hledger |    hledger | ||||||
|    <br /> |    <br /> | ||||||
|    $version$ |    $version$ | ||||||
| @ -817,8 +715,8 @@ navlinks td = [$hamlet| | |||||||
| |] | |] | ||||||
| --  \ | $ | --  \ | $ | ||||||
|  where |  where | ||||||
|    accountsjournallink  = navlink td "journal" AccountsJournalPage |    accountsjournallink  = navlink td "journal" JournalR | ||||||
|    accountsregisterlink = navlink td "register" AccountsRegisterPage |    accountsregisterlink = navlink td "register" RegisterR | ||||||
| 
 | 
 | ||||||
| navlink :: TemplateData -> String -> HledgerWebAppRoute -> Hamlet HledgerWebAppRoute | navlink :: TemplateData -> String -> HledgerWebAppRoute -> Hamlet HledgerWebAppRoute | ||||||
| navlink TD{here=here,a=a,p=p} s dest = [$hamlet|%a#$s$link.$style$!href=@?u@ $s$|] | navlink TD{here=here,a=a,p=p} s dest = [$hamlet|%a#$s$link.$style$!href=@?u@ $s$|] | ||||||
|  | |||||||
							
								
								
									
										135
									
								
								data/web/static/hledger.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								data/web/static/hledger.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,135 @@ | |||||||
|  | /* hledger web ui javascripts */ | ||||||
|  | /* depends on jquery, other support libs, and additional js inserted inline */ | ||||||
|  | 
 | ||||||
|  | $(document).ready(function() { | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | function filterformToggle() { | ||||||
|  |  var a = document.getElementById('addform'); | ||||||
|  |  var e = document.getElementById('editform'); | ||||||
|  |  var f = document.getElementById('filterform'); | ||||||
|  |  var i = document.getElementById('importform'); | ||||||
|  |  var t = document.getElementById('transactions'); | ||||||
|  |  var alink = document.getElementById('addformlink'); | ||||||
|  |  var elink = document.getElementById('editformlink'); | ||||||
|  |  var flink = document.getElementById('filterformlink'); | ||||||
|  |  var ilink = document.getElementById('importformlink'); | ||||||
|  |  var jlink = document.getElementById('journallink'); | ||||||
|  |  var rlink = document.getElementById('registerlink'); | ||||||
|  | 
 | ||||||
|  |  if (f.style.display == 'none') { | ||||||
|  |   flink.style['font-weight'] = 'bold'; | ||||||
|  |   f.style.display = 'block'; | ||||||
|  |  } else { | ||||||
|  |   flink.style['font-weight'] = 'normal'; | ||||||
|  |   f.style.display = 'none'; | ||||||
|  |  } | ||||||
|  |  return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function addformToggle() { | ||||||
|  |  var a = document.getElementById('addform'); | ||||||
|  |  var e = document.getElementById('editform'); | ||||||
|  |  var f = document.getElementById('filterform'); | ||||||
|  |  var i = document.getElementById('importform'); | ||||||
|  |  var t = document.getElementById('transactions'); | ||||||
|  |  var alink = document.getElementById('addformlink'); | ||||||
|  |  var elink = document.getElementById('editformlink'); | ||||||
|  |  var flink = document.getElementById('filterformlink'); | ||||||
|  |  var ilink = document.getElementById('importformlink'); | ||||||
|  |  var jlink = document.getElementById('journallink'); | ||||||
|  |  var rlink = document.getElementById('registerlink'); | ||||||
|  | 
 | ||||||
|  |  if (a.style.display == 'none') { | ||||||
|  |   alink.style['font-weight'] = 'bold'; | ||||||
|  |   elink.style['font-weight'] = 'normal'; | ||||||
|  |   ilink.style['font-weight'] = 'normal'; | ||||||
|  |   jlink.style['font-weight'] = 'normal'; | ||||||
|  |   rlink.style['font-weight'] = 'normal'; | ||||||
|  |   a.style.display = 'block'; | ||||||
|  |   e.style.display = 'none'; | ||||||
|  |   i.style.display = 'none'; | ||||||
|  |   t.style.display = 'none'; | ||||||
|  |  } else { | ||||||
|  |   alink.style['font-weight'] = 'normal'; | ||||||
|  |   elink.style['font-weight'] = 'normal'; | ||||||
|  |   ilink.style['font-weight'] = 'normal'; | ||||||
|  |   a.style.display = 'none'; | ||||||
|  |   e.style.display = 'none'; | ||||||
|  |   i.style.display = 'none'; | ||||||
|  |   t.style.display = 'block'; | ||||||
|  |  } | ||||||
|  |  return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function editformToggle() { | ||||||
|  |  var a = document.getElementById('addform'); | ||||||
|  |  var e = document.getElementById('editform'); | ||||||
|  |  var f = document.getElementById('filterform'); | ||||||
|  |  var i = document.getElementById('importform'); | ||||||
|  |  var t = document.getElementById('transactions'); | ||||||
|  |  var alink = document.getElementById('addformlink'); | ||||||
|  |  var elink = document.getElementById('editformlink'); | ||||||
|  |  var flink = document.getElementById('filterformlink'); | ||||||
|  |  var ilink = document.getElementById('importformlink'); | ||||||
|  |  var jlink = document.getElementById('journallink'); | ||||||
|  |  var rlink = document.getElementById('registerlink'); | ||||||
|  | 
 | ||||||
|  |  if (e.style.display == 'none') { | ||||||
|  |   alink.style['font-weight'] = 'normal'; | ||||||
|  |   elink.style['font-weight'] = 'bold'; | ||||||
|  |   ilink.style['font-weight'] = 'normal'; | ||||||
|  |   jlink.style['font-weight'] = 'normal'; | ||||||
|  |   rlink.style['font-weight'] = 'normal'; | ||||||
|  |   a.style.display = 'none'; | ||||||
|  |   e.style.display = 'block'; | ||||||
|  |   i.style.display = 'none'; | ||||||
|  |   t.style.display = 'none'; | ||||||
|  |  } else { | ||||||
|  |   alink.style['font-weight'] = 'normal'; | ||||||
|  |   elink.style['font-weight'] = 'normal'; | ||||||
|  |   ilink.style['font-weight'] = 'normal'; | ||||||
|  |   a.style.display = 'none'; | ||||||
|  |   e.style.display = 'none'; | ||||||
|  |   i.style.display = 'none'; | ||||||
|  |   t.style.display = 'block'; | ||||||
|  |  } | ||||||
|  |  return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function importformToggle() { | ||||||
|  |  var a = document.getElementById('addform'); | ||||||
|  |  var e = document.getElementById('editform'); | ||||||
|  |  var f = document.getElementById('filterform'); | ||||||
|  |  var i = document.getElementById('importform'); | ||||||
|  |  var t = document.getElementById('transactions'); | ||||||
|  |  var alink = document.getElementById('addformlink'); | ||||||
|  |  var elink = document.getElementById('editformlink'); | ||||||
|  |  var flink = document.getElementById('filterformlink'); | ||||||
|  |  var ilink = document.getElementById('importformlink'); | ||||||
|  |  var jlink = document.getElementById('journallink'); | ||||||
|  |  var rlink = document.getElementById('registerlink'); | ||||||
|  | 
 | ||||||
|  |  if (i.style.display == 'none') { | ||||||
|  |   alink.style['font-weight'] = 'normal'; | ||||||
|  |   elink.style['font-weight'] = 'normal'; | ||||||
|  |   ilink.style['font-weight'] = 'bold'; | ||||||
|  |   jlink.style['font-weight'] = 'normal'; | ||||||
|  |   rlink.style['font-weight'] = 'normal'; | ||||||
|  |   a.style.display = 'none'; | ||||||
|  |   e.style.display = 'none'; | ||||||
|  |   i.style.display = 'block'; | ||||||
|  |   t.style.display = 'none'; | ||||||
|  |  } else { | ||||||
|  |   alink.style['font-weight'] = 'normal'; | ||||||
|  |   elink.style['font-weight'] = 'normal'; | ||||||
|  |   ilink.style['font-weight'] = 'normal'; | ||||||
|  |   a.style.display = 'none'; | ||||||
|  |   e.style.display = 'none'; | ||||||
|  |   i.style.display = 'none'; | ||||||
|  |   t.style.display = 'block'; | ||||||
|  |  } | ||||||
|  |  return false; | ||||||
|  | } | ||||||
| @ -4,7 +4,7 @@ | |||||||
| /* overspecified for cross-browser robustness */ | /* overspecified for cross-browser robustness */ | ||||||
| body                        { font-family:helvetica,arial,"sans serif"; } | body                        { font-family:helvetica,arial,"sans serif"; } | ||||||
| pre                         { font-family:courier,"courier new",monospace; } | pre                         { font-family:courier,"courier new",monospace; } | ||||||
| #addform input.textinput    { font-family:courier,"courier new",monospace; font-size:small; } | input.textinput, .dhx_combo_input, .dhx_combo_list    { font-size:small; } | ||||||
| #editform textarea          { font-family:courier,"courier new",monospace; font-size:small; } | #editform textarea          { font-family:courier,"courier new",monospace; font-size:small; } | ||||||
| .nav2                       { font-size:small; } | .nav2                       { font-size:small; } | ||||||
| #filterform                 { font-size:small; } | #filterform                 { font-size:small; } | ||||||
| @ -75,9 +75,152 @@ table.registerreport        { border-spacing:0; } | |||||||
| .firstposting td            { } | .firstposting td            { } | ||||||
| .registerreport .odd        { background-color:#f0f0f0; } | .registerreport .odd        { background-color:#f0f0f0; } | ||||||
| 
 | 
 | ||||||
| #addform input.textinput    { background-color:#eee; padding:4px; } | #addform input.textinput, #addform .dhx_combo_input, .dhx_combo_list   { background-color:#eee; padding:4px; } | ||||||
| #addform table              { } | #addform table              { } | ||||||
| #addform #addbuttonrow      { text-align:right; } | #addform #addbuttonrow      { text-align:right; } | ||||||
| /* #editform                   { width:95%; } */ | /* #editform                   { width:95%; } */ | ||||||
| #editform textarea          { width:100%; background-color:#eee; padding:4px; } | #editform textarea          { width:100%; background-color:#eee; padding:4px; } | ||||||
| #filterform table           { border-spacing:0; padding-left:1em; } | #filterform table           { border-spacing:0; padding-left:1em; } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /*------------------------------------------------------------------------------------------*/ | ||||||
|  | 
 | ||||||
|  | .dhx_combo_input{ | ||||||
|  | /* color:#333333; */ | ||||||
|  | /* font-family: Arial; */ | ||||||
|  | /* font-size: 9pt; */ | ||||||
|  | /* border:0px; */ | ||||||
|  | /* padding:2px 2px 2px 2px; */ | ||||||
|  | /* position:absolute; */ | ||||||
|  | /* top:0px; */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* table {border:thin solid red} */ | ||||||
|  | /* div {border:thin solid yellow} */ | ||||||
|  | 
 | ||||||
|  | .dhx_combo_box{ | ||||||
|  |     position:relative; | ||||||
|  |     display:inline-block; | ||||||
|  |     /* text-align:left; */ | ||||||
|  |     /* height:20px; */ | ||||||
|  |     /* _height:22px; */ | ||||||
|  |     /* overflow:hidden; */ | ||||||
|  |     /* background-color: white; */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .dhx_combo_list{ | ||||||
|  |     position:absolute; | ||||||
|  |     z-index:230; | ||||||
|  |     overflow-y:auto; | ||||||
|  |     overflow-x:hidden; | ||||||
|  |     white-space:nowrap; | ||||||
|  |     border:1px solid black; | ||||||
|  |     height:50%; | ||||||
|  |     /* background-color: white; */ | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .dhx_combo_list div{ | ||||||
|  |     cursor:default; | ||||||
|  |     padding:2px 2px 2px 2px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .dhx_selected_option{ | ||||||
|  |     background-color:navy; | ||||||
|  |     color:white; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .dhx_combo_img{ | ||||||
|  |     /* display:none; */ | ||||||
|  |     width:18px; | ||||||
|  |     height:20px; | ||||||
|  |     position:absolute; | ||||||
|  |     top:12px; | ||||||
|  |     right:-10px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .dhx_combo_option_img{ | ||||||
|  | 	position:relative; | ||||||
|  | 	top:1px; | ||||||
|  | 	margin:0px; | ||||||
|  | 	margin-left:2px; | ||||||
|  | 	left:0px; | ||||||
|  | 	width:18px; height:18px; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* .combo_dhx_sel{ */ | ||||||
|  | /* .dhx_selected_option{ */ | ||||||
|  | /*    background-image: url("../static/images/bg_selection.gif") !important; */ | ||||||
|  | /*    background-position: bottom; */ | ||||||
|  | /*    background-repeat: repeat-x; */ | ||||||
|  | /*    color:black; */ | ||||||
|  | /* } */ | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | /* .dhx_combo_img_rtl{ */ | ||||||
|  | /* 	position:absolute; */ | ||||||
|  | /* 	top:0px; */ | ||||||
|  | /* 	left:1px; */ | ||||||
|  | /* 	width:17px; */ | ||||||
|  | /* 	height:20px; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_option_img_rtl{ */ | ||||||
|  | /* 	float:right; */ | ||||||
|  | /* 	margin-right :0px; */ | ||||||
|  | /* 	width:18px; height:18px; */ | ||||||
|  | /* } */ | ||||||
|  | 
 | ||||||
|  | /* .dhx_combo_list_rtl{ */ | ||||||
|  | /* 	direction: rtl; */ | ||||||
|  | /* 	unicode-bidi : bidi-override; */ | ||||||
|  | /*    position:absolute; */ | ||||||
|  | /*    z-index:230; */ | ||||||
|  | /*    overflow-y:auto; */ | ||||||
|  | /*    overflow-x:hidden; */ | ||||||
|  | /*    border:1px solid black; */ | ||||||
|  | /*    height:100px; */ | ||||||
|  | /*    /\* font-family: Arial; *\/ */ | ||||||
|  | /*    font-size: 9pt; */ | ||||||
|  | /*    background-color: white; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_list_rtl div{ */ | ||||||
|  | /* 	direction: rtl; */ | ||||||
|  | /* 	unicode-bidi : bidi-override; */ | ||||||
|  | /* 	padding:2px 2px 2px 2px; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_list_rtl div div{ */ | ||||||
|  | /* 	float :right !important; */ | ||||||
|  | /* 	cursor:default; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_list_rtl div img{ */ | ||||||
|  | /* 	float :right !important; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_list_rtl div input{ */ | ||||||
|  | /* 	float :right !important; */ | ||||||
|  | /* } */ | ||||||
|  | 
 | ||||||
|  | /* .dhx_combo_box.dhx_skyblue{ */ | ||||||
|  | /* 	border:1px solid #a4bed4; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_box.dhx_skyblue .dhx_combo_input { */ | ||||||
|  | /* 	font-family:Tahoma; */ | ||||||
|  | /* 	font-size: 11px; */ | ||||||
|  | /* 	padding:3px; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_list.dhx_skyblue_list{ */ | ||||||
|  | /* 	background-color: #eaf2fb; */ | ||||||
|  | /* 	border:1px solid #a4bed4; */ | ||||||
|  | /* 	font-family:Tahoma; */ | ||||||
|  | /* 	font-size: 11px; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_list.dhx_skyblue_list div{ */ | ||||||
|  | /* 	cursor:default; */ | ||||||
|  | /* 	padding:3px 4px; */ | ||||||
|  | /* } */ | ||||||
|  | /* .dhx_combo_list_rtl.dhx_skyblue_list{ */ | ||||||
|  | /*    background-color: #eaf2fb; */ | ||||||
|  | /* 	border:1px solid #a4bed4; */ | ||||||
|  | /* 	font-family:Tahoma; */ | ||||||
|  | /* 	font-size: 11px; */ | ||||||
|  | /* } */ | ||||||
|  | 
 | ||||||
| @ -23,7 +23,12 @@ cabal-version:  >= 1.2 | |||||||
| build-type:     Custom | build-type:     Custom | ||||||
| data-dir:       data | data-dir:       data | ||||||
| data-files: | data-files: | ||||||
|                 web/style.css |                 web/static/style.css | ||||||
|  |                 web/static/hledger.js | ||||||
|  |                 web/static/jquery.js | ||||||
|  |                 web/static/dhtmlxcommon.js | ||||||
|  |                 web/static/dhtmlxcombo.js | ||||||
|  |                 web/static/images/combo_select.gif | ||||||
| extra-tmp-files: | extra-tmp-files: | ||||||
| extra-source-files: | extra-source-files: | ||||||
|   README.rst |   README.rst | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user