SQL 请求过程与JS

SQL request process with JS

我想从包含 SQL 查询结果的 JSP 变量中添加一个 with JS。

这是我的两个输入:

<tr>
    <td><label>Code postal* :</label></td>
    <td><input type="number" name="cp" placeholder="CP du lieu de résidence" required /></td>
    <td><label>Ville* :</label></td>
    <td><select name="ville" required disabled/></select></td>
</tr>

这是我的 JS 和 JSTL 查询:

<sql:query dataSource="jdbc/Referentiel" var="communeCp" > 
    SELECT code_postal, nom_commune_min, insee_commune FROM  commune
</sql:query>
<script>
    $('input[name=cp]').keyup(function(){
        if ($(this).val().length == 5) 
        {   
            $('select[name=ville]').prop('disabled', false);
            var communeListe = "${communeCp}";
            for (var i in communeListe)
            {
                var currentCp = communeListe[i][code_postal];
                var currentVille = communeListe[i][nom_commune_min];
                if($('input[name=cp]').val() == currentCp)
                { 
                    $('select[name=ville]').append('<option value="'+ currentVille +'">'+ currentVille +'</option>');
                }
            }
        }
        else
        {
            $('select[name=ville]').prop('disabled', true);
        }
    });
</script>

我的导航器说 "code_postal is not defined"。

我被迫使用 ajax 来做这个?我真的不知道ajax。 :/

"code_postal is not defined" 的发生是因为 java 脚本的这一行:

var currentCp = communeListe[i][code_postal]; 

Javascript 认为 code_postal 是一个变量的名称,但是 javascript 中的任何地方都没有 "var codePostal = ..."。

这是您的 JSP 页面的情况:

首先,您的 JSP 被渲染。 JSP 调用 SQL 查询并将结果存储在 communeCp 变量(javax.servlet.jsp.jstl.sql.Result 类型的对象)中。

JSP 然后替换这一行:

var communeListe = "${communeCp}";

计算结果"communeCp.toString()"。我不知道那是什么,但它可能与默认 Object.toString 实现一样简单,所以这是将呈现给页面的实际 java 脚本:

var communeListe = "javax.servlet.jsp.jstl.sql.Result@123456".

现在 JSP 已经呈现,浏览器执行 java 脚本。它甚至无法评估,因为你有未定义的 code_postal 引用,但如果由于某种原因这不是问题,它会失败,因为你试图在 communeListe 上为每个循环做一个循环,但是 javascript 发现 communeListe 只是一个简单的字符串,因此对其进行 for 循环没有意义。

现在,理解了这一点,我将尝试解释如何在没有 AJAX 的情况下实现您想要的行为。

从您的代码来看,您似乎想要以下行为:用户需要输入邮政编码和 select 该邮政编码中的一个 ville。在他们输入邮政编码的 5 个字符后,启用 "ville" 下拉菜单并使用该邮政编码可能的别墅选择填充它。

您有实现此目的的一种方法的基本思路:在 JSP 中执行查询以获取所有邮政编码和所有村庄,然后,当输入邮政编码时,以某种方式查看此数据java编写脚本并使用该邮政编码中的村庄填充村庄下拉列表。

问题在于使 SQL 查询中的数据可用于 java 脚本。如果没有 AJAX,您可以这样做。基本思想是使用通过渲染 JSP:

生成的文字来初始化对象的 javascript 数组
<sql:query dataSource="jdbc/Referentiel" var="communeCp" > 
    SELECT code_postal, nom_commune_min, insee_commune FROM  commune
</sql:query>
<script>
    var communeListe= [];
    <c:forEach var="row" items="${communeCp.rows}">
        communeListe.push({
            code_postal: '${row.code_postal}',
            nom_commune_min: '${row.nom_commune_min}',
            insee_commune: '${row.insee_commune}'
        });
    </c:forEach>
    $('input[name=cp]').keyup(function(){
        if ($(this).val().length == 5) 
        {   
            $('select[name=ville]').prop('disabled', false);
            $.each(communeListe, function(index, currentRow) {
                var currentCp = currentRow.code_postal;
                var currentVille = currentRow.nom_commune_min;
                if($('input[name=cp]').val() == currentCp)
                { 
                    $('select[name=ville]').append('<option value="'+ currentVille +'">'+ currentVille +'</option>');
                }
            });
        }
        else
        {
            $('select[name=ville]').prop('disabled', true);
        }
    });
</script>

请注意! 如果您在公社 table 中有很多行,这可能会使页面加载非常缓慢,因为您正在发送每一行的文本到用户的浏览器。

对于您的用例,使用 AJAX 几乎肯定是一个更好的整体设计。这将提高加载速度的方式是它只会查询它需要的 villes,并且只需要将所有可能的 villes 的一小部分发送回用户的浏览器。我可以提供一些指导:

基本上,您首先需要开发一个服务器端网络服务。您可能只使用 Java servlet 就可以做到这一点,因为您已经在使用 JSP。这个 servlet 需要接受一个邮政编码作为请求参数,并根据该邮政编码查询公社数据库(因此它应该只获取 postal_code == 邮政编码请求参数值的行)。然后它将 return JSON 包含代表公社数据库中那些行的对象数组,所以像这样:

//assume this is the request coming to your webservice
/get_villes?postalCode=12345

//This would be the JSON response returned by your webservice
[
    {
        'nom_commune_min': 'ville name 1',
        'insee_commune': 'insee_commune 1'
    },
    {
        'nom_commune_min': 'ville name 2',
        'insee_commune': 'insee_commune 3'
    },
    ... and so on depending on how many villes have that postal code
]

要实现此 Web 服务,您可以制作一个简单的 java 对象,称为 Commune 之类的对象,并将其作为字段提供 nom_commune_min 和 insee_commune。然后,您可以使用一个简单的 JSON 序列化库,例如 Jackson 将该对象序列化为一个字符串,并 return 从您的 servlet 中将其序列化为 HTTP 响应的主体。

在前端,您需要更改 java 脚本,以便在输入邮政编码时使用 $.ajax({ ... }) 和调用该网络服务,您将邮政编码的值传递给它以进行查找。

对 $.ajax 的调用可能看起来像这样(我可能会使用 $.get 只是因为它是 $.ajax 的更简单版本):

$.get({
    url: "/get_villes?postalCode=" + postalCode,
    success: function(communeCp){
        $.forEach(communeCp,function(index,currentRow){
            //put code here to populate the dropdown list using
            //currentRow.postal_code, just like the previous code I provided                
        });
    },
});

另一件需要考虑的事情是,由于这是异步的,当浏览器执行此查询时,下拉列表将在该查询运行期间暂时空白(但用户仍可以自由地与页面,并且可能会被空白启用的 ville 下拉列表混淆)。因此,当 javascript ajax 查询运行时,您需要告知用户您正在等待 Web 服务的结果。所以,你可以做一些事情,比如在他们输入邮政编码的 5 位数字时在某处显示 "Loading..." 文本,然后在 $.get 的成功函数中隐藏该文本(在填充下拉列表后)。

除此之外,我建议您花一些时间了解 AJAX 和网络服务的工作原理,并查看一些教程和示例。网络服务、ajax 以及与构建动态网站相关的一切都是现代网络开发的重要组成部分。