質問

投稿者:i
登録日:2024年11月7日(木)

非同期通信について

SPIRALの仕様上、ページの一部分だけを更新させることは可能でしょうか? 添付の画面イメージで、画面全体ではなく、必要な部分のみをPHPからポストバックさせたいと考えております。具体的には、各レコード情報にリンクが設置されており、そのリンクを押下することによって各レコードに該当するデータをAPIで取得して、bodyに返したい…というイメージです。この際、画面全体を更新させるのではなく、各レコード部分だけを更新させる方法がありましたらご教示いただけますと幸いです。

更新日:2024年11月13日(水)
いいね

コメント

  • 非同期通信を利用してページの一部分だけを更新させることは可能となります。 ご連絡いただいたイメージと同じようなものとなりますが、 下記のような流れとなります。 データ取得用のページを別に作成いただき、 リンクイベントのurlパラメータにレコードID等のデータ取得用パラメータを追加して データ取得用ページに非同期通信を実施。 データ取得用ページでphpでパラメータを元にデータ取得のAPIを実行し、 取得した値を、非同期通信にて該当レコード部分と入れ替えていただく。

    • いいね
    2024年11月7日(木)
  • i

    ご回答いただきありがとうございます。 大まかな流れは理解できましたが、現在の業務において非同期通信(Ajax)に長けているメンバーがおらず、SPIRAL上で非同期通信を実装する手順が具体的に分からない状況にございます。よろしければ、SPIRAL上で非同期通信を実装したサンプルプログラム等を共有いただけないでしょうか? 一般的なAjaxのサンプルプログラムを試してみたところ、SPIRAL上では上手く動かすことができませんでした…。非同期通信に関する知識が乏しく恐縮ですが、お力添えいただけますと幸いです。

    • いいね
    2024年11月7日(木)
  • 非同期処理を実装するサンプルがございましたので、共有いたします。 「入力ページ」…その名の通り入力を行うページ(登録フォームブロック) 「PHP用ページ」…PHPを配置する通信先のページ この2つのページをご用意いただく想定で作成しております。 処理の流れとして、 入力ページの入力内容が、PHP用ページからレスポンスされた条件と 一致しているかどうかをチェックします。 一致した場合…「次へ」ボタンを活性化 不一致の場合…「false」を表示 サンプルコードの内容は以下の通りです。 ・fetch_js 入力ページで PHP用ページへ非同期通信を行うJavaScriptです。 設定値に関しては、環境に合わせて修正をお願いいたします。 ・btn_body 入力ページfetch_jsのbodyに設定するボタン部分です。 「チェック」ボタン押下で非同期通信が実行されます。 また、次へボタンを「disabled」としております。 ・check_php ・check_body PHP用ページのPHPとbodyです。 PHPでは、入力欄で「hoge」が入力されている場合「true」 、 その他の場合は「false」がレスポンスされるよう実装しております。 あくまで非同期通信の実装のサンプルのため、 組み込む際は、サンプルを元にリンクのurlにパラメータを設定いただき、 通信先のページでパラメータを元にデータ取得APIを実行するように記述してください。 また、取得したデータに置き換えるよう組み替えていただく必要がございます。 ※注意事項 PHP側に認証をかけていないため、ブラウザで開くとレコードの取得が可能な状態です。 実際に運用される場合は、パラメータによる制御や、 認証エリアに設定するなどの対策を行うようお願いいたします。

    fetch_js(1)
    document.addEventListener('DOMContentLoaded', function() {
        const checkButton = document.querySelector('.sp-form-next-button[name="check"]');
        const f01Input = document.querySelector('input[name="f0xx"]');
        const nextButton = document.querySelector('.sp-form-next-button[name="action"]');
        const checkUrl = 'https://example.com/check';
    
        if (checkButton && f01Input && nextButton) {
            checkButton.addEventListener('click', function(event) {
                event.preventDefault(); // デフォルトの動作を防ぐ
    
                // フォームのデータを取得
                const checkData = f01Input.value;
                const data = new URLSearchParams();
                data.append('checkData', checkData);
    
                // データを送信
                fetch(checkUrl, { // サーバーのエンドポイント
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    body: data.toString()
                })
                .then(response => {
                    if (!response.ok) {
                        return response.text().then(text => { throw new Error(text) });
                    }
                    return response.text(); // HTMLレスポンスをテキストとして取得
                })
    fetch_js(2)
                .then(htmlString => {
                    // HTMLレスポンスをパースしてDOMとして処理
                    const parser = new DOMParser();
                    const doc = parser.parseFromString(htmlString, 'text/html');
                    const responseElement = doc.querySelector('#response');
    
                    // サーバーからの応答を処理
                    if (responseElement && responseElement.textContent.trim() === 'true') {
                        nextButton.disabled = false;
                        console.log('サーバーからの応答:true')
                    } else {
                        alert('サーバーからの応答: false');
                        nextButton.disabled = true; // エラーが発生した場合もボタンを無効にする
                    }
                })
                .catch(error => {
                    console.error('エラー:', error);
                    alert('エラーが発生しました: ' + error.message);
                });
            });
        } else {
            console.error('要素が見つかりませんでした。');
        }
    });
    btn_body
    <div class="sp-form-item sp-form-interaction">
        <button class="sp-form-next-button" name="check" value="next" th:text="チェック">チェック</button>
        <button class="sp-form-prev-button" type="submit" name="action" value="previous" th:if="!${step.isFirst}" th:text="${step.prevButtonLabel}">Prev</button>
        <button class="sp-form-next-button" type="submit" name="action" value="next" th:text="${step.nextButtonLabel}" disabled>Next</button>
      </div> 
    check_php
    <?php
    $checkData = $SPIRAL->getParam("checkData");
    if($checkData == "hoge"){
        $response = "true";
    }else{
        $response = "false";
    }
    $SPIRAL->setTHValue("response",$response);
    check_body
    <th:block th:if="${cp.result.isSuccess}">
        <!-- PHP正常完了した場合に表示 -->
        <p id="response" th:text="${cp.result.value['response']}"></p>
    </th:block>
    <th:block th:if="${!cp.result.isSuccess}">
        <!-- PHPにエラー起こった場合に表示 -->
        <p th:text="${cp.result.errorMessage}">error message</p>
    </th:block>
    • いいね
    2024年11月8日(金)
  • i

    サンプルプログラムを試したところ、非同期通信のレスポンス(true/false)によって、JavaScript内で分岐を行なっていたように見受けられました。 まず、今回のような非同期通信の場合、サーバーからは必ず「true」または「false」の情報が返ってくるという認識で合っておりますか? また、実際には、非同期通信を用いてSPIRALのファイルダウンロードAPIを実行したいのですが、その結果をJavaScriptに渡す方法がありましたら共有いただけないでしょうか? 結果は、バイナリデータを想定しております。 イメージですが、非同期通信のレスポンス(true/false)と同時に、ファイルダウンロードAPIの結果(バイナリデータ)をJavaScriptに返したいと考えております。 前提の知識に誤りがある可能性がありますが、ご回答のほどよろしくお願いいたします。

    • いいね
    2024年11月12日(火)
  • >今回のような非同期通信の場合、サーバーからは必ず「true」または「false」の情報が返ってくるという認識で合っておりますか? 今回のサンプルでのレスポンスは「true」または「false」ですが、あくまでそう値を返すように設定しているだけで、 非同期通信のレスポンスは、必ず「true」または「false」の情報が返ってくるものではありません。 非同期通信ではBODYに出力された内容を、Javascriptで受け取っております。 phpでファイルダウンロードAPIを実行し、バイナリデータをBODYに出力いただくことで、 JavaScriptで受け取ることができます。 下記にファイルダウンロードAPIの記事を共有いたします。 お試しいただけますと幸いです。 ▼APIメソッドごとのサンプルコードまとめ Record File ファイルダウンロードメソッド https://knowledge.spirers.jp/article/development/detail/5503

    • いいね
    2024年11月13日(水)
あなたもログインして、
回答してみませんか?