1

抱歉,如果在其他地方有人问过这个问题,但我环顾四周,找到了一些答案,但不是一个完整的例子,我仍然对此表示怀疑。

因此,我将 Spring 控制器中的自动填充列表添加到我的 jsp 中,并且我想在我的 javascript/jquery 函数内的列表中添加项目。可能吗?

我尝试了下面的代码来测试功能,但它不起作用(列表元素根本没有出现在生成的 html 中)。所以我不确定我是否弄乱了 javascrit/spring/jsp 语法,或者它是否不可能。

这是代码:

控制器代码:

@RequestMapping(value="/create_custobject.html",method = RequestMethod.GET)
public ModelAndView showCreateCustObjectPage() {
    Map<String, Object> model = new HashMap<String, Object>();

    CreateObjectForm form = new CreateObjectForm();
    model.put("createObjectform", form);

    return new ModelAndView("create_custobject", model) ;

}

表格代码:

public class CreateObjectForm {

      private AutoPopulatingList<Criteria> ruleArray = new AutoPopulatingList<Criteria>(Criteria.class);

     public AutoPopulatingList<Criteria> getRuleArray() {
    return ruleArray;
        }

         public void setRuleArray(AutoPopulatingList<Criteria> ruleArray) {
    this.ruleArray = ruleArray;
        }

         public CreateObjectForm() {}
      }

标准代码:

public class Criteria{

   String attribute;

    String operator;
       //... constructor + getters and setters
}

javascript/jquery 代码(在与 jsp 相同的页面上):

<script type="text/javascript">
$(document).ready(function(){
    //startup functionality

 var i = 0;
 document.getElementById("addCriteria").onclick = function() {

         $("#msgid").html("${ruleArray[i].attribute}");

        ${ruleArray[i].attribute} = $('#attributeValue').val();             
        ${ruleArray[i].operator} = $('#operatorValue').val(); 

                    i++;            

      }
   }
4

4 回答 4

3

对于表单中的现有项目,请使用 jstl 作为

<c:forEach items="${form.items}" var="item" varStatus="status" >
<span class="count" > 
<form:input   path="items[${status.index}].field" />

这将呈现这样的形式

<form id = "idform" >
<span class="count" > 
    <input   name="items[0].field"  id="items0.field" />
</span>
</form>

然后您只需添加带有相应索引的 javascript 新表单“行”

例如

 var is = $('.count').size()
 $('#idform span:last').after('<span class="count" ><input name="items[' + is + '].field"' + is + '.field" /></span>')

我认为如果您使用的是 spring 3 +,则不需要使用 AutopopulatingList ,任何集合都应该足够了。

于 2012-11-13T12:01:40.293 回答
1

您不正确地混合 JSP EL 和 Javascript。您不能var i在 JSP 表达式中使用,即。${ruleArray[i].operator}. 我建议使用 JSTL 遍历列表并在脚本中创建属性。

此时,您的脚本可以设置为仅0在表达式中使用字符串文字。我假设您需要比这更强大的功能,您能否更好地描述它。

$(document).ready(function(){
     document.getElementById("addCriteria").onclick = function() {

     $("#msgid").html("${ruleArray[0].attribute}");

     //I assume you wanted to set the element to the value pulled from JSP EL
     $('#attributeValue').val(${ruleArray[0].attribute});           
     $('#operatorValue').val(${ruleArray[0].operator});           

     }
 }

使用 JSTL 的解决方案类似于:

<script>
 var criteria = [];
 <c:forEach var="criteria" items=${ruleArray}>
    criteria.push({attr:${criteria.attribute}, oper: ${criteria.operator});
 </c:forEach>

 for(var i = 0; i < criteria.length; i++){
  alert(criteria[i].attribute);
 }
</script>

该解决方案基本上使用 JSTL 编写 Javascript。修改控制器以返回 JSON 并在页面加载时进行 Ajax 调用可能是更好的解决方案。

于 2012-11-13T10:30:01.500 回答
0

在以下行中i,您在 jsp 代码中引用,但 i 未定义:

$("#msgid").html("${ruleArray[i].attribute}");

定义的javascript代码i在客户端(即浏览器)上执行。在将呈现的 html 发送到客户端之前,jsp 代码在服务器上执行。

于 2012-11-13T10:38:53.793 回答
0

即使这个线程较旧并且回答正确,为了其他初学者的利益,也为了解释逻辑以实现删除添加的行。

让我用一个最小的代码和用户示例来解释一下名字、电子邮件、用户名和性别字段。
考虑到您从控制器发送用户列表中的 3 个空用户,这将创建 3 个空行。现在您想要添加行并将添加的行动态绑定到 modelAttribute。

(如果是最初的 3 行)如果您检查/查看页面源代码,您将看到

  • <input> tags具有不同id 的Rows( )喜欢list0.firstName list1.firstName
  • <input> tags具有不同名称的行( ),例如list[0].firstName list[1].firstName

每当提交表单时,服务器不会考虑id(添加仅用于帮助客户端验证),但name 属性将被解释为请求参数并用于构造你的 modelAttribute,因此属性名称在插入行时非常重要。

添加行

那么,如何构造/追加新行?
如果我从 UI 提交 6 个用户,控制器应该从 usersList 接收 6 个用户对象。下面给出了实现相同的步骤
1. 右键单击-> ​​查看页面源代码。你会看到这样的行(你可以*[0].*在第一行和*[1].*第二行看到)

<tr>
    <td><input id="list0.firstName" name="list[0].firstName" type="text" value=""/></td>
    <td><input id="list0.email" name="list[0].email" type="text" value=""/></td>
    <td><input id="list0.userName" name="list[0].userName" type="text" value=""/></td>
    <td>
        <span>
            <input id="list0.gender1" name="list[0].gender" type="radio" value="MALE" checked="checked"/>Male
        </span>
        <span>
            <input id="list0.gender2" name="list[0].gender" type="radio" value="FEMALE"/>Female
        </span>
    </td>
</tr>

<tr>
    <td><input id="list1.firstName" name="list[1].firstName" type="text" value=""/></td>
    <td><input id="list1.email" name="list[1].email" type="text" value=""/></td>
    <td><input id="list1.userName" name="list[1].userName" type="text" value=""/></td>
    <td>
        <span>
            <input id="list1.gender1" name="list[1].gender" type="radio" value="MALE" checked="checked"/>Male
        </span>
        <span>
            <input id="list1.gender2" name="list[1].gender" type="radio" value="FEMALE"/>Female
        </span>
    </td>
</tr>
  1. 复制第一行并构造一个 javascript 字符串并将 '0' 替换为变量名索引。如以下示例所示
'<tr>'+
    '<td><input id="list'+ index +'.firstName" name="list['+ index +'].firstName" type="text" value=""/></td>'+
    '<td><input id="list'+ index +'.email" name="list['+ index +'].email" type="text" value=""/></td>'+
    ...
'</tr>';
  1. 将构造的行附加到<tbody>. 在 UI 中添加行也将在提交表单时在控制器中接收新添加的行。

删除行

删除行有点复杂,我将尝试以最简单的方式解释

  • 假设您添加了 row0、row1、row2、row3、row4、row5
  • 删除了第 2 行、第 3 行。不要只是隐藏行,而是通过捕获事件将其从 DOM 中删除。
  • 现在 row0,row1,row4,row5 将被提交,但在控制器中,您的 userList 将有 6 个用户对象,但 user[2].firstName 将为 null,user[3].firstName 将为 null。
  • 因此,在您的控制器中迭代并检查 null 并删除用户。(使用迭代器不要使用 foreach 删除用户对象)

发布代码以使初学者受益。

//  In Controller
@RequestMapping(value = "/app/admin/add-users", method = RequestMethod.GET)
public String addUsers(Model model, HttpServletRequest request)
{
    List<DbUserDetails> usersList = new ArrayList<>();

    ListWrapper userListWrapper = new ListWrapper();
    userListWrapper.setList(usersList);


    DbUserDetails user;
    for(int i=0; i<3;i++)
    {
        user = new DbUserDetails();
        user.setGender("MALE"); //Initialization of Radio button/ Checkboxes/ Dropdowns
        usersList.add(user);
    }


    model.addAttribute("userListWrapper", userListWrapper);
    model.addAttribute("roleList", roleList);

    return "add-users";
}

@RequestMapping(value = "/app/admin/add-users", method = RequestMethod.POST)
public String saveUsers(@ModelAttribute("userListWrapper") ListWrapper userListWrapper, Model model, HttpServletRequest request)
{
    List<DbUserDetails> usersList = userListWrapper.getList();
    Iterator<DbUserDetails> itr = usersList.iterator();

    while(itr.hasNext())
    {
        if(itr.next().getFirstName() == null)
        {
            itr.remove();
        }
    }

    userListWrapper.getList().forEach(user -> {
        System.out.println(user.getFirstName());
    });
    return "add-users";
}

//POJO
@Entity
@Table(name = "userdetails")
@XmlRootElement(name = "user")
public class DbUserDetails implements Serializable
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String  firstName;
    private String  userName;
    private String  email;
    private String  gender;

    //setters and getters
}

//list wrapper
public class ListWrapper
{
    private List<DbUserDetails> list;

    //setters and getters
}

在 JSP 中

<form:form method="post" action="${pageContext.request.contextPath}/app/admin/add-users" modelAttribute="userListWrapper">
    <table class="table table-bordered">
        <thead>
            <tr>
                <th><spring:message code="app.userform.firstname.label"/></th>
                <th><spring:message code="app.userform.email.label"/></th>
                <th><spring:message code="app.userform.username.label"/></th>
                <th><spring:message code="app.userform.gender.label"/></th>
            </tr>
        </thead>
        <tbody id="tbodyContainer">
            <c:forEach items="${userListWrapper.list}" var="user" varStatus="loop">
                <tr>
                    <td><form:input path="list[${loop.index}].firstName" /></td>
                    <td><form:input path="list[${loop.index}].email" /></td>
                    <td><form:input path="list[${loop.index}].userName" /></td>
                    <td>
                        <span>
                            <form:radiobutton path="list[${loop.index}].gender" value="MALE" /><spring:message code="app.userform.gender.male.label"/>
                        </span>
                        <span>
                            <form:radiobutton path="list[${loop.index}].gender" value="FEMALE" /><spring:message code="app.userform.gender.female.label"/>
                        </span>
                    </td>
                </tr>
            </c:forEach>
        </tbody>
    </table>
    <div class="offset-11 col-md-1">
        <button type="submit" class="btn btn-primary">SAVE ALL</button>     
    </div>
</form:form>

Javascript 需要包含在 JSP 中

var currentIndex = 3; //equals to initialRow (Rows shown on page load)
function addRow()
{
    var rowConstructed = constructRow(currentIndex++);
    $("#tbodyContainer").append(rowConstructed);
}

function constructRow(index)
{
    return '<tr>'+
    '<td><input id="list'+ index +'.firstName" name="list['+ index +'].firstName" type="text" value=""/></td>'+
    '<td><input id="list'+ index +'.email" name="list['+ index +'].email" type="text" value=""/></td>'+
    '<td><input id="list'+ index +'.userName" name="list['+ index +'].userName" type="text" value=""/></td>'+
    '<td>'+
        '<span>'+
            '<input id="list'+ index +'.gender1" name="list['+ index +'].gender" type="radio" value="MALE" checked="checked"/>Male'+
        '</span>'+
        '<span>'+
            '<input id="list'+ index +'.gender'+ index +'" name="list['+ index +'].gender" type="radio" value="FEMALE"/>Female'+
        '</span>'+
    '</td>'+
'</tr>';
}
于 2019-09-05T03:22:40.067 回答