LoginSignup
3
0

More than 1 year has passed since last update.

【Salesforce Visualforce】実行ボタンの2度押し防止(スピナー)

Last updated at Posted at 2021-11-08

はじめに

Visualforceで画面を作成していて、実行ボタンが2度押しされたことはないでしょうか?

ブラウザのタブで実行中のクルクルが回ってますが、あれ押したかな?動いているのかな?とユーザはお構いなしにボタンを何度も押すことが多いようです。

その対策として、ユーザにも分かりやすいように、処理中だと画面で分かるようにし
かつ、2重実行が出来ないようにしたいと思います。

※Lightning Web Conponent等を利用すれば簡単にできそうですが
 すでにVisualforceで作成してしまっているので、そちらで実現をしたいと思います。

いろんなやり方はあると思いますが、今回は動画ファイル不要のCSSだけのもので実現をしています。

実装概要

実行ボタンを押した時に、実行中を示す(スピナー)を表示させ、ユーザの2度押しを防止する。

実装イメージ

image.png

サンプルコード

<apex:page lightningStylesheets="true" docType="html-5.0" recordSetVar="tests" standardController="test__c" extensions="TestDataCreate">

    <!-- jQuery -->
    <apex:includeScript value="{!$Resource.jquery}"/>

    <apex:form >
        <apex:pageMessages />
        <apex:pageBlock >
            <apex:pageBlockSection >
                <apex:selectList value="{!year}" size="1" label="年度">
                    <apex:selectOptions value="{!yearList}" />
                </apex:selectList>
            </apex:pageBlockSection>
            <apex:pageBlockButtons location="bottom">
                <apex:commandButton value="作成" onclick="return confirmExecAction();" action="{!create}"/>
            </apex:pageBlockButtons>
        </apex:pageBlock>
    </apex:form>

    <div id="overlay">
        <div class="cv-spinner">
            <span class="spinner"></span>
        </div>
    </div>

    <script type="text/javascript">
        // action実行確認
        function confirmExecAction() {
            if (window.confirm("実行します。よろしいですか?")) {

                $("#overlay").fadeIn(500); //二度押しを防ぐloading表示
                setTimeout(function() {
                    $("#overlay").fadeOut(20000);
                }, 20000);

                return true;
            }

            return false;
        }
    </script>

    <style>  
        #overlay{
            position: fixed;
            top: 0;
            left: 0;
            z-index: 999;
            width: 100%;
            height:100%;
            display: none;
            background: rgba(0,0,0,0.6);
        }
        .cv-spinner {
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
        }
        .spinner {
            width: 80px;
            height: 80px;
            border: 4px #ddd solid;
            border-top: 4px #999 solid;
            border-radius: 50%;
            animation: sp-anime 0.8s infinite linear;
        }
        @keyframes sp-anime {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(359deg); }
        }
        .is-hide{
            display:none;
        }
    </style>
</apex:page>

説明

<apex:pageBlockButtons location="bottom">
    <apex:commandButton value="作成" onclick="return confirmExecAction();" action="{!create}"/>
</apex:pageBlockButtons>

onclickで実行確認のダイアログ、スピナー実行のjavascriptを呼び出しています。

<!-- jQuery -->
<apex:includeScript value="{!$Resource.jquery}"/>

jQueryを使用している為、登録済み静的リソースを呼び出し

<style>  
    #overlay{
        position: fixed;
        top: 0;
        left: 0;
        z-index: 999;
        width: 100%;
        height:100%;
        display: none;
        background: rgba(0,0,0,0.6);
    }
    .cv-spinner {
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
    }
    .spinner {
        width: 80px;
        height: 80px;
        border: 4px #ddd solid;
        border-top: 4px #999 solid;
        border-radius: 50%;
        animation: sp-anime 0.8s infinite linear;
    }
    @keyframes sp-anime {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(359deg); }
    }
    .is-hide{
        display:none;
    }
</style>

spinner用cssです。

<script type="text/javascript">
    // action実行確認
    function confirmExecAction() {
        if (window.confirm("実行します。よろしいですか?")) {

            $("#overlay").fadeIn(500); //二度押しを防ぐloading表示
            setTimeout(function() {
                $("#overlay").fadeOut(20000);
            }, 20000);

            return true;
        }

        return false;
    }
</script>

確認ダイアログを表示
 ・OK     ・・・ spinnerを表示させ、actionを実行
 ・キャンセル ・・・ actionを中止

今回処理時間が長めなのでtimeout値を多めにとっています。
CSSは直接書いていますが、複数の機能で使用する場合は、共通のCSSとして静的リソースに登録をしてしまったほうがよいかと思います。

その他

今回は使用していないので未検証ですが、ajaxを利用する場合は以下のようなコードになります。

<script>
    $(".sbmitbtn").on("click", function(){
        $(document).ajaxSend(function() {
            $("#overlay").fadeIn(500);
        });
        $.ajax({
            type: 'GET',
            success: function(data){
                console.log(data);
            }
        }).done(function() {
            setTimeout(function(){
                $("#overlay").fadeOut(500);
            },3000);
        });
        return false;
    });
</script>
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0