How to pass dynamic URLs to DOM

297 views
Skip to first unread message

Kariyushi Rao

unread,
Sep 25, 2020, 1:59:40 AM9/25/20
to oTree help & discussion
I know this topic has been discussed before on the forum, but I was just stumped on it for a few hours, so I'm going to post the solution I found here in case anyone else finds themselves in a similar situation in the future (e.g. if you are redirecting participants to an external form in Qualtrics, or if you are tracking participants in a system like SONA and want to automatically mark participants as having "completed" your study in SONA by redirecting them to a SONA confirmation URL).

I need to send participants to an external URL at the end of my oTree app.  But, this external URL needs to be dynamic.  At the end of the URL, I need to append the participant's bonus amount, and their participant label.  So, something like this...

Stable part of URL: www.somesurvey.qualtrics.com/
Bonus parameter: bonus=[participant_bonus]
Label parameter: id=[participant_label]


The way I am building the dynamic URL is through the vars_for_template(self): function defined on the class for the last page in my oTree app.  E.g.

class LastPage(Page):    
     
def vars_for_template(self):
          label
= self.player.participant.label
          bonus
= c(self.player.payoff).to_real_world_currency(self.session)
          link
= "www.somesurvey.qualtrics.com/?bonus=" + str(bonus) + "&id=" + str(label)
         
return{'link': link}

Then, on the last page of my app, I use a javascript function to open the external URL in a new tab when the participant clicks the "Next" button.  Here's the html for that final page (that DID NOT work)...

{% extends "global/Page.html" %}
{% load staticfiles otree_tags %}

{% block scripts %}
<script>
   
var link = "{{ link }}"; //this doesn't work
   
function NewTab() {
        window
.open(link, "_blank");
   
}
</script>
{% endblock %}

{% block content %}
 <p>Click Next to complete the Payment Survey</
p>

<button id="id_submit_button" onclick="NewTab()" class="otree-btn-next btn btn-primary next-button otree-next-button">Next</button>

{% endblock %}

The javascript function sort of works as expected.  It sends the participant to the external URL in a new tab.  But, I see in the address bar of the new tab that the ampersand character that precedes the participant label parameter in the URL has been replaced with the encoded named entity "&amp;" - as a result, the external site does not recognize that there is a new entity reference ahead of the participant label parameter, and fails to capture that parameter.

In Debug mode, the link variable passed to the DOM appears to be correct.  But, when I view the source for the final page of my oTree app, I see the following in the script block...


I didn't see anyone mention this elsewhere on the forum, but apparently Django escapes variables for you when you pass them into the DOM.  So, if you want to pass a URL to javascript, you have to make sure that Django doesn't escape the ampersand characters in your URL by using the following syntax:  {{ [url_variable_name] | escapejs }}

Here's what that looks like in the present example I started with above...


{% extends "global/Page.html" %}
{% load staticfiles otree_tags %}

{% block scripts %}
<script>
   
var link = "{{ link | escapejs }}"; //here's where that new syntax comes in
   
function NewTab() {
        window
.open(link, "_blank");
   
}
</script>
{% endblock %}

{% block content %}
 <p>Click Next to complete the Payment Survey</
p>

<button id="id_submit_button" onclick="NewTab()" class="otree-btn-next btn btn-primary next-button otree-next-button">Next</button>

{% endblock %}

I think this is still relevant if you are trying to use the window.location solution, as opposed to the weird custom button function I'm using here.  I couldn't figure out how to get this to work using the js_vars function, so I'm not sure if the better solution is to just use js_vars, and I'm just doing js_vars wrong.  The {{ [variable_name] | escapejs }} syntax works, though, in any case, so I figured I'll leave it here in case anyone needs it.

ErikK

unread,
Oct 5, 2020, 6:46:45 AM10/5/20
to oTree help & discussion
I'm trying to figure out the same thing? Have you already found a solution?

Op vrijdag 25 september 2020 om 07:59:40 UTC+2 schreef kariyu...@gmail.com:

Chris @ oTree

unread,
Oct 5, 2020, 6:56:03 AM10/5/20
to oTree help & discussion
Hi, thanks for posting this guide. Regarding js_vars, it seems to work fine for me:

class MyPage(Page):
def js_vars(self):
return dict(url='https://www.google.com/search?q=ronaldo')

<script>
function NewTab() {
window.open(js_vars.url, "_blank");
}
</script>
<p>Click Next to complete the Payment Survey</p>

<button onclick="NewTab()" class="otree-btn-next btn btn-primary">Next</button>

ErikK

unread,
Oct 6, 2020, 4:48:55 AM10/6/20
to oTree help & discussion
thanks! I'll try it out!

Erik

Op maandag 5 oktober 2020 om 12:56:03 UTC+2 schreef Chris @ oTree:

ErikK

unread,
Oct 23, 2020, 10:06:50 AM10/23/20
to oTree help & discussion
I tried out the js solution, which worked well, but it also seems to work with a simple html redirect, so I decided to use that instead. I used a similar vars_for_template code in pages that was suggested above, and then put the following line in the last html file:

<meta http-equiv="Refresh" content="0; url='{{link}}'" />

qualltrics seems to pick up the variables I wanted to transfer just fine. so no need really for js in this case.

Erik

Op dinsdag 6 oktober 2020 om 10:48:55 UTC+2 schreef ErikK:

Andrea Martinangeli

unread,
Mar 26, 2021, 3:55:40 AMMar 26
to oTree help & discussion
I am trying to find a way to modify Kariyu's code to refresh the and open the link rather than opening a new window (tried window. refresh(...) but it seems not to work), or ErikK's to refresh on click rather than automatically.
Both codes work for me, only the first opens a new window and the second opens the link automatically.
Would very much appreciate a suggestion!

Tommaso Batistoni

unread,
Mar 26, 2021, 4:30:12 AMMar 26
to Andrea Martinangeli, oTree help & discussion
If you just need a redirect link passing some parameter, that solution is extraordinarily overcomplicated.
You could for example do this (it will redirect in the same tab):

in your page class (assuming you are using the non-self syntax):
def vars_for_template(player):
total_earnings = player.participant.payoff_plus_participation_fee()
link = f'your_link/?total_earnings={total_earnings}'
return dict(link=link)

in your template:
<a href="{{ link }}" class="btn btn-primary">Link</a>

--
You received this message because you are subscribed to the Google Groups "oTree help & discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to otree+un...@googlegroups.com.
To view this discussion on the web, visit https://groups.google.com/d/msgid/otree/6388998a-f849-4288-9729-563f1b283e26n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages