Значение из массива как флаг для рендеринга VF элемента
Ну вот еще логическая задачка:
В контроллере есть массив числовых значений, который может содержать например 5, 10, 34.
На фронте есть 100 компонентов, которые должны рендерится или не рендерится в зависимости от наличия или отсутсвия в данном массиве какого значения. Например "VF компонент 1" должен рендерится только если в массиве есть значение "1". Но как перебрать массив в разметке?
логическая задачка. если не удастся это решить таким образом, то придется делать 100 булен флагов в контроллере и передавать их в соответствующий компонент.
Ну вот еще логическая задачка:
В контроллере есть массив числовых значений, который может содержать например 5, 10, 34.
На фронте есть 100 компонентов, которые должны рендерится или не рендерится в зависимости от наличия или отсутсвия в данном массиве какого значения. Например "VF компонент 1" должен рендерится только если в массиве есть значение "1". Но как перебрать массив в разметке?
логическая задачка. если не удастся это решить таким образом, то придется делать 100 булен флагов в контроллере и передавать их в соответствующий компонент.
Первое что пришло в голову сделать репитор выгрузить на пейджу числа сразу скрыть репитор. javascript пройтись по чайлдом собрать значения.Вот тебе массив.
Первое что пришло в голову сделать репитор выгрузить на пейджу числа сразу скрыть репитор. javascript пройтись по чайлдом собрать значения.Вот тебе массив.
еще Написать внутрений веб сервис который возращает массив в javascript.Единственный нюанс ест сallout вроде как при обращении.
[quote="Sergey Prichepo"]Первое что пришло в голову сделать репитор выгрузить на пейджу числа сразу скрыть репитор. javascript пройтись по чайлдом собрать значения.Вот тебе массив.[/quote]
этот вариант - перевесить все работу на JS рассматривал. Можно передать значения репетиром или через JSON стринг. Но хочу все сделать на сервере.
И главное - это будет PDFнутая страница, там не то что JS, даже стили толком не работают.
ну не знаю тогда если перебирать массив в разметки, последнее что пришло на ум rendered="{!if(array[x] == '3',true,false)}" незнаю точно сработает ли попробуй.
[quote="Den Brown"]Ну вот еще логическая задачка:
массив в разметке?
[/quote]
ну не знаю тогда если перебирать массив в разметки, последнее что пришло на ум rendered="{!if(array[x] == '3',true,false)}"
незнаю точно сработает ли попробуй.
Сергей, ты имел введу, что на место "х" нужно ставить индекс?
в том то и дело, что мы не знаем какой набор цифр в массиве будет в этот раз, на каком идексе будет "3", да и буде ли вообще.
так что пока делаю переменные флаги в контроллере и буду их индивидуально выбивать в зависимости от содержания массива.
и еще: булеаны-флаги можно собрать в массив, с которым работать много проще, но это имеет смысл если в рендер атрибуте мы может обратиться к элементу массива.
[quote="Sergey Prichepo"]
array[x] == '3'
[/quote]
Сергей, ты имел введу, что на место "х" нужно ставить индекс?
в том то и дело, что мы не знаем какой набор цифр в массиве будет в этот раз, на каком идексе будет "3", да и буде ли вообще.
так что пока делаю переменные флаги в контроллере и буду их индивидуально выбивать в зависимости от содержания массива.
и еще: булеаны-флаги можно собрать в массив, с которым работать много проще, но это имеет смысл если в рендер атрибуте мы может обратиться к элементу массива.
а это я еще не проверил
быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:
быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:
[code]
<apex:repeat items="{!array}" var="elem">
<apex:outputPanel rendered="{! 1 == elem}">
<!-- component 1 -->
<apex:outputPanel/>
...
<apex:outputPanel rendered="{! 8 == elem}">
<!-- component 8 -->
<apex:outputPanel/>
...
<apex:repeat/>
[/code]
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.
[quote="Den Brown"][quote="Sergey Prichepo"]
array[x] == '3'
[/quote]
Сергей, ты имел введу, что на место "х" нужно ставить индекс?
в том то и дело, что мы не знаем какой набор цифр в массиве будет в этот раз, на каком идексе будет "3", да и буде ли вообще.
так что пока делаю переменные флаги в контроллере и буду их индивидуально выбивать в зависимости от содержания массива.
и еще: булеаны-флаги можно собрать в массив, с которым работать много проще, но это имеет смысл если в рендер атрибуте мы может обратиться к элементу массива.
а это я еще не проверил[/quote]
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.
быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:
[quote="dlisovsky"]быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:
[code]
<apex:repeat items="{!array}" var="elem">
<apex:outputPanel rendered="{! 1 == elem}">
<!-- component 1 -->
<apex:outputPanel/>
...
<apex:outputPanel rendered="{! 8 == elem}">
<!-- component 8 -->
<apex:outputPanel/>
...
<apex:repeat/>
[/code][/quote]
а вот это интересная мысль. Для моего случая разметки этот вариант не подходит (по крайней мере я пока не додумался как это использовать).
Но тем не менее [b]это ответ на поставленный вопрос[/b].
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.
[quote="Sergey Prichepo"]
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.[/quote]
спасибо за идею. можете показать пример кода?
а пока я все бесстыже захардкодил...
быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:
[quote="Den Brown"][quote="dlisovsky"]быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:
[code]
<apex:repeat items="{!array}" var="elem">
<apex:outputPanel rendered="{! 1 == elem}">
<!-- component 1 -->
<apex:outputPanel/>
...
<apex:outputPanel rendered="{! 8 == elem}">
<!-- component 8 -->
<apex:outputPanel/>
...
<apex:repeat/>
[/code][/quote]
а вот это интересная мысль. Для моего случая разметки этот вариант не подходит (по крайней мере я пока не додумался как это использовать).
Но тем не менее [b]это ответ на поставленный вопрос[/b].[/quote]
Еще можно использовать репитор в нутри репитора если там еще болле сложная логика.
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.
спасибо за идею. можете показать пример кода?
а пока я все бесстыже захардкодил...
global class myClass {
global class searchedBean { global String var1 { get; set; } global String somevar { get; set; } global Boolean checkBox { get; set; } global Boolean Before { get; set; } } List<searchedBean> beanList = new List<searchedBean>(); } Классическое ООП,последний лист можно испльзвать как проперти.
[quote="Den Brown"][quote="Sergey Prichepo"]
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.[/quote]
спасибо за идею. можете показать пример кода?
а пока я все бесстыже захардкодил...[/quote]
global class myClass {
global class searchedBean {
global String var1 { get; set; }
global String somevar { get; set; }
global Boolean checkBox { get; set; }
global Boolean Before { get; set; }
}
List<searchedBean> beanList = new List<searchedBean>();
}
Классическое ООП,последний лист можно испльзвать как проперти.
Den Brown, я бы советовал тебе поменьше логики ставлять в Visualforce страницу. Salesforce построен на MVC принципе и бизнес логика должна быть в контроллере. Visualforce поменьше используй для всякого рода сложных проверок.
Теперь позвольте вставить и мои пять копеек на счет твоей задачи про 100 значений (1, 2, 3, ...) и рендеринге элементов.
Я тут придумал 2 способа (первый мне нравится больше):
1. преобразовать твой список значений в Map<Integer, Boolean> типо такого {1=true, 2=false, ...} В контроллере это сделать не сложно А на странице проверять так: rendered="{!map[1]}", rendered="{!map[2]}" ! важно чтобы в мап были все ключи, которые ты проверяешь на Visualforce странице или получишь следующее ошибку "Map key 3 not found in map"
2. способ как альтернативный: преобразовать твой список значений в специальную строку вида "::1::4:: ... ::98::" а на странице проверять: rendered="{!CONTAINS(specialString, '::1::')}", rendered="{!CONTAINS(specialString, '::2::')}"
Den Brown, я бы советовал тебе поменьше логики ставлять в Visualforce страницу.
Salesforce построен на [b]MVC [/b]принципе и бизнес логика должна быть в контроллере. Visualforce поменьше используй для всякого рода сложных проверок.
Теперь позвольте вставить и мои пять копеек на счет твоей задачи про 100 значений (1, 2, 3, ...) и рендеринге элементов.
Я тут придумал 2 способа (первый мне нравится больше):
[b]1.[/b] преобразовать твой список значений в Map<Integer, Boolean>
типо такого [b]{1=true, 2=false, ...}[/b] В контроллере это сделать не сложно
А на странице проверять так: [b]rendered="{!map[1]}", rendered="{!map[2]}"[/b]
! важно чтобы в мап были все ключи, которые ты проверяешь на Visualforce странице или получишь следующее ошибку "Map key 3 not found in map"
[b]2.[/b] способ как альтернативный:
преобразовать твой список значений в специальную строку вида [b]"::1::4:: ... ::98::"[/b]
а на странице проверять: [b]rendered="{!CONTAINS(specialString, '::1::')}", rendered="{!CONTAINS(specialString, '::2::')}"[/b]
Den Brown, я бы советовал тебе поменьше логики ставлять в Visualforce страницу. Salesforce построен на MVC принципе и бизнес логика должна быть в контроллере. Visualforce поменьше используй для всякого рода сложных проверок.
Теперь позвольте вставить и мои пять копеек на счет твоей задачи про 100 значений (1, 2, 3, ...) и рендеринге элементов.
Я тут придумал 2 способа (первый мне нравится больше):
1. преобразовать твой список значений в Map<Integer, Boolean> типо такого {1=true, 2=false, ...} В контроллере это сделать не сложно А на странице проверять так: rendered="{!map[1]}", rendered="{!map[2]}" ! важно чтобы в мап были все ключи, которые ты проверяешь на Visualforce странице или получишь следующее ошибку "Map key 3 not found in map"
2. способ как альтернативный: преобразовать твой список значений в специальную строку вида "::1::4:: ... ::98::" а на странице проверять: rendered="{!CONTAINS(specialString, '::1::')}", rendered="{!CONTAINS(specialString, '::2::')}"
[quote="Dmitry Shnyrev"]Den Brown, я бы советовал тебе поменьше логики ставлять в Visualforce страницу.
Salesforce построен на [b]MVC [/b]принципе и бизнес логика должна быть в контроллере. Visualforce поменьше используй для всякого рода сложных проверок.
Теперь позвольте вставить и мои пять копеек на счет твоей задачи про 100 значений (1, 2, 3, ...) и рендеринге элементов.
Я тут придумал 2 способа (первый мне нравится больше):
[b]1.[/b] преобразовать твой список значений в Map<Integer, Boolean>
типо такого [b]{1=true, 2=false, ...}[/b] В контроллере это сделать не сложно
А на странице проверять так: [b]rendered="{!map[1]}", rendered="{!map[2]}"[/b]
! важно чтобы в мап были все ключи, которые ты проверяешь на Visualforce странице или получишь следующее ошибку "Map key 3 not found in map"
[b]2.[/b] способ как альтернативный:
преобразовать твой список значений в специальную строку вида [b]"::1::4:: ... ::98::"[/b]
а на странице проверять: [b]rendered="{!CONTAINS(specialString, '::1::')}", rendered="{!CONTAINS(specialString, '::2::')}"[/b][/quote]
Второй способ Интересный.
Den Brown, я бы советовал тебе поменьше логики ставлять в Visualforce страницу. Salesforce построен на MVC принципе и бизнес логика должна быть в контроллере. Visualforce поменьше используй для всякого рода сложных проверок.
Теперь позвольте вставить и мои пять копеек на счет твоей задачи про 100 значений (1, 2, 3, ...) и рендеринге элементов.
Я тут придумал 2 способа (первый мне нравится больше):
1. преобразовать твой список значений в Map<Integer, Boolean> типо такого {1=true, 2=false, ...} В контроллере это сделать не сложно А на странице проверять так: rendered="{!map[1]}", rendered="{!map[2]}" ! важно чтобы в мап были все ключи, которые ты проверяешь на Visualforce странице или получишь следующее ошибку "Map key 3 not found in map"
2. способ как альтернативный: преобразовать твой список значений в специальную строку вида "::1::4:: ... ::98::" а на странице проверять: rendered="{!CONTAINS(specialString, '::1::')}", rendered="{!CONTAINS(specialString, '::2::')}"
Какой бы вариант не использовался, суть то одна - нам нужен какой-то контейнер с флагами (массив, мапа, строка) и ключ (идентификатор, индекс) нужного элемента который будет рендериться если этот ключ есть в контейнере, вот только в моём варианте я использую уже существующий массив чисел, который описал автор темы.
[quote="Dmitry Shnyrev"]Den Brown, я бы советовал тебе поменьше логики ставлять в Visualforce страницу.
Salesforce построен на [b]MVC [/b]принципе и бизнес логика должна быть в контроллере. Visualforce поменьше используй для всякого рода сложных проверок.
Теперь позвольте вставить и мои пять копеек на счет твоей задачи про 100 значений (1, 2, 3, ...) и рендеринге элементов.
Я тут придумал 2 способа (первый мне нравится больше):
[b]1.[/b] преобразовать твой список значений в Map<Integer, Boolean>
типо такого [b]{1=true, 2=false, ...}[/b] В контроллере это сделать не сложно
А на странице проверять так: [b]rendered="{!map[1]}", rendered="{!map[2]}"[/b]
! важно чтобы в мап были все ключи, которые ты проверяешь на Visualforce странице или получишь следующее ошибку "Map key 3 not found in map"
[b]2.[/b] способ как альтернативный:
преобразовать твой список значений в специальную строку вида [b]"::1::4:: ... ::98::"[/b]
а на странице проверять: [b]rendered="{!CONTAINS(specialString, '::1::')}", rendered="{!CONTAINS(specialString, '::2::')}"[/b][/quote]
Какой бы вариант не использовался, суть то одна - нам нужен какой-то контейнер с флагами (массив, мапа, строка) и ключ (идентификатор, индекс) нужного элемента который будет рендериться если этот ключ есть в контейнере, вот только в моём варианте я использую уже существующий массив чисел, который описал автор темы.
PS вариант с мапой хорош)
На выходных буду сидеть - разбирвать ваши варианты.
На выходных буду сидеть - разбирвать ваши варианты.
Выглядят впечатляюще.
Спасибо
Продолжу эту тему,
снова рабочая ситуация, и наверняка вы с ней сталкивались.
на ВФ странице несколько статичных элементов <area> имеют атрибут href.
в этот атрибут нужно динамически прибавить ID.
хардкодить специальные для этого переменные в контроллере не хочу.
планирую кверить (в лист или мап) из объекта следующее: id and name.
и на ВФ к каждому атрибут href добавить формулу, которая перебирает массив и если item.name = nameКотороеТребуетсяДляЭтогоЭлемента, то вписывать item.id.
но не уверен, что можно в ВФ формуле можно перебирать массив...
буду разбираться c этим через несколько часов, если кто-то подбросит какую идею по теме до этого - спасибо
Продолжу эту тему,
снова рабочая ситуация, и наверняка вы с ней сталкивались.
на ВФ странице несколько статичных элементов <area> имеют атрибут href.
в этот атрибут нужно динамически прибавить ID.
хардкодить специальные для этого переменные в контроллере не хочу.
планирую кверить (в лист или мап) из объекта следующее: id and name.
и на ВФ к каждому атрибут href добавить формулу, которая перебирает массив и если item.name = nameКотороеТребуетсяДляЭтогоЭлемента, то вписывать item.id.
но не уверен, что можно в ВФ формуле можно перебирать массив...
буду разбираться c этим через несколько часов, если кто-то подбросит какую идею по теме до этого - спасибо
Никаких переборов на VF!!! Или делай мапу или делай inner class в котором будет и твой item и твой nameКотороеТребуетсяДляЭтогоЭлемента. Все не просто а ОЧЕНЬ просто.
Никаких переборов на VF!!!
Или делай мапу или делай inner class в котором будет и твой item и твой nameКотороеТребуетсяДляЭтогоЭлемента.
Все не просто а ОЧЕНЬ просто.
Или делай мапу или делай inner class в котором будет и твой item и твой nameКотороеТребуетсяДляЭтогоЭлемента. Все не просто а ОЧЕНЬ просто.
[quote="Dmitry Shnyrev"]Или делай мапу или делай inner class в котором будет и твой item и твой nameКотороеТребуетсяДляЭтогоЭлемента.
Все не просто а ОЧЕНЬ просто.[/quote]
с мапой то было бы вообще отлично...
нашел:
http://www.salesforce.com/docs/developer/pages/Content/pages_dynamic_vf_maps_lists.htm
живем!
с мапой то было бы вообще отлично...
Проблема будет если в мапе не будет значения по нужному тебе ключу - получишь вредную ошибку. И как проверить есть ли ключ в мапе на самой странице VF я не нашел. Поэтому фокус с мапой только на случай если в мапе есть значения для всех нужных тебе ключей. Я вообще везде использую именно inner class.
[quote="Den Brown"]с мапой то было бы вообще отлично... [/quote]
Проблема будет если в мапе не будет значения по нужному тебе ключу - получишь вредную ошибку. И как проверить есть ли ключ в мапе на самой странице VF я не нашел. Поэтому фокус с мапой только на случай если в мапе есть значения для всех нужных тебе ключей.
Я вообще везде использую именно inner class.
Я вообще везде использую именно inner class.
спасибо, дай плиз пример как ты работаешь с inner class в ВФ разметке в данном случае.
[quote="Dmitry Shnyrev"]Я вообще везде использую именно inner class.[/quote]
спасибо, дай плиз пример как ты работаешь с inner class в ВФ разметке в данном случае.
Пример вот такой
тебе надо вывести список контактов и для каждого контакта какой-нибудь еще дополнительный параметр
в контроллере объявляешь inner class
class ContactWrapper { public Contact contact { get; set; } public String someAdditionalParam { get; set; } public ContactWrapper(Contact contact, String p){ this.contact = contact; this.someAdditionalParam = p; } }
После этого достаешь контакты, идешь по ним в цикле, вычисляешь для каждого контакта нужный ему someAdditionalParam и создаешь ContactWrapper и складываешь его в cwList:
List<ContactWrapper> cwList { get; set; }
А уже на самой странице в <apex:repeat var="cw" value="{!cwList}"> идешь не по самим контактам, а по ContactWrappers из cwList и получается что у тебя сразу есть и сам контакт (cw.contact.Id, cw.contact.Name) и собственно параметр для этого контакта (cw.someAdditionalParam)
Все.
В таком стиле ContactWrapper можно усложнять просто на сколько фантазии хватает. Можно вкладывать другие inner class. Зато на странице не будет и не должно быть никакой логики, тупо перебор.
Пример вот такой
тебе надо вывести список контактов и для каждого контакта какой-нибудь еще дополнительный параметр
в контроллере объявляешь inner class
[code]class ContactWrapper {
public Contact contact { get; set; }
public String someAdditionalParam { get; set; }
public ContactWrapper(Contact contact, String p){
this.contact = contact;
this.someAdditionalParam = p;
}
}[/code]
После этого достаешь контакты, идешь по ним в цикле, вычисляешь для каждого контакта нужный ему someAdditionalParam и создаешь ContactWrapper и складываешь его в cwList:
[code]List<ContactWrapper> cwList { get; set; }[/code]
А уже на самой странице в <apex:repeat var="cw" value="{!cwList}"> идешь не по самим контактам, а по ContactWrappers из cwList и получается что у тебя сразу есть и сам контакт (cw.contact.Id, cw.contact.Name) и собственно параметр для этого контакта (cw.someAdditionalParam)
Все.
В таком стиле ContactWrapper можно усложнять просто на сколько фантазии хватает. Можно вкладывать другие inner class. Зато на странице не будет и не должно быть никакой логики, тупо перебор.