Html dialog box to set and get information

Be careful. JavaScript is not the same as the Java programming language. The two are distinct.

As I said …

There are different conventions for Ruby and JavaScript identifiers, but both are loose and allow most any kind of reference identifier.

JS normally uses var identifiers that begin with a lower case letter and are camelCaseNames (some times called “snake-case”.)
Ruby conventions use CamelCaseClass for class and module names and use variable and method identifiers as lowercase with underscore separators. ie … some_value = my_method("argument")

But then, JavaScript will also not care if you use Ruby-like variable names like my_var either.

But if you are using simple lower case identifiers like ary or data, etc., the names can be the same on both sides and you won’t break any convention.

As it says in the UI::HtmlDialog class documentation for #add_action_callback()

Basic types such as booleans, numbers, strings, arrays and hashes are automatically converted between Ruby and JavaScript.

You just need to try and remember that JavaScript uses Objects for what Ruby calls a Hash. So if you pass a JS Object to a Ruby dialog callback proc, the SketchUp API will convert it to a Ruby Hash.

So … let us say that your data array is named @atts (short for attributes,) on the Ruby side, and you pass it over to the dialog JavaScript named as atts. (JS doesn’t have @vars so you’d omit the @ prefix.)

From your dialog’s JS, you need a button click to send the updated array back to Ruby …

    var applyButton = document.getElementById('apply');

    applyButton.onclick = function() {
        sketchup.receive_data(atts);
    }

* This snippet assumes your HTML has a <button> element whose id is set to "apply".

Then your code must have already attached an action callback to your Ruby dialog object, in order to receive the updates from the dialog. So in Ruby …

def attach_callbacks(dialog)
  dialog.add_action_callback("receive_data") { |_unused, atts|
    # When this gets called from the JavaScript side, ...
    # the block parameter atts will be a Ruby array. So, just make the
    # assignment to the local instance var referencing the array:
    @atts = atts
    # Now close the dialog:
    dialog.close
  }
end

You’ll also probably need a Cancel button, so in the dialog’s JavaScript …

    var cancelButton = document.getElementById('cancel');

    cancelButton.onclick = function() {
        sketchup.close_dialog();
    }

And on the Ruby side a callback to accept this call from JS, so we need to insert a callback attachment to the previous method …

def attach_callbacks(dialog)
  dialog.add_action_callback("close_dialog") { |_unused|
    dialog.close
  }
  dialog.add_action_callback("receive_data") { |_unused, atts|
    # The block parameter atts is now a Ruby array.
    # So just make the reference assignment to the local instance var:
    @atts = atts
    # Now close the dialog:
    dialog.close
  }
end

:nerd_face:

1 Like