色々な方法でスタイルを指定してみます

Visualforceに対して色々な方法でスタイルを指定してみます。

Webページであれば、CSSファイルを外部ファイルとして
参照しているケースが多いと思いますが、Visualforceでは
静的リソース にCSSファイルを置いて、参照すればよさそうです。

また、Zipファイルにまとめた場合、圧縮しているパスを指定して
CSSファイルを参照すればOKです。

こんな感じですね。

{!URLFOR($Resource.common, 'style.css')}

TestStyle.css(静的リソース「TestStyle」)

.sample {
   color: #F00;
   font-style: italic;
}

style.css(静的リソース「common」)

.main {
   background-color: #ccc;
}

common.zipとして静的リソースを登録しています。

Visualforceページ

<apex:page standardstylesheets="false" sidebar="false" showheader="true">

    <apex:stylesheet value="{!$Resource.TestStyle}" />
    <apex:stylesheet value="{!URLFOR($Resource.common, 'style.css')}" />

    <style>
        [id*=myid] {
            font-weight: bold;
            color: #F00;
            background-color: #DDF;
        }
    </style>
    
    <p><h1>色々な手法でスタイルを指定してみる</h1></p>

    
    <p><apex:outputtext style="font-weight: bold; background-color: #DFD;" value="これは要素に直接スタイルを指定" /></p>

    <p><apex:outputtext id="myid" value="これは DOM ID からスタイルを指定" /></p>

    <p class="sample">apex:stylesheet にて teststyle 静的リソースからスタイルを指定</p>  
    
    <div class="main">
        <p>aepx:stylesheet にて common.zip の style.css 静的リソースからスタイルを指定</p>
        <p>{!URLFOR($Resource.common, 'style.css')}</p>
    </div>

    <br />

</apex:page>

実行結果

f:id:MNakayama:20160315181327j:plain


あとは通常のHTMLのCSS当て方と一緒ですね。
1点だけ、勉強になったのは、IDへのスタイル設定です。

VisualforceではIDが階層のように XXX:YYY:ID01 という感じで
自動で割り当てられてしまうのですが、

CSSセレクタに[id*=ID01]という形で、記述しておけば
「含まれていれば」と設定できるので、覚えておけば便利そうです。
でもidにスタイルはあまり推奨されないかな、、できれば class の方が良いかもですね。

日々精進。ほんならね~

まずはここからVisualforce Componentの基本的な作成

apexでカプセル化されているメソッドなどは再利用ができるようになっています。
VisualforceComponent も同じ考えで、HTMLやVFPageなどを再利用できるような機能です。

VisualforcePageから < c:(Component名) > という感じで呼び出せます。

また、Component側に attribute を持たせて、引数のように
親から値を渡すことができます。

サンプルで、PageからComponentを呼び出し、
テキストとカラーコードを渡して表示させます。

Visualforce Component

Component名 CustomComponentSample としました

<apex:component>
    
    <apex:attribute name="text" description="テキストの内容"
        type="String" required="true" />
    <apex:attribute name="color" description="カラーコード"
        type="String" required="true" />
    
    <div style="border: 1px solid #ccc; padding: 20px;">
            
        <h1>Componentのコンテンツです</h1>
        <h1 style="color:{!color}; ">
            <apex:outputtext value="{!text}" />
        </h1>
    </div>

</apex:component>

Visualforce Page(呼び出し側)

<apex:page>

  <h1>Visualforce</h1>
  <p>ページのコンテンツ</p>

  <c:CustomComponentSample text="最初のコンポーネント" color="#FF0000" />
  <c:CustomComponentSample text="2個目のコンポーネント" color="#00AA00" />
  <c:CustomComponentSample text="3個目のコンポーネント" color="#0000FF" />
  
</apex:page>

実行結果

f:id:MNakayama:20160302191221j:plain

他にもComponentにはクラスを持たせたり色々使いどころがありそうです。
日々精進。ほんならね~。

StandardControllerに拡張クラスを付ける

さっと作れそうだったのでメモ。

Visualforceページの standardcontroller にオブジェクトを指定を
ますは指定します。(今回はAccountを指定)

続けて、extensions に拡張したいクラスを指定します。
クラスのコンストラクタには、ApexPages.StandardController を引数で指定しておく。
これは、SFIDで指定されたレコードらしいです。
クラス内では getRecord() で取得できるみたいです。


Visualforceページ

<!-- SFIDを付けて表示する -->
<apex:page standardcontroller="Account" extensions="extensionsClass">
  <h1>{!exText}</h1>
   <apex:detail /> 
</apex:page>

Class

public class extensionsClass {
    
    public String exText {get; set;}
    
    private final Account acc;
    
    public extensionsClass(ApexPages.StandardController controller) {
        
        this.acc = (Account)controller.getRecord();

        exText = acc.Id + '(拡張で付与しています)';
        
    }
    
}

実行結果

.../apex/StandardControllerSample?id=0011000000w1Qdc
のようにSFIDパラメータを付けて表示
f:id:MNakayama:20160301122043j:plain
h1 に拡張クラスで作成したテキストが表示できました。

参考

https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/apex_pages_standardcontroller.htm

【いまさらネタ】static(静的)について理解してみた

Apexは基本javaと同じなので、staticの考えは一緒です。
仕事で利用しているにも関わらず、
書かれているコードに対して、なぜつける必要があるんだっけ?
とか、説明ができなかったりと、、

見慣れているはずなのに、あれ?これってなんだっけ?
てなって、あー理解してなかったな、、と改めて感じました。

ということで、以下サイトを参考に勉強しました。
【Java】 staticって何? | 一番かんたんなJava入門

ふむふむ、なるほど。

インスタンスに属するか、クラスに属するか、という事だったのか。
後者がstaticなメンバとなる。

実際にapexで書いてみよう。

humanクラス

public class human {

    public static integer human_cnt = 0;

    public string name;
    
    public human(String name) {
        human_cnt += 1;
        this.name = name;
    }

    public static void testcall() {
        system.debug('human_cnt:' + human_cnt);
    }
}

実行するApexコード

// インスタンス作成
human h1 = new human('太郎');
human h2 = new human('次郎');
human h3 = new human('三郎');

// h1インスタンスの名前
system.debug(h1.name);

// humanの件数
system.debug(human.human_cnt);

// human(静的)メソッドの呼び出し
human.testcall();

実行結果

f:id:MNakayama:20160225154506j:plain

humanクラスを用意して、h1,h2,h3のインスタンスを作成、
nameメンバはそれぞれのインスタンスに属している。
(h1.name は 太郎、といった感じ)

human_cntメンバはクラスが持っているので、
human.human_cntのような感じで呼び出せる。
メソッドの呼び出しも同様。

この場合、h1.human_cnt や human.name などは属している
領域が違うのでコンパイルエラーになる。

もやもやがとれて頭がすっきりしました。
日々精進。ほんならね~