Visualforce
오픈소스 비즈니스 컨설팅
Force.com중 Visualforce를 정리 합니다.
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
<span style="page-break-before: always;" />
<span style="page-break-after: always;" />
<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> ]





