Js/html/ruby

Hello everyone
I have been trying for two days to make the example of Mr. SCARPINO, which I found in the book, Automatic Sketchup, but every time I try, it sends me errors, yet I have not changed anything. have a copy paste directly in ruby ​​code editor, the goal of my work is to understand how ruby, javascript and html are linked to be able to do a simple test, create a form with a text box, in which I type a text or a number that will be displayed in a UI.messagebox by pressing a button to validate

create_face ='<html>   
<head>      
<script type="text/javascript">         
function sendPoints()        
{ 
var ids = new Array ("x1", "y1", "z1", "x2", "y2", "z2","x3", "y3", "z3", "x4", "y4","z4");            
var arg = "" ; var entry = "" ; var valid = true ;            
// Iterate through the text boxes to form output argument   

for (i in ids)           
{              
             entry = document.getElementById(ids[i]).value               
               if ((entry.length == 0) || isNaN(entry))               
                  {                  
                    valid = false ;              
                     }             
               else              
              {                 
                arg = arg + entry + ",";             
               }           
                      }          
// Send argument to SketchUp script for processing            
                    if (!valid)            
                    {               
                    arg = "" ;             
                      }            
          window.location = 'skp:create_face@' + arg; 
}           
</script>   
</head>
 <body>     
 <!-- Location of the first vertex -->      
 Point 1:      
 <input type="text" id="x1" value="0.0" size="10" maxlength="6"/>      
 <input type="text" id="y1" value="0.0" size="10" maxlength="6"/>      
 <input type="text" id="z1" value="0.0" size="10" maxlength="6"/>      
 <br /><br />     
 <!-- Location of the second vertex -->      
 Point 2:     
 <input type="text" id="x2" value="10.0" size="10" maxlength="6"/>     
 <input type="text" id="y2" value="0.0" size="10" maxlength="6"/>      
 <input type="text" id="z2" value="0.0" size="10" maxlength="6"/>     
 <br /><br />      <!-- Location of the third vertex -->      
 Point 3:     
 <input type="text" id="x3" value="10.0" size="10" maxlength="6"/>      
 <input type="text" id="y3" value="10.0" size="10" maxlength="6"/>      
 <input type="text" id="z3" value="0.0" size="10" maxlength="6"/>      
 <br /><br />      
 <!-- Location of the fourth vertex -->      
 Point 4:      
 <input type="text" id="x4" value="0.0" size="10" maxlength="6"/>      
 <input type="text" id="y4" value="10.0" size="10" maxlength="6"/>      
 <input type="text" id="z4" value="0.0" size="10" maxlength="6"/>      
 <br /><br />      
 <!-- Send points to JavaScript -->     
 <input type="submit" onclick="sendPoints();"value="Create Face" />   
 </body> 
 </html>' 
 face_dialog.add_action_callback("create_face") {|d, arg|    
if arg.to_s.length == 0      
puts "Invalid input. Coordinates must be valid numbers."   
else      v = arg.to_s.split(",")     
pt1 = Geom::Point3d.new(Float(v[0].strip), Float(v[1].strip),Float(v[2].strip))     
pt2 = Geom::Point3d.new(Float(v[3].strip), Float(v[4].strip),Float(v[5].strip))     
pt3 = Geom::Point3d.new(Float(v[6].strip), Float(v[7].strip),Float(v[8].strip)) 
pt4 = Geom::Point3d.new(Float(v[9].strip), Float(v[10].strip),Float(v[11].strip))     vec1 = pt2 - pt1    
vec2 = pt2 - pt3      
plane = [pt1, vec1 * vec2]     
if pt4.on_plane? plane         
Sketchup.active_model.entities.add_face pt1, pt2, pt3, pt4      
else        
puts "Invalid input. Points must lie on the same plane."     
end      
end 
}
face_dialog= UI::WebDialog.new("face_dialog")

# Display the dialog box
 if RUBY_PLATFORM.index "drawin"  
 face_dialog.show_modal 
else  
 face_dialog.show 
end

although very good, Mat’s book is also very old, and some things in both SU and Ruby have changed…

One thing to be careful of is copy pasting directly from the PDF as it will contain formatting that can easily break the snippets…

this is partly why the code isn’t working for you…

if you format the snippets first it is easier to follow…

create_face ='<html>   
....
 </html>' 
 
face_dialog= UI::WebDialog.new("face_dialog")

##############################################
## you have to SET the html you want to use
face_dialog.set_html(create_face)
##############################################

face_dialog.add_action_callback("create_face") {|d, arg|    
  if arg.to_s.length == 0      
    puts "Invalid input. Coordinates must be valid numbers."   
  else      v = arg.to_s.split(",")     
    pt1 = Geom::Point3d.new(Float(v[0].strip), Float(v[1].strip),Float(v[2].strip))     
    pt2 = Geom::Point3d.new(Float(v[3].strip), Float(v[4].strip),Float(v[5].strip))     
    pt3 = Geom::Point3d.new(Float(v[6].strip), Float(v[7].strip),Float(v[8].strip)) 
    pt4 = Geom::Point3d.new(Float(v[9].strip), Float(v[10].strip),Float(v[11].strip))

    ##################################################
    # vec1 was on the end of 'pt4  =' line above, breaking the code...
    vec1 = pt2 - pt1    
    ##################################################

    vec2 = pt2 - pt3      
    plane = [pt1, vec1 * vec2]     
    if pt4.on_plane? plane         
      Sketchup.active_model.entities.add_face pt1, pt2, pt3, pt4      
    else        
      puts "Invalid input. Points must lie on the same plane."     
    end      
  end 
}
# Display the dialog box
if RUBY_PLATFORM.index "drawin"  
 face_dialog.show_modal 
else  
 face_dialog.show 
end

john

Good morning, John
thank you very much for the clarifications that you brought, it is true that the bookin of Matt is old but I find it is good to start and to learn with examples, concerning the example which I quoted, I have checked line by line to see where it does not work, the html part no worries on it, the sketchup part when I remove some line, no error and it works in part, but no interaction with html page, the two lines are:
the first : window.location = 'skp:create_face@' + arg;
the second :```if RUBY_PLATFORM.index “drawin”
face_dialog.show_modal
else
face_dialog.show
if RUBY_PLATFORM.index “drawin”
face_dialog.show_modal
else
face_dialog.show
end

I fixed it so that it works, and wrote comments where I changed it…

    ##################################################
    # vec1 was on the end of 'pt4  =' line above, breaking the code...
    vec1 = pt2 - pt1    
    ##################################################

    ############################################## 
    ## you have to SET the html you want to use
    face_dialog.set_html(create_face)
    ##############################################

john

1 Like

Just following along … a newbie myself and just spend 5 days figuring out my own issue. Following an older tutorial for 2D game in Ruby and just digging in hard to get it to run. I figured out what cause`s a uninitialized constant (Name Error). Stick with it and at least with Rudy scripts for SketchUp. You have a good forum to look to. I just got lucky and commented out what I thought needed to be included.

Feel like a blind man looking for the corner of a round room …Peace

#↓ 0 spaces               ↓r This branch will only detect macOS if it's correctly written. If you don't use macOS you would have never found that there is something wrong.
if RUBY_PLATFORM.index "darwin"  
  face_dialog.show_modal
#↑ 2 spaces
else

Take a look at a Ruby style guide. Try to develop an attention for detail. You should not aim to get your code “working” but also that it is structured and easily readable. Then mistakes will catch your eye and you can avoid them. Most beginners’ mistakes happen because people don’t see them.

1 Like

In addition to @Aerilius’ recommendation, if you use a good code editor, its highlighting and indentation will reveal many syntax errors as it can’t make sense of the same things the interpreter can’t parse.

1 Like

thank you for every body
but i tried the code posted by john, and always the same thing,
this is the report error that i looked on ruby console : “Nil result (no result returned or run failed)”
Error: #<SyntaxError: :26: syntax error, unexpected tIDENTIFIER, expecting end-of-input
window.location = ‘skp:create_face@’ + arg;
^>
C:/Users/LOUZA/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/as_rubyeditor/as_rubyeditor.rb:324:in eval' C:/Users/LOUZA/AppData/Roaming/SketchUp/SketchUp 2017/SketchUp/Plugins/as_rubyeditor/as_rubyeditor.rb:324:in block in initialize’
SketchUp:1:in `call’

In typography (and book publishing) there exist many similar-looking characters with specific meanings in written texts. But programming languages do not use typography and are very sensitive that you use the only valid character. If you copy code from a book and the publisher has not properly disabled typography for code blocks, you get ‘…’ which is not the same as '…'.

This would have become obvious if you had formatted the code in the forum post with `.

The second problem is that the variable create_face is a string delimited with single quotes which contains another nested string wrapped in single quotes. So it is ambiguous where the outer string ends! After window.location = ' or after </html>' ? Therefore, the type of quotes that delimit a string must be escaped when they also occur within the string, using the escape character \:

'… window.location = \'skp:create_face@\' + arg; …'

Besides single-quoted '…' and double-quoted "…" strings, Ruby has a third way of defining strings which is much better for long strings like HTML documents:

<<-HEREDOC
No escaping of single quotes ' and double quotes " needed!
HEREDOC

The fact that the forum’s code highlighter paints the whole html string with all the colors of the rainbow should make you skeptical because a string is one single token and is usually highlighted with a single color. Therefore use a code editor with code highlighting.

1 Like

thanks Aerilius
the blocking is finished on the window.location … and the window html opens normally, except that, even by entering values ​​the face is not created after validation, i try to make a UI.messagebox in each line, to see where they block, but the ruby code don"t receive informations

thank you every body
i fouded the mistake
thanks

what was it…

it may help others to know what you found wrong…

john

hi every body

the mistake was mixing the html form names, the terminology in general, and the accents and quotation marks in the sentence ; window.location …
thank you john and thanks for every body

another example by changing the webdialog by htmldialog the code no longer works, and the html page is not displayed, so is there anyone who can inform me the top …

dlg_html ='<html>   
<head>      
<script type="text/javascript">         
function sendPoints()        
{ 
var ids = new Array ("x1", "x2", "x3" );            
var arg = "" ; var entry = "" ; var valid = true ;            
// Iterate through the text boxes to form output argument   

for (i in ids)           
{              
             entry = document.getElementById(ids[i]).value               
               if ((entry.length == 0) || isNaN(entry))               
                  {                  
                    valid = false ;              
                     }             
               else              
              {                 
                arg = arg + entry + ",";             
               }           
                      }          
// Send argument to SketchUp script for processing            
                    if (!valid)            
                    {               
                    arg = "" ;             
                      }            
          window.location = \'skp:dlg_html@\' + arg ;           
}           
</script>   
</head>
 <body>     
 <!-- Location of the first vertex -->      
 Point 1:      
 <input type="text" id="x1" value="0.0" size="10" maxlength="6"/>      
     
 <input type="text" id="x2" value="10.0" size="10" maxlength="6"/>     
        
 <input type="text" id="x3" value="10.0" size="10" maxlength="6"/>      
          
     
    
 <br /><br />      
 <!-- Send points to JavaScript -->     
 <input type="submit" onclick="sendPoints();"value="Create Point" />   
 </body> 
 </html>' 
 
point_dialog = UI::HtmlDialog.new("dlg_html")


point_dialog.set_html(dlg_html)

point_dialog.add_action_callback("dlg_html") {|d, arg| 
arr= arg.to_s

UI.messagebox(arr)
 

  
}
# Display the dialog box
if RUBY_PLATFORM.index  "drawin"  
 point_dialog.show_modal 
else  
 point_dialog.show 
end

if you run the code directly from ‘Ruby Console’ it tells you the problem…

Error: #<TypeError: wrong argument type String (expected Hash)>

so the minimum you need to do is:

face_dialog= UI::HtmlDialog.new{"face_dialog"}   # a hash with one key

but you should also loose the conditional for mac, as it’s no longer needed…

# Display the dialog box
#if RUBY_PLATFORM.index "drawin"  
# face_dialog.show_modal 
#else  
 face_dialog.show 
#end

have a look at the API for other things the hash can contain…

john

hello john
thank you very much,
with your advice, I finally managed to make the code work