cybozu developer network

カテゴリー内の他の記事

Geolocation API(位置情報)を使ったモバイル用のカスタマイズをしよう

2020年8月改訂のセキュアコーディング ガイドラインに抵触する内容が含まれています。認証情報が漏洩した場合の影響を考慮して慎重に検討してください。
該当箇所:JavaScriptプログラムの10行目

(著者:kintoneエバンジェリスト 山下 竜

kintoneではスマートフォン用のJavaScriptも収容できるようになり、関連する情報も充実してきました。
これでモバイルでの用途・使いやすさは更に増していくことと思います。

今回は、HTML5の標準APIのひとつであるGeolocation APIを使ったシンプルなkintoneモバイルアプリを作ってみたいと思います。
kintoneに保存するデータとして場所と時間を一緒に押さえておくことで、便利に使えることがあります。
現場の懸案管理、訪問管理など屋外の動向管理に役に立つと思いますので、お試し頂ければと思います。

やや長めですが、お付き合い頂ければ幸いです。

※ サンプルでは、地図の常時にGoogle Maps PlatformのMaps JavaScript APIを使用しています。
ご利用方法によっては有償ライセンスの購入が必要になる場合があります。Googleのライセンスをご確認ください。

準備とJavaScriptの適用方法

次のフィールドを含むアプリをご準備ください。

フィールドタイプ フィールド名(例) フィールドコード
文字列(1行) 緯度 lat
文字列(1行) 経度 lng
スペース Map
レコード番号 レコード番号 record_no

 

JavaScriptの適用方法としては「JavaScriptソースコード」をsample.js等ファイル名を付けて保存し、、「PC用のJavaScriptファイル」と「スマートフォン用のJavaScriptファイル」にそれぞれ同じファイルをアップしてください。(※ソースコードは下記に記載しています。)

出来上がりイメージ(モバイル画面)

見た目は、公式サンプルの「レコード一覧で顧客訪問リストを地図にピン表示する」と似たような感じになります。違うのは緯度経度の取得方法で、登録済みレコードの詳細画面で「緯度経度更新」ボタンを押すことで、緯度経度の値を更新することがきます。

JavaScriptソースコード

11行目の「YOUR_GOOGLE_MAPS_JAVASCRIPT_API_KEY」の部分を取得したMaps JavaScript APIキーに書き換えてください。

ソースコードの説明

「レコード一覧で顧客訪問リストを地図にピン表示する」との違いは次の3ポイントですので、この辺りを中心にご説明します。

  • 緯度経度をGeolocation APIで取得
  • スマートフォンに対応
  • PC用とスマートフォン用のJavaScriptを1つのファイルに記述(イベント以外の関数の共用)

【一覧画面で地図を配置する要素の設定】

やはりPC用とスマホ用で違ってきます。スマホ用ではスクロールに耐えられるよう高さを150pxとしました。また、PC用とスマホ用でヘッダースペース要素の取得関数が「kintone.app.getHeaderSpaceElement(PC用)」と「kintone.mobile.app.getHeaderSpaceElement(スマホ用)」で異なるため、これらを使い分けます。

【詳細画面における地図を配置する要素の設定】

ここもPC用とスマホ用で違ってきます。PC用では要素IDが「Map」のスペースフィールドに、スマホ用では、「kintone.mobile.app.getHeaderSpaceElement」に対応する要素に配置します。合わせて、PC用では、親要素のサイズを変更しておきます。

【緯度経度を取得し、レコードを更新する関数】

Geolocation APIで取得した値を用いてレコード(緯度、経度)を更新します。

【注意事項】

今回の注意点は次の通りです。

  • 筆者はMacintoshのGoogle ChromeとiOS7のSafariで動作確認を行っています。
  • 「addEventListener」はブラウザによって対応が異なるので、それぞれご確認ください。
  • 今回は地図ライブラリとして「Google Maps API」を用いていますが、ライセンス等利用に関する制限は各自でご確認ください。

最後に

やや長めのTipとなってしまいましたが、いかがでしたでしょうか?今回はGeolocation APIを利用することで、タブレットやスマホからのレコード登録に合わせて位置情報を取り込む例をご紹介しました。

クラウドはモバイルとの親和性を高めることでより便利に使うことができますが、現状ではスマホ用のサンプルも少ないので、皆さまの参考になれば幸いです。

変更履歴

  • 2019/04/05
    • Maps JavaScript API キーを使用したコードに修正
  • 2019/06/07
    • PC版とスマートフォン版での処理を共通化(スマートフォン版のレコード一覧表示イベントで event.records 取得可能になったため)

このTipsは、2019年5月版 kintoneで確認したものになります。

記事に関するフィードバック

記事のコメント欄は記事に対するフィードバックをする場となっております。
右の記事フィードバックのためのガイドを参照してコメントしてください。
記事のリンク切れなど、気になる点がある場合も、こちらのフォームからフィードバックいただけますと幸いです。

Avatar
Eriko

いつも大変お世話になっております。
こちらの地図表示ですが、緯度経度ではなく住所で表示することは可能でしょうか?
もし可能であれば、サンプルコードをいただけるとありがたいです。

Avatar
にしかわ

Erikoさん
http://www.geocoding.jp/api/

住所から緯度経度を取得できそうなので、住所フィールドを用意しておいていっかい変換をかける感じでつくればいけるかと思います。

Avatar
橋本恵子

橋本です。

納品設置場所の地図を登録したいという話の中、納品場所によっては住所の番地では表示できない場所があり

現地に行った際に緯度・経度で地図表示・登録が出来るこちらのコードはまさに!といった感じです。

GPSでの緯度経度の取得だと、場所によっては微妙にずれます。

ピンを刺す場所を手動で指定するようには変更できないものでしょうか?

 

Avatar
cybozu Development team

橋本様

developer network事務局です。ピンを手動指定とは、具体的にはどのようなイメージでしょうか?

 

Avatar
橋本恵子

橋本です。

説明が雑ですみません。

自分のいる現在地を地点登録をしたいのですが、GPSでの登録だと微妙にずれるので、地図上の任意の位置に

しるしをつけた地図画面をKintone上に表示できるようにならないかという意味でした。

 

Avatar
cybozu Development team

橋本様

詳しいご説明をありがとうございます。地図上の緯度と経度を取得するには、Google Map APIでできるはずですので、手動取得用のボタンを別に作ってGoogle Map APIから取得するようにすれば実現可能だと思います。

Avatar
a_o_admin

お世話になっております。

本サンプルコードを参考にさせて頂きカスタマイズをしています。

現在スマートフォン版の実装で行き詰まっています。

下記のサンプルコードですとrecode_noを降順に全レコード出力することになりますが、

// スマホ用では、eventにrecordsはないのでAPIで直近の分を取得
var appUrl = kintone.api.url('/k/v1/records') + '?app='+ event.appId + '&query=' + encodeURI('order by record_no desc&fields[0]=record_no&fields[1]=lat&fields[2]=lng');

レコード絞込でプルダウンでレコードを絞り込んだタイミングで
絞込と同様の検索を上記の kintone.api.url(…で実現するにはどうすればよいでしょうか?
絞り込み条件の取得の仕方、その条件をクエリに入れ込む記法等がわかりませんでした。
お手数ですがご教授のほどよろしくお願いいたします。

Avatar
cybozu Development team
a_o_admin様
 
ご質問いただきありがとうございます。cybozu developer network運営チームです。
 
モバイルではkintone.app.getQueryを使えないので、location.href を使って一覧のURLを取得する方法があると思います。
具体的に、次のように指定した絞り込み条件を満たす一覧画面が表示されたタイミング(一覧表示event)でURLを取得します。
例:
    kintone.events.on("mobile.app.record.index.show", function(e) {
        var appUrl = location.href;
   
    })
 
上記サンプルコードの105行目のところ、次のように書き換えれば行けるかと思います。
} else if(event.type == "mobile.app.record.index.show"){ // スマホ用
   // スマホ用では、eventにrecordsはないのでAPIで直近の分を取得
 var appUrl = location.href;  
   
queryの指定方法について、次のページは参考になるかと思います。
Avatar
a_o_admin

cybozu developer network運営チーム ご担当者様

お世話になっております。ご回答ありがとうございます。

最終的に、絞り込み条件を満たす一覧画面のJSONを取得したいのですが、ご提案頂いたソースだと取得できませんでした。

location.hrefで取得したHTMLの中から絞り込み条件(cybozu.data.page['QUERY_STRING'])を取得すればいいのかと思いましたが、

cybozu.data.page['QUERY_STRING']以降の値を取得する処理を自作しなければいけないものなのでしょうか?

当方あまりJavascriptに明るくないので、申し訳ありません。ご回答の程よろしくお願いします。

 

Avatar
cybozu Development team

a_o_admin様

ご質問いただきありがとうございます。cybozu developer network運営チームです。

失礼しました。location.hrefだと、クエリ以外の部分も取得しますね。

location.searchを使えば、絞り込み条件を取得できます。

例:var qr = location.search;
  console.log(qr);  → ?view=20&q=f5318666%20%3E%3D%20LAST_WEEK()

ただし、必要なのは「q=f5318666%20%3E%3D%20LAST_WEEK()】だけですが、?view=20が入ってしまいますので、

/q=(.*?)(&|$)/ で 2番目のパラメータを取れるかと思います。

詳細は次のページをご参考ください。

http://did2memo.net/2015/12/28/javascript-url-parameter/

 

Avatar
a_o_admin

cybozu developer network運営チーム ご担当者様

お世話になっております。ご回答ありがとうございます。

kintoneはクエリまで出力する仕様なのでしょうか?

PC版、スマホ版両方で試してみましたが、 location.search;ですと 例にある ?view=20 部分しか取得できないようです。

 

ご回答の程よろしくお願いします。

 

 

Avatar
cybozu Development team

a_o_admin様

大変申し訳ございませんが、改めてa_o_admin様のコメントを読ませていただいたところ、

「レコード絞込でプルダウンでレコードを絞り込んだタイミングで」のところに認識がずれていることに気づきました。


をクリックして絞り込み条件を変えてレコードを絞り込んだタイミングではなく、

から一覧を切り替えたタイミングですよね?

一覧を切り替える場合、 location.searchを使って?view=20部分しか取れません。
「一覧の設定の取得」APIを使えば、レスポンスとして返ってくる「views.(ビュー名).filterCond」には絞り込み条件が入っています。
詳細は「一覧の設定の取得」をご参考ください。
https://cybozudev.zendesk.com/hc/ja/articles/204529784

ソースコード例:
(function() {
  "use strict";
  kintone.events.on("mobile.app.record.index.show", function(e) {

        var body = {
        "app": 1,
         "lang": "ja"
         };

        kintone.api(kintone.api.url('/k/v1/app/views', true), 'GET', body, function(resp) {
           // success
           console.log(resp);
       }, function(error) {
         // error
      console.log(error);
         });
     });
})(jQuery);

たびたび申し訳ございませんでした。
よろしくお願いいたします。

cybozu Development teamにより編集されました
Avatar
a_o_admin

cybozu developer network運営チーム ご担当者様

お世話になっております。

返信遅くなりました。

ご回答ありがとうございます。なんとか目的の通り実装できました。ありがとうございました。

Avatar
nishida316

お世話になります。
このスクリプトを試用してみましたところ、PC側では緯度経度更新ボタンが機能するのですが、
モバイル(iPhone8側)ではボタンを押しても地図が表示されません。。。
実装の際に何か注意点などございますでしょうか?

Avatar
cybozu Development team

nishida316さん

コメントありがとうございます。cybozu developer network運営事務局です。

こちらのTipsはPC版のみに対応したものになります。PCとモバイルでは指定するイベント名が違うためです。
(例)
PC: app.record.index.show
モバイル: mobile.app.record.index.show

PC版のイベントで可能な操作が、モバイル版だと不可能な場合もありますので、それぞれのイベント情報をご確認ください。
https://developer.cybozu.io/hc/ja/articles/201941954

Avatar
nishida316

お世話になります。早速ありがとうございました。iPhoneのブラウザではきちんと動作いたしました。

Avatar
Ryu Yamashita

@cybozu Development team @nishida316

このTipsはPCビューとモバイルビューのカスタマイズファイルを同じファイルで極力共用するしているところも技術的ポイントで、そのため「準備とJavaScriptの適用」で触れている通り同じカスタマイズファイルを「PC用」と「モバイル用」に適用できるようにしていますし、コードをよく見ていただくとわかりますが、同一ファイル内でPC用とモバイル用のイベントを書き分けています。

(Geolocation APIを使おうというのに、PCオンリーという想定はちょっとツラいシナリオ想定になっちゃいますので)

 

先ほど、iPhone XのSafari/Chromeですが「出来上がりイメージ(モバイル版)」にあるモバイルビューの動き手元で確認できました(モバイルアプリは執筆時点から確認されてないため確認していません)。

JS設定画面で、モバイル用のファイルとしてもアップロードされているとすると、固有の原因も想定して、モバイルブラウザ用のツールを用いて調べられるのがよろしいかと思います。

 

また、このTipsから記載が外れたように思いますが、確認は2014年5月時点で、Google Maps APIの利用方法もライセンス以外にもアップデートが現状必要な状況かと思いますので、ライセンス購入されてて実運用を目指されるとすると、書き換えが必要な部分がままあるかと思いますので、ご注意いただくのが良いかと思います。

Avatar
nishida316

お世話になります。
詳細に教えて頂きありがとうございました。

Avatar
cybozu Development team

nishida316さん、Ryu Yamashitaさん

誤ったご案内で大変失礼しました。Ryu Yamashitaさん、ご丁寧にフォローしていただきありがとうございます。

Avatar
kita-san

スマホアプリが更新されました。スマホ表示のheight:を変更して表示したら、レコードが真ん中に表示されます。

どうしたらよいのでしょうか?

Avatar
cybozu Development team

kita-san 様

お世話になっております、cybozu developer network事務局です。

ご指摘の点ですが、弊社環境でも再現いたしました。
モバイルに関するアップデートが行われたばかりでもあるため、
原因の確認を進め、本件の対応につきまして、改めてこちらでご報告させていただきます。

ご不便をおかけして申し訳ございません。

Avatar
kita-san

わかりました。

旧表示で使います。

また、報告をお待ちしております。

ご連絡ありがとうございました。

Avatar
cybozu Development team

kita-san 様

お世話になっております、cybozu developer network事務局です。
ご指摘いただいた内容ですが、サイボウズ開発も現象を認識しており、現在修正を行っております

修正され次第、再度ご案内させていただきますので、
今しばらくお待ちいただけますと幸いでございます。

ご迷惑をおかけし申し訳ございませんが宜しくお願いいたします。

Avatar
Nami SATO

お世話になっております。

こちらのサンプルソースですが,

app.record.create.submit'および'mobile.app.record.create.submit'の時に,レコード登録画面からのみ,ボタンクリックをイベントハンドラとして実装したい場合,

主にどのあたりの記述を修正すれば良いか,アドバイス頂けませんでしょうか?

・ソースコードの規模が大きく,修正点が全体にあるようにも見えるのですが,その認識は合っていますでしょうか?

・19,28,37行目の取得する要素をフィールドにする必要があると考えています。

function detailShow(event)およびfunction indexShow(event) の構文がKintoneAPI等の説明ページを見ても分からない状況です。これは349行目以降のイベントハンドラにて実行される関数になっている,ということでしょうか?

Nami SATOにより編集されました
Avatar
cybozu Development team

SAT 様

お世話になっております。

レコード登録画面にボタンを配置し、ボタンクリックで動作させたいということでしょうか?
ボタンのクリック時に処理を動作させる方法は、以下の記事を参考にしてください。

19,28,37行目は、地図を描画する場所の要素を取得している箇所です。
地図を表示する場所を変えたい場合は書き換えていただく必要があります。

 

イベントハンドラーの登録について、本記事での書き方についてご説明します。

イベントハンドラーを登録する

kintone.events.on(event, handler(event))

本記事サンプルコード349行目

kintone.events.on(['app.record.index.show', 'mobile.app.record.index.show'], indexShow);

サンプルコード349行目末尾の「indexShow」が、「イベントハンドラーを登録する」ドキュメントの関数に記載されている「handler(event)」にあたります。
つまり、349行目では「レコード一覧画面を開いたとき、indexShow関数を実行する」ということを実行しています。
indexShow関数はサンプルコードの63~66行目です。
※indexShow関数はloadGMap、waitLoaded関数を実行しています。処理の詳細はそれぞれの関数内をご確認ください。

関数の使い方については、以下の記事が参考になります。
はじめようJavaScript第9回 JavaScriptの基本機能 関数を使う その1

なお、こちらは記事のフィードバック欄です。
サンプルコードに書き換えについてご不明点がありましたら、コミュニティをご活用ください。
よろしくお願いいたします。

Avatar
てん

いつもお世話になっております。

 

提供いただいているコードをそのまま用いてサンプルアプリを作成してみました。

Google Map の仕様変更に伴い、一部 コードを更新し、API キーを組み込みましたが、下記画像のところまでしか実装できておりません。

 

「OK」ボタンを押せばそのポップアップは消えるものの、暗い画面で「For Development Purpose Only」という表示が残ってしまいます。

これ以上は、Google Map の有償契約をしなければ説明いただいているような表示にはならないでしょうか?

 

 

 

 

 

Avatar
cybozu Development team

てん 様

お世話になっております。cybozu developer network事務局です。

「For Development Purpose Only」という表示は、Google Map の有償契約をしなければ消えません。
ただ、1 か月 $200までであれば無料で利用できるようです。料金については、Google Maps Platform のHPをご確認ください。

Avatar
てん

cybozu developer network事務局 ご担当社 様

 

早速のお返事ありがとうございます。

また、参考情報までご提示いただき助かりました。

 

今後とも宜しくお願い致します。

Avatar
fttbs

お世話になっております。
編集画面を開いて保存をする際に下記のエラーが発生致します。

You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors.

こちらは無視してもいいものでしょうか。動作におかしい点は見当たりません。
宜しくお願い致します。

fttbsにより編集されました
Avatar
cybozu Development team

fttbs 様

お世話になっております。cybozu developer network 事務局です。

You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors.

上記のエラーは Google Maps Javascript API を複数回実行している際に出力されるものです。
コンソール画面に表示されるエラーについてはデバッグすることをおすすめいたします。

まずは、ご自身が適用している Javascript ファイルに API を実行するソースコードが重複していないか等、ご確認いただければと思います。

そのほか、記事をもとにした発展的な内容や、記事を参考にした技術的な質問については cybozu developer network コミュニティも合わせてご利用ください。

サインインしてコメントを残してください。