繁体   English   中英

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

[英]How can I create unique javascript variable names in a django template for loop?

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

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

所以 for 循环试图一遍又一遍地重新声明同一个变量。 Throughout the rest of the script I'm using JQuery which is perfectly happy to use the django variable {{ hp_tracker.id }}, but javascript is not because "-" characters, which are in the object IDs are not allowed in variable names .

我到底应该在这里做什么来解决这个热的烂摊子。 有没有办法在没有全局变量的情况下运行我的代码? 我可以在不使用 object 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>

@Swati,您的回答并没有完全满足我的需求,但您确实将我推向了正确的方向,并帮助我填补了我对这一切如何运作的理解中的一些漏洞。 所以我将你的答案标记为正确,谢谢你的帮助,这是我最终使用的代码(我知道 ajax 错误 function 不起作用。但那是另一天..:):

html

<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" data-id="{{ hp_tracker.id }}" class="hp-value-change-form">
                    {% csrf_token %}
                    <div class="hp-control-box">
                        <button type="button" data-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 }}-HpValueChangeCover" class="hp-value hp-change-value-cover"></div>
                        <div id="{{ hp_tracker.id }}-HpValueChange" class="hp-value hp-change-value"></div>
                        <button type="button" data-id="{{ hp_tracker.id }}-HpValueIncreaseBtn" class="hp-value-change-btn increase">+</button>
                    </div>
                </form>
            </div>
        {% endfor %}
    </div>
</div>

js

// ajax call for HpValueForm
$('.hp-value-change-form').submit(function(e) {
    'use strict';
    e.preventDefault();
    let data_id = $(this).attr("data-id");
    // serialize the form data.
    let serializedData = $(this).serialize();
    // make POST ajax call
    $.ajax({
        type: 'POST',
        url: $(this).attr('action'),
        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"]);
        }
    });
});



//control timeout before hp_value increase or decrease is submitted
localStorage.setItem('hp_change_value', '0');
let timeoutHandler;

function timeoutControl(element) {
    'use strict';
    clearTimeout(timeoutHandler);
    // select the closest for to the clicked button
    let selector = $(element).closest('.hp-value-change-form');

    // assign the unique django object id to a variable
    let data_id = selector.attr("data-id");

    // get the hp change value from local storage
    let hp_change_value = parseInt(localStorage.getItem('hp_change_value'));

    // get the current hp value being provided by django context
    let hp_initial_value = parseInt($("#" + data_id + "-HpValue").text());

    // calculate the amount to be entered into the hp value change form
    let hp_add_subtract_value = hp_initial_value + hp_change_value;

    // After a 2 second delay submit the form and reset the change value to 0
    timeoutHandler = setTimeout(function () {
        $('#' + data_id + '-HpValueInput input').val(hp_add_subtract_value);
        $('#' + data_id + '-HpValueForm').submit();
        $('#' + data_id + '-HpValueChange').css({'display': 'none'});
        $('#' + data_id + '-HpValueChangeCover').css({'display': 'none'});
        localStorage.setItem('hp_change_value', '0');
    }, 2000);
}
// increase the hp value with each button click - value is not submitted until 
// after a 2 second delay via timeoutControl()
$('.hp-value-change-btn.increase').click(function (e) {
    'use strict';
    let selector = $(this).closest('.hp-control-box');
    let hp_change_value = parseInt(localStorage.getItem('hp_change_value'));
    hp_change_value++;
    localStorage.setItem('hp_change_value', hp_change_value.toString());
    $(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);

});

// decrease the hp value with each button click - value is not submitted until 
// after a 2 second delay via timeoutControl()
$('.hp-value-change-btn.decrease').click(function (e) {
    'use strict';
    let selector = $(this).closest('.hp-control-box');
    let hp_change_value = parseInt(localStorage.getItem('hp_change_value'));
    hp_change_value--;
    localStorage.setItem('hp_change_value', hp_change_value.toString());
    $(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);

});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM