There is so much wrong with your code that it's hard to tell what you're trying to achieve here. At first glance :
- Please describe your goal and issue in more readable terms. We're not in your head
- Please indent and format your code correctly so we can read it easily.
- Don't use scriptlet tags is JSPs (those <%...%> things are deprecated since at least 2009). You should look into JSTL/el
- You should be generating your initial HTML entirely from JSP, and then offer the user a way to append some fields using javacript, maybe by making some kind of HTML template (invisible) with JSP and then duplicate it as needed
One solution here:
Java file DataFilter.java
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
@WebFilter(urlPatterns = "/data.jsp")
public class DataFilter implements Filter {
@Override
public void init(FilterConfig arg0) throws ServletException { }
@Override
public void destroy() { }
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
String[] status = {"status1", "status2", "status3"};
String[] eta = {"2021-05-01", "2021-05-02", "2021-05-03"};
req.setAttribute("status", status);
req.setAttribute("eta", eta);
chain.doFilter(req, res);
}
}
JSP file data.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Tomcat test</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
$(_e => {
const fields = $('.fields');
let lastEntryNum = fields.find('.fieldWrapper').length;
addRemoveHandler(fields.find('button.remove'));
$('#adder-form').on('submit', e=> {
e.preventDefault();
const jqfrm = $(e.target).closest('form');
const frm = jqfrm[0];
const template = $('#field-row-template .field-row').clone();
template.prop('id', template.prop('id') + (++lastEntryNum));
template.find('*[name="status"]').val(frm.status.value);
template.find('*[name="eta"]').val(frm.eta.value);
const remBut = template.find('button.remove');
remBut.value = lastEntryNum;
fields.append(template);
addRemoveHandler(remBut);
frm.reset();
});
function addRemoveHandler(jQButton) {
jQButton.on('click', e => {
e.preventDefault();
$(e.target).closest('.fieldwrapper').remove();
});
}
});
</script>
</head>
<body>
<main>
<div class="fields">
<h5>Data:</h5>
<c:forEach items="${requestScope.status}" varStatus="fstat" var="curStatus">
<c:set var="curEta" value="${requestScope.eta[fstat.index]}" />
<div class="fieldwrapper" id="field-${fstat.index}">
<input type="text" class="fieldname" name="status" value="<c:out value="${curStatus}" />" />
<input type="date" name="eta" value="${curEta}" />
<button type="button" class="remove" name="remove" value="${fstat.index}">-</button>
</div>
</c:forEach>
</div>
<form name="adder" id="adder-form">
<h5>Add row:</h5>
<input type="text" class="fieldname" name="status" />
<input type="date" name="eta" />
<button type="submit" name="add">Add</button>
</form>
</main>
<template id="field-row-template">
<div class="field-row">
<div class="fieldwrapper" id="field-">
<input type="text" class="fieldname" name="status" required="required" />
<input type="date" name="eta" required="required" />
<button type="button" class="remove" name="remove" value="${fstat.index}">-</button>
</div>
</div>
</template>
</body>
</html>
On a side note, if you have "eta" dates matching each "status" string, your data would be better organized in a LinkedHashMap
, that would match one ETA date for one status string, preserving insertion order.
It would make your jstl easyier as you could get the ETA for each status in a loop like:
<c:forEach items="${requestScope.dataMap}" varStatus="fstat" var="entry">
<div class="fieldwrapper" id="field-${fstat.index}">
<input type="text" class="fieldname" name="status" value="<c:out value="${entry.key}" />" />
<input type="date" name="eta" value="${entry.value}" />
<button type="button" class="remove" name="remove" value="${fstat.index}">-</button>
</div>
</c:forEach>