Home > Software design >  How to use a javascript variable inside a Django {% url %} tag?
How to use a javascript variable inside a Django {% url %} tag?

Time:11-10

Im trying to dynamically change the link of a button based on which div a user has currently selected.

I tried to run a quick test with a JS variable in the HTML script tag, but Django isn't reading the variable like a num.

<script type="text/javascript">
    const testing = 10
</script>

<a href="{% url 'battlefield:onevsone_trainer_selection' num_trainers=testing %}"  class='description__button btn btn__large'>Next ></a>

URL looks like:

path('one-vs-one/trainers/<int:num_trainers>', views.oneVsOne, name='onevsone_trainer_selection')

Not sure exactly why it's not working. When I passed it a string of '10' it worked

CodePudding user response:

Django templates are handled server side by django, which means by the time the client browser has received the HTML, the url function, i.e. {% url 'battlefield:onevsone_trainer_selection' num_trainers=testing %}, will have been processed. Javascript, of course, runs in the browser, and you can't pass a javascript variable to a django function after it has arrived at the client.

If you want to change this clientside (without communicating with the server via ajax or something) you might need to change the href attribute directly. You could do something like:

<a id='changeableUrl' href="{% url 'battlefield:onevsone_trainer_selection' num_trainers=1 %}"  class='description__button btn btn__large'>Next ></a>

<script>
  //figure out where the URL should be going
  const testing = 10
  //get the current URL
  url = document.getElementById('changeableUrl').getAttribute("href")
  ///replace the end of the url href with our value
  url.replace('/1/', '/' testing '/')
  ///write back to the link attribute
  document.getElementById('changeableUrl').setAttribute("href", url)
</script>

CodePudding user response:

What you should understand is that django template engine works server-side, whereas Javascript only does its job on client side. What happens is that you are asking django to render the following template :

<script type="text/javascript">
    const testing = 10
</script>

<a href="one-vs-one/trainers/testing" class='description__button btn btn__large'>Next ></a>

Here, testing is not a javascript variable, it's just plain html content. Moreover, it's not an integer at rendering time, so the regex used internally by django shall not be matched and a rendering error shall be raised.

If you really want to set the url paramater client-side, then I see two solutions :

The first is to build the url manually without using the django url function. :

<a href="" id="to-change" class='description__button btn btn__large'>Next ></a>

<script type="text/javascript">
    document.getElementById("to-change").href = "one-vs-one/trainers/"   num_trainer;
</script>

The second solution is the one proposed by SamSparx.

Whatever the solution you choose, you should carefully keep in mind that neither of the two if fully safe. In the first case, you make the code a little bit less maintainable by giving more work if one day you change the url in your urls.py file. In the second one, you expose you to a url that is predefined. If JS is not enabled or if something wrong happens on the browser of your client, it may mean that your link shall be linked to what it should not.

  • Related