首页 > 解决方案 > JS 代码不适用于从 Django 模型中检索到的所有数据

问题描述

我正在endDate使用 HTML 页面上的 forloop 从 Django 模型中检索一个字段。
我想检查所有即将到来的 endDate 是否都小于今天的日期。为此,我正在使用 JS 代码。

我的代码只能在检索到的第一个日期执行检查,但它不适用于其他日期。

这是我用于检索数据的HTML 代码:

{% for p in object_list %}
    <h4>{{ p.jobName }}</h4>
    <p><b style="color: red">Expires On: </b><b>{{ p.endDate }}</b></p>

    <a href="{{ p.get_absolute_url }}" target="_blank">View info</a>    

    <input type="hidden" id="endDate" name="variable" value="{{ p.endDate }}">
    <span id="check"></span>            

{% endfor %}

检查日期的JavaScript 代码:

<script type="text/javascript">       
    var endDate = document.getElementById("endDate").value;
    var ToDate = new Date();
    if(new Date(endDate).getTime()<=ToDate.getTime()){
        document.getElementById("check").innerHTML = "Expired";
        document.getElementById("check").className = "label danger";
    }
    else{
        document.getElementById("check").innerHTML = "Active";
        document.getElementById("check").className = "label success";
    }
</script>

{{ p.jobName }}现在有2个。第一个应该显示Expired而第二个应该显示Active
我的代码仅适用于第一次约会,即仅适用于计算机管理员。

这是我得到的输出: 在此处输入图像描述

谁能告诉我是什么问题?

谢谢

标签: javascriptdjangodjango-modelsdjango-templates

解决方案


扩展我在评论中已经说过的内容:

你的问题的本质在这里:

{% for p in object_list %}
...   
    <input type="hidden" id="endDate" name="variable" value="{{ p.endDate }}">
    <span id="check"></span> 
...
{% endfor %}

HTML 文档只能有一个特定 ID 的元素(否则它不能很好地“识别”该元素 - 这是 HTML 规范的一部分)。在您的情况下,每当循环具有多个元素时,您最终都会得到多个元素,所有元素都带有endDateID,以及多个元素带有checkID。

重复这样的 ID 以及本身是错误的,可能会产生重大的功能影响 - 正如您在代码中看到的那样。也就是说,由于给定 ID 只应该(至多)一个元素,因此在页面上运行的任何 Javascript 代码都有权假设是这种情况。特别是,document.getElementById返回一个表示单个HTML 元素的对象,这与document.getElementsByClassName等类似方法相反,后者返回 DOM 节点的“集合”。(因为类与 ID 不同,可以应用于同一文档中的多个元素。)

因此,简而言之,就是如何解决您遇到的问题。只需将id="endDate"上面的 替换为class="endDate",类似地check,并更改您的 javascript 以考虑到这一点。您不仅必须将getElementById方法更改为getElementsByClassName,还必须考虑到这会返回一个集合(您可以使用 循环.forEach),并且您需要定位相邻的.check跨度而不是第一个,或任何旧的随机一。以下代码是使其工作的一种方法(注意使用 ES6Array.from将集合转换为真正的 Array 以便您可以使用.forEach):

var endDateElts = Array.from(document.getElementsByClassName("endDate"));
var ToDate = new Date();

endDateElts.forEach(function(dateElt) {
    var endDate = dateElt.value;
    var check = dateElt.nextSibling;
    if(new Date(endDate).getTime()<=ToDate.getTime()){
        check.innerHTML = "Expired";
        check.className = "label danger";
    }
    else{
        check.innerHTML = "Active";
        check.className = "label success";
    }
});

推荐阅读