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

[Code] Material.names to Webdialog.

Scheduled Pinned Locked Moved Developers' Forum
55 Posts 4 Posters 686 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.
  • J Offline
    jolran
    last edited by jolran 27 Dec 2012, 12:34

    [mod=Solution:2yiho50t]Sample code posted here: http://sketchucation.com/forums/viewtopic.php?f=180&t=49704#p447346 [/mod:2yiho50t]

    Hi.
    I'm passing in material names to webdialog, and sometimes they may include illegal characters.
    So using some string.gsub to make them more acceptable for the html works.
    But then again it is difficult(impossible?) to rebuild that string when coming back to SU-Ruby.
    So I'm searching for info about the subject and meanwhile have a solution thats working for my case, but I am a bit worried the method can fail at some point.

    The main idea is to get model material names to array1.
    Then make a "clone" of array1 with same strings, in same order, but illegal characters removed .
    Pass clone-array to Webdialog. Then back to SU I'll catch the "index" value from the selection. And use strings from array1[index] to assign the material.

    Here some code, not optimized but works when sending the array "web_mats" to a hidden inputfield in HTML and listing the items as options in dropdownlist.

    def getmats()
    	@mat_names=[]; web_mats=[] 
    	Sketchup.active_model.materials.each {|e| @mat_names << e.name if e.valid? } #
    	@mat_names.sort! #Not very precise since there could be numbers. But decent enough.
    	@mat_names.each{|e| web_mats << e.gsub(/[^_0-9A-Za-z]/, '')  } 
    	return web_mats.join('|')
    end
    

    So as I said the index number of the selection option, should match array 1 material name that has the correct stringconvention for SU.
    Not posting any JS here to shorten the topic.

    Now!
    I see that IF the gsub routine fails and the string to HTML is "illegal", there is a blank in the dropdownlist. BUT, the index numbers still seems to be correct. So the 2 arrays still contains same number of items in the right order. But some nils. I can live with that..
    But again if somehow the index would return wrong number, all materials would get mixed up, and thats not a good thing to say at least.

    Is this a bad way of doing things? Some pitfall I havent thought of? I'm sure there is a smarter way even though I like the simplicity in this solution.

    1 Reply Last reply Reply Quote 0
    • T Offline
      thomthom
      last edited by 27 Dec 2012, 13:08

      Illegal characters? SketchUp names (or any string from SketchUp) are UTF-8 encoded - if you encode your WebDialog in UTF-8 there should be no problems. Makes me wonder if you're properly escaping the execute_string argument... ?

      Mind you, you probably want to send a hash to the webdialog because you have Material.name and Material.display_name which serves two different purposes. Material.display_name is for displaying the material in the UI - like SketchUp does. Material.name is a unique key to identify/refer to a material from the materials list.
      http://www.thomthom.net/thoughts/2012/03/the-secrets-of-sketchups-materials/

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

      1 Reply Last reply Reply Quote 0
      • J Offline
        jolran
        last edited by 27 Dec 2012, 13:32

        @unknownuser said:

        UTF-8 encoded?

        I think so, will doublecheck. Some materials came out as blank until I escaped some characters.

        @unknownuser said:

        Properly escaping the execute_string argument?

        Not sure what you mean.

        I'm currently populating the dialog with excecute script and passing in each values. Some are methods like the one posted #{method}. Could and probably will be turned into hash later on. I will pay more attention to your homepage, some good reading on materials there.

        So you are saying that all SU characters are legitimate? No need to escape as long as UTF-8?
        I am sending user material names if that has anything to do with it.
        Testing with some wierd names like "%&%/((%)%)=?&(&". Actually I just thought this was something one had to do before sending strings to html/js. Just proves how little I know 😄

        1 Reply Last reply Reply Quote 0
        • T Offline
          thomthom
          last edited by 27 Dec 2012, 13:57

          SketchUp gives you strings that are UTF-8 encoded.
          If you encode your WebDialog in UTF-8 they will display correctly. (Beware that SketchUp's Ruby 1.8 does not handle strings as UTF-8 so if you modify the strings you risk corrupting it.)

          When you use WebDialog.execute_string you are sending a string to be evaluated in JavaScript.

          So if you try to do this:
          wd.execute_script('alert(Hello);') You will get an error, because what the JavaScript engine will evaluate is: alert(Hello);
          Notice there is no quotes around "Hello" - JS will expect Hello to be an object.

          wd.execute_script('alert("Hello");')
          evaluates to:
          alert("Hello");

          wd.execute_script("alert('Hello');")
          evaluates to:
          alert('Hello');

          wd.execute_script('alert(\'Hello\');')
          evaluates to:
          alert('Hello');

          wd.execute_script(%{alert('Hello');})
          evaluates to:
          alert('Hello');

          wd.execute_script(%{alert('Hello "Quoted" World');})
          evaluates to:
          alert('Hello "Quoted" World');

          You see how it's important to properly escape quotes?
          If you're getting unexpected results when you use WebDialog.execute_script check that what you're passing to the method is valid JavaScript.

          I compile the JavaScript string to a variable before I send it to .execute_script so I can easily output the string for debugging and inspect that the string is valid.

          <span class="syntaxdefault">javascript </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">'alert("Hello");'<br /></span><span class="syntaxdefault">puts javascript </span><span class="syntaxcomment"># DEBUG<br /></span><span class="syntaxdefault">webdialog</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">execute_script</span><span class="syntaxkeyword">(</span><span class="syntaxdefault"> javascript </span><span class="syntaxkeyword">)&nbsp;</span><span class="syntaxdefault"></span>
          

          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
            thomthom
            last edited by 27 Dec 2012, 14:01

            @jolran said:

            Actually I just thought this was something one had to do before sending strings to html/js.

            But youare sending strings - the material names.

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

            1 Reply Last reply Reply Quote 0
            • J Offline
              jolran
              last edited by 27 Dec 2012, 14:22

              Ahh, now I see what you mean by Properly escaping the execute_string argument.

              Yes I think I'm doing that properly cause I'm populating the dialog with materialnames already. Some come out as blank though. But they are extreme names like ÄÅäöp()&&¤# etc, just for testing.
              I do get an JS error if NOT escaping some characters like I do in the method.
              even if they are strings. Maybe my meta-tag is incorrect?

              <meta http-equiv="X-UA-Compatible" content="IE=8"/>
              <meta http-equiv="content-type" content="text/html; charset=utf-8"/> 
              

              material.display_name is interesting though. Cause I also wanted to display more user-friendly names in the dialog.

              1 Reply Last reply Reply Quote 0
              • T Offline
                thomthom
                last edited by 27 Dec 2012, 14:46

                @jolran said:

                Some come out as blank though. But they are extreme names like ÄÅäöp()&&¤# etc, just for testing.

                Make sure you make the data valid for HTML. & is a special characters used to denote character entities. Do you use plain JavaScript?
                I think a framework, like jQuery, will take care of inserting text correctly for you. (I never do any HTML/JS work without jQuery these days.)

                Remember, you have a a Ruby string which you pass on to JavaScript for evaluation where you're inserting it into HTML. You must ensure the data is passed on to the next layer in a valid format. All the characters should be displayable in HTML.

                You might want to run some isolated tests with static HTML to ensure you know how the data needs to be formatted.

                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
                  thomthom
                  last edited by 27 Dec 2012, 14:47

                  Do you have a simple test where a string fails?

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

                  1 Reply Last reply Reply Quote 0
                  • J Offline
                    jolran
                    last edited by 27 Dec 2012, 19:02

                    Thomthom, thanks for your help.
                    I am using Jquery as well. I'm using it noway near its potential, though. But I think the JQ selectors themself is worth the try learning it.
                    Don't have a programmer background so all this is quite new to me.

                    @unknownuser said:

                    static HTML
                    ?

                    Do you mean running the HTML straight from Notepad? I do that often, but not with theese
                    variables though. I thought theese problems came from ruby-side so..

                    @unknownuser said:

                    Make sure you make the data valid for HTML. & is a special characters used to denote character entities

                    Well, I am sending strings, yes. I'm always aware of that.

                    But the material names can be made by a user. Sketchup.active_model.materials. So I thought (besides having tidy names in the dialog) the convention was to trap for cases where the user enters some invalid characters in the material name.

                    Its difficult to post snippets from a larger piece of code but I can try.

                    In the JS I have an body onload function like which call a function to SU for default options:

                    $(document).ready(function(){
                    getSU_opts('populate_UI');
                    }
                    

                    This function then make a callback to SU for default values.

                    function getSU_opts(vals) { // populates the Webdialog from SKP. 
                    		window.location.href = 'skp;get_data@' + vals;
                    }
                    

                    Back in SU after creating the webdialog I have this callback to send default values.

                    @hatchUI.add_action_callback("get_data") do |@hatchUI, vals|
                    		if vals=="populate_UI"
                    			@hatchUI.execute_script(%(document.getElementById("mat_list").value   ="#{getmats()}";))
                      end
                    end
                    

                    "mat_list" is a hidden inputfield. In case the list gets long.

                    So to populate the Html dropdownlist I'll use this michmach Jquery-JS code.

                    function populate_List(i,j){ //i=id of "hidden storage-element"(array). j=id for selectionbox where to create new option from i
                    		
                    		var Listitem = $(i).val().split('|');
                    		
                    		$.each(Listitem, function(val, text) {             
                    			$(j).append( $('<option></option>').val(val).html(text) )             
                    		}); 
                    }
                    

                    The code is working somewhat.
                    I do get a dropdownlist with the material names, except for thoose extreme names.
                    They get blank, but are selectable.
                    And if I dont use string.gsub(/[^_0-9A-Za-z/, '')]
                    I get an JS error. If it not standard to trap for extreme non english name I think I'm ok?

                    Note I'm just showing the relevant code parts to this topic.

                    1 Reply Last reply Reply Quote 0
                    • T Offline
                      thomthom
                      last edited by 28 Dec 2012, 14:05

                      Have you tried:

                      $(j).append( $('<option></option>').val(val).text(text) )

                      ?

                      .html() expects HTML content - but you just want to insert a plain string - so I'm wondering if
                      .text() would work here.

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

                      1 Reply Last reply Reply Quote 0
                      • D Offline
                        Dan Rathbun
                        last edited by 28 Dec 2012, 14:54

                        Just a good place to note some differing behavior.

                        I am not sure which of the following jQuery uses for it's text() function: %(#8000BF)[innerText] (invented by MicroSoft,) or %(#8000BF)[textContent] (the newer W3C standard function.)

                        Recently, when dynamically writing a stylesheet into a %(#8000BF)[<STYLE>] tag, when I used %(#8000BF)[innerText], it inserted %(#8000BF)[<BR>] tags at the end of everyline, causing a double linebreak when the source is viewed in the browser's Development Tools.

                        When I added a conditional statement to use %(#8000BF)[textContent] if it was not %(#8000BF)[null], the stylesheet text was inserting as entirely plain text.

                        This was in a Chrome content script extension, BTW.

                        So I'm raising a flag here to check to be sure that unwanted line breaks are not being inserted.


                        FYI.. I have a tokenized CSS stylesheet in a separate file, I load it into a js var, then replace ALLCAPS tokens with values from a js options Object, before inserting the CSS into a %(#8000BF)[<STYLE>] element in the document's %(#8000BF)[<HEAD>].
                        In this way I have only 1 stylesheet, instead of like 24 covering all the optional permutation. And I can also, insert the unique extension ID url into the CSS text when it's needed, and not have to have users edit the CSS to manually insert their unique extension ID (usually mulitple places.)

                        I'm not here much anymore.

                        1 Reply Last reply Reply Quote 0
                        • T Offline
                          thomthom
                          last edited by 28 Dec 2012, 15:22

                          Screenshot.png


                          materials.rb


                          MaterialsToWebDialog.skp

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

                          1 Reply Last reply Reply Quote 0
                          • J Offline
                            jolran
                            last edited by 28 Dec 2012, 15:25

                            ThomThom, thanks and good point! I will definately investigate text vs HTML content.

                            Dan. Interresting read. Not quite following it all, but if JQ is using innerText(my MS) may that cause problems with MAC?
                            Although I thought JQUERY took care of platform incompabilities?

                            EDIT: something dropped down the mailbox. Will have a look at that Thomthom!

                            1 Reply Last reply Reply Quote 0
                            • T Offline
                              thomthom
                              last edited by 28 Dec 2012, 15:30

                              @jolran said:

                              Dan. Interresting read. Not quite following it all, but if JQ is using innerText(my MS) may that cause problems with MAC?
                              Although I thought JQUERY took care of platform incompabilities?

                              jQuery takes care of platform differences. Which is why I never use anything else. See the example I just posted. A bare bone example of populating a webdialog with names from SketchUp displaying names as SU does while still able to obtain the name (used as key in model.materials).

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

                              1 Reply Last reply Reply Quote 0
                              • J Offline
                                jolran
                                last edited by 28 Dec 2012, 15:40

                                Thank you very much Thomthom ☀ . I havent tried it, but I trust it works.

                                May I add parts of it and mimic some into my script?
                                Will have to rewrite lots of my stuff but this looks very well structured, and I like my code to be that as well 😄 .

                                Edit. Just tested and it works nicely 👍

                                1 Reply Last reply Reply Quote 0
                                • J Offline
                                  jolran
                                  last edited by 28 Dec 2012, 15:57

                                  BTW do you always use Jquery source with ajax.googleapis.com etc..?
                                  Or was it just for this example.
                                  It's only works if you not in the need for costum interface right?

                                  1 Reply Last reply Reply Quote 0
                                  • T Offline
                                    thomthom
                                    last edited by 28 Dec 2012, 16:27

                                    @jolran said:

                                    May I add parts of it and mimic some into my script?

                                    Go ahead!

                                    I found it easier to write a bare bone example than trying to work what was going on with a complex script I didn't have access to. In general I find it useful to write small snippets like this when I have an issue in my plugins - isolating the desired function into a small test in order to get a working concept - then port it back into the main project.
                                    I might just use it as an example for a new blog entry as it deals with a few common issues in communication with webdialogs.

                                    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
                                      thomthom
                                      last edited by 28 Dec 2012, 16:29

                                      @jolran said:

                                      BTW do you always use Jquery source with ajax.googleapis.com etc..?
                                      Or was it just for this example.

                                      Just this example yes, in order to keep the test in a self-contained .rb file.

                                      @jolran said:

                                      It's only works if you not in the need for costum interface right?

                                      Not sure what you mean by this though. 😕 Custom interface?

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

                                      1 Reply Last reply Reply Quote 0
                                      • J Offline
                                        jolran
                                        last edited by 28 Dec 2012, 16:47

                                        [
                                        @unknownuser said:

                                        Go ahead!

                                        That is very kind of you! I've never used a for loop before so I'll might rewrite some stuff to the codingstyle I'm used to. Otherwise I'll have a hard time to follow.

                                        @unknownuser said:

                                        Not sure what you mean by this though. Custom interface?

                                        costum UI, [like "jquery-ui-1.8.16.custom.min.js". Download whats needed.

                                        @unknownuser said:

                                        I might just use it as an example for a new blog entry as it deals with a few common issues in communication with webdialogs.

                                        I think you should 👍 It's a good example I think. Not too long not too short.
                                        Trying to learn from someone elses script with 500 + lines of ruby + HTML, JS etc can be very time consuming and difficult. And Googles examples leave you in need for more.

                                        1 Reply Last reply Reply Quote 0
                                        • T Offline
                                          thomthom
                                          last edited by 28 Dec 2012, 16:59

                                          @jolran said:

                                          That is very kind of you! I've never used a for loop before so I'll might rewrite some stuff to the codingstyle I'm used to. Otherwise I'll have a hard time to follow.

                                          Sure, it's a very quick script that does one job only. A simple proof of concept.

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

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

                                          Advertisement