Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

sugarcube 2: referencing widget args with javascript?

Is it possible to reference the args of a widget using javascript in that widget? How about if say, the first arg ($args[0]) is an array? I've been trying to figure out how to do this, but can't find anything explaining that.

Thank you!

Comments

  • edited June 2017
    Try the State.variables.args array. Outside widget definitions and calls, $args can be set by you or is undefined, so be careful to only use it inside your widget definitions themselves.

    To get an array out of an array, just include another index:
    $args[0][0]
    
    State.variables.args[0][0]
    

    Personally, I don't like to work with mysteriously named variables, so consider giving them better names using temp variables inside the widget:
    <<widget blah>>
        <<set _array to $args[0]>>
        <<set _number to $args[1]>>
        <<if _array[0] and _number is 6>>
    ...
    
  • You need to state the name and full version number of the Story Format you are using, as answers can be different for each one. I will assume you are using v2.18.0

    As I know it the TwineScript code in the widget runs in a different scope then the Javascript code which means they can't directly access the same variable references, even if that Javascript code is called using a <<script>> macro within the widget.

    There are a number of ways around this issue depending on exactly what you are trying to do, two of them being:

    1. Use a <<print>> macro to dynamically create the call to your Javascript code.
    <<widget "print-var1">>
    	<<if $args[0]>>
    		<<print "<script>console.log('var1: " + $args[0] + "');</script>">>
    	<</if>>
    <</widget>>
    


    2. Assign the parameter passed to the widget to a temporary variable and then use SugarCube's State object to access the temporary variable from within the Javascript code if using a <<script>> macro.
    <<widget "print-var2">>
    	<<if $args[0]>>
    		<<set _var to $args[0]>>
    		<<script>>
    			console.log('var2: ' + State.temporary["var"]);
    		<</script>>
    	<</if>>
    <</widget>>
    


    You can pass an array to a widget using a variable like so:
    <<set _list to ["A", "B", "C"]>>
    
    <<print-var1 _list>>
    
  • Thank you for these answers! I understand parts of them, but there are some things that elude me. (Yes, twine 2.1.3 and sugarcube 2.18.0.)

    Is Chapel's suggestion to use State.variables.args contradicted by greyelf's observations about scope? I had been trying to use State.variables.args, but without success.

    greyelf, I don't understand your first approach. I might be able to if I spend more time trying to parse it.

    I think I understand your second approach, which seems straight forward. I'm not clear on why I'm able to reference var in javascript, but not args[0], yet I can still assign the one to the other. My understanding of scope is that variables either can or cannot communicate. Do I have the wrong idea?
  • edited June 2017
    I can't test it right now, but I have every confidence in greyelf, so my method is probably wrong, sorry about that.

    I'm not sure how the scope is changed like that, even after looking at the source code, since it looks like the macro uses the State object to set it all up. I would also be interested in why that happens.
  • JasoninMN wrote: »
    I had been trying to use State.variables.args, but without success.
    You can access the $args array directly
    <<widget "print-var1">>
    	<<if $args[0]>>
    		<<script>>
    			console.log('var1: ' + State.variables["args"]);
    		<</script>>
    	<</if>>
    <</widget>>
    
    .... and
    <<print-var1 "ABC">>
    

    The issue is that the $args variable name is shared between all widget, and maybe macros as well (im not sure about the second and haven't time to test it atm). I am also unsure what would happen if you 'accidentally' changed a value in the $args array in Javascript.

    This is the main reason I suggested using your own temporary variable to pass data between the TwineScript and the Javascript layers, as that is totally within your control.
  • Thanks so much everyone!
Sign In or Register to comment.