sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Web dialog on a Mac

    Scheduled Pinned Locked Moved Developers' Forum
    69 Posts 9 Posters 7.3k Views 9 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.
    • Dan RathbunD Offline
      Dan Rathbun
      last edited by

      (1) The button is just a button. Use onclick= instead of onsubmit=

      (2) You are missing ; at the end of some JS statements. Try using a syntax checker like JSLint to check your code.
      http://www.jslint.com

      I'm not here much anymore.

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

        Ok I see a major booboo.

        location is an attribute of the window object.

        ... so in your call_ruby() function, it needs to be:

        
                    function call_ruby( callback_name, message ) {
                        window.location = 'skp;' + callback_name + '@' + message;
                    }
        
        

        I'm not here much anymore.

        1 Reply Last reply Reply Quote 0
        • s_k_e_t_c_h_yS Offline
          s_k_e_t_c_h_y
          last edited by

          Thanks for the replies Dan,
          I'm still having issues, but I'll keep tinkering =P.

          1 Reply Last reply Reply Quote 0
          • s_k_e_t_c_h_yS Offline
            s_k_e_t_c_h_y
            last edited by

            Ok,
            I've got it!! I made a few design decisions which should be reasonably documented in the code, but I've enclosed a fully working example below for submitting forms that works on a Mac and a Windows system.

            The example below presents a single form with a radio buttons and checkboxes and after selecting them how you desire and hitting submit all of the settings are sent one by one. To get around the asynchronous/synchronous problem, I essentially have message passing between Ruby and JavaScript to force sending one option at a time (making both Operating Systems act asynchronously) from a options list. It should be quite easy to extend from here.
            

            Here is the HTML/JavaScript Code:

            
            <html>
                <body >
                    Multi-Platform WebDialog form submission test<br><br>
            
                    <form name="stuff">
                        Favorite Food;<br>
                        <input type="radio" name="food" value="Pizza">Pizza<br>
                        <input type="radio" name="food" value="Hotdogs">Hotdogs<br>
                        <br>Favorite Animals;<br>
                        <input type="checkbox" id="a_cat" value="a_cat">Cat<br>
                        <input type="checkbox" id="a_dog" value="a_dog">Dog<br>
                        <input type="checkbox" id="a_squirrel" value="a_squirrel">Squirrel<br>
                            
                        <input type="button" value="Submit" onclick="sendformdata()">
                    </form>
                    
                    <script>
                        var options = {};   // object that stores all of our settings
                        
                        //Sends a mesage to SU / Ruby
                        function call_ruby( callback_name, message ) {
                            window.location = 'skp;' + callback_name + '@' + message;
                        }
                    
                        //Add a checkbox value to the options object
                        function add_checkbox_data(var_str) {
                            if (document.getElementById(var_str).checked) {
                                options[var_str] = "1";
                            } else {
                                options[var_str] = "0";
                            }
                        }
                    
                        //Add a radio button value to the options object
                        function add_radio_data(field) {
                            //Get the field data
                            var ps = document.getElementsByName(field);
                        
                            for (var i = 0, length = ps.length; i < length; i++) {
                                if (ps[i].checked) {
                                    // store value in our object
                                    options[field] = ps[i].value;
                                    // only one radio can be logically checked, don't check the rest
                                    break;
                                }
                            }
                        }
                    
                        //Send a single setting to SU, callbacks will come and get the rest
                        function send_setting()
                        {
                            var size = 0, key;
                            var seting, value;
                            
                            for (key in options) {
                                if (options.hasOwnProperty(key)) size++;
                            }
                            
                            if (size > 0) {
                                for (setting in options) break; // Get the first setting
                                value = options[setting];
                                delete options[setting];
                                call_ruby(setting, value);
                            } else {
                                call_ruby("submit", 1);
                            }
                        }
                    
                        function sendformdata()
                        {
                            add_radio_data("food");
                            
                            //The checkbox options all have unique names to simplify storage in 'options' receipt at the SU end (more callback handlers needed though)
                            //Could have concatenated all check options into a string, sent them as a single submit and parsed the string at the SU end too
                            add_checkbox_data("a_cat");
                            add_checkbox_data("a_dog");
                            add_checkbox_data("a_squirrel");
                            
                            //Send the first setting to SU, the callbacks will get the rest
                            send_setting();
                        }
            
                    </script>
                </body>
            <html>
            
            

            Here is the Ruby Code:

            
            @d = nil
            @d = UI;;WebDialog.new("Test", true, "", 800, 800, 200, 200, true)
            
            htmlset = File.join( File.dirname(__FILE__), "test.html" )
            @d.set_file( htmlset )
            
            #set the callback for the radiobuttons
            @d.add_action_callback('food') { |dialog, params|
                puts '>> Food; ' + params
                @d.execute_script('send_setting();')    #check for more settings to send
            }
            
            @d.add_action_callback('a_cat') { |dialog, params|
                puts '>> Animal; Cat - ' + params
                @d.execute_script('send_setting();')    #check for more settings to send
            }
            
            @d.add_action_callback('a_dog') { |dialog, params|
                puts '>> Animal; Dog - ' + params
                @d.execute_script('send_setting();')    #check for more settings to send
            }
            
            @d.add_action_callback('a_squirrel') { |dialog, params|
                puts '>> Animal; Squirrel - ' + params
                @d.execute_script('send_setting();')    #check for more settings to send
            }
            
            #Make the window persistant on top of SU
            RUBY_PLATFORM =~ /(darwin)/ ? @d.show_modal() ; @d.show
            
            

            Thanks to all for the advice along the way.

            Sincerely, Paul

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

              Hi Paul,

              I'll give it a run later...
              I've been trying to tidy up my own version to see if it would be of any use, but you beat me to it...

              I'll post it anyway, for your perusal, and maybe see if it works on a PC [I don't have one]

              I wanted to use only ruby and the least 'vanila' js to do all the sorting. To achieve this I use a common id(+digit) for each element, then a ruby range loop collects them...

              Let me know if it seems sensible?
              john
              output to UI.messagebox to show it works on mac...
              it's a one pager for convenience of testing...

              
              def js_2_ruby
              
                  dlg = UI;;WebDialog.new("optionsDialog", false, "tlDlg", 300, 250, 150, 150, false)
              
                  # the html for structure needs values and names in specific groups for the js to work for radio buttons and or checkboxes.
              
                  html =<<HTML
                  <html>
                  <title>Web Form in SU</title>
                  <head>
                  <script>
                  function js2ruby() {
                  window.location='skp;js2ruby';
                  }
              
                  function radio(chk) {
                      try {
                      exists = document.getElementById(chk.name);
                      exists.id = exists.value;}
                      catch(err){}
                      finally {
                      if (chk.checked === true)
                       chk.id = chk.name;}
                  }
              
                  function validate(chk) {
                      if (chk.checked === true)
                       chk.value = chk.name;
                      else chk.value = chk.title;
                  }
                  </script>
              <style></style>
              
                      </head>
                  <body>
              
                  <h1>Send to ruby</h1>
              
                  <form name="f1" id="f1">
                      A Greeting to;
                      <input type="text" name="greet" id="add2array1" placeholder=" to all fine gentlemen "><br/>
                      Your Name;
                      <input type="text " name="name " id='add2array2';" placeholder="John">
                      <br />
                      Your Order;
                      <br />
                      <input type="radio" name="add2array3" id="Pizza" value="Pizza" onclick='return radio(Pizza);'>Pizza
                      <br />
                      <input type="radio" name="add2array3" id="Hotdogs" value="Hotdogs" onclick='return radio(Hotdogs);'>Hotdogs
                      <br/>
                      <input type="checkbox" name="with sauce" id="add2array4" title="without sauce"  value="" onClick='return validate(add2array4);'>with "Tomato" Sauce?
                      <br />
                      <br />
                      Send to Ruby;
                      <input type="button" value="Submit" onClick="js2ruby();">
                  </form>
                   </body>
                  </html>[attachment=0]2013-12-27 03.35.26 pm.png[/attachment]
              HTML
              
                  @html = html
              
                  # the gist; make an array
                  @tl = []
              
                  # get 'user replys' from the webdialog,
                  dlg.add_action_callback("js2ruby") {|d,_|
                  # need to hard code number range to match html...
                  (1..4).each{ |i| tl = d.get_element_value("add2array#{i}")
                  # then add a placeholder for missing values, I like to be obvious...
                  tl = "missing value" if not tl.length > 0
                  # then push the full range into the array...
                  @tl << tl
                  }
                  # if only used once per session, you could use @tl[0..3], but just incase, user make a change...
                  UI.messagebox("    Greetings to #{@tl[-4]}\n   from #{@tl[-3]}\n  #{@tl[-2]} #{@tl[-1]}")
                  }
                  # then set_html or file/url if separate...
                  dlg.set_html html
                  if( (RUBY_PLATFORM =~ /darwin/i) )
                  dlg.show_modal
                  else
                  dlg.show
                  end #if
              
              end # def js_2_ruby
              
              # to run
              js_2_ruby
              
              

              learn from the mistakes of others, you may not live long enough to make them all yourself...

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

                The reference to the dialog object needs to be an instance var @dlg, or else Ruby's garbage collection will sweep up the local var inside the method when it returns.

                Ie.. the dialog will close by itself, and be destroyed. (or you can return the dialog object at the end of the method, and let the caller have the responsibility to hold the object reference.)

                I'm not here much anymore.

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

                  hi dan

                  it's a quick[well not so quick] lash-up of a few concepts I've had on the back-burner for far to long...

                  so there is room for improvements in the coding, so fire away...

                  I could never see the need for the hidden field to hold the js values, when ruby could collect them directly for itself?

                  I'm just adding to it to bounce back some interactive ruby, i.e. Sketchup as server, which has also been on the bb...

                  I guess that's what xmas is for...

                  BIG ?? does it run on Windows...

                  john

                  learn from the mistakes of others, you may not live long enough to make them all yourself...

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

                    Without even trying I can tell you we will see the dialog for a second and then POOF it will be gone.

                    But if you return dlg as the last line of the method,...

                    and then call it using a reference assignment like:
                    my_dialog = js2ruby()
                    it WILL work because Ruby will hold a reference to the dialog object.

                    I'm not here much anymore.

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

                      so why does it always work on a mac...

                      never had one vanish?

                      I can even add a bunch of GC.start 's and it's stay's... just tried it...

                      just curious...

                      john

                      learn from the mistakes of others, you may not live long enough to make them all yourself...

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

                        Specifically I do not know.

                        Generally the OSX GUI is different from the MS Windows GUI.

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • G Offline
                          Garry K
                          last edited by

                          I have also been experimenting with web dialogs. This works with Windows 7 and sketchup 7,8 and 2013.

                          Hopefully someone with a MAC can try this and see if it works in Safari.

                          I have Chrome, IE11 and Firefox installed. The code works with these Browsers but only if I rem out the line that references sk


                          web dialog


                          This file adds a menu Item under Plugins called "Web Dialog Test"

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

                            looks like this in SU, and works
                            but you do need a version of

                                # then set_html or file/url if separate...
                                @dlg.set_html html
                                if( (RUBY_PLATFORM =~ /darwin/i) )
                                @dlg.show_modal
                                else
                                @dlg.show
                                end #if
                            

                            john

                            learn from the mistakes of others, you may not live long enough to make them all yourself...

                            1 Reply Last reply Reply Quote 0
                            • G Offline
                              Garry K
                              last edited by

                              Thanks

                              I can easily add that.

                              When you clicked "Ok" button did you get a list of Control Id's and values?

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

                                you mean this?

                                pre-setting the size [webDialog] is better as well.

                                john

                                learn from the mistakes of others, you may not live long enough to make them all yourself...

                                1 Reply Last reply Reply Quote 0
                                • G Offline
                                  Garry K
                                  last edited by

                                  Yes - that is what I meant.

                                  Pre-setting the size would help on Windows for the first time it is run. But after that the window uses the last known size and position that the user set it to.

                                  Does it work differently on the MAC?

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

                                    same, it just seems more polished if it comes in at the correct size...
                                    john

                                    learn from the mistakes of others, you may not live long enough to make them all yourself...

                                    1 Reply Last reply Reply Quote 0
                                    • G Offline
                                      Garry K
                                      last edited by

                                      I hear you. If you change the first line of the function to this does it work correctly?

                                      dlg = UI::WebDialog.new( "Stair Measurements", false, "StairMaker_Web_Dialog", 570, 452, 0, 0, true );

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

                                        I think I used 628 × 500, SU include the Title-bar in it's size on most mac's...

                                        I'll check later

                                        john

                                        learn from the mistakes of others, you may not live long enough to make them all yourself...

                                        1 Reply Last reply Reply Quote 0
                                        • G Offline
                                          Garry K
                                          last edited by

                                          One difference that I see is with margin.
                                          margin: 2px works on Windows = but it appears that the margin is larger in Safari.

                                          Perhaps the margin is simply ignored with Safari.

                                          The other difference that I see is the check box. I set width to 120px, the same for everything. It centers in Windows and left justifies with Safari.

                                          Is this the same for all MAC's ???

                                          1 Reply Last reply Reply Quote 0
                                          • G Offline
                                            Garry K
                                            last edited by

                                            I added this line immediately after <head> and also tried it immediately after <html>
                                            I tried it set to "yes" and set to "no with Windows and did not see any difference.

                                            There is a <style> section prior to <head>
                                            When I put the line immediately after <style type="text/css"> then the background color for the body failed to apply regardless if I set content to "yes" or to "no"

                                            So I'm not sure exactly what this metatag is suppose to do. I'm not sure where the tag should go ( although I did read a microsoft page where they placed it immediately after <head>

                                            Also - what will it do with Safari? Did you suggest it because the margins are different with safari?

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

                                            Advertisement