HTMLDialog Fill inputbox from csv data

I explained this in the other topics I linked above.

(1) Load the .json file into Ruby as a JSON String.

(2) Convert that JSON String into a Ruby Hash object using JSON.parse.

(3) Then replace the %{hash_key} parameters that you should have embedded into your HTML with the values from the data hash, using the String#% method.

In the snippet you posted above in post 3 , the line:

    :json_data  => File.read(File.join(path, "some_data.json"));

… should not be in the replacements hash (looks like it was inserted and a comma does not follow it which would be a syntax error. The semicolon is not needed anyway.)

Instead, the data json should be loaded into a Ruby hash, like:

INCORRECT CODE (corrected below)
    path = __dir__

    # Load the stylesheet and javascript into a replacement hash:
    replacements = {
      :stylesheet => File.read(File.join(path, "stylesheet.css")) ,
      :javascript => File.read(File.join(path, "javascript.js" )) ,
    }

    # Load the HTML text into a Ruby String:
    html_text = File.read(File.join(path, "dialog.html"))

    # Load the external JSON data file into a Ruby String:
    json_data = File.read(File.join(path, "some_data.json"))
    # Convert to a Ruby hash:
    data = JSON.parse(json_data)

    # Now replace the embedded %{hash_key} parameters in the HTML text.
    # In your latest edition, the parameters within the HTML text should be:
    # %{nam}, %{id1}, %{id2} and %{id3}
    html_with_data = html_text % data

    # Now replace the %{stylesheet} and %{javascript} parameters with the
    # :stylesheet and :javascript values from the replacements hash into
    # the HTML text and pass to dialog:
    @dialog.set_html( html_with_data % replacements )

    # Show the dialog:
    @dialog.show

EDIT: The above (collapsed code) is actually incorrect. You cannot do replacements twice as I showed above because the first time a KeyError exception is raised when the %{stylesheet} and %{javascript} parameters do not have matching keys in the data hash.
Instead, we must merge the two hashes together and do the String#% replacement operation ONCE.

Corrected code:

    path = __dir__

    # Load the stylesheet and javascript into a replacement hash:
    replacements = {
      :stylesheet => File.read(File.join(path, "stylesheet.css")) ,
      :javascript => File.read(File.join(path, "javascript.js" )) ,
    }

    # Load the HTML text into a Ruby String:
    html_text = File.read(File.join(path, "dialog.html"))

    # Load the external JSON data file into a Ruby String:
    json_data = File.read(File.join(path, "some_data.json"))
    # Convert to a Ruby hash:
    data = JSON.parse(json_data)

    # Combine the data hash into the replacements hash:
    replacements.merge!(data)

    # Now replace the embedded %{hash_key} parameters in the HTML text.
    # In your latest edition, the parameters within the HTML text should be:
    # %{nam}, %{id1}, %{id2} and %{id3}
    # This will also replace the %{stylesheet} and %{javascript} parameters
    # with the :stylesheet and :javascript values from the replacements hash.
    # Then pass the HTML text and to the dialog:
    @dialog.set_html( html_text % replacements )

    # Show the dialog:
    @dialog.show

So within your HTML text, lets say you are using <input type="text">

    <div id="form">
        <input type="text" id="nam" value="%{nam}" />
        <input type="text" id="id1" value="%{id1}" />
        <input type="text" id="id2" value="%{id2}" />
        <input type="text" id="id3" value="%{id3}" />
    </div>

… and after the html_with_data = html_text % data statement executes, the %{key} parameters in the HTML text should be replaced with the values from the data hash corresponding to its hash symbol keys, and the result assigned to the html_with_data string.


You should not be hardcoding paths. Your extension should be in a subfolder of the “Plugins” path which is in the user’s %AppData% path … if, …
IF the data is extension / users specific but not model specific.

plugins_path = Sketchup.find_support_file('Plugins')

Also from a file in your extensions subfolder (beneath "Plugins") you could also do:

plugins_path = File.dirname(__dir__)

If the data is model specific, either it likely should be saved to model.path or saved within the model itself as an attribute dictionary.

Going from JSON to attribute dictionary:

dict = model.attribute_dictionary('DaveStudys_DrawBoxWizard', true)
hash = JSON.parse( json_text )
hash.each { |key, value| dict[key]= value }

Going from existing attribute dictionary to JSON:

dict = model.attribute_dictionary('DaveStudys_DrawBoxWizard')
json_text = dict.to_h.to_json
1 Like