无法在Spring Mvc中显示两个下拉框,并且关于ModelAndView的问题。

huangapple go评论66阅读模式
英文:

Can't display two dropdown box in Spring Mvc and question about ModelAndView

问题

我正在处理一个 JSP 页面,应该有两个下拉框,其中第二个下拉框依赖于第一个下拉框。

运行应用程序时,第一个下拉框会填充一些元素。
当列表框的 onChange 方法被触发时,会调用客户端端的 jQuery Ajax 方法,向控制器提供一个 ID 值供控制器使用。

我的问题如下:

如何填充并显示第二个下拉框?我所有的尝试似乎都失败了。我检索了所有活动和文档列表的值,但只能显示第一个下拉框。第二个下拉框从未显示过。
我该如何解决这个问题?
关于模型:

模型本身只包括一些属性以及它们自己的 getter 和 setter 方法

	private String action;
	private String activityId;
    private Integer documentId;

控制器有一个简单的调度器,如下所示:

@RequestMapping(value = "/act", method = { RequestMethod.POST, RequestMethod.GET })
public String dispatcher(@Validated @ModelAttribute("activityForm") ActivityModel activityModel,
    BindingResult errors, HttpServletRequest request, HttpServletResponse response)
    throws Exception {

    String methodName = activityModel == null ? null : activityModel.getAction();
    Map<String, String> map = null;
    if ("documentFilter".equals(methodName)) {
        return documentFilter(activityModel, map, errors, request, response);
    }
  
}

由于上面的代码,会调用此方法,并显示第一个下拉框并填充一些元素

@RequestMapping(value = "/act/index", method = {RequestMethod.GET })
public ModelAndView act(HttpServletRequest request) {
    List<Activity> activities;
            
    try {
        activities = activitiesService.getActivities();
    } catch (DataNotFoundException e) {
        log.error("Failed to get the activities (Activity). Returning an empty list.", e);
        activities = new ArrayList<Activity>(0);
    }

    request.setAttribute("act", activities);
    request.setAttribute("activityForm", new ActivityModel());
    return new ModelAndView("act");
}

当填充了第一个下拉框后,客户端的 JavaScript 会管理 onChange 事件,当触发时,会发送一个 post 请求,如下所示:

$.ajax({
    url : baseUrl + "act/documentFilter",
    type : 'POST',
    data : JSON.stringify({
        'activityId' : activity.value
    }),
    dataType : 'json',
    contentType : 'application/json',

然后请求命中以下映射的方法:

@RequestMapping(value = "/act/documentFilter", method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String documentFilter(@ModelAttribute("activityForm") ActivityModel form, 
        @RequestBody Map<String,String> map, BindingResult errors,
        HttpServletRequest request, HttpServletResponse response) {
    
    form.setActivityId(map.get("activityID"));
    ActivityModel myForm = form;
    Integer sessionIdQuest = (Integer) request.getSession()
        .getAttribute("sessionIdQuest");
    
    Activity activity = null;
    Document document = null;
    
    try {
        if (myForm.getActivityId() == null) {
            document = activitiesService.getDocument(sessionId);
            myForm.setActivityId(document.getActivity().getId());
        } else {
            Integer activityCode = Integer.valueOf(myForm.getActivityId().substring(5));
            String year = myForm.getActivityId().substring(0, 4);
            activity = activitiesService.getActivity(activityCode, year);
            document = activity.getDocument().get(0);
        }
    } catch (DataNotFoundException e) {
        log.warn("Warning: ", e);
        throw new ServiceException();
    }
    
    List<Activity> activities = null;
    List<Document> documents = null;
    try {
        activities = activitiesService.getActivities();
        Integer activityCode = Integer.valueOf(myForm.getActivityId().substring(5));
        String year = myForm.getActivityId().substring(0, 4);
        documents = activitiesService.getDocument(activityCode, year);
        // 在这里我有活动和文档
        request.setAttribute("activities", activities);
        request.setAttribute("documents", documents);
    } catch (DataNotFoundException e) {
        log.error("Fatal Error: " , e);
        throw new IllegalStateException();
    }
    
    /* 我应该返回什么?
        页面总是返回第一个下拉框
    */
    return "act";
}

这是 JSP 页面:

<form:form action="${pathPrefix}act" enctype="multipart/form-data"
name="activityForm" method="post" modelAttribute="activityForm">
<form:hidden path="action" />
<div id="contentBox">
<div style="font-size: medium;">
<p>Welcome</p>
<p>${results}</p>
</div>
</div>
<label for="survey">Select an activity:</label>
<form:select path="activityId" itemValue="${actSel}" onchange="javascript:submitForm('documentFilter');" htmlEscape="false">
<c:if test="${documents==null}">
<option value="">
<!-- <spring:message code="activity.label.selectActivity" /> -->
</option>
</c:if>
<form:options items="${activities}" itemValue="id" itemLabel="description" />
</form:select>
<!-- Document block -->
<c:if test="${documents!=null}">
<form:select path="documentId" onchange="javascript:submitForm('FilterData');"
htmlEscape="false">
<form:options items="${documents}" itemValue="id" itemLabel="label" />
</form:select>
</c:if>
<br>
<br>

现在我检索到了所有活动和文档列表的值,但只能显示第一个下拉框。第二个下拉框从未显示过。
我该如何解决这个问题?

英文:

i'm working on a JSP that should have two dropdown box, where the second dropdown box is depending from the first one.

Running the app, the first drowpdown box is populated with some elements.
A client side jquery ajax method is called when the listbox onChange method is fired, providing to the controller an id value to use in the controller

My question is as follow:

How to populate and display the second dropdown box? All my attemps seems to fails. I retrieve all the values for the Activity and Document List, but i can display the first dropdown box only. The second dropdown box is never showed.
How can i solve this?
About the model:

The model itself just includes some properties along with their own getters and setters

	private String action;
private String activityId;
private Integer documentId;

The controller have a simple dispatcher as follow:

@RequestMapping(value = &quot;/act&quot;, method = { RequestMethod.POST,
RequestMethod.GET })
public String dispatcher(
@Validated @ModelAttribute(&quot;activityForm&quot;) ActivityModel activityModel,
BindingResult errors, HttpServletRequest request, HttpServletResponse response)
throws Exception {
String methodName = activityModel == null ? null : activityModel.getAction();
Map &lt;String, String&gt; map = null;
if (&quot;documentFilter&quot;.equals(methodName)) {
return documentFilter(activityModel, map, errors, request, response);
}
}

Due to the above code, this method is called and the first dropdown box is shown and filled with some elements

@RequestMapping(value = &quot;/act/index&quot;, method = {RequestMethod.GET })
public ModelAndView act(HttpServletRequest request) {
List&lt;Activity&gt; activities;
try {
activities = activitiesService.getActivities();
} catch (DataNotFoundException e) {
log.error(&quot;Failed to get the activities (Activity). Returning an empty list.&quot;, e);
activities = new ArrayList&lt;Activity&gt;(0);
}
request.setAttribute(&quot;act&quot;, activities);
request.setAttribute(&quot;activityForm&quot;, new ActivityModel());
return new ModelAndView(&quot;act&quot;);
}

When the first dropdown box is populated, the cliend side Javascript manage the onChange event, that, when fired, sends a post request as follow:

$.ajax({
url : baseUrl + &quot;act/documentFilter&quot;,
type : &#39;POST&#39;,
data : JSON.stringify({
&#39;activityId&#39; : activity.value
}),
dataType : &#39;json&#39;,
contentType : &#39;application/json&#39;,

and the request hits the following mapped method:

	@RequestMapping(value = &quot;/act/documentFilter&quot;, method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@ResponseBody
public String documentFilter(@ModelAttribute(&quot;activityForm&quot;)ActivityModel form, 
@RequestBody Map&lt;String,String&gt; map, BindingResult errors,
HttpServletRequest request, HttpServletResponse response) {
form.setActivityId(map.get(&quot;activityID&quot;));
ActivityModel myForm = form;
Integer sessionIdQuest = (Integer) request.getSession()
.getAttribute(&quot;sessionIdQuest&quot;);
Activity activity = null;
Document document = null;
try {
if (myForm.getActivityId() == null) {
document = activitiesService.getDocument(sessionId);
myForm.setActivityId(document.getActivity().getId());
} else {
Integer activityCode = Integer.valueOf(myForm.getActivityId().substring(5));
String year = myForm.getActivityId().substring(0, 4);
activity = activitiesService.getActivity(activityCode, year);
document = activity.getDocument().get(0);
}
} catch (DataNotFoundException e) {
log.warn(&quot;Warning: &quot;, e);
throw new ServiceException();
}
List&lt;Activity&gt; activities = null;
List&lt;Document&gt; documents = null;
try {
activities = activitiesService.getActivities();
Integer activityCode = Integer.valueOf(myForm.getActivityId().substring(5));
String year = myForm.getActivityId().substring(0, 4);
documents = activitiesService.getDocument(activityCode, year);
// here i have both activities and documents
request.setAttribute(&quot;activities&quot;, activities);
request.setAttribute(&quot;documents&quot;, documents);
} catch (DataNotFoundException e) {
log.error(&quot;Fatal Error: &quot; , e);
throw new IllegalStateException();
}
/* what should i return exactly?
the page return always the first drowpdown box
*/
return &quot;act&quot;;
}

this is the jsp page:

	&lt;form:form action=&quot;${pathPrefix}act&quot; enctype=&quot;multipart/form-data&quot;
name=&quot;activityForm&quot; method=&quot;post&quot; modelAttribute=&quot;activityForm&quot;&gt;
&lt;form:hidden path=&quot;action&quot; /&gt;
&lt;div id=&quot;contentBox&quot;&gt;
&lt;div style=&quot;font-size: medium;&quot;&gt;
&lt;p&gt;Welcome&lt;/p&gt;
&lt;p&gt;${results}&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;label for=&quot;survey&quot;&gt;Select an activity:&lt;/label&gt;
&lt;form:select path=&quot;activityId&quot; itemValue=&quot;${actSel}&quot; onchange=&quot;javascript:submitForm(&#39;documentFilter&#39;);&quot; htmlEscape=&quot;false&quot;&gt;
&lt;c:if test=&quot;${documents==null}&quot;&gt;
&lt;option value=&quot;&quot;&gt;
&lt;%--               &lt;spring:message code=&quot;activity.label.selectActivity&quot; /&gt; --%&gt;
&lt;/option&gt;
&lt;/c:if&gt;
&lt;form:options items=&quot;${activities}&quot; itemValue=&quot;id&quot; itemLabel=&quot;description&quot; /&gt;
&lt;/form:select&gt;
&lt;%-- Document block --%&gt;
&lt;c:if test=&quot;${documents!=null}&quot;&gt;         
&lt;form:select path=&quot;documentId&quot; onchange=&quot;javascript:submitForm(&#39;FilterData&#39;);&quot;
htmlEscape=&quot;false&quot;&gt;
&lt;form:options items=&quot;${documents}&quot; itemValue=&quot;id&quot; itemLabel=&quot;label&quot; /&gt;
&lt;/form:select&gt;
&lt;/c:if&gt;     
&lt;br&gt;
&lt;br&gt;
Now i retrieve all the values for the Activity and Document List, but i can display the first dropdown box only. The second dropdown box is never showed.
How can i solve this?

答案1

得分: 1

  • 当第一个下拉列表更改时调用 Ajax 将给出文档列表作为结果,但问题在于 Ajax 调用不会重新加载页面,因此返回的列表不会在页面上更新。
  • 在你的情况下,一个简单的解决方案是将 JSP 页面的完整代码放在单个 div 标签下,如下所示:
    <div id="mainDiv"> 在此处插入页面 </div>

然后在你的 Ajax 调用中使用 'success' 块,如下所示:

success: function(result) {
$("#mainDiv").html(result);
}
英文:
  • Ajax called on change of first drop down list will give documents list as a result but problem here is Ajax call will not reload your page and hence returned list is not updated on page.
  • One simple solution in your case will be put your complete code of JSP page under single div tag as
    div id="mainDiv"> page here </div

After that in you Ajax call use 'success' block as
success: function(result) { $("#mainDiv").html(result); }

huangapple
  • 本文由 发表于 2020年10月6日 00:51:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/64212951.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定