I'm using a Freemarker macro for managing the content of two maps.
<#macro MACRO_NAME v>
<#nested v.val, v.msg>
</#macro>
Fruit map is structured like this
Map("fruits" -> Map("val", Map("banana" -> "yellow, "orange" -> "orange"), "msg" -> null))
And the other map, animals, looks like this
Map("animals" -> Map("insects" -> Map("butterflies" -> Map("val" -> Map("Hasora anura" -> "blue", Hasora badra -> "yellow"), "msg" -> null))))
It is ok if val is null, because I've a check in my Freemarker code. If fruits.val is null the following code will output false, false (the correct behavior)
${fruits.val???c}
<#MACRO_NAME fruits; fu, fuMsg>
${fu???c}
</#MACRO_NAME>
${animals.insects.butterflies.val???c}
<#MACRO_NAME animals.insects.butterflies; butterflies, buMsg>
${butterflies???c}
</#MACRO_NAME>
But my Problem is that if animals.insects.butterflies.val is null, this will output false, true but it should be false, false too.
I've have no idea why this happens.
wow a really weird behavior I think
the answer is: never, never name the loop var like your map key.
<#MACRO_NAME animals.insects.butterflies; bu, buMsg> instead of
<#MACRO_NAME animals.insects.butterflies; butterflies, buMsg> will work...
it was just a naming problem.
Related
Please Note: I could not a find a solution that could work here, so I used ports for the same.
I need to use Browser.Events.onKeyDown for which I have also written a decoder, I need to create some shortcuts for my web app thus I need to prevent default behavior of Meta key (on Mac) and Ctrl key (on other Os)
In my Subscription method I am using the following.
But there is no exposed way of using prevent Default.
let
decoder : Decode.Decoder Msg
decoder =
keyDecoder
|> Decode.andThen
(\( keyCode, ctrlKey ) ->
case keyCode of
39 ->
Decode.succeed <| ShortCutNext
37 ->
Decode.succeed <| ShortCutPrevious
_ ->
Decode.fail ""
)
in
Sub.batch
[ Browser.Events.onKeyDown decoder]
keyDecoder : Decode.Decoder ( Int, Bool )
keyDecoder =
Decode.map2 (\a -> \b -> ( a, b ))
(Decode.field "keyCode" Decode.int)
(Decode.field "metaKey" Decode.bool)
Note: The event is on the page itself and not on any element such as textarea thus Html.Events.custom "keydown" options decoder is not applicable.
I am trying to get the x and y coordinates of the mouse during a mouse-wheel-move event in the Elm 0.19 programming language.
I attempt it with this package. See under "Advanced Usage":
https://package.elm-lang.org/packages/mpizenberg/elm-pointer-events/3.1.0/Html-Events-Extra-Wheel
The package itself did not describe a clear example so I looked for an example in a similar package.
See the example under "advanced usage" in this page:
https://package.elm-lang.org/packages/mpizenberg/elm-pointer-events/3.1.0/Html-Events-Extra-Mouse
This example is very similar to what I need, but I can also not get this to work. Get exactly the same problem.
Here is my code adapted from the example to fit with mouse wheel:
module WheelDecoder exposing(..)
import Html exposing (div, text)
import Html.Events.Extra.Wheel as Wheel
import Json.Decode as Decode
type alias WheelEventWithOffsetXY =
{ wheelEvent : Wheel.Event
, offsetXY : {x: Float, y: Float}
}
decodeWeelWithOffsetXY : Decode.Decoder WheelEventWithOffsetXY
decodeWeelWithOffsetXY =
Decode.map2 WheelEventWithOffsetXY
Wheel.eventDecoder
offsetXYDecoder
offsetXYDecoder : Decode.Decoder {x: Float, y: Float}
offsetXYDecoder =
Decode.map2 (\a b -> {x=a,y=b})
(Decode.field "offsetY" Decode.float)
(Decode.field "offsetY" Decode.float)
type Msg
= WheelOffsetXY {x: Float, y: Float}
view =
div
[ (onWheelOffsetXY (\wheelEvent -> WheelOffsetXY (wheelEvent.offsetXY))) ]
[ (text "mousewheel here") ]
onWheelOffsetXY : (WheelEventWithOffsetXY -> msg) -> Html.Attribute msg
onWheelOffsetXY tag =
let
options = { stopPropagation = True, preventDefault = True }
func = Decode.map tag decodeWeelWithOffsetXY
attribute = Wheel.onWithOptions options func
in
attribute
When I try to compile with "elm make" I get the following error:
-- TYPE MISMATCH -------------------------------------- src/Map/WheelDecoder.elm
The 2nd argument to `onWithOptions` is not what I expect:
39| attribute = Wheel.onWithOptions options func
^^^^
This `func` value is a:
Decode.Decoder msg
But `onWithOptions` needs the 2nd argument to be:
Wheel.Event -> msg
Hint: I always figure out the argument types from left to right. If an argument
is acceptable, I assume it is “correct” and move on. So the problem may actually
be in one of the previous arguments!
This error message makes sense as I can see there is a type mismatch, but I have no clue about how to solve it.
It seems like Wheel.eventDecoder was meant to work with Html.Events.on or Html.Events.onWithOptions rather than Wheel.onWithOptions. These were removed in 0.19 in favor of Html.Events.custom, however, which is slightly different. Replacing onWheelOffsetXY with this seems to work:
onWheelOffsetXY : (WheelEventWithOffsetXY -> msg) -> Html.Attribute msg
onWheelOffsetXY tag =
let
options message =
{ message = message
, stopPropagation = True
, preventDefault = True
}
decoder =
decodeWeelWithOffsetXY
|> Decode.map tag
|> Decode.map options
in
Html.Events.custom "wheel" decoder
PS: There's a typo in decodeWeelWithOffsetXY, btw. I've left the typo in place.
PPS: Also, you're looking at outdated documentation. Here's the documentation for the latest version.
[error] Unexpected Exception: [Exception... "The URI scheme corresponds to an unknown protocol handler"
nsresult: "0x804b0012 (NS_ERROR_UNKNOWN_PROTOCOL)"
location: "JS frame :: chrome://selenium-ide/content/tools.js ->
file:///D:/SeleniumTestCases/UserExtensions/include.js?1426324803395 :: IDEIncludeCommand.prototype.getIncludeDocumentBySynchronRequest :: line 82" data: no]. toString -> function toString() { [native code] },
message -> , result -> 2152398866, name -> NS_ERROR_UNKNOWN_PROTOCOL,
filename -> chrome://selenium-ide/content/tools.js ->
file:///D:/SeleniumTestCases/UserExtensions/include.js?1426324803395,
lineNumber -> 82, columnNumber -> 0, inner -> null, data -> null,
stack -> IDEIncludeCommand.prototype.getIncludeDocumentBySynchronRequest#chrome://selenium-ide/content/tools.js
-> file:///D:/SeleniumTestCases/UserExtensions/include.js?1426324803395:82:4
xmlTestData.prototype.load#chrome://selenium-ide/content/tools.js ->
file:///D:/SeleniumTestCases/UserExtensions/datadriven.js?1426324803392:54:21
Selenium.prototype.doLoadTestData#chrome://selenium-ide/content/tools.js
-> file:///D:/SeleniumTestCases/UserExtensions/datadriven.js?1426324803392:103:4
fnBind/retval#chrome://selenium-ide/content/selenium-core/scripts/htmlutils.js:60:11
ActionHandler.prototype.execute#chrome://selenium-ide/content/selenium-core/scripts/selenium-commandhandlers.js:314:27
._executeCurrentCommand#chrome://selenium-ide/content/selenium-runner.js:306:18
TestLoop.prototype.resume#chrome://selenium-ide/content/selenium-core/scripts/selenium-executionloop.js:78:12
fnBind/retval#chrome://selenium-ide/content/selenium-core/scripts/htmlutils.js:60:11
, location -> JS frame :: chrome://selenium-ide/content/tools.js ->
file:///D:/SeleniumTestCases/UserExtensions/include.js?1426324803395
:: IDEIncludeCommand.prototype.getIncludeDocumentBySynchronRequest ::
line 82
I included all js file in user-extension.js text box
like D:\SeleniumTestCases\UserExtensions\user-extension.js, D:\SeleniumTestCases\UserExtensions\sideflow.js,D:\SeleniumTestCases\UserExtensions\datadriven.js, D:\SeleniumTestCases\UserExtensions\include.js
I referred my test case by How can I read variables from data pool with selenium IDE
sounds like improper xml file attempting to be loaded.
What is the selenium code causing this? how is the url written?
i have a table called system it has some columns mainly number / char types but there is one binary type for holding a document (word or excel etc)
ignore for now if we should hold the file inline or external i.e. bfile or blob... the question is more about how to handle it in the play framework
I have got the form working with the model view and controller... but i set it up without the file-field just to get it working:
I have a case class in the model
case class System(sys_id: Pk[Long] = NotAssigned
, sys_name: String
, sys_desc: String
, sys_owner1: Long
, sys_owner2: Long)
a form in the controller
val systemForm = Form(
mapping(
"sys_id" -> ignored(NotAssigned:Pk[Long]),
"sys_name" -> nonEmptyText,
"sys_desc" -> nonEmptyText,
"sys_owner1" -> longNumber,
"sys_owner2" -> longNumber
)(System.apply)(System.unapply)
)
and a form in the view
#form(routes.Systems.save(), 'class -> "form-horizontal") {
#inputText(systemForm("sys_name"), '_label -> "System Name")
#inputText(systemForm("sys_desc"), '_label -> "Description")
#select(
systemForm("sys_owner1"),
persons,
'_label -> "Primary Owner", '_default -> "-- Choose a person --",
'_showConstraints -> false
)
#select(
systemForm("sys_owner2"),
persons,
'_label -> "Secondary Owner", '_default -> "-- Choose a person --",
'_showConstraints -> false
)
<div class="control-group">
<div class="controls">
<input type="submit" value="Create System" class="btn btn-success"> or
Cancel
</div>
</div>
}
This all works well... but now i want to add the file in, what should i do?
I have seen this http://www.playframework.com/documentation/2.1.2/ScalaFileUpload
but it confuses me it makes no mention of if or how i should change the case class - and what variable is the file stored in (if it is) so that I can access it in my code?
should I modify my case class (if so what type should i add)?
should I modify the Form in the controller (again if so what type should I add?)
im not bothered whether I store it inline or as a bfile - but how can I handle it as asked above?
Thank you
There are some items to consider:
In your .scala.html file, you'll need a file upload field <input type="file" name="someName">.
You'll need to set the encoding type of the form as stated in the documentation: 'enctype -> "multipart/form-data".
You can then change your controller to to handle multipart form-data, so it looks like the one in the example. Use Action(parse.multipartFormData) to parse the form. I think you should then also be able to use your form with systemForm.bindFromRequest (from Form API), although I haven't tried that before.
Edit:
What I meant was to treat the uploaded file and the rest of the form data as separate items.
Try changing the example form the documentation to look like this:
def upload = Action(parse.multipartFormData) { request =>
request.body.file("picture").map { picture =>
import java.io.File
val filename = picture.filename
val contentType = picture.contentType
picture.ref.moveTo(new File("/tmp/picture"))
// this is the new part
val formContents = systemForm.bindFromRequest.value
// now you can do stuff with `formContents` and `picture`
Ok("File uploaded")
}.getOrElse {
Redirect(routes.Application.index).flashing(
"error" -> "Missing file"
)
}
}
I am writing Jasmine test but it shows strange behavior.
This is my code:
root = exports ? this
class root.SomeClass
constructor: ->
#index = 0
incrementIndex: -> #index++
decrementIndex: -> #index--
And this is my test code:
describe "Object", ->
object = new SomeClass
describe ".index", ->
describe "when index = 3", ->
object.index = 3
describe "when next button is clicked", ->
object.incrementIndex()
it "returns 4", ->
expect(object.index).toBe 4
describe "when previous button is clicked", ->
object.decrementIndex()
it "returns 3", ->
expect(object.index).toBe 2
The test result is below:
Failing 2 specs
Photos initialized .index when index = 3 when next button is clicked returns 4.
Expected 3 to be 4.
Photos initialized .index when index = 3 when previous button is clicked returns 3.
Expected 3 to be 2.
And it is strange that when I comment out the last 4 lines of test code, the test pass. I could not understand what is happening... >_<
Thank you for your help.
Your tests interact which each other. Do setup in beforeEach blocks.
describe "Object", ->
object = undefined
beforeEach ->
object = new SomeClass
describe ".index", ->
describe "when index = 3", ->
beforeEach ->
object.index = 3
describe "when next button is clicked", ->
beforeEach ->
object.incrementIndex()
it "returns 4", ->
expect(object.index).toBe 4
describe "when previous button is clicked", ->
beforeEach ->
object.decrementIndex()
it "returns 3", ->
expect(object.index).toBe 2
Not checked if this piece of code is valid, but still shows how you should fix your tests. Note object = undefined in the 2 line. You need to declare variable here, otherwise object will be local to each beforeEach and it block.