Pergunta

Suponha que estou tendo três controles de lista suspensa nomeados dd1, dd2 e dd3. O valor de cada lista suspensa vem do banco de dados. dd3O valor de depende do valor de dd2 e dd2O valor de depende do valor de dd1. Alguém pode me dizer como eu chamo o servlet para esse problema?

Foi útil?

Solução

Existem basicamente três maneiras de conseguir isso:

  1. Envie o formulário para um servlet durante o evento OnChange do 1º menu suspenso (você pode usar o JavaScript para isso), deixe o servlet obter o item selecionado do 1º suspensão como parâmetro de solicitação, obtenha os valores associados do segundo suspensão do banco de dados como um Map<String, String>, deixe -os armazená -los no escopo da solicitação. Finalmente, deixe o JSP/JSTL exibir os valores no segundo suspensão. Você pode usar Jstl (Basta cair jstl-1.2.jar dentro /WEB-INF/lib) c:forEach tag para isso. Você pode prepuplicar a 1ª lista no doGet() Método do Servlet associado à página JSP.

    <select name="dd1" onchange="submit()">
        <c:forEach items="${dd1options}" var="option">
            <option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
        </c:forEach>
    </select>
    <select name="dd2" onchange="submit()">
        <c:if test="${empty dd2options}">
            <option>Please select parent</option>
        </c:if>
        <c:forEach items="${dd2options}" var="option">
            <option value="${option.key}" ${param.dd2 == option.key ? 'selected' : ''}>${option.value}</option>
        </c:forEach>
    </select>
    <select name="dd3">
        <c:if test="${empty dd3options}">
            <option>Please select parent</option>
        </c:if>
        <c:forEach items="${dd3options}" var="option">
            <option value="${option.key}" ${param.dd3 == option.key ? 'selected' : ''}>${option.value}</option>
        </c:forEach>
    </select>
    

    Uma vez que a advertência for, no entanto, isso enviará o inteira formam e causam um "flash de conteúdo" que pode ser ruim para a experiência do usuário. Você também precisará reter os outros campos da mesma forma com base nos parâmetros de solicitação. Você também precisará determinar no servlet se a solicitação é atualizar um menu suspenso (o valor suspenso Child é nulo) ou enviar o formulário real.

  2. Imprima todos os valores possíveis do 2º e 3º suspensão como um objeto JavaScript e use uma função JavaScript para preencher o segundo suspensão com base no item selecionado do 1º suspenso durante o evento OnChange do 1º suspenso. Nenhum formulário envia e nenhum ciclo do servidor é necessário aqui.

    <script>
        var dd2options = ${dd2optionsAsJSObject};
        var dd3options = ${dd3optionsAsJSObject};
        function dd1change(dd1) {
            // Fill dd2 options based on selected dd1 value.
            var selected = dd1.options[dd1.selectedIndex].value;
            ...
        }
        function dd2change(dd2) {
            // Fill dd3 options based on selected dd2 value.
            var selected = dd2.options[dd2.selectedIndex].value;
            ...
        }
    </script>
    
    <select name="dd1" onchange="dd1change(this)">
        <c:forEach items="${dd1options}" var="option">
            <option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
        </c:forEach>
    </select>
    <select name="dd2" onchange="dd2change(this)">
        <option>Please select parent</option>
    </select>
    <select name="dd3">
        <option>Please select parent</option>
    </select>
    

    Uma ressalva é, no entanto, que isso pode se tornar desnecessariamente demorado e caro quando você tem muito de itens. Imagine que você tem 3 etapas de cada 100 itens possíveis, o que significaria 100 * 100 * 100 = 1.000.000 de itens em objetos JS. A página HTML cresceria mais de 1 MB de comprimento.

  3. Utilize o XMLHTTPREQUEST em JavaScript para disparar um pedido assíncrono a um servlet durante o evento de OnChange do 1º suspenso, deixe o servlet obter o item selecionado do 1º Dropdown como parâmetro de solicitação, obtenha os valores associados do 2º suspenso do Dropdown do The 2nd Dropdown do banco de dados, devolva -o como xml ou JSON corda. Finalmente, deixe o JavaScript exibir os valores no segundo suspensão através da árvore html dom (a maneira Ajax, como sugerido antes). A melhor maneira para isso seria usar jQuery.

    <%@ page pageEncoding="UTF-8" %>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <title>SO question 2263996</title>
            <script src="http://code.jquery.com/jquery-latest.min.js"></script>
            <script>
                $(document).ready(function() {
                    $('#dd1').change(function() { fillOptions('dd2', this); });
                    $('#dd2').change(function() { fillOptions('dd3', this); });
                });
                function fillOptions(ddId, callingElement) {
                    var dd = $('#' + ddId);
                    $.getJSON('json/options?dd=' + ddId + '&val=' + $(callingElement).val(), function(opts) {
                        $('>option', dd).remove(); // Clean old options first.
                        if (opts) {
                            $.each(opts, function(key, value) {
                                dd.append($('<option/>').val(key).text(value));
                            });
                        } else {
                            dd.append($('<option/>').text("Please select parent"));
                        }
                    });
                }
            </script>
        </head>
        <body>
            <form>
                <select id="dd1" name="dd1">
                    <c:forEach items="${dd1}" var="option">
                        <option value="${option.key}" ${param.dd1 == option.key ? 'selected' : ''}>${option.value}</option>
                    </c:forEach>
                </select>
                <select id="dd2" name="dd2">
                    <option>Please select parent</option>
                </select>
                <select id="dd3" name="dd3">
                    <option>Please select parent</option>
                </select>
            </form>
        </body>
    </html>
    

    ..onde o Servlet atras do /json/options pode ficar assim:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String dd = request.getParameter("dd"); // ID of child DD to fill options for.
        String val = request.getParameter("val"); // Value of parent DD to find associated child DD options for.
        Map<String, String> options = optionDAO.find(dd, val);
        String json = new Gson().toJson(options);
        response.setContentType("application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write(json);
    }
    

    Aqui, Gson é Google GSON O que facilita a conversão de objetos de Java Fullworthy para JSON e vice -versa. Veja também Como usar servlets e Ajax?

Outras dicas

A julgar pela sua pergunta, você realmente não está usando uma estrutura da web, mas usando servlets para renderizar o HTML.

Serei legal e digo que você está cerca de uma década atrás dos tempos :), as pessoas usam JSPs (e uma estrutura da web como struts) para esse tipo de coisa. No entanto, tendo dito isso, aqui vai:

  1. Crie um campo oculto no seu formulário e defina o valor como '1', '2' ou '3', dependendo da queda, deve ser preenchida;
  2. Em seu servlet, capture este valor (request.getParamter ()) e use -o uma instrução 'case'/if/else para retornar os valores suspensos apropriados.

Vou dizer de novo, basta usar uma estrutura na web ou pelo menos JSP antigo e simples para fazer isso.

Você pode precisar de vários servlets para isso.

Servlet 1: carregue os valores para a primeira lista suspensa do banco de dados. Na página JSP, construa a lista suspensa. No usuário, selecionando um valor enviado ao servlet dois.

Servlet 2: Recupere o valor da primeira lista e execute sua pesquisa de banco de dados pelos valores da segunda lista. Construir a segunda lista. Quando o usuário selecionar o segundo valor, envie -o ao Servlet 3.

Servlet 3: Recupere o valor selecionado na segunda suspensão e execute a pesquisa de banco de dados para obter valores para a última suspensão.

Você pode considerar o AJAX para fazer com que a população das listas pareça perfeita para os usuários. O JQuery tem alguns plugins muito bons para facilitar isso se você estiver disposto a fazer isso.


     <form action="servlet2.do">
          <select name="dd1" onchange="Your JavaScript Here">
               <option>....
          </select>
     </form>

Você pode escrever JavaScript que envia o formulário no evento OnChange. Novamente, se você usar uma biblioteca existente como o jQuery, será 10 vezes mais simples.

Essa foi uma solução simples incrível. Gosto de quão pequeno é o código jQuery e realmente aprecio o link para a API GSON. Todos os exemplos fizeram disso uma implementação fácil.

Teve um problema na construção do URL do servidor JSON com a referência à seleção dos pais (por exemplo, $(this).val() ) [necessário para especificar o :selected atributo]. Modifiquei um pouco o script para incluir as atualizações sugeridas. Obrigado pelo código inicial.

<script>
$(document).ready(function() 
{
    $('#dd1').change(function() { fillOptions('dd1', 'dd2'); });
    $('#dd2').change(function() { fillOptions('dd2', 'dd3'); });
});

function fillOptions(parentId, ddId) 
{
    var dd = $('#' + ddId);
    var jsonURL = 'json/options?dd=' + ddId + '&val=' + $('#' + parentId + ' :selected').val();
    $.getJSON(jsonURL, function(opts) 
    {
        $('>option', dd).remove(); // Clean old options first.
        if (opts) 
        {
            $.each(opts, function(key, value) 
            {
                dd.append($('<option/>').val(key).text(value));
            });
        } 
        else 
        {
            dd.append($('<option/>').text("Please select parent"));
        }
    });
}
</script>
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top