diff --git a/Application.hs b/Application.hs index 4f5abda..d7b05e5 100644 --- a/Application.hs +++ b/Application.hs @@ -50,6 +50,7 @@ import Handler.YourAccount import Handler.AccountReset import Handler.Presentation import Handler.Tags +import Handler.EditSubmission -- This line actually creates our YesodDispatch instance. It is the second half -- of the call to mkYesodData which occurs in Foundation.hs. Please see the diff --git a/Handler/EditSubmission.hs b/Handler/EditSubmission.hs new file mode 100644 index 0000000..0083fa4 --- /dev/null +++ b/Handler/EditSubmission.hs @@ -0,0 +1,31 @@ +{-# LANGUAGE TupleSections, OverloadedStrings, RankNTypes #-} + +module Handler.EditSubmission where + +import Import +import Yesod.Form.Bootstrap3 (BootstrapFormLayout (..), renderBootstrap3, bfs) + +getEditSubmissionR :: SubmissionId -> Handler Html +getEditSubmissionR submissionId = do + (formWidget, formEnctype) <- generateFormPost editSubmissionForm + doEditSubmission formWidget formEnctype submissionId + +postEditSubmissionR :: SubmissionId -> Handler Html +postEditSubmissionR submissionId = do + ((result, formWidget), formEnctype) <- runFormPost editSubmissionForm + doEditSubmission formWidget formEnctype submissionId + +doEditSubmission formWidget formEnctype submissionId = do + submission <- runDB $ get404 submissionId + defaultLayout $ do + setTitle "Edit a submission" + $(widgetFile "edit-submission") + +editSubmissionForm :: Form (Text, Maybe Text) +editSubmissionForm = renderBootstrap3 BootstrapBasicForm $ (,) + <$> areq textField (bfs MsgSubmissionDescription) Nothing + <*> aopt textField (tagsfs MsgSubmissionTags) Nothing + +tagsfs :: RenderMessage site msg => msg -> FieldSettings site +tagsfs msg = attrs { fsAttrs = ("data-role"::Text,"tagsinput"::Text):(fsAttrs attrs)} + where attrs = bfs msg diff --git a/config/routes b/config/routes index fd40b22..b6dbb81 100644 --- a/config/routes +++ b/config/routes @@ -33,4 +33,6 @@ /tags TagsR GET POST +/edit-submission/#SubmissionId EditSubmissionR GET POST + /presentation/4real Presentation4RealR GET diff --git a/gonito.cabal b/gonito.cabal index 8aadcc2..ef07cba 100644 --- a/gonito.cabal +++ b/gonito.cabal @@ -46,6 +46,7 @@ library Handler.AccountReset Handler.Presentation Handler.Tags + Handler.EditSubmission if flag(dev) || flag(library-only) cpp-options: -DDEVELOPMENT diff --git a/messages/en.msg b/messages/en.msg index d6dfb8c..1bf1880 100644 --- a/messages/en.msg +++ b/messages/en.msg @@ -13,6 +13,7 @@ Submit: Submit SubmissionUrl: Submission repo URL SubmissionBranch: Submission repo branch SubmissionDescription: Submission description +SubmissionTags: Submission tags YourAccount: your account AboutMe: about me AccountName: name diff --git a/static/css/bootstrap-tagsinput.css b/static/css/bootstrap-tagsinput.css new file mode 100644 index 0000000..b31f01c --- /dev/null +++ b/static/css/bootstrap-tagsinput.css @@ -0,0 +1,55 @@ +.bootstrap-tagsinput { + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075); + display: inline-block; + padding: 4px 6px; + color: #555; + vertical-align: middle; + border-radius: 4px; + max-width: 100%; + line-height: 22px; + cursor: text; +} +.bootstrap-tagsinput input { + border: none; + box-shadow: none; + outline: none; + background-color: transparent; + padding: 0 6px; + margin: 0; + width: auto; + max-width: inherit; +} +.bootstrap-tagsinput.form-control input::-moz-placeholder { + color: #777; + opacity: 1; +} +.bootstrap-tagsinput.form-control input:-ms-input-placeholder { + color: #777; +} +.bootstrap-tagsinput.form-control input::-webkit-input-placeholder { + color: #777; +} +.bootstrap-tagsinput input:focus { + border: none; + box-shadow: none; +} +.bootstrap-tagsinput .tag { + margin-right: 2px; + color: white; +} +.bootstrap-tagsinput .tag [data-role="remove"] { + margin-left: 8px; + cursor: pointer; +} +.bootstrap-tagsinput .tag [data-role="remove"]:after { + content: "x"; + padding: 0px 2px; +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover { + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05); +} +.bootstrap-tagsinput .tag [data-role="remove"]:hover:active { + box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125); +} diff --git a/static/js/bootstrap-tagsinput.min.js b/static/js/bootstrap-tagsinput.min.js new file mode 100644 index 0000000..3adbfd9 --- /dev/null +++ b/static/js/bootstrap-tagsinput.min.js @@ -0,0 +1,7 @@ +/* + * bootstrap-tagsinput v0.6.1 by Tim Schlechter + * + */ + +!function(a){"use strict";function b(b,c){this.itemsArray=[],this.$element=a(b),this.$element.hide(),this.isSelect="SELECT"===b.tagName,this.multiple=this.isSelect&&b.hasAttribute("multiple"),this.objectItems=c&&c.itemValue,this.placeholderText=b.hasAttribute("placeholder")?this.$element.attr("placeholder"):"",this.inputSize=Math.max(1,this.placeholderText.length),this.$container=a('
'),this.$input=a('').appendTo(this.$container),this.$element.before(this.$container),this.build(c)}function c(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(a){return a[c]}}}function d(a,b){if("function"!=typeof a[b]){var c=a[b];a[b]=function(){return c}}}function e(a){return a?i.text(a).html():""}function f(a){var b=0;if(document.selection){a.focus();var c=document.selection.createRange();c.moveStart("character",-a.value.length),b=c.text.length}else(a.selectionStart||"0"==a.selectionStart)&&(b=a.selectionStart);return b}function g(b,c){var d=!1;return a.each(c,function(a,c){if("number"==typeof c&&b.which===c)return d=!0,!1;if(b.which===c.which){var e=!c.hasOwnProperty("altKey")||b.altKey===c.altKey,f=!c.hasOwnProperty("shiftKey")||b.shiftKey===c.shiftKey,g=!c.hasOwnProperty("ctrlKey")||b.ctrlKey===c.ctrlKey;if(e&&f&&g)return d=!0,!1}}),d}var h={tagClass:function(a){return"label label-info"},itemValue:function(a){return a?a.toString():a},itemText:function(a){return this.itemValue(a)},itemTitle:function(a){return null},freeInput:!0,addOnBlur:!0,maxTags:void 0,maxChars:void 0,confirmKeys:[13,44],delimiter:",",delimiterRegex:null,cancelConfirmKeysOnEmpty:!0,onTagExists:function(a,b){b.hide().fadeIn()},trimValue:!1,allowDuplicates:!1};b.prototype={constructor:b,add:function(b,c,d){var f=this;if(!(f.options.maxTags&&f.itemsArray.length>=f.options.maxTags)&&(b===!1||b)){if("string"==typeof b&&f.options.trimValue&&(b=a.trim(b)),"object"==typeof b&&!f.objectItems)throw"Can't add objects when itemValue option is not set";if(!b.toString().match(/^\s*$/)){if(f.isSelect&&!f.multiple&&f.itemsArray.length>0&&f.remove(f.itemsArray[0]),"string"==typeof b&&"INPUT"===this.$element[0].tagName){var g=f.options.delimiterRegex?f.options.delimiterRegex:f.options.delimiter,h=b.split(g);if(h.length>1){for(var i=0;i#{show $ submissionStamp $ submission} + +