Visualforce
Force.com중 Visualforce를 정리 합니다.
목차
- 1 Visualforce Overview
- 2 View - Page
- 3 View - Standard Component
- 4 View - Global Variables
- 5 View - StandardController
- 6 View - StandardSetController
- 7 View - Custom Controller
- 8 View - 필드 집합
- 9 View - 사용자 정의 설정
- 10 View - 사용자 정의 라벨
- 11 View - 구성 요소
- 12 View - 정적 자원
- 13 View - 탭
- 14 View - 버튼 및 링크
- 15 View - 필드
- 16 View - 사이트
- 17 View - 대시보드
- 18 View - Flow
- 19 표준 페이지 Layout
- 20 목록 Layout
- 21 개체 Layout
- 22 Mobile Page
- 23 VF Tips
- 24 참고 문헌
Visualforce Overview
Page Overview
Page Lifecycle
- 버그(오류) 사항
- Component(구성 요소)를 사용할 경우, Controller가 동일한 구성 요소가 여러개 있을 경우 view state가 정상적으로 관리되지 않습니다.
- 참고 문헌
Development Mode
- 설정 -> 개인정보
- 개발 모드 : Visualforce Page 하단에 개발 모드 표시
- 개발 모드 상태 보기 표시 : View State 표시
- View State
- Controller의 정보
- 수식의 표현식 정보
- Size Limit : 135 KB
- No Transient로 선언된 변수는 View State에서 관리되지 않습니다.
View - Page
- 접속 URL : /apex/pageName
- {!변수}
- "설정 -> 개인 설정 -> 내 개인 정보 -> 개인 정보" 메뉴에서 "개발 모드", "개발 모드 상태 보기 표시"
- Visualforce Page Sample
<apex:page standardController="Contact" extensions="CtrZztemp01" recordSetVar="data" tabStyle="Contact" title="연락처" showHeader="true"> <apex:sectionHeader title="연락처" subtitle="pageBlockTable" /> <apex:form > <apex:pageBlock title="연락처 목록" rendered="{!$ObjectType.Account.accessible}"> <apex:pageBlock id="list"> <apex:pageBlockTable value="{!data}" var="item“ cellpadding="0" cellspacing="0"> <apex:column value="{!item.FirstName}" /> <apex:column value="{!item.LastName}" /> </apex:pageBlockTable> <apex:panelGrid columns="2"> <apex:commandLink action="{!previous}" rerender="list" value="이전" /> <apex:commandLink action="{!next}" rerender="list" value="다음" /> </apex:panelGrid> </apex:pageBlock> </apex:pageBlock> </apex:form> </apex:page>
- Layout에서 Visualforce Page를 사용하려면 다음과 같이 선언된 페이지를 미리 만들어야 합니다.
<apex:page standardController="해당_개체">
Parameter
- Visualforce Page
- {!$CurrentPage.parameters.name}
- Apex Code
- ApexPages.currentPage().getParameters().get(‘name’)
- PageReference를 사용한 Parameter 입출력
- ApexPages.currentPage().getParameters().get('id')
- ApexPages.currentPage().getParameters().put('id', '~')
- Visualforce Page에서 Parameter 입출력
- {!$CurrentPage.parameters.parameter_name}
- 각 필드의 고유한 ID를 확인 합니다.
- "설정 -> App설정 -> 작성 -> 개체 -> [개체 선택] -> [필드 선택]"을 하면 아래와 같은 URL이 표시 됩니다.
- 이때 00NA0000008Gc9u 이 이 필드의 고유한 ID 입니다.
- URL에서 각 Input 필드별로 다음 값을 전달하면 데이터가 입력되어 있는 화면이 표시 됩니다.
- 일반 필드
- 필드_아이디=값
- 값이 &를 포함할 경우 %26으로 변경하여 사용할 것
- 검색 관계 필드 또는 마스터-세부 사항 관계 필드
- 필드_아이디=화면에_표시될_이름
- 필드_아이디_lkid=아이디_값(검색 관계에 있는 개체의 아이디)
- /a0B/e?CF00NA0000005JzZX={!ObjectMaster__c.Name}&CF00NA0000005JzZX_lkid={!ObjectMaster__c.Id}&00NF00000082xeJ={!ObjectMaster__c.TextField__c}&retURL=/{!ObjectMaster__c.Id}
https://na7.salesforce.com/a0w/e? CF00NA0000008Gc9u=이름 &CF00NA0000008Gc9u_lkid=아이디
- 관련목록에서 값을 전달하여 새로운 개체를 등록하는 방법
- Display Type : List Button
- "Display Checkboxes"는 선택하지 않음
- Behavior : Display in existing window without sidebar or header
- Content Source : URL
- {!URLFOR($Action.Agenda__c.New)}&CF00NV0000000JoKP={!Event__c.Name}&CF00NV0000000JoKP_lkid={!Event__c.Id}&00NV0000000JoLE={!Event__c.BU__c}
- Prefix : Schema.getGlobalDescribe().get('Contact').getDescribe().getKeyPrefix()
- EncodingUtil.urlEncode()
- 참고 문헌
Data
- Visualforce Page
{!name} {!$ObjectType.Account.fields.fieldName.label} <apex:inputText value=“{!name}” id=“nameId” /> <apex:inputField value=“{!name}” id=“nameId” />
- window.document.all['{!Component.nameId}']
- Apex Code
public String name {get;} public String getName() public String name {get; set;} public String getName(), public void setName(String Name)
AJAX
- Visualforce Page
Action, rerender=“id”, rendered <apex:actionStatus /> Controller.getAccount(Args, function(result, event), options) ~ = sforce.apex.execute(“ClassName”, “makeContact”, Args) sforce.SObject, sforce.connection.query/insert/update/delete
- Apex Code
public PageReference ~() { ~ } @RemoteAction global static Account getAccount(~) { ~ } webService static Id makeContact(~) { ~ } SOQL, DML
- Page's view state
- Transient 변수 : view state에 저장되지 않음
<apex:form /> <- -> 일반 변수
Style
tabStyle (/dCSS/dStandard.css, allCustom.css) style, styleClass <apex:stylesheet value=“~” /> $User.UITheme, $User.UIThemeDisplayed http://wiki.developerforce.com/index.php/Using_the_Salesforce_CSS_in_Your_Apps
Cookie
- Visualforce Page
window.document.cookie
- Apex Code
ApexPages.currentPage.getCookies().get(name) Apex.currentPage().setCookies(new Cookie[] {~})
Message
- Visualforce Page
<apex:pageMessages />, <apex:pageMessage /> <apex:messages />, <apex:message />
- Apex Code
private transient ApexPages.Message msg = null; //--- ERROR, WARN, INFO, DEBUG, FINE, FINER, FINEST msg = new ApexPages.Message(ApexPages.severity.ERROR, '이메일을 입력 하세요.'); ApexPages.addMessage(msg); ApexPages.addMessage(new ApexPages.Message(ApexPages.severity.ERROR, ‘~’)) ApexPages.addMessages(Exception) sObject.addError(~), addError(Exception)
PageReference
- Visualforce Page
{!URLFOR(‘~’)} {!URLFOR($Page.pageName)} URLFOR($Action.개체.Tab, $ObjectType.개체) URLFOR($Action.개체.List, $ObjectType.개체) URLFOR($Action.개체.View, 아이디) URLFOR($Action.개체.New) URLFOR($Action.개체.Edit, 아이디) URLFOR($Action.개체.Delete, 아이디), Clone, Accept
- Apex Code
new PageReference(‘~’) Page.pageName Page.failure, Page.success, ~.setRedirect(true) Schema.SObjectType.개체.getKeyPrefix() 사용 new ApexPages.StandardController(~).view()
- PageReference
- Blob getContentAsPDF()
- Blob getContent()
- getParameter().put(‘~’, ‘~’)
contentType
- Excel 페이지
<apex:page standardController="Account" contentType="application/vnd.ms-excel"> <apex:page contentType="application/vnd.ms-excel;charset=euc-kr#contacts.xls", text/rtf
Excel로 저장
- Office 파일 작성 방법 (Excel 사례)
- Excel 파일에서 변수를 출력할 부분에 {!~} 문자열을 사용하여 작성
- Excel을 htm으로 저장
- "부호화 -> UTF-8 인코딩" 후 원래 htm을 복사하여 저장
- replace : '돋움, monospace;' -> 'Arial Unicode MS'
- replace : '굴림체, monospace;' -> 'Arial Unicode MS'
- 아래 사항 추가
<style type="text/css"> body { font-family: Arial Unicode MS; } </style>
- zip 파일로 압축하여 Static Resource로 추가
- Apex Code 예
public class CtrPaymentRequestVoucher { public String urlBase = 'https://cs12.salesforce.com/resource/1319787964000/Template001/'; public String content {get; set;} public CtrPaymentRequestVoucher(ApexPages.StandardController standardController) { PageReference page = null; page = new PageReference(urlBase + 'Template001.htm'); content = page.getContent().toString(); content = content.replace('{!title}', '안녕하세요'); } }
- Visualforce Page 예
- Excel로 저장 : contentType="application/vnd.ms-excel#Template.htm"
<apex:page standardController="Event__c" extensions="CtrPaymentRequestVoucher" tabStyle="Event__c" title="Payment Request Voucher" showHeader="false" contentType="application/vnd.ms-excel#Template.htm"> <apex:outputText value="{!content}" escape="false" /> </apex:page>
PDF Page
PDF 개요
- Visualforce Page를 PDF로 저장
- 최대 15MB
<apex:page standardStylesheets="false" renderAs="pdf"> </apex:page>
- PDF에 한글 출력
<style type="text/css"> body { font-family: Arial Unicode MS; } </style>
- PDF Page
- portrait : 720px * 960px
- A4 portrait : 900px * 1027px
- landscape : 960px * 720px (?)
<style type="text/css"> @page { size: A4 landscape; } </style> size: 210mm 297mm; margin-top : 6.0mm; margin-left : 6.0mm; margin-right : 6.0mm; margin-bottom : 6.0mm;
- @page
- @page :left { ~ }, :right, :first
@page { margin-top: 10px; margin-right: 10px margin-bottom: 10px; margin-left: 10px; }
- top-left-coner, top-left, top-center, top-right, top-right-coner
- right-top, right-middle, right-bottom
- bottom-left-coner, bottom-left, bottom-center, bottom-right, bottom-right-coner
- left-top, left-middle, left-bottom
@page { @bottom-center { content: counter(page) "/" counter(pages); color: green; } }
- counter(page), counter(pages), TODAY()
- Page Break
<style type="text/css"> .pageBreak { page-break-before: always; } </style>
- CSS3, http://dev.w3.org/csswg/
- Page : http://dev.w3.org/csswg/css3-page/
- Box 위치, 크기, 색상
margin : top right bottom left border : width style color : thin solid black border-width: thin thick medium medium; border-style: dashed solid solid solid; none, hidden, dotted, dashed, solid, double, groove, ridge, inset, outset border-color: lime lime lime lime; padding : top right bottom left
- Text 위치, 크기, 색상
vertical-align: middle 방법 : <img class="virticalImage"/> 또는 line-height: 50px; text-align: center; text-wrap: normail; text-decoration: none; font-color: black; font-size: 18px; font-weight: bold;
- 참고 문헌
동적 CSS3로 PDF 만들기
정적 CSS3로 PDF 만들기
HTML로 PDF 만들기
View - Standard Component
Page |
|
Look & Feel |
|
List |
|
Form |
<apex:outputLink value=“~”> <apex:param name=“~” value=“~” /> </apex:outputLink>
|
AJAX |
|
동적 화면 구성 |
|
Chatter |
|
Workfow |
|
Ideas |
|
Knowledge |
|
Messaging |
|
Site |
|
미분류 |
|
- 페이지 호출 방법
- https://salesforce_instance/apex/PageName
- id=개체의 ID : 개체의 데이터 조회시 사용
- 반복문
<apex:repeat var="job" value="{!dataJob}"> </apex:repeat>
- Button
<apex:commandButton action="{!del}" value="삭제" onclick="return checkDel();" />
Rerender
Visualforce Page에서 Controller에 해당하는 Apex Code 함수를 호출하여 동적으로 페이지를 갱신하기 위해서 rerender를 사용할 수 있습니다.
<apex:commandButton value="Go!" action="{!doSearch}" rerender="block" status="status"/> <apex:commandLink rerender="detail"> {!contact.Name} <apex:param name="cid" value="{!contact.id}"/> </apex:commandLink> <apex:actionFunction action="{!methodOne}" name="methodOneInJavascript" rerender="showstate"> <apex:param name="firstParam" assignTo="{!state}" value="" /> </apex:actionFunction> <apex:actionSupport event="onmouseover" rerender="detail"> <apex:param name="cid" value="{!contact.id}"/> </apex:actionSupport> <apex:actionPoller action="{!incrementCounter}" rerender="counter" status="counterStatus" interval="7"/> <apex:actionStatus id="counterStatus" startText=" (incrementing...)" stopText=" (done)"/> <apex:pageBlock mode="edit" id="block"> <apex:outputText value="Watch this counter: {!count}" id="counter"/>
View - Global Variables
수식에서도 7가지의 전역 변수를 사용할 수 있습니다.
Action
- $Action
- ApexPages.Action
- 참조: 단추 및 링크
API
- $Api
- $Api.Session_ID
Component
- $Component
- 화면에서 id로 지정된 항목을 관리 합니다.
- 주의 : 같은 PageBlock 안에서만 정상 동작 합니다.
//--- Visualforce Page에서 id가 test로 지정된 항목의 실제 ID값 (text)을 반환 합니다. {!$Component.test} window.document.all['{!$Component.test}'].innerText
- $Component.~.~
ComponentLabel
- $componentLabel
CurrentPage
- $CurrentPage
{!$CurrentPage.parameters.parameter_name} {!$CurrentPage.parameters.caseId != null}
Label
- $Label
- $Label.Site
ObjectType
- $ObjectType
- $ObjectType.Account == Schema.SObjectType.Account.getKeyPrefix() (Apex Code에서)
- 목록 : "/{!$ObjectType.SNB_HR_empoloyees__c}/l", /a0R/l
- 등록 : "/{!$ObjectType.SNB_HR_empoloyees__c}/e", /a0R/e
- 관련 목록 등록
- 수정 : "/개체ID/e", /a0RA000000GA9mDMAT/e
- 복제 : /a0RA000000GFfks/e?clone=1
- 삭제 : /setup/own/deleteredirect.jsp?id=a0RA000000GFfks&delID=a0RA000000GFfks&_CONFIRMATIONTOKEN=~
- 기타 URL
- /a0RA000000GA9mDMAT/a : 소유권 편집
- /a0RA000000GFfks/m : 1열로 보기
- /a0RA000000GFfks/p : 출력 양식 보기
- 기타 Parameter
- retURL : 취소시 돌아갈 URL
$ObjectType.empoloyees__c $ObjectType.objectname.accessible $ObjectType.account.fields.Name.label $ObjectType.Case.Fields[caseField].label <apex:repeat value="{!$ObjectType.Contact.FieldSets.properNames}" var="f"> {!$ObjectType.Contact.Fields[f].label} ({!$ObjectType.Contact.Fields[f].type}): <apex:outputField value="{!Contact[f]}"/> </apex:repeat>
Organization
- $Organization
Page
- $Page, Page (in Apex Code)
- {!URLFOR($Page.ViewItem03)}
Profile
- $Profile
Resource
- $Resource
SControl
- $SControl
Site
- $Site
System
- $System.OriginDateTime
User
- $User : Field는 User 개체 참조
UserRole
- $UserRole
URLFOR
탭 |
|
|
목록 |
|
|
보기 |
|
|
새로 만들기 |
|
|
편집 |
|
|
삭제 |
|
|
복제 |
| |
수락 |
- URLFOR 문법
- URLFOR(resource, path)
- URLFOR(target, id, [inputs], [no override])
- inputs : [name1='value', name2='value2']
- retURL=%2F00190000007Pa5U : 작업 완료시 돌아갈 URL
- saveURL=~
- cancelUrl=~ : 작업 취소시 돌아갈 URL
- 재정의 방지 방법
- URLFOR를 사용할 경우 no override 파라메터로 true를 전달 합니다.
- 원본 URL에 ?nooverride=1 을 추가 합니다.
- 기타 Salesforce에서 사용하는 URL
다운로드 |
|
|
소유권 편집 |
| |
1열로 보기 |
| |
출력 양식 보기 |
|
View - StandardController
- ApexPages.StandardController
- getId(), getRecord()
- view(), save(), edit(), delete(), cancel()
public with sharing class ~ { public CtrViewItem(ApexPages.StandardController controller) { } }
- Visualforce Page
- /apex/pageName?id=~
<apex:page standardController="Contact__c“ extensions="CtrViewItem, CtrN1“ tabStyle=“Contact__c" />
- {!contact.~} : 소문자 객체명을 데이터명으로 사용
- {!$ObjectType.objectName.accessible}
View - StandardSetController
- ApexPages.StandardSetController
- getRecords(), getSelected()
- list(), first(), prev(), next(), last(), getHasNext(), getHasPrevious()
- save(), cancel()
- getPageSize(), getPageNumber(), getResultSize()
- getFilterId(), getListViewOptions()
public with sharing class ~ { public CtrViewList(ApexPages.StandardSetController controller) { } }
- Visualforce Page
<apex:page standardController="Contact__c“ extensions="CtrViewList“ recordSetVar="data" tabStyle=“Contact__tab" />
- recordSetVar에서 지정한 data를 데이터 집합명으로 사용
View - Custom Controller
Custom Controller
Extendsion of Controller
- StandardController 확장
public with sharing class BaseItemController { public BaseItemController(ApexPages.StandardController controller) { } }
- StandardSetController 확장
public with sharing class BaseDataController { public BaseDataController(ApexPages.StandardSetController standardSetController) { } }
- Visualforce Page에서 사용
<apex:page controller="myController" tabStyle="Account" extensions="BaseDataController">
View - 필드 집합
- 각 개체 화면에서 "필드 집합" 메뉴 (Beta)
- 사용법
- Field : Label, Type, Required, FieldPath, DBRequired
- {!$ObjectType.Account.FieldSets.~}
<apex:repeat value="{!$ObjectType.Contact.FieldSets.fsName}" var=“item"> <apex:outputText value="{!Contact[item]}" /> </apex:repeat>
View - 사용자 정의 설정
- 사용자가 정의한 설정 값(개체)을 관리 합니다.
- "설정 -> App 설정 -> 개발 -> 사용자 정의 설정" 메뉴
- 설정 유형 : 목록. 전사적으로 설정, 계층. 사용자별, 프로파일별로 설정 (User -> Profile -> Organization)
- 가시성 : 공용. 모두 사용, 비공개. Managed Package로 배포될 경우 보이지 않음
- 데이터 유형 : URL, 날짜/시간, 백분율, 숫자, 이메일, 일자, 전화, 텍스트, 텍스트 영역, 통화, 확인란
- 제약 사항 : 최대 2MB
- 사용법
Map<String name, ~> ~.getAll() ~ = ~.getInstance(name) ~ = ~.getValues(name)
~ = ~.getInstance() ~ = ~.getInstance(userId 또는 profileId) ~ = ~.getValues(userId 또는 profileId) ~ = ~.getOrgDefaults()
View - 사용자 정의 라벨
- 사용자 정의 텍스트 값
- "설정 -> App 설정 -> 작성 -> 사용자 정의 라벨" 메뉴, 다국어 지원 가능
- 제약 사항 : 최대 5000개, 1개당 최대 1000자
- 사용법
- Name으로 지정하면 Value가 표시됨
{!$Label.~} System.Label.~
View - 구성 요소
- Visualforce Page에서 재사용 가능한 공통된 디자인 패턴 (코드 블럭)
- "설정 -> App 설정 -> 개발 -> 구성 요소" 메뉴
- 제약 사항 : 하나당 최대 1MB
- 선언
<apex:component controller=“~” extensions=“~”> <apex:attribute name=“~” type=“~” description=“~” default=“~” required=“true” assignTo=“{!~}” /> {!~} : name 또는 assignTo에 할당된 변수 사용법 <apex:componentBody> //--- 전달된 component의 본문(내용) <apex:variable var=“~” value=“{!~}” /> //--- 본문에서 사용할 변수 할당 </apex:componentBody> </apex:component>
- Default attribute : id, rendered
- type : String, String[], sObject, Apex class
- assignTo는 controller를 사용할 경우, controller의 저장할 변수를 지정함
- Visualforce Page에서 호출 방법
- <c:~ name=‘value’ />
- http://~/apexcomponent/~
- 오류에 대한 조치
- Error: Literal value is required for attribute
- Visualforce Page에서 Attribute로 변수에 담겨져 있는 값을 넘길 때, Component에서 받을 때 Default 값을 선언하면 오류가 발생함
View - 정적 자원
- Visualforce Page에서 참조하려는 .zip 및 .jar 파일, 이미지, 스타일시트, JavaScript 및 기타 정적 파일
- "설정 -> App 설정 -> 개발 -> 정적 자원" 메뉴
- 캐시 관리 : 공용. 공유됨, 비공개. 본인만 사용
- 제약 사항 : 하나당 5MB, 최대 250MB
- 사용법
{!$Resource.~} : 정적 자원의 URL {!URLFOR($Resource.~, ‘image/aaa.png’)} : 정적 자원이 zip 파일인 경우 aaa.png 파일의 URL
View - 탭
"설정 -> App 설정 -> 작성 -> 개체 -> [개체 선택] -> 표준 버튼 및 링크/사용자 정의 버튼 및 링크"
View - 버튼 및 링크
"설정 -> App 설정 -> 작성 -> 개체 -> [개체 선택] -> 표준 버튼 및 링크/사용자 정의 버튼 및 링크"
View - 필드
"설정 -> App 설정 -> 작성 -> 개체 -> [개체 선택] -> 페이지 레이아웃"
View - 사이트
- "설정 -> App 설정 -> 개발 -> 사이트"
View - 대시보드
View - Flow
- 복잡한 사용자 인터페이스를 손쉽게 개발
- "설정 -> 개인 설정 -> 내 개인 정보 -> 개인 정보" 메뉴에서 Force.com Flow 사용자
- <flow:interview />
- name=flowname
- interview=“{!myflow}”
- finishlocation=PageReference
<apex:param name="vaCaseNumber" value="{!case.CaseNumber}"/> Map<String, Object> myMap = new Map<String, Object>(); myMap.put('vaCaseNumber','123456'); myflow = new Flow.Interview.ModemTroubleShooting(myMap);
표준 페이지 Layout
- 사이트 : 풍부한 사용자 경험 제공 (RIA, Rich Internet Application)
- Eclipse 통합 개발 환경(IDE) 설치
Overview
로그인 후에 사용할 수 있는 Visualforce Page로 사이트에서 사용시 로그인 없이도 접속이 가능 합니다.
- 호출 URL
- /apex/페이지명
- 예) https://c.na7.visual.force.com/apex/test
- 구성 요소 참조 : https://na7.salesforce.com/apexpages/apexcomponents.apexp
<apex:page controller="SNB_P_EMP_BIZTRIP" tabStyle="Mydesk__tab" sidebar="false" showHeader="false" title="{!$Label.SNB_HRprocess}" > <body> //--- HTML, JavaScript 등 //--- EMP_METATAG 구성 요소 추가 <c:EMP_METATAG toptitle="{!$Label.SNB_Account}" ></c:EMP_METATAG> //--- 정적자원 (Resource) 사용 방법 //--- zip 형태의 resource에 포함된 qstyles_N.css 사용 <apex:includeScript value="{!URLFOR($Resource.Common, 'common.js')}"/> <apex:stylesheet value="{!URLFOR($Resource.SNB_advancedpdfresource, 'qstyles_N.css')}"/> </body> </apex:page>
- Visualforce Components
- actionFunction : JavaScript 함수 생성
StandardController
- {!EvaluationResult__c.필드명} : StandardController에 해당하는 레코드의 필드값
<apex:page standardController="Account" extensions="CtrCustomAccount" recordSetVar="accounts" tabStyle="Account" title="계정" showHeader="{!isHeader}" sidebar="true"> <apex:sectionHeader title="계정" subtitle="목록" /> <apex:form > <apex:pageBlock title="평가 통계"> <apex:pageMessages /> <apex:pageBlockSection columns="2"> <apex:inputField value="{!result.Manage__c}" required="true" /> </apex:pageBlockSection> <apex:pageBlockButtons location="bottom"> <apex:commandButton action="{!view}" value="조회" /> </apex:pageBlockButtons> </apex:pageBlock> </apex:form> <apex:pageBlock title="Batch 로그 - {!BatchStep}" rendered="{!BatchStep != }"> <apex:pageBlockTable value="{!job}" var="item"> <apex:column value="{!item.id}"/> <apex:column value="{!item.Status}"/> </apex:pageBlockTable> </apex:pageBlock> </apex:page>
Standard Extension - Single
<apex:page standardController="Account" extensions="CtrCustomAccount" tabStyle="Account" title="계정"> public class CtrUserHome { private final SNB_HR_empoloyees__c item; public CtrUserHome(ApexPages.StandardController controller) { ID id = null; if (id == null) { item = new SNB_HR_empoloyees__c(); } else { item = [SELECT id FROM Account WHERE id = :ApexPages.currentPage().getParameters().get('id')]; } //--- 또는 item = (Account)controller.getRecord(); } public PageReference gotoTest() { PageReference acctPage = new PageReference('/apex/test); acctPage.setRedirect(true); return acctPage; } }
Standard Extension - Multi
<apex:page standardController="Account" extensions="CtrCustomAccount" recordSetVar="accounts" tabStyle="Account" title="계정"> public class CtrUserHome { public ApexPages.StandardSetController controller = null; private final List<SNB_HR_empoloyees__c> data; public CtrUserHome(ApexPages.StandardSetController controller) { if (this.controller == null) { this.controller = new ApexPages.StandardSetController(Database.getQueryLocator( [SELECT id, name,closedate FROM Account])); } //--- 또는 data = (List<SNB_HR_empoloyees__c>)controller.getRecords(); } public PageReference gotoTest() { PageReference acctPage = new PageReference('/apex/test); acctPage.setRedirect(true); return acctPage; } }
목록 Layout
목록 Controller
- pageBlockButtons
<apex:pageBlockButtons location="bottom"> <apex:commandButton action="{!view}" value="조회" /> </apex:pageBlockButtons>
- panelGrid
<apex:panelGrid columns="2"> <apex:outputLabel value="View:"/> <apex:selectList value="{!filterId}" size="1"> <apex:actionSupport event="onchange" rerender="list"/> <apex:selectOptions value="{!listviewoptions}"/> </apex:selectList> <apex:commandButton value="검색" action="{!list}"/> </apex:panelGrid>
Table 목록
- enhancedList
- Page에서 showHeader가 true인 경우에만 사용할 수 있음
<apex:page standardController="Account" recordSetVar="accounts" tabStyle="Account" title="계정" showHeader="true"> <apex:sectionHeader title="계정" subtitle="enhancedList" /> <apex:enhancedList type="Account" height="370" rowsPerPage="10" id="AccountList" customizable="true" rendered="{!$ObjectType.Account.accessible}"></apex:enhancedList> <apex:pageBlock rendered="NOT({!$ObjectType.Account.accessible})"> <p>개체에 대한 권한이 없습니다.</p> </apex:pageBlock> </apex:page>
- ListViews
<apex:page standardController="Account" extensions="CtrTestPage" recordSetVar="accounts" tabStyle="Account" title="계정" showHeader="{!showHeader}" sidebar="{!sidebar}"> <apex:sectionHeader title="계정" subtitle="ListViews" /> <apex:ListViews type="Account" rendered="{!$ObjectType.Account.accessible}"></apex:ListViews> <apex:pageBlock rendered="NOT({!$ObjectType.Account.accessible})"> <p>개체에 대한 권한이 없습니다.</p> </apex:pageBlock> </apex:page>
- pageBlockTable
<apex:page standardController="Account" extensions="CtrTestPage" recordSetVar="accounts" tabStyle="Account" title="계정" showHeader="{!showHeader}" sidebar="{!sidebar}"> <apex:sectionHeader title="계정" subtitle="pageBlockTable" /> <apex:pageBlock title="계정 목록" rendered="{!$ObjectType.Account.accessible}"> <apex:pageBlockTable value="{!accounts}" var="item"> <apex:column value="{!item.name}"/> <apex:column value="{!item.site}"/> <apex:column value="{!item.type}"/> <apex:column value="{!item.accountNumber}"/> </apex:pageBlockTable> </apex:pageBlock> <apex:pageBlock rendered="NOT({!$ObjectType.Account.accessible})"> <p>개체에 대한 권한이 없습니다.</p> </apex:pageBlock> </apex:page>
Text 목록
- dataTable
<apex:page standardController="Account" extensions="CtrTestPage" recordSetVar="accounts" tabStyle="Account" title="계정" showHeader="{!showHeader}" sidebar="{!sidebar}"> <apex:sectionHeader title="계정" subtitle="dataTable" /> <apex:dataTable value="{!accounts}" var="item" rowClasses="odd,even" styleClass="tableClass" rendered="{!$ObjectType.Account.accessible}"> <apex:facet name="caption">계정 목록</apex:facet> <apex:facet name="header">table header</apex:facet> <apex:facet name="footer">table footer</apex:facet> <apex:column > <apex:facet name="header">Name</apex:facet> <apex:facet name="footer">column footer</apex:facet> <apex:outputText value="{!item.name}"/> </apex:column> <apex:column > <apex:facet name="header">Owner</apex:facet> <apex:facet name="footer">column footer</apex:facet> <apex:outputText value="{!item.owner.name}"/> </apex:column> </apex:dataTable> <apex:pageBlock rendered="NOT({!$ObjectType.Account.accessible})"> <p>개체에 대한 권한이 없습니다.</p> </apex:pageBlock> </apex:page>
- dataList
<apex:page standardController="Account" extensions="CtrTestPage" recordSetVar="accounts" tabStyle="Account" title="계정" showHeader="{!showHeader}" sidebar="{!sidebar}"> <apex:sectionHeader title="계정" subtitle="dataList" /> <apex:dataList var="item" value="{!accounts}" id="lista" rendered="{!$ObjectType.Account.accessible}"> {!item.name}, {!item.site}, {!item.type}, {!item.accountNumber} </apex:dataList> <apex:pageBlock rendered="NOT({!$ObjectType.Account.accessible})"> <p>개체에 대한 권한이 없습니다.</p> </apex:pageBlock> </apex:page>
배열 표시
- List, Map에 저장된 data 표시 방법
<apex:page standardController="Account" extensions="CtrTestPage" recordSetVar="accounts" tabStyle="Account" title="계정" showHeader="{!showHeader}" sidebar="{!sidebar}"> <apex:sectionHeader title="계정" subtitle="repeat" /> <apex:repeat value="{!accounts}" var="item" rendered="{!$ObjectType.Account.accessible}"> <apex:outputText value="{!item.name}"/>, <apex:outputText value="{!item.site}"/>, <apex:outputText value="{!item.type}"/>, <apex:outputText value="{!item.accountNumber}"/>
</apex:repeat> <apex:pageBlock rendered="NOT({!$ObjectType.Account.accessible})"> <p>개체에 대한 권한이 없습니다.</p> </apex:pageBlock> </apex:page>
개체 Layout
개체 정보
- detail
<apex:page standardController="Account" extensions="CtrTestPage" tabStyle="Account" title="계정" showHeader="{!showHeader}" sidebar="{!sidebar}"> <apex:detail inlineEdit="true" rendered="{!$ObjectType.Account.accessible}"></apex:detail> <apex:pageBlock rendered="NOT({!$ObjectType.Account.accessible})"> <p>개체에 대한 권한이 없습니다.</p> </apex:pageBlock> </apex:page>
- pageBlockSection / inputField, outputField
<apex:page standardController="Account" extensions="CtrTestPage" tabStyle="Account" title="계정" showHeader="{!showHeader}" sidebar="{!sidebar}"> <apex:sectionHeader title="계정" subtitle="pageBlockSection" /> <apex:form rendered="{!$ObjectType.Account.accessible}"> <apex:pageBlock title="계정 세부 사항" rendered="{!$ObjectType.Account.accessible}"> <apex:pageBlockSection title="계정" columns="2"> <apex:outputField value="{!Account.name}"/> <apex:outputField value="{!Account.site}"/> <apex:inputField value="{!Account.type}"/> <apex:inputField value="{!Account.accountNumber}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form> <apex:relatedList list="Opportunities" /> <apex:pageBlock rendered="NOT({!$ObjectType.Account.accessible})"> <p>개체에 대한 권한이 없습니다.</p> </apex:pageBlock> </apex:page>
- apex:dynamicComponent
<apex:dynamicComponent componentValue="{!dynamicDetail}" />
개체 필드
관련 목록
- relatedList
<apex:relatedList list="Opportunities" />
Mobile Page
- Mobile 확인을 위한 UserAgent 체크
String userAgent = null; userAgent = ApexPages.currentPage().getHeaders().get('USER-AGENT'); if (userAgent.contains('iPhone')) { } else if(userAgent.contains('Android')) { } else if(userAgent.contains('BlackBerry')) { }
- 모바일 화면의 높이를 계산
function getScreenHeight() { var orientation = null; try { orientation = jQuery.event.special.orientationchange.orientation(); } catch (ex) { orientation = "portrait"; } var port = orientation === "portrait", winMin = port ? 480 : 320, screenHeight = port ? screen.availHeight : screen.availWidth, winHeight = Math.max( winMin, $( window ).height() ), pageMin = Math.min( screenHeight, winHeight ); return pageMin; }
VF Tips
DatePicker
- <apex:inputText id="smsReserveDate" value="{!smsReserveDate}" onfocus="DatePicker.pickDate(true, this.id, false);" style="width: 75px;" />
- [ <a href="javascript:DatePicker.insertDate('2012. 4. 12', '{!$Component.smsReserveDate}', true);">2012. 4. 12</a> ]