Webdialog data into Ruby

The line:

@defn.set_attribute( 'dynamic_attributes', '_type_formula', "#{value}")

passes a reference ‘value’ that is NOT defined.
The callback passes a value, but in your code it is named ‘p’ !
Doh!
So either change ‘p’ to ‘value’ or ‘value’ to ‘p’ !

Hey, TIG, there may be an alternative, but I am unsure if it is cross-platform (ie, W3C HTML-DOM.)

The MSDN pages show that selection elements on MSIE can use a selectedIndex property.

So it’s may be possible to simplfy thing to:

JAVASCRIPT:

function sendKolomChoice( choice ) {
	
        window.location = "skp:kolom@"+choice;
}

HTML:

<select id="this_drop_list" onchange="sendKolomChoice(this[this.selectedIndex].value);">

Still no result.

Everything is working but it is going wrong with the callback. It doesn’t recognaize the value.

Does a similar example working fine for you, Dan and Tig?

Thanks

run this with Ruby Console open and you can see what is being sent and received…

I added </head> closing tag, fixed the javascript alert, fixed the action_callback value to return

def kolom

         @mod = Sketchup.active_model
         @ents = @mod.active_entities
         @defs = @mod.definitions
         @defn = nil
         
         @dlg=UI::WebDialog.new("Entresolvloer", false,"WDID",1000,1100,200,200,true)
         @dlg.set_background_color("white")
         html = <<-HTML
 
         <html>
            <head>
               <meta charset="utf-8" />
                
              <script>

               function sendKolomChoice( value ) {
               window.location = "skp:kolom@"+value;
               
               alert( 'Javascript will send ' + value + ' to SU Ruby'  );
               
              }   
            </script>
            
            </head> 
            
            <body>
              <!-- <form action='skp:kolom@'> -->

              Select Column type:
              <select id="this_drop_list" onchange="sendKolomChoice(this.value);">
              <option value="200">200</option>
              <option value="300">300</option>
              <option value="400">400</option>
              <option value="500">500</option>
              <option value="600" selected>600</option>
              </select>
              
             <center><input type="image" src="C://Users/techniek/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/12.gif" alt="Build FLoor" width="95" height="80"
             onClick="sendKolomChoice(this_drop_list.value);"
             /></center>

<!-- 
             <center><input type="image" src="C://Users/techniek/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/12.gif" alt="Build FLoor" width="95" height="80"/></center>
             </form>
 -->
          </body>
         </html>
         HTML

         @dlg.set_html(html)
#         @dlg.add_action_callback("kolom") {|d,p| 
         @dlg.add_action_callback("kolom") {|dlg,value|
           # 
           puts "This is the #{value.class} from #{dlg} >> #{value}"
           p value.to_i != 0
           skp = "Z:/Algemeen 2016/Systeemvloeren/Tekeningen/Sketchup/Enkelzijdige kolom C350.skp"
           
           if File.exists?(skp) and value.to_i != 0
           
           @mod.start_operation "Create Kolom"
            
#             model = Sketchup.active_model
#             @defn = model.definitions
#             componentdefinition = @defn.load ( "Z:/Algemeen 2016/Systeemvloeren/Tekeningen/Sketchup/Enkelzijdige kolom C350.skp" )
           @defn = @defs.load ( skp )
#             @defn = componentdefinition 
#             @defn = model.active_entities.add_instance( @defn, [0,0,0] ) 
           @ents.add_instance( @defn, [0,0,0] ) 
#           @defn.set_attribute( 'dynamic_attributes', '_type_formula', "#{value}")
           @defn.set_attribute( 'dynamic_attributes', '_type_formula', value) 
           dcs = $dc_observers.get_latest_class
           dcs.redraw_with_undo(@defn)
           # close the operation
           @mod.commit_operation
           
           end
          };
                  
         RUBY_PLATFORM =~ /(darwin)/ ? @dlg.show_modal() : @dlg.show();
         
      end
kolom

I commented out the form element as what it returns is wrong and I changed your image button to return the current shown option on my mac, IE may handle that differently…

john

[quote=“john_drivenupthewall, post:25, topic:27624”]

Thanks John,

Put this code into ruby but still no result so it doesn’t change the ‘type’ value.

This is what the editor says:

This is the String from #<UI::WebDialog:0x000000245c8e28> >> 600
true
Error: #<NoMethodError: undefined method `transform!' for #<Sketchup::ComponentDefinition:0x0000002467e548>>
c:/users/techniek/appdata/roaming/sketchup/sketchup 2016/sketchup/plugins/su_dynamiccomponents/ruby/dcclass_v1.rbs:458:in `redraw'
c:/users/techniek/appdata/roaming/sketchup/sketchup 2016/sketchup/plugins/su_dynamiccomponents/ruby/dcclass_v1.rbs:410:in `redraw_with_undo'
(eval):67:in `block in kolom'
SketchUp:1:in `call'

that error is occurring after a successful return of the value from javascript…

I don’t have the DC, so I wasn’t testing any of that code…

delete the line [I deleted it in the snippet above]…

@mod.abort_operation if

as it’s an unfinished typo…

john

Test the DC bits separately first…

 def kolom_test(value)

  @mod = Sketchup.active_model
  @ents = @mod.active_entities
  @defs = @mod.definitions
  @defn = nil
  skp = "Z:/Algemeen 2016/Systeemvloeren/Tekeningen/Sketchup/Enkelzijdige kolom C350.skp"

  @mod.start_operation "Create Kolom"
  @defn = @defs.load ( skp )

  @ents.add_instance( @defn, [0,0,0] ) 
  @defn.set_attribute( 'dynamic_attributes', '_type_formula', value) 
  
  puts  @defn.get_attribute( 'dynamic_attributes', '_type_formula')
  
  dcs = $dc_observers.get_latest_class
  dcs.redraw_with_undo(@defn)
  # close the operation
  @mod.commit_operation
           
end           

kolom_test('600')

john

Yes is saw that so i deleted it already :slight_smile:

Looks is has something to do with the dc. So i added it to this reply so you can also test it.

Because it is placing the component but doesn’t change the size.

Thanks.Enkelzijdige kolom C350.skp (384.9 KB)

To check what the changed list item is [without yet sending it to the callback] use:
<select id="this_drop_list" onchange="alert(this.id);alert(this.value);alert(this[this.selectedIndex].value)">
The 3 js alerts show after you chage an item in the list will show you what is getting collected by those various alternatives.
Assuming one works use that in the function call that runs the callback.
On the ruby side, ensure that the passed value and what is sent to the attribute is the same - in your last posted example you still get |d,p| but then perversely pass ‘value’ to the attribute - try |d,value|

  • in the add_action_callback code add:
    UI.messagebox(value)
    To check it is working…

NOTE: you also have a @mod.start_operation "Create Kolom" - but you never ‘commit’ it after the attribute changes…

AND you set a second reference to the active_model as model=... to get the definitions, when you already have @mod set earlier !

AND you have some very muddled referencing - first you set @defn to the model’s definitions and then immediately use it to reference an actual definition, and then immediately reset it to refer to a newly added instance of that definition.
Are you not really trying to set this attribute for the component’s definition - and not the instance of the component itself ?
If so, then you should use references like @defns, @defn= and @instance=, and then @defn.set_attribute(... should work…

ALSO don’t put a space between a method and the opening parenthesis around its arguments:
@defn.load ( "Z:/Algemeen...
should be
@defn.load( "Z:/Algemeen...
It can break Ruby…

@defn.get_attributes( 'dynamic_attributes').each{|a| p a};nil
["_formatversion", 1.0]
["_has_movetool_behaviors", 1.0]
["_hasbehaviors", 1.0]
["_inst___iscollapsed_access", nil]
["_inst___iscollapsed_formlabel", nil]
["_inst___iscollapsed_formula", nil]
["_inst___iscollapsed_formulaunits", nil]
["_inst___iscollapsed_label", nil]
["_inst___iscollapsed_options", nil]
["_inst___iscollapsed_units", nil]
["_inst__iscollapsed", "false"]
["_inst__x_access", nil]
["_inst__x_formlabel", nil]
["_inst__x_formula", "0-Enkelzijdige kolom!type/2"]
["_inst__x_formulaunits", nil]
["_inst__x_label", "X"]
["_inst__x_options", nil]
["_inst__x_units", nil]
["_inst__y_access", nil]
["_inst__y_formlabel", nil]
["_inst__y_formula", "5"]
["_inst__y_formulaunits", nil]
["_inst__y_label", "Y"]
["_inst__y_options", nil]
["_inst__y_units", nil]
["_inst__z_access", nil]
["_inst__z_formlabel", nil]
["_inst__z_formula", "voetplaat!LenZ"]
["_inst__z_formulaunits", nil]
["_inst__z_label", "Z"]
["_inst__z_options", nil]
["_inst__z_units", nil]
["_inst_x", -11.811023622047244]
["_inst_y", 1.968503937007874]
["_inst_z", 0.39370078740157477]
["_lastmodified", "2016-06-08 10:54"]
["_lengthunits", "CENTIMETERS"]
["_lenx_error", "<span class=subformula-success>60.0</span>"]
["_lenx_formula", "Enkelzijdige kolom!type"]
["_lenx_label", "LenX"]
["_leny_formula", "Enkelzijdige kolom!type"]
["_leny_label", "LenY"]
["_lenz_access", "TEXTBOX"]
["_lenz_error", "<span class=subformula-success>300.0</span>+-1*<span class=subformula-success>0.9999999999999999</span>+-39.3"]
["_lenz_formlabel", "Hoogte"]
["_lenz_formula", "Enkelzijdige kolom!LenZ-voetplaat!LenZ-39.3"]
["_lenz_label", "LenZ"]
["_lenz_units", "CENTIMETERS"]
["_name", "Kolom"]
["lenx", 23.62204724409449]
["leny", 23.62204724409449]
["lenz", 102.24409448818896]

Oke think i’m going to lose it. See so much solutions now haha

it’s seem so easy.

The "value"is also not working as you use it as a point:

@ents.add_instance( @defn, [value,0,0] )

Thanks with the explanation TIG for is the working code :-):

def kolom

         @mod = Sketchup.active_model
         @ents = @mod.active_entities
         @defs = @mod.definitions
         @defn = nil
         
         @dlg=UI::WebDialog.new("Entresolvloer", false,"WDID",1000,1100,200,200,true)
         @dlg.set_background_color("white")
         html = <<-HTML
 
         <html>
            <head>
               <meta charset="utf-8" />
                
              <script>

               function sendKolomChoice( value ) {
               window.location = "skp:kolom@"+value;
                       
              }   
            </script>
            
            </head> 
            
            <body>
              <!-- <form action='skp:kolom@'> -->

              Select Column type:
              <select id="this_drop_list">
              <option value="200">200</option>
              <option value="300">300</option>
              <option value="400">400</option>
              <option value="500">500</option>
              <option value="600" selected>600</option>
              </select>
              
             <center><input type="image" src="C://Users/techniek/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/12.gif" alt="Build FLoor" width="95" height="80"
             onClick="sendKolomChoice(this_drop_list.value);"
             /></center>

          </body>
         </html>
         HTML

         @dlg.set_html(html)
         @dlg.add_action_callback("kolom") {|d,value| 

       
         
            model = Sketchup.active_model
            @defn = model.definitions
            componentdefinition = @defn.load( "Z:/Algemeen 2016/Systeemvloeren/Tekeningen/Sketchup/Enkelzijdige kolom C350.skp" )
            @defn = componentdefinition 
            @defn = model.active_entities.add_instance( @defn, [0,0,0] )  
            @defn.set_attribute( 'dynamic_attributes', '_type_formula', "#{value}") 
              dcs = $dc_observers.get_latest_class
              dcs.redraw_with_undo(@defn)
           
         }         
         RUBY_PLATFORM =~ /(darwin)/ ? @dlg.show_modal() : @dlg.show();
         
      end
kolom

You are still using @defn to refer to three different things,
and doesn’t the DC attribute belongs in the definition NOT with its instance ??

Oke gona fix that.

Last question about this code. After clicking the image it appears with the right value.

But how you handle when you also want to at a table where you can give in coordinates and put it under the same callback?

see picture below what i mean. So it needs to get the value of the select and table.

@defn = model.active_entities.add_instance( @defn, [@X,@Y,@Z] )
@defn.set_attribute( 'dynamic_attributes', '_type_formula', "#{value}") 

You are still resetting @defn to be the instance !
And what is @X etc ?
Are the X/Y/Z extracted from the ‘value’ ???

AND don’t you want to set the attribute to the actual definition ?
NOT the definition’s instance ??

Sorry, but your explanations are very confusing, and hinder us in formulating a constructive response !
Can you fix ALL known issues and then present any remaining issues…
At the moment we are trying our best, but you are putting hurdles in our path at every turn !

Sorry TIG for my bad explanation. So i will try it one last time :wink:

To make it eassier to understand i have placed only a "messagebox’ what will give me the results from the @dlg callback.
So my last issue is that i can’t find the method to pass ‘this_drop_list.value’ tot the @dlg callback after clicking the image button.

The messagebox will give me the first result from ‘@X’ so that works fine (split) but know i have no idea to get the second messagebox with the ‘this_drop_list.value’

This is really the last thing i need to know and then you won’t hear me again :wink:

def colomn

         @mod = Sketchup.active_model
         @ent = @mod.active_entities
         
         @X = 0.mm unless @X
         @Y = 0.mm unless @Y
         @Z = 0.mm unless @Z

         @dlg=UI::WebDialog.new("Entresolvloer", false,"WDID",1000,1100,200,200,true)
         @dlg.set_background_color("white")
         html = <<-HTML
         <html>
            <head>
               <meta charset="utf-8" />
  

<form action='skp:column@'>

              <script>

               function sendKolomChoice( value ) {
               window.location = "skp:column@"+value;                       
              }   
            </script>

              Select Column type:
              <select id="this_drop_list">
              <option value="100" selected>100x100x3mm</option>
              <option value="100">100x100x4mm</option>
              <option value="120">120x120x3mm</option>
              <option value="120">120x120x4mm</option>
              <option value="120">120x120x5mm</option>
              <option value="140">140x140x5mm</option>                              
            </select>

                  <fieldset>
                     <legend style='font-size:125%;color:grey'><b> Coordinate </b></legend>
                     <table style='font-size:100%'>
                        <tr><td align='left' width=50>X:</td>
                        <td><input name='X' type='text' value='#{@X}' size=5/></td></td></tr>
                        <tr><td align='left' width=50>Y:</td>
                        <td><input name='Y' type='text' value='#{@Y}' size=5/></td></tr>
                        <tr><td align='left' width=50>Z:</td>
                        <td><input name='Z' type='text' value='#{@Z}' size=5/></td></tr>
                     </table>
                  </fieldset><br>       

                 <center><input type="image" src="C://Users/techniek/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/mp.jpg" alt="maken" width="120" height="80"
                 onClick="sendKolomChoice(this_drop_list.value);"/></center>
                 
               </form>
           </body>
         </html>
         HTML

         @dlg.set_html(html)
         
         @dlg.add_action_callback("column") {|d,p|
            p.gsub!("?",""); tokens=p.split("&"); puts p
            tokens.each{|t|
               var,val = t.split("="); puts t
               case var              
                  when 'X' then @X = val.to_l
                  when 'Y' then @Y = val.to_l
                  when 'Z' then @Z = val.to_l
                  
                  end
}
UI.messagebox(@X)
UI.messagebox('this_drop_list.value')
}

         
      
         RUBY_PLATFORM =~ /(darwin)/ ? @dlg.show_modal() : @dlg.show();
         
      end
colomn

if you need to get them all don’t use a form or id’s, use a classname in your javascript…

def colomn

	 @mod = Sketchup.active_model
	 @ent = @mod.active_entities
 
         @k = '1003' unless @k
	 @X = 0.mm  unless @X
	 @Y = 0.mm  unless @Y
	 @Z = 0.mm  unless @Z

	 @dlg=UI::WebDialog.new("Entresolvloer", false,"WDID",1000,1100,200,200,true)
	 @dlg.set_background_color("white")
	 html = <<-HTML
	 <!DOCTYPE html>
	 <html>
	 <head>
		<meta charset="utf-8">
		<script>
			function js2ruby() {
				var ary = [];
				var val = document.getElementsByClassName('v4su');
				for (var i = 0, len = val.length; i < len; i++) {
						ary[i] = val[i].value
				}
				window.location = 'skp:js2ruby@' + ary;
			}
		</script>
		<title></title>
	</head>
	<body>
		Select Column type: <select class='v4su'>
			<option selected value="1003">
				100x100x3mm
			</option>
			<option value="1004">
				100x100x4mm
			</option>
			<option value="1203">
				120x120x3mm
			</option>
			<option value="1204">
				120x120x4mm
			</option>
			<option value="1205">
				120x120x5mm
			</option>
			<option value="1405">
				140x140x5mm
			</option>
		</select>
		<fieldset>
			<legend style='font-size:125%;color:grey'><b>Coordinate</b></legend>
			<table style='font-size:100%'>
				<tr>
					<td align='left' width="50">X:</td>
					<td><input class='v4su' size="5" type='text' value='#{@X}'></td>
				</tr>
				<tr>
					<td align='left' width="50">Y:</td>
					<td><input class='v4su' size="5" type='text' value='#{@Y}'></td>
				</tr>
				<tr>
					<td align='left' width="50">Z:</td>
					<td><input class='v4su' size="5" type='text' value='#{@Z}'></td>
				</tr>
			</table>
		</fieldset><br>
		<center>
			<input alt="maken" height="80" onclick="js2ruby();" src=
			"C://Users/techniek/AppData/Roaming/SketchUp/SketchUp%202016/SketchUp/mp.jpg"
			type="image" width="120">
		</center>
	</body>
	</html>
 HTML

	 @dlg.set_html(html)
 
	 # get 'user replys' from the webdialog,
	 @dlg.add_action_callback("js2ruby") {|d,v| 
	   UI.messagebox(v)
	   input = []
		 v.split(',').each do |c|
			 input << c
		 end
		 @k = input[0].to_i 
		 @X = input[1].to_l
		 @Y = input[2].to_l
		 @Z = input[3].to_l
	 }

	 RUBY_PLATFORM =~ /(darwin)/ ? @dlg.show_modal() : @dlg.show()
 
	end
colomn

john

Thanks John!

Exactly what i mean :slight_smile:

Hi,

Thanks to the help from you guys i have a good working dialog:

The only thing on my wish list is when you press the report button a webdialog appears with the count of components, name etc. When i press it now it saves a txt file.

So i was trying to translate the code to create a text file to a webdialog from ruby to html.

definition = Sketchup.active_model.definitions["C-profiel"]
@number = definition.count_instances
instance = definition.instances[0]
@name = instance.name

@dataline = "%-20s   %-25s   %-8s  %-8s   %-8s  %-s\n"

dictionary_name = "dynamic_attributes"

definition = Sketchup.active_model.definitions["C-profiel"]
@number = definition.count_instances
instance = definition.instances[0]
@name = instance.name
dname = "C-profiel"
deflist = Sketchup.active_model.definitions
matches = deflist.find_all {|d|
  !d.group? && !d.image? && d.name =~ /\A(#{dname})/
}

total = 0
matches.each {|definition|
  number = definition.count_used_instances
  total += number  

  attribute = definition.get_attribute(dictionary_name, 'lenx').to_f.to_mm/25.4
  @height = Sketchup.format_length( attribute )
  @total= @height.to_i*number
  @report = format( @dataline, definition.name, @name, number, @height, "-", "-" )
}

dialog = UI::WebDialog.new("Count", true, "sachi_pluginname_dialogname", 410, 875, 1030, 0, true)

dialog.add_action_callback("pass_data") { |dialog, htmlpage|
  js = "set_details(#{@report.inspect}, #{@total.inspect})" # It's not java.
  dialog.execute_script(js)
}

html_path = Sketchup.find_support_file "count.html" ,"Plugins"
dialog.set_file(html_path)
dialog.show()
<html>
<head>
<script>
function callRuby(htmlpage) {
  // Declare the variable with "var" so that it is not global.
  var query = 'skp:pass_data@' + htmlpage;
  window.location.href = query;
}

function set_details(a, b){alert(a);
  // Example 1
  var text = document.createTextNode(a);
  document.getElementById("detail1").appendChild(text);
  // Example 2
  document.getElementById("detail2").value = b;
}
</script>
</head>

<body>
  <div id="detail1"></div>
  <input id="detail2" />
</body>

<script>
// If you will access element in the page, you need to do this after the page (body) has loaded.
callRuby("pull_selection_count");
</script>
</html>

The result i get is this:

So it doesn’t count the two other C-profiles with an other length. Also when i want to add a new a new line in the html it doesn’t work:

  <div id="detail1"></div>
  <div id="detail2" </div> #instead of <input id="detail2" />
</body>```

Thanks.

I think you may be jumping ahead of yourself again…

does the text file contain the correct information?

if it’s correct you can just use it for the webDialog…

add an example of the text file…

john