Установите цвет фона для каждого отдельного флажка p: selectManyCheckbox

Я использую этот http://www.primefaces.org/showcase-labs/ui/selectManyCheckbox.jsf компонент primefaces для получения динамических значений booleanCheckboxes

<p:selectManyCheckbox value="#{bean.selectedMovies}"  
            layout="pageDirection">  
            <f:selectItems value="#{bean.movies}" />  
        </p:selectManyCheckbox> 

Мне нужно применить разные цвета ко всем логическим флажкам, как показано на рисунке ниже.

если id=1, то цвет будет красным, если id=2, то цвет будет оранжевым и так далее.

Как мы знаем, это динамические значения в фильмах, так как же я могу установить фоновый цвет для этих динамических флажков из вспомогательного компонента?

Я попытался применить стиль к selectManyCheckbox, но он применяется в качестве цвета фона ко всей панели selectManyCheckbox.

Итак, как мне установить цвет из фонового компонента для динамических значений selectManyCheckbox?

введите здесь описание изображения


person Java    schedule 14.09.2012    source источник
comment
Дайте мне знать, если кому-то нужны дополнительные разъяснения...   -  person Java    schedule 15.09.2012


Ответы (4)


Может быть выполнимо с чистым CSS3

В зависимости от ваших реальных требований. Предполагая, что та же структура html для последних флажков является структурой по умолчанию, как в примере, на который вы ссылаетесь, тогда следующий способ должен быть чистым css3 для его выполнения.

Обратите внимание, что этот метод не привязывает цвет конкретно к конкретному фильму/идентификатору, он всегда устанавливает первый фильм красным, второй — оранжевым и т. д. Он также имеет практическое ограничение. Если вы планируете перечислить 100 фильмов, каждый из которых имеет уникальный индивидуальный цвет, то этот метод не ты.

Но если вы указываете небольшой набор (максимум 10?) или не возражаете, если цвета повторяются после определенной небольшой выборки, это вполне может быть вашим лучшим выбором.

Вот скрипт, показывающий оба следующих

Маленький набор

.ui-selectmanycheckbox tr:nth-of-type(1) .ui-state-default {
    background-color: red;
}

.ui-selectmanycheckbox tr:nth-of-type(2) .ui-state-default {
    background-color: orange;
}

.ui-selectmanycheckbox tr:nth-of-type(3) .ui-state-default {
    background-color: red;
}

.ui-selectmanycheckbox tr:nth-of-type(4) .ui-state-default {
    background-color: orange;
}

Повторяющиеся 4 цвета

.ui-selectmanycheckbox tr:nth-of-type(4n+1) .ui-state-default {
    background-color: red;
}

.ui-selectmanycheckbox tr:nth-of-type(4n+2) .ui-state-default {
    background-color: orange;
}

.ui-selectmanycheckbox tr:nth-of-type(4n+3) .ui-state-default {
    background-color: green;
}

.ui-selectmanycheckbox tr:nth-of-type(4n+4) .ui-state-default {
    background-color: blue;
}
person ScottS    schedule 23.09.2012

Это невозможно со стандартным <p:selectManyCheckbox>, по крайней мере, с такой динамикой. Если бы это были статические значения, вы могли бы просто использовать для этого селектор CSS3 nth-child(). С динамическими значениями в <p:selectManyCheckbox> вам в основном нужно переопределить его средство визуализации (что не является тривиальной задачей) или опубликовать запрос функции (что может занять больше времени, чем вы хотите).

Вместо этого лучше всего использовать <ui:repeat> или <h:dataTable>, где вы визуализируете один <p:selectBooleanCheckbox> для каждой строки. Это позволяет указать styleClass для каждого флажка. Это также требует технических изменений в способе заполнения свойства selectedMovies.

Вот конкретный стартовый пример с <h:dataTable> (примечание: сам <p:selectManyCheckbox> также генерирует <table>, так что с технической точки зрения разница не так уж велика, вы всегда можете выбрать <ui:repeat>, если таблица беспокоит вас семантически):

<h:dataTable value="#{bean.movies}" var="movie" styleClass="ui-selectmanycheckbox ui-widget">
    <h:column>
        <p:selectBooleanCheckbox id="checkbox" converter="javax.faces.Boolean"
            value="#{bean.checkedMovieIds[movie.id]}" styleClass="#{movie.type}" />
    </h:column>
    <h:column>
        <p:outputLabel for="checkbox" value="#{movie.title}" />
    </h:column>
</h:dataTable>

<p:commandButton value="Submit" actionListener="#{bean.collectMovies}" action="#{bean.submit}" />

Примечания:

  • <h:dataTable styleClass> использует тот же CSS, что и <p:selectManyCheckbox>, поэтому внешний вид таблицы флажков точно такой же.
  • converter="javax.faces.Boolean" является (на самом деле, к моему удивлению) обязательным, поскольку в противном случае проверенные значения true и false будут установлены как String вместо Boolean; этой проблемы нет в <h:selectBooleanCheckbox>, возможно, ошибка PF?
  • styleClass="#{movie.type}" в этом конкретном случае имеет больше смысла, чем styleClass="#{movie.id}", потому что кажется нелепой задачей указывать отдельный класс стиля для каждого отдельного значения «id», которое обычно представляет собой уникальный автоматически назначаемый идентификатор БД; вы всегда можете изменить его в своем реальном коде, если хотите.
  • actionListener выполняет работу по сбору selectedMovies до фактического метода action. Конечно, вы также можете выполнить эту работу в реальном методе action, но тогда он уже не будет так четко разделен.

Компонент поддержки выглядит следующим образом (checkedMovieIds предполагает, что Movie имеет свойство Long id):

private List<Movie> movies;
private Map<Long, Boolean> checkedMovieIds;
private List<Movie> selectedMovies;

@PostConstruct
public void init() {
    movies = populateItSomehow();
    checkedMovieIds = new HashMap<Long, Boolean>();
}

public void collectMovies(ActionEvent event) {
    selectedMovies = new ArrayList<Movie>();
    for (Movie movie : movies) {
        if (checkedMovieIds.get(movie.getId())) {
            selectedMovies.add(movie);
        }
    }
}

public void submit() {
    System.out.println(selectedMovies);
    // ...
}

// +getters (note: no setters necessary for all those three properties)

Предполагая, что #{movie.type} может иметь значения action, comedy, fantasy и horror (кстати, это идеальный кандидат типа enum), тогда вы можете стилизовать отдельные флажки следующим образом:

.action .ui-chkbox-box {
    background-color: red;
}

.comedy .ui-chkbox-box {
    background-color: orange;
}

.fantasy .ui-chkbox-box {
    background-color: green;
}

.horror .ui-chkbox-box {
    background-color: blue;
}
person BalusC    schedule 17.09.2012

Я знаю, что это решение немного хакерское, но оно работает :)

Xhtml-файл:

<p:selectManyCheckbox binding="#{requestScope.movieSelect}" layout="pageDirection">
    <f:selectItems value="#{bean.movies}" />
</p:selectManyCheckbox>

<script>
(function() {
    var selectName = '#{requestScope.movieSelect.clientId}';
    var kids = jQuery("input[id*="+selectName+"]");
    var index = 0;

    <ui:repeat value="#{bean.movies}" var="movie">
        jQuery(kids[index++]).parent().next().css('background-color', '#{movie.description}');
    </ui:repeat>
}());
</script>

Поддерживающая фасоль:

public class Bean {

    private List<SelectItem> movies = Arrays.asList(
            new SelectItem("Scarface", "Scarface", "green"),
            new SelectItem("Goodfellas", "Goodfellas", "red"),
            new SelectItem("Godfather", "Godfather", "blue"),
            new SelectItem("Carlito's Way", "Carlito's Way", "yellow"));

    public List<SelectItem> getMovies() {
        return movies;
    }
}

CSS-файл:

.ui-chkbox-box {
    background-image : none;
}

p.s. : файл css может быть не нужен.

person Kaalras    schedule 17.09.2012

не уверен, каковы цели вашего браузера, но почему бы не использовать селекторы атрибутов?

ui-selectmanycheckbox input[value=1] {
    color: red;
}

Это просто общая идея... Я не знаком с этими элементами управления, но документация делает вид, что вы должны быть в состоянии сделать эту работу...

person BLSully    schedule 17.09.2012