关于form:select表单的onchange事件问题

关于form:select表单的onchange事件问题

我在报销单添加页面增加了一个表单项(id=items0.item2),目的是实现item的二级菜单,在页面下方写了一个script脚本,想通过ajax的方式根据一级菜单的值动态添加二级菜单项,经测试发现<form:select>的onchange事件触发不了,请老师看看什么原因,以下是页面代码:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:include page="top.jsp"/>

<section id="content" class="table-layout animated fadeIn">
   <div class="tray tray-center">
       <div class="content-header">
           <h2> 填写报销单 </h2>
           <p class="lead"></p>
       </div>
       <div class="admin-form theme-primary mw1000 center-block" style="padding-bottom: 175px;">
           <div class="panel heading-border">
               <form:form id="admin-form" name="addForm" action="/claim_voucher/add" modelAttribute="info">
                   <div class="panel-body bg-light">
                       <div class="section-divider mt20 mb40">
                           <span> 基本信息 </span>
                       </div>
                       <div class="section">
                           <label for="claimVoucher.cause" class="field prepend-icon">
                               <form:input path="claimVoucher.cause" cssClass="gui-input" placeholder="事由..."/>
                               <label for="claimVoucher.cause" class="field-icon">
                                   <i class="fa fa-lock"></i>
                               </label>
                           </label>
                       </div>
                       <div class="section-divider mt20 mb40">
                           <span> 费用明细 </span>
                       </div>
                       <div class="section row" id="items">
                           <div>
                               <div class="col-md-3">
                                   <label for="items0.item" class="field prepend-icon">
                                       <form:select id="items0.item" path="items[0].item" cssClass="gui-input" placeholder="花销类型..." items="${items}"/>
                                   </label>
                               </div>
                               <div class="col-md-3">
                                   <label for="items0.item2" class="field prepend-icon">
                                       <form:select id="items0.item2" path="items[0].item2" cssClass="gui-input" placeholder="花销类型2..."/>
                                   </label>
                               </div>
                               <div class="col-md-3">
                                   <label for="items[0].amount" class="field prepend-icon">
                                       <form:input path="items[0].amount" cssClass="gui-input money" placeholder="金额..."/>
                                       <label for="items[0].amount" class="field-icon">
                                           <i class="fa fa-lock"></i>
                                       </label>
                                   </label>
                               </div>
                               <div class="col-md-5">
                                   <label for="items[0].comment" class="field prepend-icon">
                                       <form:input path="items[0].comment" cssClass="gui-input" placeholder="备注..."/>
                                       <label for="items[0].comment" class="field-icon">
                                           <i class="fa fa-lock"></i>
                                       </label>
                                   </label>
                               </div>
                               <div class="col-md-1" style="text-align:right;">
                                   <button type="button" class="button"> X </button>
                               </div>
                           </div>
                       </div>
                       <div class="section row">
                           <div class="col-md-3">
                               <label for="totalMoney" class="field prepend-icon">
                                   <form:input id="totalMoney" path="claimVoucher.totalAmount" cssClass="gui-input" placeholder="总金额..." readonly="true"/>
                                   <label for="totalMoney" class="field-icon">
                                       <i class="fa fa-user"></i>
                                   </label>
                               </label>
                           </div>
                           <div class="section" style="text-align:right;">
                               <div class="col-md-9">
                                   <button type="button" class="button" id="addItemButton"> + </button>
                               </div>
                           </div>
                       </div>
                       <div class="panel-footer text-right">
                           <button type="submit" class="button"> 保存 </button>
                           <button type="button" class="button" onclick="javascript:window.history.go(-1);"> 返回 </button>
                       </div>
                   </div>
               </form:form>
           </div>
       </div>
   </div>
</section>

<jsp:include page="bottom.jsp"/>
<script type="text/javascript" >
   $(function () {

       $("#items0.item").change(function () {
           alert("1234560123");
           // var first_menu=$(this).val();
           // alert(first_menu);
           $.ajax({
               url:"/claim_voucher/cascade",
               type:"get",
               data:"first_menu="+first_menu,
               dataType:"json",
               success:function (json) {
                   for(var i=0;i<json.length;i++){
                      alert(json[i]);
                       $("#items0.item2").append("<option value='"+json[i]+"'>"+json[i]+"</option>");
                   }
               }
           })
       })
   })
</script>

正在回答

登陆购买课程后可参与讨论,去登陆

8回答

同学你好,根据报错信息以及同学对应的代码内容:

Uncaught SyntaxError: missing ) after argument list--》参数列表后的拼接内容没有正确获取

出现这个报错,一般是参数列表后面缺少 )   或者是拼接参数的时候不能正确的识别。结合同学贴出的代码,同学可能是在复制代码的时候,因为编码不同的问题,导致复制过程中出现一些内容没有正常解析展示,比如:

http://img1.sycdn.imooc.com//climg/5e82dc8d09c18dcc05710359.jpg

空格的解析出现问题,同学就删除这个空格乱码内容,再来重试一下。

如果我的回答解决了你的疑惑,请采纳,祝学习愉快~

  • 慕沐8221787 提问者 #1
    功能是实现了,但是这个chang函数还带了一个“.items0”的参数,这个参数什么意思,我在w3c网站找遍了,也没看到这样的语法介绍,请问老师在哪里有这样的资料,想完整学习一下,谢谢!
    2020-03-31 16:42:00
  • 好帮手慕小班 回复 提问者 慕沐8221787 #2
    同学你好,这里的.items0其实就是class选择器,通过父元素绑定子元素,它其实就是jquery中on方法的使用形式,同学可以参考这个内容再来具体理解学习一下: https://www.runoob.com/jquery/event-on.html 如果我的回答解决了你的疑惑,请采纳,祝学习愉快~
    2020-03-31 19:41:03
好帮手慕小班 2020-03-30 18:30:37

同学你好,动态添加的元素需要添加上change事件,才可以在动态添加的标签中获取到二级菜单的内容。

    1、首先老师尝试将两个菜单的内容按照如下形式书写:

http://img1.sycdn.imooc.com//climg/5e81c80609523db110240378.jpg

    2、我们可以尝试将事件绑定在父元素上,比如:

http://img1.sycdn.imooc.com//climg/5e81c67f09d93f6f07380588.jpg

这样先增加的才能够有change事件,查看被选择的元素和需要赋值的元素的特点,有一个2的区别:

http://img1.sycdn.imooc.com//climg/5e81c70c094a79b205310178.jpg

然后对应可以使用name选择器来进行对应赋值的操作:


http://img1.sycdn.imooc.com//climg/5e81c6e30937b47a07170599.jpg

就实现了动态添加的元素上实现的change事件的赋值。

修改后的claim_voucher_add.jsp代码如下:

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:include page="top.jsp"/>

<section id="content" class="table-layout animated fadeIn">
    <div class="tray tray-center">
        <div class="content-header">
            <h2> 填写报销单 </h2>
            <p class="lead"></p>
        </div>
        <div class="admin-form theme-primary mw1000 center-block" style="padding-bottom: 175px;">
            <div class="panel heading-border">
                <form:form id="admin-form" name="addForm" action="/claim_voucher/add" modelAttribute="info">
                    <div class="panel-body bg-light">
                        <div class="section-divider mt20 mb40">
                            <span> 基本信息 </span>
                        </div>
                        <div class="section">
                            <label for="claimVoucher.cause" class="field prepend-icon">
                                <form:input path="claimVoucher.cause" cssClass="gui-input" placeholder="事由..."/>
                                <label for="claimVoucher.cause" class="field-icon">
                                    <i class="fa fa-lock"></i>
                                </label>
                            </label>
                        </div>
                        <div class="section-divider mt20 mb40">
                            <span> 费用明细 </span>
                        </div>
                        <div class="section row" id="items">
                            <div>
                                <div class="col-md-3">
                                    <label for="items[0].item" class="field prepend-icon ">
                                        <form:select  path="items[0].item" cssClass="gui-input items0" placeholder="花销类型..." items="${items}"/>
                                    </label>
                                </div>
                                <div class="col-md-3">
                                    <label for="items[0].item2" class="field prepend-icon">
                                        <form:select id="items[0].item2" path="items[0].item2" cssClass="gui-input" placeholder="花销类型2..."/>
                                    </label>
                                </div>
                                <div class="col-md-3">
                                    <label for="items[0].amount" class="field prepend-icon">
                                        <form:input path="items[0].amount" cssClass="gui-input money" placeholder="金额..."/>
                                        <label for="items[0].amount" class="field-icon">
                                            <i class="fa fa-lock"></i>
                                        </label>
                                    </label>
                                </div>
                                <div class="col-md-5">
                                    <label for="items[0].comment" class="field prepend-icon">
                                        <form:input path="items[0].comment" cssClass="gui-input" placeholder="备注..."/>
                                        <label for="items[0].comment" class="field-icon">
                                            <i class="fa fa-lock"></i>
                                        </label>
                                    </label>
                                </div>
                                <div class="col-md-1" style="text-align:right;">
                                    <button type="button" class="button"> X </button>
                                </div>
                            </div>
                        </div>
                        <div class="section row">
                            <div class="col-md-3">
                                <label for="totalMoney" class="field prepend-icon">
                                    <form:input id="totalMoney" path="claimVoucher.totalAmount" cssClass="gui-input" placeholder="总金额..." readonly="true"/>
                                    <label for="totalMoney" class="field-icon">
                                        <i class="fa fa-user"></i>
                                    </label>
                                </label>
                            </div>
                            <div class="section" style="text-align:right;">
                                <div class="col-md-9">
                                    <button type="button" class="button" id="addItemButton"> + </button>
                                </div>
                            </div>
                        </div>
                        <div class="panel-footer text-right">
                            <button type="submit" class="button"> 保存 </button>
                            <button type="button" class="button" onclick="javascript:window.history.go(-1);"> 返回 </button>
                        </div>
                    </div>
                </form:form>
            </div>
        </div>
    </div>
</section>

<jsp:include page="bottom.jsp"/>
<script type="text/javascript" >
    
</script>

修改后的items如下:

$(document).ready(function(){
    builderIndex();
    calculateMoney();
    $("#addItemButton").click(
        function(){
            $("#items").children("div").last().after($("#items").children("div").first().clone());
            $("#items").children("div").find("button").click(
                function(){
                    $(this).parent().parent().remove();
                    if($("#items").children("div").size()==1){
                        $("#items").find("button").attr("disabled",true);
                    }
                    builderIndex();
                    calculateMoney();
                }
            );
            $("#items").find("button").attr("disabled",false);
            builderIndex();
            $(".money").change(
                function(){
                    calculateMoney();
                }
            );
            calculateMoney();
        }
    );
    $(".money").change(
        function(){
            calculateMoney();
        }
    );
});// JavaScript Document

function builderIndex(){
    $.each($("#items").children(),function(i,val){
        $("#items").children("div").eq(i).children().eq(0).find("select").attr("name","items["+i+"].item");
        /*添加子菜单的class*/
        $("#items").children("div").eq(i).children().eq(1).find("select").attr("name","items["+i+"].item2");
        $("#items").children("div").eq(i).children().eq(2).find("input").attr("name","items["+i+"].amount");
        $("#items").children("div").eq(i).children().eq(3).find("input").attr("name","items["+i+"].comment");

    });
}
/*实现对应的change事件*/
$("#items").on("change", ".items0", function(e){
   
    var doc=e.currentTarget;
    var varname=$(doc).attr("name")+2;//获取到子菜单的name,
    var first_menu=$(this).val();
    alert(first_menu);
    $.ajax({
        url:"/claim_voucher/cascade",
        type:"get",
        data: {"first_menu":first_menu},
        dataType:"json",
        success:function (json) {
            for(var i=0;i<json.length;i++){
                console.log(json[i]);
                /*对子菜单进行赋值*/
                $("[name='"+varname+"']").append("<option value='"+json[i]+"'>"+json[i]+"</option>");
            }
        }
    })

});

function calculateMoney(){
    var totalMoney=0;
    $.each($(".money"),function(i,val){
        totalMoney+=parseFloat($(".money").eq(i).val());
    });
    $("#totalMoney").attr("value",totalMoney);
}

        3、最后同学还有一个小问题,如果切换菜单的话应该将之前的二级菜单删除再新增,否则会一直叠加,这个内容同学可以参考之前二阶段中登录注册功能章节的内容,在向元素添加查询结果之前,先删除原有的内容,再来添加。这个功能同学可以自己实现一下。

如上就是老师的小例子,同学可以参考着自己实现一下。

如果我的回答解决了你的疑惑,请采纳,祝学习愉快~

  • 提问者 慕沐8221787 #1
    参照老师的代码后,浏览器调试窗口报错: Uncaught SyntaxError: missing ) after argument list items.js:47 具体错误位置如下: /*瀹炵幇瀵瑰簲鐨刢hange浜嬩欢*/ $("#items").on("change",聽".items0",聽function(e){ var聽doc=e.currentTarget; var聽varname=$(doc).attr("name")+2;//鑾峰彇鍒板瓙鑿滃崟鐨刵ame锛�
    2020-03-31 08:32:10
好帮手慕小班 2020-03-30 10:55:19

同学你好,点击页面“+”后,新增报销单详情表单,同学是否在对应的items.js中添加了新增的的二级菜单的select,比如:

http://img1.sycdn.imooc.com//climg/5e815cec099b728715800537.jpg

如上所示,只是老师自己的举例,同学根据自己的具体的内容来添加那个二级菜单的对应标签内容,来修改这个items.js中的内容。

另外,如上修改后,ajax的请求,获取二级菜单的响应内容,同学也需要修改一下,获取对应的标签写入对应的响应内容。

如果我的回答解决了你的疑惑,请采纳,祝学习愉快~

  • 提问者 慕沐8221787 #1
    items.js的代码一开始就像老师写的那样添加了,虽然每点击一次“+”后,报销单明细表单增加了一行,但是id=bb的select标签项的name属性值始终不变,一直是name=items[0].item2,很是疑惑,同时新增部分的二级菜单不能加载,获取二级菜单的响应内容需要如何修改?
    2020-03-30 11:09:33
好帮手慕小班 2020-03-29 16:12:18

同学你好,同学二级菜单仍然加载不到页面是否是因为同学没有注意上一个回答中的id设置问题,同学是否同上面的场景一样修改了一下id的设置。比如:

http://img1.sycdn.imooc.com//climg/5e8057eb0923d0b015400204.jpg

http://img1.sycdn.imooc.com//climg/5e805806093ca10411560285.jpg

这只是一个例子,同学可以根据自己的要求来修改id。

http://img1.sycdn.imooc.com//climg/5e80585e09cc1bfe06520182.jpg

如果我的回答解决了你的疑惑,请采纳,祝学习愉快~

  • 提问者 慕沐8221787 #1
    不好意思,又有一个新问题,点击页面“+”后,新增报销单详情表单,新增部分的二级菜单不能加载,不知道js怎么改,麻烦老师讲一下。
    2020-03-29 20:13:04
好帮手慕小班 2020-03-29 14:45:24

同学你好,测试同学代码,传递的参数是first_menu是null。

http://img1.sycdn.imooc.com//climg/5e803b3d093eeb9512930226.jpg

这里有一个小知识点,@Param:用来在DAO层中声明参数,采用#{}的方式把@Param注解括号内的参数进行引用,例如:

http://img1.sycdn.imooc.com//climg/5e8041e909dcabe610990098.jpg

http://img1.sycdn.imooc.com//climg/5e80427d095fdfaa10600135.jpg

如上所示,括号内参数对应的是形参--> userName对应的是name。

所以同学不能在Controller里用@Param,建议后台接收参数名与前台传的参数名称一致,例如:

http://img1.sycdn.imooc.com//climg/5e804342097941cb08900333.jpg

另外,在前台中传递ajax的参数注意是如下形式

http://img1.sycdn.imooc.com//climg/5e80439409d570ac06090217.jpg

如上所改,再来尝试一下

http://img1.sycdn.imooc.com//climg/5e8043e909550e5507510256.jpg


如果我的回答解决了你的疑惑,请采纳,祝学习愉快~

  • 提问者 慕沐8221787 #1
    我把@Param改为@RequestParam注解后,不传null值了,但是二级菜单仍然加载不到页面,看看哪里问题?
    2020-03-29 15:31:38
好帮手慕阿满 2020-03-28 21:38:19

同学你好,测试同学的代码,这里应该是id有问题,当把id换成aa,例如:

http://img1.sycdn.imooc.com//climg/5e7f534609e9029d06160219.jpg

http://img1.sycdn.imooc.com//climg/5e7f530a0940209c05880304.jpg

就可以获取change函数中弹出的值,如:

http://img1.sycdn.imooc.com//climg/5e7f525e09faca7506330207.jpg

http://img1.sycdn.imooc.com//climg/5e7f5270093af89e05620185.jpg

http://img1.sycdn.imooc.com//climg/5e7f52bf0923658206250226.jpg

祝:学习愉快~

  • 提问者 慕沐8221787 #1
    但是二级菜单还是显示不了,什么原因?
    2020-03-29 08:40:45
好帮手慕小班 2020-03-24 17:45:42

同学你好,从之前的回复中,得知同学alert("1234560123");这句测试代码放到change上边可以弹出。那放在change中是不可以弹出,对吗?

$("#items0.item")可以正常获取,change函数使用没错,那么change函数中alert("")应该也可以弹出。

        建议使用不同的内容,查看change中是否可以弹出,在重新选择#items0.item的下拉选项后,再来试一下,是否能正常触发。

如果我的回答解决了你的疑惑,请采纳,祝学习愉快~

  • 提问者 慕沐8221787 #1
    重新选择#items0.item的下拉选项后,仍然不行,我的代码都贴在问题中了,老师可以看看写的有没有问题,我的目的主要是测试一下利用ajax获取二级菜单选项。
    2020-03-25 21:43:03
  • 好帮手慕小班 回复 提问者 慕沐8221787 #2
    同学你好,老师单独测试了同学的js代码,当select标签发生改变时,change事件是可以触发的,可以弹出对应的内容。所以同学的js代码并没有问题。 是不是同学的引入的jq文件版本问题,这里老师使用的3.3.1版本,同学尝试重新引入jq文件再来试一下。 ​如果我的回答解决了你的疑惑,请采纳,祝学习愉快~
    2020-03-26 15:29:09
  • 提问者 慕沐8221787 #3
    我换了jquery3.4.1版本,还是不行,浏览器调试窗口出现一堆warn信息,如下: Failed to decode downloaded font: http://localhost:8080/assets/fonts/glyphicons/glyphicons-halflings-regular.html to_add:1 OTS parsing error: Failed to convert WOFF 2.0 font to SFNT to_add:1 Failed to decode downloaded font: http://localhost:8080/assets/fonts/font-awesome/fontawesome-webfonte0a5.html?v=4.3.0 to_add:1 OTS parsing error: Size of decompressed WOFF 2.0 is less than compressed size DevTools failed to parse SourceMap: chrome-extension://ncennffkjdiamlpmcbajkmaiiiddgioo/js/xl-content.js.map to_add:1 A cookie associated with a cross-site resource at http://hm.baidu.com/ was set without the `SameSite` attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032. to_add:1 A cookie associated with a cross-site resource at http://baidu.com/ was set without the `SameSite` attribute. It has been blocked, as Chrome now only delivers cookies with cross-site requests if they are set with `SameSite=None` and `Secure`. You can review cookies in developer tools under Application>Storage>Cookies and see more details at https://www.chromestatus.com/feature/5088147346030592 and https://www.chromestatus.com/feature/5633521622188032.
    2020-03-27 10:10:25
好帮手慕小班 2020-03-23 15:31:37

同学你好,同学的onchange事件不能触发,请问同学当前页面加载是否有问题,服务器控制台和浏览器控制台是否有报错,当前页面是否正常加载了。

http://img1.sycdn.imooc.com//climg/5e7865c90960e77106590337.jpg

在Sources中是否正常加载了。如果正常加载了,同学可以再检查一下script代码是否正常执行了。

如果我的回答解决了你的疑惑,请采纳,祝学习愉快~

  • 提问者 慕沐8221787 #1
    加载正常,如果把 alert("1234560123");这句测试代码放到change行数上一行,也就是页面就绪函数的第一行,运行弹框正常,请问接下来如何分析?
    2020-03-23 16:36:06
  • 好帮手慕小班 回复 提问者 慕沐8221787 #2
    同学你好,然后同学可以尝试输出$("#items0.item"),查看是否正常获取到了对应的元素。排查是否是因为元素没有获取到导致的change事件没有触发。 如果我的回答解决了你的疑惑,请采纳,祝学习愉快~
    2020-03-23 19:19:57
  • 提问者 慕沐8221787 #3
    一级菜单($("#items0.item"))输出是正常的,可以点击切换菜单值。
    2020-03-23 19:58:58
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
SSM主流框架入门与综合项目实战2018版
  • 参与学习           人
  • 提交作业       205    份
  • 解答问题       4317    个

Java中非常实用的SSM整合开发内容,从Spring开始,到MyBaits的进阶内容,再到SpringMVC的应用,最后是SSM整合开发案例,逐步深入,助你成长为一名Java工程师!

了解课程
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师