Visualforce

오픈소스 비즈니스 컨설팅
이동: 둘러보기, 검색

Force.com중 Visualforce를 정리 합니다.

Visualforce Overview

Page Overview

VfPage01.png VfPage02.png

Page Lifecycle

VfPageLifecycle.png

  • 버그(오류) 사항
  • 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}

CustomButton001.png

  • 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>
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
  • page, pageMessage, pageMessages
  • scontrol
Look & Feel
  • pageBlock, pageBlockButtons, pageBlockSection, pageBlockSectionItem, pageBlockTable
  • panelBar, panelBarItem, sectionHeader
  • tab, tabPanel, toolbar, toolbarGroup
List
  • dataList, dataTable, facet, column (/w inputField)
  • panelGrid, panelGroup
  • repeat, detail
  • enhancedList, listViews, relatedList
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
AJAX
  • actionSupport, actionStatus, actionPoller, actionFunction, actionRegion
동적 화면 구성
  • component, attribute, componentBody, variable
  • composition, define, insert
  • include, includeScript, stylesheet, iframe, flash
  • dynamicComponent
Chatter
  • feed, feedWithFollowers, follow, followers
Workfow
  • interview
Ideas
  • detailOutputLink, listOutputLink, profileListOutputLink
Knowledge
  • articleCaseToolbar, articleList, articleRendererToolbar, articleTypeList, categoryList
Messaging
  • attachment, emailHeader, emailTemplate, htmlEmailBody
Site
  • googleAnalyticsTracking, previewAsAdmin
미분류
  • vote
  • 페이지 호출 방법
  • 반복문
<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

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($Action.개체.Tab, $ObjectType.개체)
  • /{!$ObjectType.개체}/o
  • '/' + Schema.SObjectType.Account.getKeyPrefix() + '/o'
  • /001/o
목록
  • URLFOR($Action.개체.List, $ObjectType.개체)
  • /{!$ObjectType.개체}/l
  • /001/l
  • /001?fcf=00B90000002WTzh
보기
  • URLFOR($Action.개체.View, 아이디)
  • /00B90000002WTzh
새로 만들기
  • URLFOR($Action.개체.New)
  • URLFOR($Action.개체.New, null, [c_id=campaignID, parent_id=ParentId])
  • /{!$ObjectType.개체}/e
  • /001/e
  • RecordType을 지정하여 등록 화면 생성
  • /a09/e?RecordType=012V00000008U60IAE
편집
  • URLFOR($Action.개체.Edit, 아이디)
  • /00190000007Pa5U/e
삭제
  • URLFOR($Action.개체.Delete, 아이디)
복제
  • /00190000007Pa5U/e?clone=1
수락
  • 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
다운로드
  • URLFOR($Action.Attachment.Download, 아이디)
소유권 편집
  • /00190000007Pa5U/a
1열로 보기
  • /00190000007Pa5U/m
출력 양식 보기
  • /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

~ = ~.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에서 호출 방법
  • 오류에 대한 조치
  • 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

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

Overview

로그인 후에 사용할 수 있는 Visualforce Page로 사이트에서 사용시 로그인 없이도 접속이 가능 합니다.

  • 호출 URL
<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> ]

참고 문헌

지원 업체

SuiteCRM을 사용한 영업관리, 고객관리는 아래 담당자에게 연락하여 주시면, 빠르고 친절하게 전문적인 답변을 드리겠습니다.

영업 문의 sales@obcon.biz 010-4667-1106 영업 대표
기술 문의 tech@obcon.biz 구축/컨설팅 담당
고객 지원 support@obcon.biz 고객 지원 담당

OBCon 홈페이지 바로가기