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

    .get_element_value with radio button sets

    已排程 已置頂 已鎖定 已移動 Developers' Forum
    22 貼文 6 Posters 791 瀏覽 6 Watching
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • sdmitchS 離線
      sdmitch
      最後由 編輯

      Having never used html, I have resisted getting envolved with WebDialog but I have been working on a plugin that needs a user interface with multiple radio buttons. But I have run into a problem trying to get the value of the selected button using the .get_element_value function. Everything works as expected with a single radio button but, as soon as I add a second radio button, it fails to return the selected value and returns a null string instead. I searched the Plugins and Developer's forums but did find anyone else with this problem.

      Here is the basic code I'm using

      dialog = UI;;WebDialog.new
      dialog.set_file "c;/users/public/sketchup/plugins/sam.html"
      dialog.show
      dialog.add_action_callback("sdm") {|dialog, params|
      puts params
      var1 = dialog.get_element_value("align")
      var2 = dialog.get_element_value("space")
      puts var1, var2
      }
      
      
      <body>
      <form action="skp;sdm@true">
      Align/Distribute Options;<hr />
      Align Objects; 
      <br><input name="align" type="radio" value="Top-X" checked="checked" />Top-X 
      <input name="align" type="radio" value="Ctr-X" />Ctr-X
      <br>Distribute Objects; 
      <br><input type="radio" name="space" value="Lft-Z" checked="checked" />Lft-Z 
      <br><input type="radio" name="space" value="Ctr-Z" checked="checked" />Ctr-Z
      <br><input type="submit" name="submit" value="Enter" />
      </form>
      </body>
      
      

      Nothing is worthless, it can always be used as a bad example.

      http://sdmitch.blogspot.com/

      1 條回覆 最後回覆 回覆 引用 0
      • thomthomT 離線
        thomthom
        最後由 編輯

        You can add a hidden input field and hook up the onChange events for the radioboxes which updates the hidden field with the value you need.

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

        1 條回覆 最後回覆 回覆 引用 0
        • D 離線
          driven
          最後由 編輯

          #----------------------------------------------------------------------------------------------------
          html1=<<SETHTML
          <!DOCTYPE html>
          <html lang="en">
          <head>
              <meta charset="utf-8">
              <title>
                SDMitch_test
              </title>
          <style> body {background-color; Window; color; WindowText; font; message-box; user-select; none; cursor; default; overflow; hidden}</style>
          </head>
          <body>
          <form action="skp;sdm@true">
          Align/Distribute Options;<hr />
          Align Objects;
          <br><input name="align" type="radio" value="Top-X" checked="checked" />Top-X
          <input name="align" type="radio" value="Ctr-X" />Ctr-X
          <br>Distribute Objects;
          <br><input type="radio" name="space" value="Lft-Z" checked="checked" />Lft-Z
          <br><input type="radio" name="space" value="Ctr-Z" checked="checked" />Ctr-Z
          <br><input type="submit" name="submit" value="Enter" />
          </form>
          </body>
          </html>
          SETHTML
          
          html=(html1)
          dlg8 = UI;;WebDialog.new("it works again8",false,"img", 190, 180, 150, 150, false);
          dlg8.set_html(html)
          dlg8.show_modal
          dlg8.add_action_callback("sdm") {|dlg8, params|
          puts params
          var1 = dlg8.get_element_value("align")
          var2 = dlg8.get_element_value("space")
          }
          #----------------------------------------------------------------------------------------------------
          
          

          returns html string to_s
          true?align=Top-X&space=Ctr-Z&submit=Enter true?align=Ctr-X&space=Lft-Z&submit=Enter

          edit to tidy up the html with css

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

          1 條回覆 最後回覆 回覆 引用 0
          • Dan RathbunD 離線
            Dan Rathbun
            最後由 編輯

            Sam,

            (1) Your setting both radio elements as checked, only one can be at a time, so the first (in the set,) is frivolous.

            (2) The WebDialog#get_element_value() method's dictionary text is misleading.

            The argument name is element_id, indicating that it is using the javascript function %(#8000BF)[getElementById()], but in text it says "get an element by name".

            In HTML the %(#8000BF)[id] attribute must be unique, but the %(#8000BF)[name] attribute does not need to be (and cannot be, in the case of radio button sets.)

            However, the %(#8000BF)[getElementById()] function (or the DOM,) would set the
            %(#8000BF)[name] attribute, to the %(#8000BF)[id] attribute, if you did not explicitly set the %(#8000BF)[name] attribute. (Or visa versa, it's been a long time, and I am still working on my 1st cup of coffee.)

            So the effect of calling %(#8000BF)[getElementById()]... it looks for an id match in the DOM's collection of ids, and if it does not find a match, then it uses the Js function %(#8000BF)[getElementsByTagName()], and returns the first (if the result array is not empty.)

            This "fallback" behavior may change depending on the standards mode, your %(#8000BF)[<!DOCTYPE>] tag sets.

            John's example sets the HTML in strict HTML5 mode ?

            In short... assign a unique %(#8000BF)[id] to each control element.

            💭

            I'm not here much anymore.

            1 條回覆 最後回覆 回覆 引用 0
            • Dan RathbunD 離線
              Dan Rathbun
              最後由 編輯

              The easiest way?

              Set the IDs for each button, but ONLY the value for the DEFAULT radio:
              html

              <br><input type="radio" name="space" id="Lft-Z" checked="checked" value="checked"  onchange="this.value=this.checked;"/>Lft-Z
              <br><input type="radio" name="space" id="Ctr-Z" onchange="this.value=this.checked;"/>Ctr-Z
              
              

              Now you retrieve the value, by unique ID.


              Also at MSDN... for input type=radio they show in the example that you can access the controls in the set by index .... (but this may be only in MSIE 8 Document mmode?)
              Like, Javascript:

              <script type="text/javascript">
              function detect_space()
              {
                  if (space[0].checked)
                      // send a message to the ruby side
                  else if (space[1].checked)
                      // send a different message to the ruby side
              }
              </script>
              
              

              I'm not here much anymore.

              1 條回覆 最後回覆 回覆 引用 0
              • sdmitchS 離線
                sdmitch
                最後由 編輯

                Thanks to all for your responses. I'm only a little more confused than before.

                I happened to find Chris Fullmer's "VerySimple" example that I think might be the solution to my problem.

                Nothing is worthless, it can always be used as a bad example.

                http://sdmitch.blogspot.com/

                1 條回覆 最後回覆 回覆 引用 0
                • Chris FullmerC 離線
                  Chris Fullmer
                  最後由 編輯

                  Using anything of mine as an example in the webdialog world is probably a VERY bad idea. I am SO bad with webdialogs, html, etc.

                  Out of curiousity, what is my "VerySimple" example? I can't even think of what that was? 😳

                  Lately you've been tan, suspicious for the winter.
                  All my Plugins I've written

                  1 條回覆 最後回覆 回覆 引用 0
                  • Dan RathbunD 離線
                    Dan Rathbun
                    最後由 編輯

                    You likely would to put your HTML file within the specific plugin subdir, and give it a unique name (within that plugins names of dialog files, ie: "options.html"
                    So I changed the set_file argument to: File.join(File.dirname(__FILE__),'options.html')

                    Here is a Ruby-side example that should help debug things:

                    This assumes you set unique id for the radio buttons, as I suggested above.

                    module SDM
                    
                      module SomePlugin
                      
                        @@debug = true # set false when done debugging
                      
                        class << self # anonymous singleton proxy class
                        
                          def init_vars()
                            @dialog = nil
                            @align  = "top"
                            @space  = "left"
                          end
                          
                          #  checkstate( value )
                          #
                          def checkstate(value)
                            if value == "true" || value == "checked"
                              return true
                            elsif value == "false" || value == "unchecked"
                              return false
                            end
                            return nil # default
                          end # checkstate()
                          
                          #  options_dialog()
                          #
                          def options_dialog()
                            #
                            unless @dialog # Create dialog instance ONCE (nil evals to false)
                              #
                              @dialog = UI;;WebDialog.new("Options")
                              @dialog.set_file(File.join(File.dirname(__FILE__),'options.html')
                              #
                              @dialog.add_action_callback("sdm") {|dialog, params|
                                #
                                # user clicked "Enter" button
                                #
                                topX = dialog.get_element_value("Top-X")
                                ctrX = dialog.get_element_value("Ctr-X")
                                leftZ = dialog.get_element_value("Lft-Z")
                                ctrZ = dialog.get_element_value("Ctr-Z")
                                #
                                if checkstate(topX)
                                  @align = "top"
                                else
                                  @align = "center"
                                end
                                if checkstate(leftZ)
                                  @space = "left"
                                else
                                  @space = "center"
                                end
                                @dialog.close() # close the dialog
                                #
                                # debugging
                                if @@debug
                                  puts "Callback from options_dialog() returned;"
                                  puts "  User clicked the 'Enter' button."
                                  puts "  Returned params = '#{params}'"
                                  puts "  Element values after;"
                                  puts "    Top-X = #{topX.to_s}"
                                  puts "    Ctr-X = #{ctrX.to_s}"
                                  puts "    Lft-Z = #{leftZ.to_s}"
                                  puts "    Ctr-Z = #{ctrZ.to_s}"
                                  puts "  @var values after;"
                                  puts "    @align = #{@align}"
                                  puts "    @space = #{@space}"
                                  puts()
                                end
                                #
                              } # end callback
                              #
                            end # dialog creation
                            #
                            # show the options dialog if needed
                            if @dialog.visible?
                              @dialog.bring_to_front()
                            else
                              RUBY_PLATFORM =~ /(darwin)/ ? @dialog.show_modal() ; @dialog.show()
                            end
                            #
                            # debugging
                            if @@debug
                              puts "Method options_dialog() called;"
                              puts "  Element values before;"
                              puts "    Top-X = #{@dialog.get_element_value('Top-X').to_s}"
                              puts "    Ctr-X = #{@dialog.get_element_value('Ctr-X').to_s}"
                              puts "    Lft-Z = #{@dialog.get_element_value('Lft-Z').to_s}"
                              puts "    Ctr-Z = #{@dialog.get_element_value('Ctr-Z').to_s}"
                              puts "  @var values before;"
                              puts "    @align = #{@align}"
                              puts "    @space = #{@space}"
                              puts()
                            end
                            #
                          end # options_dialog()
                        
                        end # proxy class
                        
                        # define module methods here prefixed with self.
                        
                        # RUN ONCE CODE
                        unless file_loaded?(File.basename(__FILE__))
                    
                          init_vars()
                          
                          # create menu item and/or toolbar command here
                          # whose execution proc is; { options_dialog() }
                          
                          # register file as already loaded;
                          file_loaded(File.basename(__FILE__))
                    
                        end
                      
                      end # module SomePlugin
                    
                    end # module SDM
                    

                    I'm not here much anymore.

                    1 條回覆 最後回覆 回覆 引用 0
                    • sdmitchS 離線
                      sdmitch
                      最後由 編輯

                      Sorry Mr. Fullmer, wrong Chris. It was an example by Chris Phillips.

                      Dan, thanks for the code. I believe the "verysimple" code is just what I needed but I'll keep yours just in case.

                      Nothing is worthless, it can always be used as a bad example.

                      http://sdmitch.blogspot.com/

                      1 條回覆 最後回覆 回覆 引用 0
                      • Dan RathbunD 離線
                        Dan Rathbun
                        最後由 編輯

                        @sdmitch said:

                        Sorry Mr. Fullmer, wrong Chris. It was an example by Chris Phillips.

                        Hey Chris you've got name recognition!

                        @sdmitch said:

                        Dan, thanks for the code. I believe the "verysimple" code is just what I needed but I'll keep yours just in case.

                        Found it http://sketchucation.com/forums/viewtopic.php?f=180&t=2606&p=12180&hilit=+very+simple+webdialog#p12180

                        That post is 5 years old. And it has some problems... the reference to the dialog is a local var of the method, and will go "out of scope" when the method returns. And the dialog will disappear (get garbage collected by Ruby.)

                        My example does much the same thing, but is written properly wrapped, using proper instance vars, and only creates ONE dialog instance, that is reused again.

                        The major difference is his immediately sends change notification back to the Ruby-side, without waiting for the user to confirm their changes by clicking "Enter".

                        What if they change their mind, and cancel the dialog instead, but after they have already changed a few controls ? They will expect that the changes should not take effect! .. and they really should not.

                        Anyway .. find some happy medium between the two. And enjoy!

                        I'm not here much anymore.

                        1 條回覆 最後回覆 回覆 引用 0
                        • Dan RathbunD 離線
                          Dan Rathbun
                          最後由 編輯

                          Reprise: Actually there are two kinds of WebDialogs that plugin authors create:

                          1. A standard options dialog that has an "OK" (sometimes named "Apply") button, along with a "Cancel" button.

                          This type does not apply the changes unless the user clicks the OK/Apply button.

                          1. A "toolwindow" style (aka "inspector",) dialog in which the control changes take immediate effect.

                          This type usually does not have buttons. The user closes the dialog when they are done by clicking the "X" button at the top-right of the window frame. Occasionally (if there is space,) a close button at the bottom of the dialog is provided. But most users would prefer such "toolwindows" to be as small as possible, as they will be floating open whilst they are working with the model.
                          The latter perhaps is what Chris Phillips actually wanted, which is why he wrote the Js function to immediately return the value changes to the Ruby-side.

                          So, Sam, you need to decide which of the two types you want for your plugin.

                          I'm not here much anymore.

                          1 條回覆 最後回覆 回覆 引用 0
                          • sdmitchS 離線
                            sdmitch
                            最後由 編輯

                            Dan, Since it turned out simple enough to "decode" the parameters string, I did away with the "verysimple" approach and went the conventional update on submit.

                            When starting the plugin, the webdialog created has focus. Is there a way of giving the focus back to the model without having to click the wheel button?

                            Nothing is worthless, it can always be used as a bad example.

                            http://sdmitch.blogspot.com/

                            1 條回覆 最後回覆 回覆 引用 0
                            • Dan RathbunD 離線
                              Dan Rathbun
                              最後由 編輯

                              @sdmitch said:

                              Is there a way of giving the focus back to the model without having to click the wheel button?

                              No current cross-platform method in the API. It has been requested, along with onFocus & onBlur observer callbacks.

                              Normally you could call in JS, %(#8000BF)[window.opener.focus()], but in the Microsoft WebBrowser Control interface, the %(#8000BF)[opener] window object is not exposed (presumably for security reasons?)

                              There is no API method that currently returns a handle to SketchUp's application window either, so you cannot have the html page tell the Ruby-side that the DOM loading is complete, and have the Ruby-side set focus back to the app. This has also been requested.

                              There are low-level solutions, on PC, using "Win32API.so", check the forum, ThomThom and I, and driven all discussed it. There's a topic labeled "Get Sketchup window handle" or similar.

                              I'm not here much anymore.

                              1 條回覆 最後回覆 回覆 引用 0
                              • sdmitchS 離線
                                sdmitch
                                最後由 編輯

                                Dan, Just as I expected but not a big deal.

                                Thanks.

                                Nothing is worthless, it can always be used as a bad example.

                                http://sdmitch.blogspot.com/

                                1 條回覆 最後回覆 回覆 引用 0
                                • D 離線
                                  driven
                                  最後由 編輯

                                  Sam,
                                  T think you may want window_blur http://sketchucation.com/forums/viewtopic.php?f=180&t=49075&p=441642&hilit=.window_blur#p441398
                                  but maybe not...
                                  john

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

                                  1 條回覆 最後回覆 回覆 引用 0
                                  • sdmitchS 離線
                                    sdmitch
                                    最後由 編輯

                                    John, I tried the .show_modal and, just like the API said, nothing is allowed to happen as long as the WebDialog is displayed. I couldn't figure out how the hide it and then bring it back to make a change to the options selected.

                                    Nothing is worthless, it can always be used as a bad example.

                                    http://sdmitch.blogspot.com/

                                    1 條回覆 最後回覆 回覆 引用 0
                                    • D 離線
                                      driven
                                      最後由 編輯

                                      sorry sam, I'm on a laptop without access to all my test snippets so I pointed that one...

                                      the show_modal is for my mac, works with show on PC's

                                      these test are probably what I should have pointed to
                                      http://sketchucation.com/forums/viewtopic.php?f=180&t=49075&p=441642&hilit=.window_blur#p441326
                                      you can call focus or blur whenever you want, the dialog dosn't need to be focused to use them...
                                      1ohn

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

                                      1 條回覆 最後回覆 回覆 引用 0
                                      • Dan RathbunD 離線
                                        Dan Rathbun
                                        最後由 編輯

                                        @Sam:

                                        (1) It would help if you put your OS, and SketchUp Free vs Pro, into your profile, so it appears at the left of your posts.

                                        That way people would not purposely point you towards a method that was specific to an OS that your not developing on / for.

                                        (2) Have another look at the example I wrote for you. It does exactly what you just described. (And uses a platform conditional statement to call the correct show method.)

                                        Keep in mind you need to hold the option refs as @vars on the Ruby side, and restore them to the dialog's controls after each show (because the HTML file is reloaded.)

                                        Ie.. closing the dialog with close() does not destroy it. It is still a valid object, just as it was after you created it, but before it was shown for the first time.

                                        I'm not here much anymore.

                                        1 條回覆 最後回覆 回覆 引用 0
                                        • jolranJ 離線
                                          jolran
                                          最後由 編輯

                                          Hi!

                                          In John/driven's example he uses dlg8.set_html(html) with a Ruby "inline" HTML codestring. That works on Mac? I thought set_html() was to be avoided?

                                          So doing like that and putting in an image for button like below would work on Mac?

                                          In Ruby..
                                          my_icon=File.join(File.dirname(FILE), "folder/myicon_pic.png")

                                          ( In the HTML wrapped something like html = %[html + js code etc...])

                                          Have an image as a button:
                                          <img src="#{my_icon}" width="24" height="24" onClick="jsfunction()">

                                          Note, Im not using a separate Html file in this case.
                                          I think Adam is doing something similar in Goldilocks, but uses URL if I remember it correct.

                                          Hope I'm not hijacking the thread, thought it was relevant.

                                          1 條回覆 最後回覆 回覆 引用 0
                                          • D 離線
                                            driven
                                            最後由 編輯

                                            @jolran said:

                                            Hope I'm not hijacking the thread, thought it was relevant.

                                            Hi jolran,
                                            I agree, however there's a specific thread I started on the subject http://sketchucation.com/forums/viewtopic.php?f=180&t=49338#p443472
                                            try those test files on your mac... I have others as well, that work for me.
                                            john

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

                                            1 條回覆 最後回覆 回覆 引用 0
                                            • 1
                                            • 2
                                            • 1 / 2
                                            • 第一個貼文
                                              最後的貼文
                                            Buy SketchPlus
                                            Buy SUbD
                                            Buy WrapR
                                            Buy eBook
                                            Buy Modelur
                                            Buy Vertex Tools
                                            Buy SketchCuisine
                                            Buy FormFonts

                                            Advertisement