Hello,
I have a question about getting info out of a webdialog. I have a ruby UI menu but it’s looking a bit basic. So i want to use a webdialog. The only thing i need to know is to get data into ruby. So in this example x should be the result from myTextInput
Thanks.
@dialog = UI::WebDialog.new
path = Sketchup.find_support_file "1.html", "Plugins"
@dialog.set_file path
@dialog.get_element_value("myTextInput")
@dialog.show
#Result
x = text??
<html>
<body>
<!-- Location of the third vertex -->
Text:
<input type="text" id="myTextInput" value="hello"/>
</body>
</html>
(1) You need to pass the correct amount of arguments to the UI::WebDialog
constructor method, ie, new()
.
(2) Your files need to be in a sub-folder of the “Plugins” folder.
(3) You cannot call functions upon a browser frame until it is shown and exists.
(4) Create a callback for the dialog on the Ruby side that is called when the <input>
element is updated.
@dialog.add_action_callback("text_was_input") {|d,id|
@text = @dialog.get_element_value(id)
}
(5) Then in your html page you need some JavaScript to signal the ruby side that input has occured:
And add a attribute to the <input>
element ie: oninput="input_ready(this.id);"
So the html:
<!DOCTYPE html>
<html>
<head>
<script>
function inputReady(id) {
window.location = "skp://text_was_input@"+id
}
</script>
<head>
<body>
<!-- Location of the third vertex -->
<div>Text:
<input type="text" id="myTextInput" value="hello" oninput="inputReady(this.id);"/>
</div>
</body>
</html>
Ok thanks.
Is this also the way with buttons? So when clicked, value is true.
That is the last thing I need to know how the communication between sketchup and html works.
ok this is what i have but no text result. Tried with some changes but nothing happens after clicking the button
Thanks
@dialog = UI::WebDialog.new()
path = Sketchup.find_support_file "Tekst/1.html", "Plugins"
@dialog.set_file path
@dialog.show
@dialog.add_action_callback("text_was_input") {|d,id|
@text = @dialog.get_element_value(id)
}
<!DOCTYPE html>
<html>
<head>
<script>
function inputReady(id)
{
window.location = "skp://text_was_input@" + id;
}
</script>
<head>
<body>
<!-- Location of the third vertex -->
<div>Text:
<input type="text" id="myTextInput" value="hello" oninput="inputReady(this.id);"/>
<input type="Submit" onclick="inputReady(id);"
value="Get text" />
</body>
</html>
Bliss
July 11, 2016, 12:33pm
5
First, the callback is already called everytime you change the value of the input field (oninput
fires the function on every input). Second, when you added the button, you added the inputReady(id)
function to the onclick
event, but id
is undefined. In this case, you can hardcode the input field associated with the button like this:
<input type="Submit" onclick="inputReady('myTextInput');"
You bring to my mind the fact that unless you have a debugger active or an on error handler, javascript will fail silently on this kind of error with no indication of what went wrong.
1 Like
Bliss:
Second, when you added the button, you added the inputReady(id) function to the onclick event, but id is undefined.
@vanlion , You need to use "inputReady(this.id);"
In JavaScript, this
refers to the current object.
2nd: <input type="Submit"
, this is more normally used inside a <form>
element.
As Sven says, you are firing two (2) events when the text field changes.
Choose either one way or the other. Either fire a value read when individual fields change, or make the user click a “Submit” button, and read all of the input fields.
You likely need to run through a tutorial on JavaScript.
Thanks everyone.
Made some progress.
But what i was wondering how to add a datalist, found some codes but i don’t know how to use the chosen value.
What i’m looking for is a drop datalist ` that can set the value for “Kolom” see code line underneath. at the bottom the code that is already working for input box (text)
Thanks.
@defn.set_attribute( 'dynamic_attributes', '_type_formula', "#{"Kolom"}" )
def kolom
@mod = Sketchup.active_model
@ent = @mod.active_entities
@Length = 8000.mm unless @Length
@Width = 10000.mm unless @Width
@Height = 3000.mm unless @Height
@Breedte = 4000.mm unless @Breedte
@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)
html = <<-HTML
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<form action='skp:box@'>
<fieldset>
<legend style='font-size:125%;color:blue'><b> Invoer gegevens </b></legend>
<table style='font-size:100%'>
<tr><td align='left'>Breedte vloer:</td>
<td><input name='Length' type='text' value='#{@Length}' size=5/></td></tr>
<tr><td align='left'>Diepte vloer:</td>
<td><input name='Width' type='text' value='#{@Width}' size=5/></td></tr>
<tr><td align='left'>Hoogte bovenzijde:</td>
<td><input name='Height' type='text' value='#{@Height}' size=5/></td><tr>
<tr><td align='left'>Stramienmaat in de breedte:</td>
<td><input name='Breedte' type='text' value='#{@Breedte}' size=5/></td><tr>
</table>
</fieldset>
<center><input type="image" src="C://Users/techniek/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/mp.jpg" alt="maken" width="120" height="80"/></center>
</form>
</body>
</html>
HTML
@dlg.set_html(html)
@dlg.add_action_callback("box") {|d,p|
p.gsub!("?",""); tokens=p.split("&"); puts p
tokens.each{|t|
var,val = t.split("="); puts t
case var
when 'Length' then @Length = val.to_l
when 'Width' then @Width = val.to_l
when 'Height' then @Height = val.to_l
when 'X' then @X = val.to_l
when 'Y' then @Y = val.to_l
when 'Z' then @Z = val.to_l
end
}
@mod.start_operation "Place Kolom"
model = Sketchup.active_model
@def = model.definitions
componentdefinition = @def.load ( "Z:/Algemeen 2016/Systeemvloeren/Tekeningen/Sketchup/Enkelzijdige kolom C350.skp" )
@defn = componentdefinition
@defn = model.active_entities.add_instance( @defn, [@X,@Y,@Z] )
@defn.set_attribute( 'dynamic_attributes', '_lenz_formula', "#{@Height*2.54}" )
@defn.set_attribute( 'dynamic_attributes', '_type_formula', "#{"Kolom"}" )
dcs = $dc_observers.get_latest_class
dcs.redraw_with_undo(@defn)
@mod.commit_operation
};
RUBY_PLATFORM =~ /(darwin)/ ? @dlg.show_modal() : @dlg.show();
end
kolom
You need to learn JavaScript if you are going to write WebDialogs.
There are plenty of tutorials on the Internet.
Start here: http://www.w3schools.com/
That line is of no help at all to us. We have no idea what kind of data it should be, nor what the choices in the droplist are.
In HTML this is likely a <select>
element.
You mentioned a <datalist>
element, which is not really necessary, and not supported by MSIE until version 10. (SketchUp by default is currently setting MSIE browser emulation in WebDialogs to v 9.)
So just use <select>
with nested <option>
elements.
W3Schools offers free online tutorials, references and exercises in all the major languages of the web. Covering popular subjects like HTML, CSS, JavaScript, Python, SQL, Java, and many, many more.
You need to assign an ID attribute to the <select>
element and have a function that fires when for it when it changes, ie:
(HTML)
<select id="this_drop_list" onchange="sendKolomChoice(this.id);">
<option value="this.text;">200.mm</option>
<option value="this.text;">300.mm</option>
<option value="this.text;">400.mm</option>
<option value="this.text;">500.mm</option>
<option value="this.text;" selected>600.mm</option>
</select>
And in your <script>
element (usually in the <head>
element,) you need a function that iterates the specific options
collection, of that droplist <select>
element:
(JAVASCRIPT)
function getKolomChoice( list ) {
var opts = list.options;
if (opts.length>0) {
// Iterate the options collection...
for (i=0; i< opts.length; i++) {
// ...searching for the 1st selected option:
if (opts(i).selected == true) {
return opts(i).value;
}
}
// If we get here, just return the first option:
return opts(0).value;
} else {
// Value to return if no options loaded:
return "0";
}
}
function sendKolomChoice( DropListID ) {
var list = document.getElementById(DropListID);
window.location = "skp:callback_name@"+getKolomChoice(list);
}
Thanks Dan,
I know the websites you show me, very helpfull and most part i understand.
The code you gave i also understand but not the part to get the result in a code like i said:
@defn.set_attribute( 'dynamic_attributes', '_type_formula', "#{"????"}" )
??? is result datalist
If i know that i have everything to transform the ruby menu to Webdialog
vanlion:
??? is result datalist
So, … what is it’s Ruby class ? … a String
?
If so , then if the reference name for it is result
, then simply do:
@defn.set_attribute( 'dynamic_attributes', '_type_formula', result )
If not , then do this:
@defn.set_attribute( 'dynamic_attributes', '_type_formula', result.to_s )
… and stop farting around with String interpolation when it is not needed !
1 Like
I did everything you said but the “result” doesn’t work (column is not updated)
This is the sample code. Who can see what is wrong. Thanks.
def kolom
@mod = Sketchup.active_model
@ent = @mod.active_entities
@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:kolom@'>
Select Column type:
<select id="this_drop_list" onchange="sendKolomChoice(this.id);">
<option value="this.text;">200.mm</option>
<option value="this.text;">300.mm</option>
<option value="this.text;">400.mm</option>
<option value="this.text;">500.mm</option>
<option value="this.text;" selected>600.mm</option>
</select>
<script>
function getKolomChoice( list ) {
var opts = list.options;
if (opts.length>0) {
// Iterate the options collection...
for (i=0; i< opts.length; i++) {
// ...searching for the 1st selected option:
if (opts(i).selected == true) {
return opts(i).value;
}
}
// If we get here, just return the first option:
return opts(0).value;
} else {
// Value to return if no options loaded:
return "0";
}
}
function sendKolomChoice( DropListID ) {
var list = document.getElementById(DropListID);
window.location = "skp:callback_name@"+getKolomChoice(list);
}
</script>
<center><input type="image" src="C://Users/techniek/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/12.gif" alt="Vloer bouwen" width="95" height="80"/></center>
</form>
</body>
</html>
HTML
@dlg.set_html(html)
@dlg.add_action_callback("kolom") {|d,p|
@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 = componentdefinition
@defn = model.active_entities.add_instance( @defn, [0,0,0] )
@defn.set_attribute( 'dynamic_attributes', '_type_formula', result)
};
RUBY_PLATFORM =~ /(darwin)/ ? @dlg.show_modal() : @dlg.show();
end
kolom
It would appear that you named your Ruby callback “kolom” in add_action_callback, yet you invoke it as “skp:callback_name” in your javascript.
1 Like
Yes that was supposed to be changed to a valid callback name. It was just some example code I posted.
maxB
July 17, 2016, 6:51am
15
maybe think about adding more debug options in your scripts.
in javascript: add some alerts to visually see what kind of values you are about to send to ruby.
in ruby: add some puts to see what data you just received from javascript.
by doing so you will more easily track down problems
Hi,
Done what you said but stil no result.
it was:
“skp:callback_name@”+getKolomChoice(list);
and now i have:
“skp:callback_kolom@”+getKolomChoice(list);
also added an alert but doens’t give a result only [object]
i know i’m so close…
TIG
July 18, 2016, 11:40am
18
Try value instead of id:
<select id="this_drop_list" onchange="sendKolomChoice(this.value);">
and also the callback is defined as:
@dlg.add_action_callback("kolom")...
So you need to call that explicitly in the js function:
window.location = "skp:kolom@"+getKolomChoice(list);
changed everything but stil no result:
it doesn’t recognize a value for “list” i think
def kolom
@mod = Sketchup.active_model
@ent = @mod.active_entities
@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: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>
<script>
function getKolomChoice( list ) {
var opts = list.options;
if (opts.length>0) {
// Iterate the options collection...
for (i=0; i< opts.length; i++) {
// ...searching for the 1st selected option:
if (opts(i).selected == true) {
return opts(i).value;
}
}
// If we get here, just return the first option:
return opts(0).value;
} else {
// Value to return if no options loaded:
return "0";
}
}
function sendKolomChoice( DropListID ) {
var list = document.getElementById(DropListID);
window.location = "skp:kolom@"+getKolomChoice(list);
}
</script>
<center><input type="image" src="C://Users/techniek/AppData/Roaming/SketchUp/SketchUp 2016/SketchUp/12.gif" alt="Vloer bouwen" width="95" height="80"/></center>
</form>
</body>
</html>
HTML
@dlg.set_html(html)
@dlg.add_action_callback("kolom") {|d,p|
@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 = componentdefinition
@defn = model.active_entities.add_instance( @defn, [0,0,0] )
@defn.set_attribute( 'dynamic_attributes', '_type_formula', "#{list}")
};
RUBY_PLATFORM =~ /(darwin)/ ? @dlg.show_modal() : @dlg.show();
end
kolom
TIG
July 18, 2016, 1:27pm
20
Your html code is muddled.
In the <head>
set up the <script>
In the <body>
after that set up the form, list etc.
You neither close the head or open the body !
Try this:
function sendKolomChoice( value ) {
window.location = "skp:kolom@"+value;
}
You are over complicating it…
I don’t think you need getKolomChoice
If you pass the current value to the callback you can use that directly…