1

Given this HTML:

  <div class="blah" id="div1">a</div>
  <div class="blah" id="div2">b</div>

I'm trying do make a handler depend on the value of "this", like in the following JavaScript code:

$(document).ready(function() {
  $(".blah").click(function() {
    alert(this.id); }); });

How to do it in Fay? I didn't find API to do this. It looks like it's impossible to call ffi directly from main:

main = ready $ do
  select ".blah" >>= onClick (\_ ->
    ffi "alert(this.id)")

I get "Test$ffi is not defined". I managed to call ffi using the code below:

alertthis = ffi "alert(this.id)"
main = ready $ do
  select ".blah" >>= onClick (\_ ->
    alertthis)

But now "this" refers to some Fay-specific object and doesn't have the property "id".

kxmh42
  • 3,121
  • 1
  • 25
  • 15
  • 2
    The error message does not refer to `this`, maybe something else is broken. Does `ffi alert('Test')` in that code work? – Joachim Breitner Oct 20 '13 at 18:36
  • You're right, ffi "alert('test')" doesn't work either. I reformulated the question. I still can't find the way to get "this". – kxmh42 Oct 21 '13 at 07:54
  • I can't reproduce the error you got, i get `fay: unable to resolve qualified names ffi` instead. It doesn't matter for your question, but are you running the latest version of Fay (0.18.*)? – Adam Bergmark Oct 25 '13 at 18:33
  • @AdamBergmark I get the same error for everything; have you ever been able to resolve this? – Justin L. Jan 25 '14 at 17:34
  • 1
    @JustinL. I released fay 0.19.0.2 to improve these error messages. – Adam Bergmark Feb 04 '14 at 01:06

1 Answers1

1

First of all, you don't have a type signature for your ffi calls, either make a toplevel declaration (I thought fay would give an error on this, but perhaps it doesn't, should fix that):

alert :: sometype -> Fay ()
alert = ffi "alert(%1)"

or use it at the expression level:

(\_ -> (ffi "alert(%1)" :: sometype -> Fay ()) myThis))

this isn't available in a Fay function because it doesn't have the same representation as a js function, there are some conversions happening so this gets lost in the process.

We decided that it's not good to depend on this being bound anyway. You didn't give the definition for your onClick function, but presumably the argument you are ignoring in the callback contains the event object which has a target property. This doesn't always work out because of event propagation, if that's a problem you can pass this to it as well, something like

onClick :: (Element -> Event -> Fay ()) -> JQuery -> Fay JQuery
onClick = ffi "%2.click(function (e) { %1(this, e); })"
Adam Bergmark
  • 7,316
  • 3
  • 20
  • 23