sketchucation logo sketchucation
    • Login
    πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    Javascript problem

    Scheduled Pinned Locked Moved Developers' Forum
    8 Posts 4 Posters 332 Views 4 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T Offline
      T.M
      last edited by

      Hello,

      I've been training myself to get used to creating Webdialogs with javascript and I have recently encountered a problem. I've been trying to code something that gets the materials of each face of a pre-drawn cube (except the bottom face) and simply show these in a webdialog.

      My ruby code is the following:

      $wd = UI;;WebDialog.new "Dialog"
      path = Sketchup.find_support_file "Code/Document.html", "Plugins"
      $wd.set_file path
      
      vect = Geom;;Vector3d.new(0, 0, -1) 
      f_count = 1
      		
      Sketchup.active_model.active_entities.each{|j|
      if j.class == Sketchup;;Face && vect.samedirection?(j.normal) == false
      	arg = "'" + j.material.name + "'"
      	$wd.execute_script("defMat" + f_count.to_s + "(" + arg + ")")
      	f_count = f_count + 1
      end #if
      }
      					
      $wd.show
      
      

      And this is my Javascript code:

      <html>
      	<head>
      		<script type="text/javascript">
      		function defMat1(mat)
      		{
      			document.getElementById("mt1").innerHTML = mat
      		}
      
      		function defMat2(mat)
      		{
      			document.getElementById("mt2").innerHTML = mat
      		}
      
      		function defMat3(mat)
      		{
      			document.getElementById("mt3").innerHTML = mat
      		}
      
      		function defMat4(mat)
      		{
      			document.getElementById("mt4").innerHTML = mat
      		}
      
      		function defMat5(mat)
      		{
      			document.getElementById("mt5").innerHTML = mat
      		}
      		</script>
      	</head>
      
      
      <body>
      Material 1; 
      	<b id="mt1">Material</b>
      	<br />
      Material 2; 
      	<b id="mt2">Material</b>
      	<br />
      Material 3; 
      	<b id="mt3">Material</b>
      	<br />
      Material 4; 
      	<b id="mt4">Material</b>
      	<br />
      Material 5; 
      	<b id="mt5">Material</b>
      	<br />
      </body>
      </html>
      

      It seems that the functions of my javascript code are note called because the Webdialog does diplay, but the bold "Material" strings do not get replaced by the proper material names. I know people often get tricked while passing strings from ruby to javascript but in my case I cannot figure out where my error is.

      Any ideas?

      1 Reply Last reply Reply Quote 0
      • thomthomT Offline
        thomthom
        last edited by

        You're using execute_string before you have displayed the webdialog. You must wait until the dialog has openend and the HTML DOM loaded before you can make the webdialog accept commands.

        Thomas Thomassen β€” SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 Reply Last reply Reply Quote 0
        • T Offline
          T.M
          last edited by

          I guess it's not just a question of putting the $wd.show on top, so how can I be sure in my code that execute_script is executed when the HTML DOM is loaded? Do you have any suggestions of correction for my code (even global) that could lead me?

          1 Reply Last reply Reply Quote 0
          • thomthomT Offline
            thomthom
            last edited by

            Have a look at these notes about WebDialog: http://forums.sketchucation.com/viewtopic.php?f=180&t=23445

            Thomas Thomassen β€” SketchUp Monkey & Coding addict
            List of my plugins and link to the CookieWare fund

            1 Reply Last reply Reply Quote 0
            • Dan RathbunD Offline
              Dan Rathbun
              last edited by

              The show() method of the UI::WebDialog class, is actually an optional block method.

              However there is a bug, in that the block does not work on the Mac.

              If you care only for PC, then you can do:

              module TM
                module MatlDlg
                  @@wd = UI;;WebDialog.new( "Dialog" )
                  @@dialog_path = Sketchup.find_support_file( "Code/Document.html", "Plugins" )
                  @@wd.set_file( @@dialog_path )
                    
                  @@wd.show {
                    vect = Geom;;Vector3d.new(0, 0, -1)
                    f_count = 1
                    Sketchup.active_model.active_entities.each{|j|
                      if j.class == Sketchup;;Face && vect.samedirection?(j.normal) == false
                        arg = "'" + j.material.name + "'"
                        @@wd.execute_script("defMat" + f_count.to_s + "(" + arg + ")")
                        f_count = f_count + 1
                      end #if
                    }
                  }
                end #module MatlDlg
              end #module TM
              
              

              I also suggest strongly that you organize your "filespace" by having all YOUR code within a "user/author" subfolder that identifies YOU. "TM" or whatever instead of a generic foldername like "Code".
              Beneath your author folder you make a subdir for each plugin or project.
              So the example above, would be in "Plugins/TM/MatlDlg" subdir or similar.

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • D Offline
                draftomatic
                last edited by

                @dan rathbun said:

                I also suggest strongly that you organize your "filespace" by having all YOUR code within a "user/author" subfolder that identifies YOU. "TM" or whatever instead of a generic foldername like "Code".
                Beneath your author folder you make a subdir for each plugin or project.
                So the example above, would be in "Plugins/TM/MatlDlg" subdir or similar.

                Globals are also dangerous, so $wd should not be used. I worked out a system for my plugin where I wrap all WebDialogs inside their own class and set the WebDialog as an instance variable. You should then wrap said class in your own module to be extra safe no other plugins will clash with it. Give your module a (hopefully) unique name.

                Most scripters are not full-blown software engineers, so software architecture issues like this can be difficult. I could post a sample wrapped WebDialog class if you're interested.

                1 Reply Last reply Reply Quote 0
                • Dan RathbunD Offline
                  Dan Rathbun
                  last edited by

                  @draftomatic said:

                  Globals are also dangerous, so $wd should not be used.

                  As I showed in the example above, when you wrap your plugins in their own module namespace (within your "author" toplevel module namespace,) then globals are not needed, and you can use a module var ( @@var_name,) instead, to hold the reference to the UI::WebDialog instance object. In this case there is no need to class wrap the dialog, or subclass the UI::WebDialog class (unless your doing something really fancy.)

                  @draftomatic said:

                  I worked out a system for my plugin where I wrap all WebDialogs inside their own class and set the WebDialog as an instance variable.

                  In Ruby, class Class, is the child subclass of class Module. So a class Class instance (ie, a custom class,) has everything a module has, and in addition can be have more than one instance. (Hence instance variables.)
                  The rule of thumb, is that if the code only needs 1 copy (ie, a singleton instance,) then the code should be a Module.
                  Most webdialogs are singleton in nature.
                  I have several times showed how to only create one instance of a webdialog. Here's one of my examples: http://forums.sketchucation.com/viewtopic.php?f=180&t=39836#p352081 (The module var @@editor would hold the reference the webdialog instance, in the example.)

                  @draftomatic said:

                  You should then wrap said class in your own module to be extra safe no other plugins will clash with it. Give your module a (hopefully) unique name.

                  It's just easier, to create a unique toplevel "Author" namespace, and have each one of your plugins in a submodule of that namespace. Your submodules and classes will not clash with anyone else's; and it's up to you to be sure any classes within your "author" namespace don't clash with each other. Meaning.. a class that is only used by a specific one of your plugins, should be defined within a specific plugin's submodule.
                  Any classes that you share with more than one of your plugins, can be defined within your "author" toplevel module. (The same holds true for constants.)

                  I'm not here much anymore.

                  1 Reply Last reply Reply Quote 0
                  • T Offline
                    T.M
                    last edited by

                    Thanks for you responses!

                    And yes you are right, I need to organize my scripts better, you've been of great advice!

                    1 Reply Last reply Reply Quote 0
                    • 1 / 1
                    • First post
                      Last post
                    Buy SketchPlus
                    Buy SUbD
                    Buy WrapR
                    Buy eBook
                    Buy Modelur
                    Buy Vertex Tools
                    Buy SketchCuisine
                    Buy FormFonts

                    Advertisement