Visualforce 문서 원본 보기
←
Visualforce
둘러보기로 가기
검색하러 가기
문서 편집 권한이 없습니다. 다음 이유를 확인해주세요:
요청한 명령은 다음 권한을 가진 사용자에게 제한됩니다:
사용자
.
이 문서는 편집하거나 다른 명령을 할 수 없도록 보호되어 있습니다.
문서의 원본을 보거나 복사할 수 있습니다.
[[Force.com]]중 Visualforce를 정리 합니다. *매뉴얼 : http://wiki.developerforce.com/index.php/Visualforce ==Visualforce Overview== ===Page Overview=== [[그림:VfPage01.png|800px]] [[그림:VfPage02.png|800px]] ===Page Lifecycle=== [[그림:VfPageLifecycle.png|800px]] *버그(오류) 사항 :*Component(구성 요소)를 사용할 경우, Controller가 동일한 구성 요소가 여러개 있을 경우 view state가 정상적으로 관리되지 않습니다. *참고 문헌 :*[http://wiki.developerforce.com/index.php/An_Introduction_to_Visualforce_View_State 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 입니다. ::*https://na7.salesforce.com/00NA0000008Gc9u?setupid=CustomObjects *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} [[그림:CustomButton001.png]] *Prefix : Schema.getGlobalDescribe().get('Contact').getDescribe().getKeyPrefix() *EncodingUtil.urlEncode() *참고 문헌 :*[http://raydehler.com/cloud/clod/salesforce-url-hacking-to-prepopulate-fields-on-a-standard-page-layout.html Salesforce URL Hacking to Prepopulate Fields on a Standard Page Layout, 2011.4] ===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 위치, 크기, 색상 ::*Box model : http://www.w3.org/TR/CSS2/box.html#box-dimensions 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 위치, 크기, 색상 ::*Text : http://dev.w3.org/csswg/css3-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; *참고 문헌 :*[http://wiki.developerforce.com/index.php/Creating_Professional_PDF_Documents_with_CSS_and_Visualforce Creating Professional PDF Documents with CSS and Visualforce] :*[http://force.siddheshkabe.co.in/2011/04/some-pdf-tricks-on-visualforce.html Some PDF tricks on Visualforce: Landscape, A4, page number and more, 2011.4] :*[http://www.w3.org/TR/css3-page/#page-box-page-rule paged Box media] ====동적 CSS3로 PDF 만들기==== ====정적 CSS3로 PDF 만들기==== ====HTML로 PDF 만들기==== ==View - Standard Component== {|cellspacing="0" cellpadding="2" border="1" width="100%" bgcolor="#FFFFFF" align="center" |- |width="25%" align="center" valign="middle" style="background-color:#eee;"|Page |width="75%"| *page, pageMessage, pageMessages *scontrol |- |align="center" valign="middle" style="background-color:#eee;"|Look & Feel | *pageBlock, pageBlockButtons, pageBlockSection, pageBlockSectionItem, pageBlockTable *panelBar, panelBarItem, sectionHeader *tab, tabPanel, toolbar, toolbarGroup |- |align="center" valign="middle" style="background-color:#eee;"|List | *dataList, dataTable, facet, column (/w inputField) *panelGrid, panelGroup *repeat, detail *enhancedList, listViews, relatedList |- |align="center" valign="middle" style="background-color:#eee;"|Form | *form *commandButton, commandLink, outputLink <apex:outputLink value=“~”> <apex:param name=“~” value=“~” /> </apex:outputLink> *inputText, inputField, inputCheckbox, inputFile, inputHidden, inputSecret, inputTextarea *selectList, selectOption, selectOptions, selectCheckboxes, selectRadio *outputText, outputField, outputLabel, outputPanel, image *inlineEditSupport (inlineEdit=“true”), param *message, messages |- |align="center" valign="middle" style="background-color:#eee;"|AJAX | *actionSupport, actionStatus, actionPoller, actionFunction, actionRegion |- |align="center" valign="middle" style="background-color:#eee;"|동적 화면 구성 | *component, attribute, componentBody, variable *composition, define, insert *include, includeScript, stylesheet, iframe, flash *dynamicComponent |- |align="center" valign="middle" style="background-color:#eee;"|Chatter | *feed, feedWithFollowers, follow, followers |- |align="center" valign="middle" style="background-color:#eee;"|Workfow | *interview |- |align="center" valign="middle" style="background-color:#eee;"|Ideas | *detailOutputLink, listOutputLink, profileListOutputLink |- |align="center" valign="middle" style="background-color:#eee;"|Knowledge | *articleCaseToolbar, articleList, articleRendererToolbar, articleTypeList, categoryList |- |align="center" valign="middle" style="background-color:#eee;"|Messaging | *attachment, emailHeader, emailTemplate, htmlEmailBody |- |align="center" valign="middle" style="background-color:#eee;"|Site | *googleAnalyticsTracking, previewAsAdmin |- |align="center" valign="middle" style="background-color:#eee;"|미분류 | *vote |} *페이지 호출 방법 :*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 :*참조: [[Salesforce - App 설정#단추 및 링크|단추 및 링크]] ===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=== {|cellspacing="0" cellpadding="2" border="1" width="100%" bgcolor="#FFFFFF" align="center" |- |width="20%" align="center" valign="middle" style="background-color:#eee;"|탭 |width="40%"| *URLFOR($Action.개체.Tab, $ObjectType.개체) |width="40%"| */{!$ObjectType.개체}/o *'/' + Schema.SObjectType.Account.getKeyPrefix() + '/o' */001/o |- |align="center" valign="middle" style="background-color:#eee;"|목록 | *URLFOR($Action.개체.List, $ObjectType.개체) | */{!$ObjectType.개체}/l */001/l */001?fcf=00B90000002WTzh |- |align="center" valign="middle" style="background-color:#eee;"|보기 | *URLFOR($Action.개체.View, 아이디) | */00B90000002WTzh |- |align="center" valign="middle" style="background-color:#eee;"|새로 만들기 | *URLFOR($Action.개체.New) *URLFOR($Action.개체.New, null, [c_id=campaignID, parent_id=ParentId]) | */{!$ObjectType.개체}/e */001/e *RecordType을 지정하여 등록 화면 생성 :*/a09/e?RecordType=012V00000008U60IAE |- |align="center" valign="middle" style="background-color:#eee;"|편집 | *URLFOR($Action.개체.Edit, 아이디) | */00190000007Pa5U/e |- |align="center" valign="middle" style="background-color:#eee;"|삭제 | *URLFOR($Action.개체.Delete, 아이디) | |- |align="center" valign="middle" style="background-color:#eee;"|복제 | | */00190000007Pa5U/e?clone=1 |- |align="center" valign="middle" style="background-color:#eee;"|수락 | | |} *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 {|cellspacing="0" cellpadding="2" border="1" width="100%" bgcolor="#FFFFFF" align="center" |- |width="20%" align="center" valign="middle" style="background-color:#eee;"|다운로드 |width="40%"| *URLFOR($Action.Attachment.Download, 아이디) |width="40%"| |- |align="center" valign="middle" style="background-color:#eee;"|소유권 편집 | | */00190000007Pa5U/a |- |align="center" valign="middle" style="background-color:#eee;"|1열로 보기 | | */00190000007Pa5U/m |- |align="center" valign="middle" style="background-color:#eee;"|출력 양식 보기 | | */00190000007Pa5U/p |} ==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, 날짜/시간, 백분율, 숫자, 이메일, 일자, 전화, 텍스트, 텍스트 영역, 통화, 확인란 [[그림:CustomSettings001.png]] *제약 사항 : 최대 2MB *사용법 Map<String name, ~> ~.getAll() ~ = ~.getInstance(name) ~ = ~.getValues(name) [[그림:CustomSettings002.png|500px]] ~ = ~.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 설정 -> 개발 -> 사이트" [[그림:Site001.png]] [[그림:Site002.png]] ==View - 대시보드== [[그림:Dashboard001.png|600px]] ==View - Flow== [[그림:Flow001.png]] *복잡한 사용자 인터페이스를 손쉽게 개발 *"설정 -> 개인 설정 -> 내 개인 정보 -> 개인 정보" 메뉴에서 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); [[그림:Flow002.png]] ==표준 페이지 Layout== *[http://wiki.apexdevnet.com/index.php/Apex_and_Visualforce 사이트] : 풍부한 사용자 경험 제공 (RIA, Rich Internet Application) *[http://blog.naver.com/pnuskgh/50038126288 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}"/><br/> </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> ] ==참고 문헌== *[http://www.salesforce.com/ 세일즈포스닷컴] *[http://www.salesforce.com/appexchange/ AppExchange] *[http://success.salesforce.com/ SuccessForce] *[http://developer.force.com/ Developer.force.com] [[Category:Salesforce]] [[Category:Cloud]]
이 문서에서 사용한 틀:
틀:지원업체
(
원본 보기
)
Visualforce
문서로 돌아갑니다.
둘러보기 메뉴
개인 도구
로그인
이름공간
문서
토론
변수
보기
읽기
원본 보기
역사 보기
더 보기
검색
주요 메뉴
오픈소스 컨설팅
오픈소스
오픈소스 라이선스
오픈소스 커뮤니티
오픈소스 종류
오픈소스 현황
오픈소스 한글화
문자셋과 인코딩
Storage
Network
보안
고가용성
모니터링
오픈 API
오픈 서비스
Cloud
BigData
Android
산사랑 노트
둘러보기
인기 문서
최근 수정 문서
모든 문서
모든 분류
임의 문서
위키 사용법
자매 사이트
CMS
오비컨 홈페이지
오비컨 CMS
블로그
데모 - SuiteCRM
산사랑의 Twitter
산사랑의 Facebook
친구 사이트
공개SW 포털
OLIS
한국공개소프트웨어협회
AppCenter 지원본부
OLC
PSEG
개발자 블로그
블로터
개인 메뉴
메뉴 수정
양식함
도구
여기를 가리키는 문서
가리키는 글의 최근 바뀜
특수 문서 목록
문서 정보