These are chat archives for opal/opal

25th
Aug 2016
Forrest Chang
@fkchang
Aug 25 2016 01:40
@carlosvigil what are you trying to do? Depending on what it is you might be able to do it outside of codepen
Jamie Gaskins
@jgaskins
Aug 25 2016 04:25
@carlosvigil I think @fkchang had an Opal playground app a while back. I wrote one specifically for Clearwater apps, but I don't think I ever ended up publishing it anywhere
Forrest Chang
@fkchang
Aug 25 2016 05:03
@carlosvigil said playground is here http://fkchang.github.io/opal-playground/
it has clearwater support
Bernhard Weichel
@bwl21
Aug 25 2016 10:33
This message was deleted
Bernhard Weichel
@bwl21
Aug 25 2016 10:41

@fkchang taking your word, that I can do anything in Ruby what I can do in JS ...

I have in my application file

require 'ui.js'

with ui.js as something like

 function check_unload() {
    return "Leave Zupfnoter?\nreally ...?"
  }

  function init_w2ui(uicontroller) {

    function zoomHarpPreview(size){
      $("#harpPreview svg").attr('height', size[0]).attr('width', size[1]);
    };

  $('#layout').w2layout({ ...})

I wanted to replace it first hand with

js.rb:

%x{
 function check_unload() {
    return "Leave Zupfnoter?\nreally ...?"
  }

  function init_w2ui(uicontroller) {

    function zoomHarpPreview(size){
      $("#harpPreview svg").attr('height', size[0]).attr('width', size[1]);
    };

  $('#layout').w2layout({ ...})
}

But now everything is within Opal and no longer global (e.g. the JS function init_w2ui() and check_unload())
I guess I am somehow on the wrong track. I would like to have access to the ruby variables from via #{} in the Javascript part.

Mitch VanDuyn
@catmando
Aug 25 2016 11:38
@carlosvigil I don't know about codepen but I figured out how to do it in stack overflow, and you could start with that. I thought I had it documented in a SO answer but here is a sample: http://stackoverflow.com/questions/34580560/how-to-reverse-a-linkedlist-in-place/34581616#34581616
It uses reactrb-express (but in the above example doesn't use reactrb just straight opal)
Let us know how it goes, I am very interested in promoting opal-ruby by making it work on sites like code-pen, jsfiddle, etc.
Carlos Vigil
@carlosvigil
Aug 25 2016 16:04
thanks @catmando @fkchang @jgaskins
I'm testing out Slim at the moment then I'll move in to Opal. Slim + Opal would be awesome, I haven't look around for a plug but there's Volt too, so I'll be in the hole for a while.
Forrest Chang
@fkchang
Aug 25 2016 16:17
@bwl21 I'm not quite getting your example and the problem. Big picture, what is the starting point, and what is the desired benefit change, by switching to opal. Ur example code in particular looks primarily jquery, could be reimplemented w/opal-jquery, but you make some mention of it not being global, so I'm thinking perhaps you want to expose that code to other JS code? Using opal code from JS is doable, so it's not clear what you're hoping to gain exactly.
Bernhard Weichel
@bwl21
Aug 25 2016 17:55

@fkchang sorry, for drawing a sketch only ... so I try to explaint it a bit

In the pure JS version for example check_unload is a globally available function which in can refer to e.g. in <body onbeforeunload="return check_unload()">. When I define the same within a ruby file, it is not available globally. I do not know how I should specify the onbeforeunload attribute to invode the function as defined in js.rb.

The starting point in my case is that i have the entire UI-Code (utilizing w2ui) in a separate javascript file. I would like to pull it to Ruby land, such that I can for example access ruby expressions, classes, instances etc. as #{}. I tried to do it in steps by wrapping the existing JS code in a %x{} within a ruby file and get it compiled into the application.

Forrest Chang
@fkchang
Aug 25 2016 18:01
@bwl21 u might just wrap the library from opal, #{} should work inside x-strings
and leave it as js
Bernhard Weichel
@bwl21
Aug 25 2016 18:02
yes it does. but wrapping the library defines e.g. check_unload within an object named Opal, and not in the global namespace.
Forrest Chang
@fkchang
Aug 25 2016 18:04
@bwl21 I mean wrap it the same way opal-jquery wraps jquery, which doesn't enclose jquery in x-strings, but defines methods that use x-strings in the opal code
Bernhard Weichel
@bwl21
Aug 25 2016 18:15
With Jquery-wrapping I get functions which I can call from Ruby and under tho hood invoke global JS functions with x-strings. The Invocation of these methods is done withing Ruby. But my problem is how can I define a globally available Javascript function within ruby file. Everything defined on the ruby side lives within the one Object Opal and not in the global namespace. I could not even find something like Opal.check_unload()
Mitch VanDuyn
@catmando
Aug 25 2016 18:24
@carlosvigil sadly volt is on sabbatical, in the meantime reactrb has picked up a lot of the volt goodness (isomorphic models, automatic rerendering on data changes) plus it has nice DSL that does what SLIM does, its framework agnostic, and it comes in a set of gems so you can pick the pieces you need.
@bwl21 - if understand your question correctly you want to define a method in ruby that is also accessible directly in JS code outside of ruby?
if so its about like this:
Bernhard Weichel
@bwl21
Aug 25 2016 18:28
@carlosvigil yes indeed : I want to define a method in ruby that is also accessible directly in JS code outside of ruby?
Mitch VanDuyn
@catmando
Aug 25 2016 18:38
class Foo
   def self.do_something(x,y,z)
      ...
    end
end
// somewhere in js land
    Opal.Foo.$do_something(1, 2, 3)

of course you can do this in ruby:

%x{
  window.do_something = Opal.Foo.$do_something
}

so you can more directly access do_something, and in fact you can create some methods to do this more automatically (look for export_component in the reactrb code base for an example)

you can also do something like this (although I can never quite get the syntax:)
%x{
  window.do_something = #{Foo.method(:do_something)}
}
I tend to use lambdas for these cases:
do_something = lambda { .... }
%x{
  window.do_something =#{do_something}
}
Bernhard Weichel
@bwl21
Aug 25 2016 20:16
This message was deleted
Bernhard Weichel
@bwl21
Aug 25 2016 20:22

@catmando Thanks, Mitch, you pointed in the right direction. I need to build a bridge from opal to javascript land.

%x{
     do_something = function(){alert("global do something")}
}

def do_something
  `do_something()`
end



module Foo

  %x{function do_something(){alert("Foo.do something")}}

  def self.do_something()
    alert("Foo.self.do_something")
  end

  def self.foobar()
    `do_something()`
  end

end

allows me to use

```javascript

Opal.global.do_something() // -> global do_something
Opal.Foo.$do_something() // -> Foo.self.do_something
Opal.Fool.foobar() // -> Foo.do something

```

Mitch VanDuyn
@catmando
Aug 25 2016 21:01
right... and if you need to do this a lot, you can build a bridging method/include module, etc.
The problem is of course what to do about instance methods... as long as its a class level method its not too hard.
Jamie Gaskins
@jgaskins
Aug 25 2016 22:14
Carlos Vigil
@carlosvigil
Aug 25 2016 22:15
@jgaskins awesome, thanks!
Jamie Gaskins
@jgaskins
Aug 25 2016 22:15
That's what I used with Clearwater apps before I added a virtual DOM (and had to drop HTML template support). Should still work. Let me know if not. :-)
Forrest Chang
@fkchang
Aug 25 2016 22:20
@bwl21 you could still leave the js as is in a js file, and then in your opal wrapper call it w/x-strings, u don't need to wrap the original js file in it's entirety, just the calls to it