Регистрация  |  Вход

Значение из массива как флаг для рендеринга VF элемента

Ну вот еще логическая задачка:

В контроллере есть массив числовых значений, который может содержать например 5, 10, 34.

На фронте есть 100 компонентов, которые должны рендерится или не рендерится в зависимости от наличия или отсутсвия в данном массиве какого значения. Например "VF компонент 1" должен рендерится только если в массиве есть значение "1". Но как перебрать массив в разметке?

логическая задачка. если не удастся это решить таким образом, то придется делать 100 булен флагов в контроллере и передавать их в соответствующий компонент.

Ну вот еще логическая задачка:

В контроллере есть массив числовых значений, который может содержать например 5, 10, 34.

На фронте есть 100 компонентов, которые должны рендерится или не рендерится в зависимости от наличия или отсутсвия в данном массиве какого значения. Например "VF компонент 1" должен рендерится только если в массиве есть значение "1". Но как перебрать массив в разметке?

логическая задачка. если не удастся это решить таким образом, то придется делать 100 булен флагов в контроллере и передавать их в соответствующий компонент.

Первое что пришло в голову сделать репитор выгрузить на пейджу числа сразу скрыть репитор. javascript пройтись по чайлдом собрать значения.Вот тебе массив.

Первое что пришло в голову сделать репитор выгрузить на пейджу числа сразу скрыть репитор. javascript пройтись по чайлдом собрать значения.Вот тебе массив.

еще Написать внутрений веб сервис который возращает массив в javascript.Единственный нюанс ест сallout вроде как при обращении.

еще Написать внутрений веб сервис который возращает массив в javascript.Единственный нюанс ест сallout вроде как при обращении.

Sergey Prichepo
Первое что пришло в голову сделать репитор выгрузить на пейджу числа сразу скрыть репитор. javascript пройтись по чайлдом собрать значения.Вот тебе массив.

этот вариант - перевесить все работу на JS рассматривал. Можно передать значения репетиром или через JSON стринг. Но хочу все сделать на сервере.

И главное - это будет PDFнутая страница, там не то что JS, даже стили толком не работают.

[quote="Sergey Prichepo"]Первое что пришло в голову сделать репитор выгрузить на пейджу числа сразу скрыть репитор. javascript пройтись по чайлдом собрать значения.Вот тебе массив.[/quote]

этот вариант - перевесить все работу на JS рассматривал. Можно передать значения  репетиром или через JSON стринг. Но хочу все сделать на сервере. 

И главное - это будет PDFнутая страница, там не то что JS, даже стили толком не работают.

Den Brown
Ну вот еще логическая задачка:
массив в разметке?

ну не знаю тогда если перебирать массив в разметки, последнее что пришло на ум rendered="{!if(array[x] == '3',true,false)}"
незнаю точно сработает ли попробуй.

[quote="Den Brown"]Ну вот еще логическая задачка:
массив в разметке?
[/quote]
ну не знаю тогда если перебирать массив в разметки, последнее что пришло на ум rendered="{!if(array[x] == '3',true,false)}"
незнаю точно сработает ли попробуй.

Sergey Prichepo
array[x] == '3'

Сергей, ты имел введу, что на место "х" нужно ставить индекс?

в том то и дело, что мы не знаем какой набор цифр в массиве будет в этот раз, на каком идексе будет "3", да и буде ли вообще.

так что пока делаю переменные флаги в контроллере и буду их индивидуально выбивать в зависимости от содержания массива.

и еще: булеаны-флаги можно собрать в массив, с которым работать много проще, но это имеет смысл если в рендер атрибуте мы может обратиться к элементу массива.

а это я еще не проверил

[quote="Sergey Prichepo"]

array[x] == '3'

[/quote]

Сергей, ты имел введу, что на место "х" нужно ставить индекс?

в том то и дело, что мы не знаем какой набор цифр в массиве будет в этот раз, на каком идексе будет "3", да и буде ли вообще.

так что пока делаю переменные флаги в контроллере и буду их индивидуально выбивать в зависимости от содержания массива. 

и еще: булеаны-флаги можно собрать в массив, с которым работать много проще, но это имеет смысл если в рендер атрибуте мы может обратиться к элементу массива. 

а это я еще не проверил

быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:

<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]
<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]

Den Brown
Sergey Prichepo
array[x] == '3'

Сергей, ты имел введу, что на место "х" нужно ставить индекс?

в том то и дело, что мы не знаем какой набор цифр в массиве будет в этот раз, на каком идексе будет "3", да и буде ли вообще.

так что пока делаю переменные флаги в контроллере и буду их индивидуально выбивать в зависимости от содержания массива.

и еще: булеаны-флаги можно собрать в массив, с которым работать много проще, но это имеет смысл если в рендер атрибуте мы может обратиться к элементу массива.

а это я еще не проверил


да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.

[quote="Den Brown"][quote="Sergey Prichepo"]

array[x] == '3'

[/quote]

Сергей, ты имел введу, что на место "х" нужно ставить индекс?

в том то и дело, что мы не знаем какой набор цифр в массиве будет в этот раз, на каком идексе будет "3", да и буде ли вообще.

так что пока делаю переменные флаги в контроллере и буду их индивидуально выбивать в зависимости от содержания массива. 

и еще: булеаны-флаги можно собрать в массив, с которым работать много проще, но это имеет смысл если в рендер атрибуте мы может обратиться к элементу массива. 

а это я еще не проверил[/quote]
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.

dlisovsky
быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:
<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/>

а вот это интересная мысль. Для моего случая разметки этот вариант не подходит (по крайней мере я пока не додумался как это использовать).

Но тем не менее это ответ на поставленный вопрос.

[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].

Sergey Prichepo
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.

спасибо за идею. можете показать пример кода?

а пока я все бесстыже захардкодил...

[quote="Sergey Prichepo"]
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.[/quote]

спасибо за идею. можете показать пример кода?

а пока я все бесстыже захардкодил...

Den Brown
dlisovsky
быть может я не понял условия, но если у компонента есть свой определённый номер то можно сделать так:
<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/>

а вот это интересная мысль. Для моего случая разметки этот вариант не подходит (по крайней мере я пока не додумался как это использовать).

Но тем не менее это ответ на поставленный вопрос.


Еще можно использовать репитор в нутри репитора если там еще болле сложная логика.

[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]
Еще можно использовать репитор в нутри репитора если там еще болле сложная логика.

Den Brown
Sergey Prichepo
да имел виду индекс.Ок Обычно в таком случае я делаю иннер класс внутри текущего класса , и потом делаю лист иннер класса,как вариант для тебя.

спасибо за идею. можете показать пример кода?

а пока я все бесстыже захардкодил...


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]

Dmitry Shnyrev
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]
Второй способ Интересный.

Dmitry Shnyrev
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::')}"

Какой бы вариант не использовался, суть то одна - нам нужен какой-то контейнер с флагами (массив, мапа, строка) и ключ (идентификатор, индекс) нужного элемента который будет рендериться если этот ключ есть в контейнере, вот только в моём варианте я использую уже существующий массив чисел, который описал автор темы.

PS вариант с мапой хорош)

[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КотороеТребуетсяДляЭтогоЭлемента.
Все не просто а ОЧЕНЬ просто.

Dmitry Shnyrev
Или делай мапу или делай inner class в котором будет и твой item и твой nameКотороеТребуетсяДляЭтогоЭлемента.
Все не просто а ОЧЕНЬ просто.

с мапой то было бы вообще отлично...
нашел:
http://www.salesforce.com/docs/developer/pages/Content/pages_dynamic_vf_maps_lists.htm

живем!

[quote="Dmitry Shnyrev"]Или делай мапу или делай inner class в котором будет и твой item и твой nameКотороеТребуетсяДляЭтогоЭлемента. 
Все не просто а ОЧЕНЬ просто.[/quote]

с мапой то было бы вообще отлично...
нашел:
http://www.salesforce.com/docs/developer/pages/Content/pages_dynamic_vf_maps_lists.htm

живем!

Den Brown
с мапой то было бы вообще отлично...

Проблема будет если в мапе не будет значения по нужному тебе ключу - получишь вредную ошибку. И как проверить есть ли ключ в мапе на самой странице VF я не нашел. Поэтому фокус с мапой только на случай если в мапе есть значения для всех нужных тебе ключей.
Я вообще везде использую именно inner class.

[quote="Den Brown"]с мапой то было бы вообще отлично... [/quote]
Проблема будет если в мапе не будет значения по нужному тебе ключу - получишь вредную ошибку. И как проверить есть ли ключ в мапе на самой странице VF я не нашел. Поэтому фокус с мапой только на случай если в мапе есть значения для всех нужных тебе ключей.
Я вообще везде использую именно inner class.

Dmitry Shnyrev
Я вообще везде использую именно 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. Зато на странице не будет и не должно быть никакой логики, тупо перебор.