2009-09-29 18 views
73

ho bisogno di nascondere un elemento se certi valori sono presenti nel JSPValuta una stringa list.contains in JSTL

I valori sono memorizzati in una lista così ho provato:

<c:if test="${ mylist.contains(myValue) }">style='display:none;'</c:if> 

Ma, doesn lavorare

Come valutare se un elenco contiene un valore in JSTL, l'elenco ei valori sono stringhe.

+13

Si noti che la sintassi data lavora come intented dal EL 2.2 (che è portato come parte di Servlet 3.0/JSP 2.2 che è stato rilasciato dic 2009). – BalusC

+0

possibile duplicato di [Set ed elenchi JSTL - verifica se l'elemento esiste in un set] (http://stackoverflow.com/questions/1076679/jstl-sets-and-lists-checking-if-item-exists-in-a -set) –

risposta

58

Tristemente, penso che JSTL non supporti altro che un'iterazione di tutti gli elementi per capirlo. In passato, ho usato il metodo forEach nella libreria di tag di base:

<c:set var="contains" value="false" /> 
<c:forEach var="item" items="${myList}"> 
    <c:if test="${item eq myValue}"> 
    <c:set var="contains" value="true" /> 
    </c:if> 
</c:forEach> 

Dopo questo viene eseguito, $ {} contiene sarà uguale a "true" se myList conteneva myValue.

+8

funziona bene se la lista è piccola. Basta rendersi conto che c'è un costo in termini di prestazioni per farlo in questo modo. – Chii

+0

Sì, ci sarebbe se diventasse abbastanza alto. L'ho usato per raccolte di 10-20 cose e non ho riscontrato problemi di prestazioni. La cosa che penso sia peggiore è il numero di linee di JSTL. Tuttavia, penso che questo sia l'unico modo senza impostare il proprio TLD (che non è troppo difficile e potrebbe valerne la pena). –

92

non esiste una funzionalità integrata per verificare che - ciò che si farebbe è scrivere la propria funzione tld che prende una lista e un elemento e chiama il metodo contains() dell'elenco. per esempio.

//in your own WEB-INF/custom-functions.tld file add this 
<?xml version="1.0" encoding="ISO-8859-1" ?> 
<!DOCTYPE taglib 
     PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN" 
     "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd"> 
<taglib 
     xmlns="http://java.sun.com/xml/ns/j2ee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" 
     version="2.0" 
     > 
    <tlib-version>1.0</tlib-version> 
    <function> 
     <name>contains</name> 
     <function-class>com.Yourclass</function-class> 
     <function-signature>boolean contains(java.util.List,java.lang.Object) 
     </function-signature> 
    </function> 
</taglib> 

Quindi creare una classe denominata Yourclass e aggiungere un metodo statico chiamato contiene con la firma precedente. Sono sicuro che l'attuazione di tale metodo è piuttosto auto esplicativo:

package com; // just to illustrate how to represent the package in the tld 
public class Yourclass { 
    public static boolean contains(List list, Object o) { 
     return list.contains(o); 
    } 
} 

Quindi è possibile utilizzare nel vostro jsp:

<%@ taglib uri="/WEB-INF/custom-functions.tld" prefix="fn" %> 
<c:if test="${ fn:contains(mylist, myValue) }">style='display:none;'</c:if> 

Il tag può essere utilizzato da qualsiasi JSP nel sito.

edit: maggiori informazioni riguardo il file tld - more info here

+0

: - S Dove si trova quel codice? Sembra minaccioso – OscarRyz

+1

ive modificato la risposta con qualche informazione in più. – Chii

+4

Ti consiglio di usare 'Collection' invece di' List' nel taglib - funziona allo stesso modo ma supporta più tipi di raccolta come 'Set's – Ralph

2

Il seguente è più di una soluzione che una risposta alla tua domanda, ma può essere quello che stai cercando. Se è possibile inserire i valori in una mappa anziché in un elenco, ciò risolverebbe il problema. Basta mappare i valori ad un valore non nullo e fare questo <c:if test="${mymap.myValue ne null}">style='display:none;'</c:if> o si può anche mappare style='display:none; e semplicemente uscita ${mymap.myValue}

+0

Immagino che la sintassi dovrebbe essere style = 'display: none;' In caso contrario la variabile "myValue" non viene valutata. – Andreas

25

Un altro modo di fare questo sta usando una Map (HashMap) con coppie chiave, valore che rappresenta l'oggetto.

Map<Long, Object> map = new HashMap<Long, Object>(); 
map.put(new Long(1), "one"); 
map.put(new Long(2), "two"); 

In JSTL

<c:if test="${not empty map[1]}"> 

Ciò dovrebbe restituire true se la coppia esiste nella mappa

+2

Anche questo è il mio modo preferito, imposta le hashmap nel viewmodel per tutto ciò di cui ho bisogno in una vista. Si integrano perfettamente con la sintassi EL e sono velocissimi durante la ricerca. –

+0

Ancora una cosa, se la chiave esiste ma il valore è nullo o vuoto, restituirà false. – Zai

+1

Oppure se la Mappa contiene booleani, 'test =" $ {isPresentByValue [myValue]} "'. – Noumenon

-3
<c:if test="${fn:contains(task.subscribers, customer)}"> 

Questo funziona bene per me.

+15

Questo sta facendo il controllo dopo aver convertito entrambi gli elementi in stringa. L'elenco viene convertito in una stringa e non verificato in base agli elementi. Se task.subscribers è una lista ["one", "two", "twentyone"] sarà: true per cliente = "uno" (corrispondente due volte) false per cliente = "tre" (nessuna corrispondenza) true for customer = "venti" (che non è quello che stai cercando) – rmarimon

+1

Essendo a conoscenza dell'avvertimento di rmarimon, questa risposta corrispondeva al mio caso d'uso esatto. – CodeReaper

-1

Se si utilizza Spring Framework, è possibile utilizzare Primavera TagLib e SPEL:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %> 
--- 
<spring:eval var="containsValue" expression="mylist.contains(myValue)" /> 
<c:if test="${containsValue}">style='display:none;'</c:if> 
-1

è necessario utilizzare la funzione fn:contains() o fn:containsIgnoreCase().

<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> 

...

<c:if test="${not fn:containsIgnoreCase(mylist, 'apple')}"> 
     <p>Doesn't contain 'apple'</p> 
    </c:if> 

o

<c:if test="${not fn:contains(mylist, 'Apple')}"> 
      <p>Contains 'Apple'</p> 
     </c:if> 
+0

@BalusC 1) Non esiste alcuna restrizione che risponda a una domanda con risposta è SOF. 2) Si prega di pensare prima di votare, questa risposta è corretta e ho provato questo prima di fornire la risposta. Ho aggiornato la risposta per renderlo ancora più chiaro. – tkr

+0

@BalusC Non sto ripetendo e sto solo fornendo una risposta estesa. Non voglio dare da mangiare al lettore. Penso che questo sia il punto centrale di SO. In SO possiamo ancora rispondere a una domanda se c'è una risposta accettata o meno. Non fa nessuna seduta per te. E anche rispetto il tuo voto negativo perché capisco che ogni persona che ha più di 100 rappresentanti può farlo. Quindi se vuoi chiudere la risposta gentilmente apri un voto. – tkr

Problemi correlati