2016年7月26日火曜日

夏休み前の最後のゼミです!

さて、今日は夏休み前の最後のゼミです。先週は、サーバからJSON形式で患者一覧情報と患者受診一覧情報を受け取り、それを画面に表示するプログラムを作成しました。今日は、その応用で、JSON形式ではなくXML形式で患者一覧情報と患者受診一覧情報を受け取り、それを画面に表示するプログラムを作成します。

患者一覧XMLデータ

Ajaxで取得する患者一覧のXMLデータです。このデータは次のURLで取得します。
http://172.16.108.250/~semi2015/XML/getPatientList.php
JSON形式と違ってXMLタグで各データ要素の意味が明確です。
<?xml version="1.0" encoding="UTF-8"?>
<patientList>
  <patient>
    <id>A0001</id>
    <name>在本 璃奈</name>
    <gender>female</gender>
    <birthdate>1996/4/1</birthdate>
    <address>岡山県倉敷市山田町1丁目-2-3</address>
  </patient>
  <patient>
    <id>A0002</id>
    <name>清水 伸平</name>
    <gender>male</gender>
    <birthdate>1995/5/10</birthdate>
    <address>岡山県岡山市苦米地3丁目-5-6</address>
  </patient>
  <patient>
    <id>A0003</id>
    <name>田中 昌昭</name>
    <gender>male</gender>
    <birthdate>1958/7/6</birthdate>
    <address>岡山県瀬戸内市大岡5丁目-9-8</address>
  </patient>
</patientList>

患者受診一覧XMLデータ

続いて患者受診一覧のXMLデータです。このデータは、以下のURLで取得します。
http://172.16.108.250/~semi2015/XML/getVisitData.php
<?xml version="1.0" encoding="UTF-8"?>
<visitData>
  <patient id="A0001">
    <visit>
      <date>2016/5/20</date>
      <dept>内科</dept>
      <diseaseName>気管支炎</diseaseName>
    </visit>
    <visit>
      <date>2014/1/29</date>
      <dept>外科</dept>
      <diseaseName>大腿骨骨折</diseaseName>
    </visit>
    <visit>
      <date>2015/8/6</date>
      <dept>耳鼻科</dept>
      <diseaseName>中耳炎</diseaseName>
    </visit>
  </patient>
  <patient id="A0002">
    <visit>
      <date>2016/3/19</date>
      <dept>内科</dept>
      <diseaseName>インフルエンザ</diseaseName>
    </visit>
    <visit>
      <date>2015/2/10</date>
      <dept>外科</dept>
      <diseaseName>虫垂炎</diseaseName>
    </visit>
  </patient>
  <patient id="A0003">
    <visit>
      <date>2016/4/8</date>
      <dept>眼科</dept>
      <diseaseName>白内障</diseaseName>
    </visit>
    <visit>
      <date>2013/2/5</date>
      <dept>内科</dept>
      <diseaseName>心筋梗塞</diseaseName>
    </visit>
    <visit>
      <date>2011/11/4</date>
      <dept>皮膚科</dept>
      <diseaseName>アトピー性皮膚炎</diseaseName>
    </visit>
    <visit>
      <date>2014/12/15</date>
      <dept>精神科</dept>
      <diseaseName>気分障害</diseaseName>
    </visit>
  </patient>
</visitData>
患者受診一覧XMLデータには、複数の患者の受診履歴があり、patient要素のid属性でどの患者の受診履歴か区別できるようになっています。

XML形式のデータの扱い方

サーバからのレスポンスがJSON形式からXML形式に変わったからといってもプログラムが大きく変わるわけではありません。変更点は大きく以下の2点です。
  1. サーバのURLが変わる
  2. サーバからのレスポンスが変わる
URLについては上で示した通りです。サーバからのレスポンスはJSON形式ではなくXML形式となり、Ajaxで取得したデータはJSON形式の時のように解析(JSON.parse)する必要はなく、そのまま使えます。
次に、XML形式のデータはXMLオブジェクトとしてプログラム中に取り込まれ、JSON形式のデータがJSON.parseによってjavascriptオブジェクトに変換されるのと異なります。XMLオブジェクトの取り扱い方は専用のメソッドを使います。
具体的には、タグ名が'ABC'の要素を取り出すには、$(XMLオブジェクト).find('ABC').text()とします。また,タグ名が'ABC'の要素の中にある属性値名が'XYZ'の属性値を取り出したい場合は$(XMLオブジェクト).find('ABC').attr('XYZ')とします。

2016年7月19日火曜日

いよいよ後半開始!

中間発表も終わり、いよいよ後半開始です。これまで、JSON形式のデータをスマホに表示するプログラムを作成してきましたが、ここからは、スマホに表示するデータをサーバから取得します。

AjaxによるJSON形式データの取得





図のように、スマホからHttpRequestと呼ばれるWebサービス要求を行います。すると、Webサーバは要求に対する応答をJSON形式のデータに編集してスマホへ返送します。たとえば、次の例は患者一覧を要求したときのJSON形式のレスポンスを示しています。

患者一覧要求に対するサーバのレスポンス(JSON形式)

これを受け取ったスマホ側のアプリは画面に患者一覧を表示します。このように、Webサーバと通信を行うことによって必要な情報を取得し、それを画面上に表示するプログラミング形態をAjaxと言います。これまで作成してきたアプリとの違いは、患者一覧データなどのデータを、javascriptファイルとしてあらかじめスマホ側に持たせるのではなく、必要になった時点で、サーバへ要求して取得する点が異なります。

では、Ajaxを用いたアプリを作成しましょう。修正すべきファイルは index.html と app.js です。

index.htmlの修正


患者一覧データ(js/patientList.js)と患者受診データ(js/visitData.js)は不要なのでコメントにします。

app.jsの修正


  • 患者一覧データ(patientList)を宣言する
  • 患者受診データ(visitData)を宣言する
  • 関数getPatientListを作成する
  • list-pageが表示されたとき、関数getPatientListを呼び出す
  • 関数getVisitDataを作成する
  • detail-pageが表示されたとき、関数getVisitDataを呼び出す

これまで、患者一覧データと患者受診データは、javascritファイルとして読み込んでいましたが、ここではAjaxを使ってサーバから取得するため、空の配列を宣言します。

  var currentItem = {};
  var visitData = [];
  var patientList = [];

上記の2~3行目がそれです。

患者一覧の作成


次に関数getPatientListを作成します。この関数は、app.js内に作成します(どこに作っても構いませんが、末尾に追加するのが良いでしょう)。この関数は、Ajaxを用いて、2行名に指定したURLに対して患者一覧データをリクエストしています。結果は doneコールバック関数の第1引数(response)に返ってきます。JSON形式の患者一覧を11行目でパース(解析)してjavascriptオブジェクトに変換して変数 res へ代入しています。実際の患者一覧は、このオブジェクトのメンバ変数であるpatientListに格納されているので、これを上で宣言したグローバル変数 patientList へ代入します。
function getPatientList() {
    var url = 'http://172.16.108.250/~semi2015/sample/getPatientList.php';

    $.ajax({
        type: 'GET',
        url: url,
        async: false,
        cache: false
    }).done(function(response, status, error){
        if (status == 'success') {
            var res = JSON.parse(response);
            if (res.status == 'OK') {
                patientList = res.patientList;
            } else {
                alert('ERROR:res.status=' + res.status);
            }
        } else {
            alert('文書データ取得失敗');
        }
    }).fail(function(xhr, status, error){
        var message = "xhr.status = " + xhr.status + ", xhr.statusText = " + xhr.statusText + ", status = " + status + ", error = " + error;
        alert('サーバから応答がありません: ' + message);
    });
}
作成した関数getPatientListは、list-pageが表示されたタイミングで呼び出し(2行目)、患者一覧データ(patientList)を取得した後、画面に出力します。その部分が下記のプログラムです。
  $(document).on('pageinit', '#list-page', function() {
    getPatientList();
    var html = '';
    $.each(patientList, function(i, item) {
        html += '<ons-list-item modifier="chevron" class="item">';
        html += '<ons-row>';
        html += '<ons-col width="60px"> ';
        html += '<div class="item-thum">';
        html += '</div>';
        html += '</ons-col>';
        html += '<ons-col>';
        html += '<header>';
        html += '<span class="item-id">' + item.id + '</span>';
        html += '<span class="item-gender">' + item.gender + '</span>';
        html += '</header>';
        html += '<p class="item-name">' + item.name + '</p>';
        html += '<p class="item-birthdate">' + item.birthdate + '</p>';
        html += '<p class="item-address">' + item.address + '</p>';
        html += '</ons-col>';
        html += '</ons-row> ';                        
        html += '</ons-list-item>';
      }
    );
    $("#item-list").html(html);
    var content = $("#item-list").get(0);
    ons.compile(content);

    $('.item', this).on('click', function() {
      currentItem = {
        id : $('.item-id', this).text(),
        gender : $('.item-gender', this).text(),
        name : $('.item-name', this).text(),
        birthdate : $('.item-birthdate', this).text(),
        address : $('.item-address', this).text()
      };

      app.navi.pushPage('detail.html');
    });
  });

受診一覧の作成


次に関数getVisitDataを作成します。 この関数も、app.js内に作成します。上記で作成したgetPatientListに続いて作成してください。この関数は、Ajaxを用いて、2行目に指定したURLに 対して指定した患者(patientId)の受診一覧データをリクエストしています。患者を指定するために、クエリストリング(?patientId=患者番号)を使っている点に注目してください。指定する患者IDは関数getVisitDataの引数で関数へ渡しています。結果は、getPatientListの場合と同様に doneコールバック関数の第1引数(response)に返ってきます。JSON形式の受診一覧を11行目でパース(解析)してjavascriptオ ブジェクトに変換して変数 res へ代入しています。実際の受診一覧は、このオブジェクトのメンバ変数であるvisitDataに格納されているので、これを上で宣言したグローバル変 数 visitData へ代入します。
function getVisitData(patientId) {
    var url = 'http://172.16.108.250/~semi2015/sample/getVisitData.php?patientId=' + patientId;

    $.ajax({
        type: 'GET',
        url: url,
        async: false,
        cache: false
    }).done(function(response, status, error){
        if (status == 'success') {
            var res = JSON.parse(response);
            if (res.status == 'OK') {
                visitData = res.visitData;
            } else {
                alert('ERROR:res.status=' + res.status);
            }
        } else {
            alert('文書データ取得失敗');
        }
    }).fail(function(xhr, status, error){
        var message = "xhr.status = " + xhr.status + ", xhr.statusText = " + xhr.statusText + ", status = " + status + ", error = " + error;
        alert('サーバから応答がありません: ' + message);
    });
}
作成した関数getVisitDataは、detail-pageが表示されたタイミングで当該患者ID(currentItem.id)を引数として呼び出し(2行目)、患者受診データ(visitData)を取得した後、画面に出力します。その部分が下記のプログラムです。
  $(document).on('pageinit', '#detail-page', function() {
    getVisitData(currentItem.id);
    var html = '';
    $.each(visitData, function(i, item) {
        html += '<ons-list-item class="detail-item">';
        html += '<header>';
        html += '<span class="detail-item-date">' + item.date + '</span>';
        html += '</header>';
        html += '<p class="detail-item-dept">' + item.dept + '</p>';
        html += '<p class="detail-item-diseaseName">' + item.diseaseName + '</p>';
        html += '</ons-list-item>';
    });
    $("#detail-item-list").html(html);
    var content = $("#detail-item-list").get(0);
    ons.compile(content);
    $('.item-id', this).text(currentItem.id);
    $('.item-gender', this).text(currentItem.gender);
    $('.item-name', this).text(currentItem.name);
    $('.item-birthdate', this).text(currentItem.birthdate);
    $('.item-address', this).text(currentItem.address);
    $('.add-note-action-item', this).click(function () {
        alert('dummy message');
    });
  });

なお、このプログラムが、従来の処理と違うのは、4行目の繰り返し処理において visitData が連想記憶の要素 visitData[currentItem.id] になっていない点です。これは、関数getVisitDataで取得した受診データが、指定した患者の受診データなので、わざわざ患者IDを指定して配列要素を取ってくる必要がないからです。

2016年7月13日水曜日

中間発表終わりました!

今日、中間発表が終わりました。発表自体は悪くなかったですが、質問には明快に答えられませんでした。忘れないうちに質問を書き残しておきましょう。
  • 何故電子カルテではなくORCAなのか?
  • スマホをORCAの端末として利用するという研究?
  • それは「連携」と言えるのか?
  • ORCAとスマホをつなぐ先行事例はある?
  • 研究の目的をもっとしっかり説明した方がいい(なぜ、この研究をするのか、する必要があるのか)
いかがでしょう。どれもなかなか本質を突いた厳しい質問です。漫然と言われたことだけやっていてはだめですね。何のためにやっているのかを意識しながらやらないとね。ORCAは医事コンなので、検査結果や画像データは入っていない。それを在宅医療の現場でどのように活用するのか?また、活用する意味はあるのか?そのあたりについても考えていかないといけませんね。