javascript - 如何在循环的 django 模板中创建唯一的 javascript 变量名?

标签 javascript jquery django templates

我正在使用 django 模板循环遍历 hp_tracker 对象。每个 hp_tracker 都有自己的 js 代码,用于通过 ajax 更改值。我几乎可以肯定我应该在 .js 文件中包含此代码,但我无法找到一种方法来唯一地选择每个 hp_tracker,而无需访问 .js 文件中的 django 模板变量。所以...我将 js 移到了 html 模板本身。我知道这无疑会带来巨大的安全隐患,我也愿意讨论这些问题。

无论如何,关于我的问题。我的 js 失败是因为我声明了不唯一的全局变量 (!)。它们被用来控制一些计数器和 setTimeout,我不知道现在如何使用它们来做我想做的事。

因此 for 循环尝试一遍又一遍地重新声明同一个变量。在整个脚本的其余部分,我使用的是 JQuery,它非常乐意使用 django 变量 {{ hp_tracker.id }},但 javascript 不是因为变量名称中不允许对象 ID 中的“-”字符.

我到底该怎么做才能解决这个热点问题。有没有办法在没有全局变量的情况下运行我的代码?我可以在不使用对象 ID 的情况下识别我的 for 循环中的对象吗?

<div id="ToolSessionPageWrapper">
<div class="tool-session-page-header">
    <div id=OpenToolSelectionMenuBtn class="arrow-down"></div>
</div>
<div class="tool-session-page-body">
    <div id="HpTrackersViewWrapper" class="tool-body">
        {% for hp_tracker in hp_trackers %}
            <div class="hp-tracker-box">
                <div id="{{hp_tracker.id}}-HpTrackerTitle" class="hp-tracker-title">{{ hp_tracker.title }}</div>
                <br />
                <form method="POST" action="{% url 'hp_change_value' hp_tracker.id %}" id="{{ hp_tracker.id }}-HpValueForm">
                    {% csrf_token %}
                    <div class="hp-control-box">
                        <button type="button" id="{{ hp_tracker.id }}-HpValueDecreaseBtn" class="hp-value-change-btn decrease">-</button>
                        <div id="{{hp_tracker.id}}-HpValue" class="hp-value">{{ hp_tracker.hp_value }}</div>
                        <div id="{{ hp_tracker.id }}-HpValueInput">{{ hp_change_value_form.hp_value }}</div>
                        <div id="{{ hp_tracker.id }}-HpChangeValueCover" class="hp-value hp-change-value-cover"></div>
                        <div id="{{ hp_tracker.id }}-HpChangeValue" class="hp-value hp-change-value"></div>
                        <button type="button" id="{{ hp_tracker.id }}-HpValueIncreaseBtn" class="hp-value-change-btn increase">+</button>
                    </div>
                </form>
            </div>
            <script>
                {#ajax call for HpValueForm#}
                function changeHpValue(form) {
                    'use strict';
                    $(form).submit(function (e) {
                        // preventing from page reload and default actions
                        e.preventDefault();
                        // serialize the form data.
                        let serializedData = $(form).serialize();
                        // make POST ajax call
                        $.ajax({
                            type: 'POST',
                            url: '{% url 'hp_change_value' hp_tracker.id %}',
                            data: serializedData,
                            success: function (response) {
                                let form_instance = JSON.parse(response['form_instance']);
                                let fields = form_instance[0]['fields'];
                                $('#{{hp_tracker.id}}-HpValue').empty().prepend(fields.hp_value);
                                console.log('ajaxSuccess');
                            },
                            error: function (response) {
                                console.log(response["responseJSON"]["error"]);
                            }
                        });
                    });
                }

                {#control timeout before hp_value increase or decrease is submitted#}
                let {{ hp_tracker.id|escapejs }}hp_add_subtract_value = $('#{{hp_tracker.id}}-HpValue').text(),
                    hp_change_value = 0,
                    timeoutHandler;
                function timeoutControl() {
                    clearTimeout(timeoutHandler);
                    timeoutHandler = setTimeout(function () {
                        $('#{{ hp_tracker.id }}-HpValueInput input').val(hp_add_subtract_value);
                        $('#{{ hp_tracker.id }}-HpValueForm').submit();
                        $('#{{hp_tracker.id}}-HpChangeValue').css({'display': 'none'});
                        $('#{{hp_tracker.id}}-HpChangeValueCover').css({'display': 'none'});
                        hp_change_value = 0;
                        $('#{{hp_tracker.id}}-HpChangeValue').empty().prepend(hp_change_value);
                    }, 2000);
                }
                {#increase the hp value#}
                $('#{{ hp_tracker.id }}-HpValueIncreaseBtn').click(function (e) {
                    'use strict';
                    hp_add_subtract_value++;
                    hp_change_value++;
                    $('#{{hp_tracker.id}}-HpChangeValue').css({'display': 'inline'});
                    $('#{{hp_tracker.id}}-HpChangeValueCover').css({'display': 'inline'});
                    $('#{{hp_tracker.id}}-HpChangeValue').empty().prepend(hp_change_value);
                    timeoutControl();
                });

                {#decrease the hp value#}
                $('#{{ hp_tracker.id }}-HpValueDecreaseBtn').click(function (e) {
                    'use strict';
                    hp_add_subtract_value--;
                    hp_change_value--;
                    $('#{{hp_tracker.id}}-HpChangeValue').css({'display': 'inline'});
                    $('#{{hp_tracker.id}}-HpChangeValueCover').css({'display': 'inline'});
                    $('#{{hp_tracker.id}}-HpChangeValue').empty().prepend(hp_change_value);
                    timeoutControl();
                });

                {#submit HpValueForm#}
                $('#{{ hp_tracker.id }}-HpValueForm').on('submit', changeHpValue('#{{ hp_tracker.id }}-HpValueForm'));
            </script>
        {% endfor %}
    </div>
</div>

最佳答案

您可以只创建一个适用于所有表单的脚本,而不是创建多个脚本。因此,您可以在 django 代码中进行更改:

<div id="HpTrackersViewWrapper" class="tool-body">
        {% for hp_tracker in hp_trackers %}
            <div class="hp-tracker-box">
                <div id="{{hp_tracker.id}}-HpTrackerTitle" class="hp-tracker-title">{{ hp_tracker.title }}</div>
                <br />
                //add data-id ... and a class
                <form method="POST" action="{% url 'hp_change_value' hp_tracker.id %}" data-id ="{{hp_tracker.id}}" class="form_to_submit" id="{{ hp_tracker.id }}-HpValueForm">
                    {% csrf_token %}
                    <div class="hp-control-box">
                        <button type="button" id="{{ hp_tracker.id }}-HpValueDecreaseBtn" class="hp-value-change-btn decrease">-</button>
                        <div id="{{hp_tracker.id}}-HpValue" class="hp-value">{{ hp_tracker.hp_value }}</div>
                        <div id="{{ hp_tracker.id }}-HpValueInput">{{ hp_change_value_form.hp_value }}</div>
                        <div id="{{ hp_tracker.id }}-HpChangeValueCover" class="hp-value hp-change-value-cover"></div>
                        <div id="{{ hp_tracker.id }}-HpChangeValue" class="hp-value hp-change-value"></div>
                        <button type="button" id="{{ hp_tracker.id }}-HpValueIncreaseBtn" class="hp-value-change-btn increase">+</button>
                    </div>
                </form>
            </div>
            //remove whole script from here 
        {% endfor %}        
    </div>

然后,您的 jquery 代码将如下所示:

//on submit of form
$(".form_to_submit").submit(function(e) {
  e.preventDefault();
  //get ids..
  var data_id = $(this).data("id")
  let serializedData = $(this).serialize();
  console.log(data_id)
  // make POST ajax call
  $.ajax({
    type: 'POST',
    url: '{% url hp_change_value ' + data_id + ' %}', //pass here id
    data: serializedData,
    success: function(response) {
      let form_instance = JSON.parse(response['form_instance']);
      let fields = form_instance[0]['fields'];
  $('#' + data_id + '-HpValue').empty().prepend(fields.hp_value); 
   console.log('ajaxSuccess');
    },
    error: function(response) {
      console.log(response["responseJSON"]["error"]);
    }
  });
});


var timeoutHandler;

function timeoutControl(el) {
  clearTimeout(timeoutHandler);
  //get closet form
  var selector = $(el).closest("form")
  //get hp values
  var hp_add_subtract_value = selector.find(".hp-value").text()
  //get id
  var data_id = selector.data('id')
  timeoutHandler = setTimeout(function() {
    $('#' + data_id + '-HpValueInput input').val(hp_add_subtract_value);
    selector.submit();
    selector.find('.hp-change-value').css({
      'display': 'none'
    });
    selector.find('.hp-change-value-cover').css({
      'display': 'none'
    });
    hp_change_value = 0;
    selector.find('.hp-change-value').empty().prepend(hp_change_value);
  }, 2000);
}

$('.increase').click(function(e) {
  var selector = $(this).closest(".hp-control-box")
  var hp_add_subtract_value = parseInt(selector.find(".hp-value").text())
  hp_add_subtract_value++;
  var hp_change_value = selector.find(".hp-change-value").text().trim() != "" ? parseInt(selector.find(".hp-change-value").text().trim()) : 0
  selector.find('.hp-change-value').css({
    'display': 'inline'
  });
  selector.find('.hp-change-value-cover').css({
    'display': 'inline'
  });
  selector.find('.hp-change-value').empty().prepend(hp_change_value);
  timeoutControl(this); //here this refer to increase button which is clickde..
});

$('.decrease').click(function(e) {
  //get closest outer box..
  var selector = $(this).closest(".hp-control-box")
  //use find to get other values..
  var hp_add_subtract_value = parseInt(selector.find(".hp-value").text())
  var hp_change_value = selector.find(".hp-change-value").text().trim() != "" ? parseInt(selector.find(".hp-change-value").text().trim()) : 0

  hp_add_subtract_value--;
  hp_change_value--;
  //change doms ,,,
  selector.find('.hp-change-value').css({
    'display': 'inline'
  });
  selector.find('.hp-change-value-cover').css({
    'display': 'inline'
  });
  selector.find('.hp-change-value').empty().prepend(hp_change_value);
  timeoutControl(this); //refer the button which is clicked
});

演示代码:

//on submit of form
$(".form_to_submit").submit(function(e) {
  e.preventDefault();
  //get ids..
  var data_id = $(this).data("id")
  let serializedData = $(this).serialize();
  console.log(data_id)
  // make POST ajax call
  /*$.ajax({
    type: 'POST',
    url: '{% url hp_change_value ' + data_id + ' %}', //pass here id
    data: serializedData,
    success: function(response) {
      let form_instance = JSON.parse(response['form_instance']);
      let fields = form_instance[0]['fields'];*/
  $('#' + data_id + '-HpValue').empty().prepend(44); //just for demo...
  /* console.log('ajaxSuccess');
    },
    error: function(response) {
      console.log(response["responseJSON"]["error"]);
    }
  });*/
});


var timeoutHandler;

function timeoutControl(el) {
  clearTimeout(timeoutHandler);
  //get closet form
  var selector = $(el).closest("form")
  //get hp values
  var hp_add_subtract_value = selector.find(".hp-value").text()
  //get id
  var data_id = selector.data('id')
  timeoutHandler = setTimeout(function() {
    $('#' + data_id + '-HpValueInput input').val(hp_add_subtract_value);//don't know where is input in your code..:P 
    selector.submit();
    selector.find('.hp-change-value').css({
      'display': 'none'
    });
    selector.find('.hp-change-value-cover').css({
      'display': 'none'
    });
    hp_change_value = 0;
    selector.find('.hp-change-value').empty().prepend(hp_change_value);
  }, 2000);
}

$('.increase').click(function(e) {
  var selector = $(this).closest(".hp-control-box")
  var hp_add_subtract_value = parseInt(selector.find(".hp-value").text())
  hp_add_subtract_value++;
  var hp_change_value = selector.find(".hp-change-value").text().trim() != "" ? parseInt(selector.find(".hp-change-value").text().trim()) : 0
  selector.find('.hp-change-value').css({
    'display': 'inline'
  });
  selector.find('.hp-change-value-cover').css({
    'display': 'inline'
  });
  selector.find('.hp-change-value').empty().prepend(hp_change_value);
  timeoutControl(this); //here this refer to increase button which is clickde..
});

$('.decrease').click(function(e) {
  //get closest outer box..
  var selector = $(this).closest(".hp-control-box")
  //use find to get other values..
  var hp_add_subtract_value = parseInt(selector.find(".hp-value").text())
  var hp_change_value = selector.find(".hp-change-value").text().trim() != "" ? parseInt(selector.find(".hp-change-value").text().trim()) : 0

  hp_add_subtract_value--;
  hp_change_value--;
  //change doms ,,,
  selector.find('.hp-change-value').css({
    'display': 'inline'
  });
  selector.find('.hp-change-value-cover').css({
    'display': 'inline'
  });
  selector.find('.hp-change-value').empty().prepend(hp_change_value);
  timeoutControl(this); //refer the button which is clicked
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hp-tracker-box">
  <div id="1-HpTrackerTitle" class="hp-tracker-title">Soemthings ...,,</div>
  <br />
  <!--here added data-id , class as well-->
  <form method="POST" action="{% url 'hp_change_value' 1 %}" data-id="1" class="form_to_submit" id="1-HpValueForm">
    {% csrf_token %}
    <div class="hp-control-box">
      <button type="button" id="1-HpValueDecreaseBtn" class="hp-value-change-btn decrease">-</button>
      <div id="1-HpValue" class="hp-value">22</div>
      <div id="1-HpValueInput">23</div>
      <div id="1-HpChangeValueCover" class="hp-value hp-change-value-cover"></div>
      <div id="1-HpChangeValue" class="hp-value hp-change-value"></div>
      <button type="button" id="1-HpValueIncreaseBtn" class="hp-value-change-btn increase">+</button>
    </div>
  </form>
</div>
<div class="hp-tracker-box">
  <div id="1-HpTrackerTitle" class="hp-tracker-title">Soemthings ...,,</div>
  <br />
  <form method="POST" action="{% url 'hp_change_value' 2 %}" data-id="2" class="form_to_submit" id="2-HpValueForm">
    {% csrf_token %}
    <div class="hp-control-box">
      <button type="button" id="2-HpValueDecreaseBtn" class="hp-value-change-btn decrease">-</button>
      <div id="2-HpValue" class="hp-value">22</div>
      <div id="2-HpValueInput">23</div>
      <div id="2-HpChangeValueCover" class="hp-value hp-change-value-cover"></div>
      <div id="2-HpChangeValue" class="hp-value hp-change-value"></div>
      <button type="button" id="2-HpValueIncreaseBtn" class="hp-value-change-btn increase">+</button>
    </div>
  </form>
</div>

关于javascript - 如何在循环的 django 模板中创建唯一的 javascript 变量名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66717252/

相关文章:

django - 如何从 Django Admin 中删除 Wagtail Core、图像、文档

python - 使用 Django 从数据库中预填充 HTML 表单表

javascript - React hooks onClick 仅针对父级(模式)触发

javascript - 单击特定下拉选项时不要打开 fancybox

Django 注释平均查询不显示小数位

ajax - 在Ajax响应中获取整个页面: Spring MVC, Ajax

javascript - 无法让滑出菜单正常显示

javascript - QtWebEngine:打印由javascript调用的网页

javascript - Meteor - 如何更新数组中的文档

javascript - 如何在 jQuery 中将文本替换为 HTML?