読者です 読者をやめる 読者になる 読者になる

phpとか

自分用備忘録なので、自分が分かる程度にしか書いてません。

datepickerでDBにデータある日付のみ選択可能に

タイトルに関わる箇所だけ抜粋
パラメータとかは見ずらくなるので抜いてます。

project.calendar= function () {
    var options= this;
    options.month;
    options.dateArray = [];
  options.url = '/test/';
  options.timeout = 5000;
};

//dbにある日付か
project.calendar.prototype.invalidateion = function (date) {
  var ieFlg = project.calenar.prototype.validataionIe(),ymdArr = date.toLocaleDateString().split('/');
  if(ieFlg){
    ymdArr= [date.getFullYear(),date.getMonth() + 1,date.getDate()];
  }
  var y = ymdArr[0],m = ("0" + ymdArr[1]).slice(-2),d = ("0" + ymdArr[2]).slice(-2), ymd = y + m + d;
  if (m !== options.month) {
    if (parseInt(d) > 1) {
      if (parseInt(m) === 12) {
        y = parseInt(y) + 1;
        m = '01';
      } else {
        m = ("0" + (parseInt(m) + 1)).slice(-2);
      }
    }
    //データある日付
    project.calendar.prototype.getDateAjax(y + m)
      .done(function (data) {
        options.dateArray = data['result'];
      })
      .fail(function () {
        options.dateArray = [];
      });
    options.month = m;
  }
  return $.inArray(ymd, options.dateArray ) !== -1 ? result = [true, ''] : [false, ''];
}

//データ取得
project.calendar.prototype.getDateAjax = function (ym) {
  var dfd = $.Deferred();
  $.ajax({
    async: false,
    url: options.url + '?ym=' + ym,
    type: 'get',
    dataType: 'json',
    timeout: options.timeout,
    success: function (data) {
      if (data['err'] !== '') {
        return dfd.reject();
      }
      return dfd.resolve(data);
    },
    error: function () {
      return dfd.reject();
    }
  });
  return dfd.promise();
}

//initialization
var calendar= new project.calendar();
$('.datepicker').datepicker({
  beforeShowDay: function (date) {
    return calendar.invalidateion(date)
  }
});

1.datepicker設定

var calendar= new project.calendar();
$('.datepicker').datepicker({
  beforeShowDay: function (date) {
    return calendar.invalidateion(date)
  }
});

「beforeShowDay」で、[真偽値, '']の形式で返すことにより、選択の可否を設定できます。

[true, '']は有効、[false, '']は無効。
 第二引数はクラス名

2.「beforeShowDay」で渡される、表示される月のカレンダーの日付を分割

var ieFlg = project.calenar.prototype.validataionIe(),ymdArr = date.toLocaleDateString().split('/');
if(ieFlg){
  ymdArr= [date.getFullYear(),date.getMonth() + 1,date.getDate()];
}

ieやedgeだと、日付の形式が他のブラウザとちがうので、分けてます。
ie判定はユーザエージェントで
てか、全部getFullYear()とかでやればいいですね・・・

3.表示可否決定

if (m !== options.month) {
  if (parseInt(d) > 1) {
    if (parseInt(m) === 12) {
      y = parseInt(y) + 1;
      m = '01';
    } else {
      m = ("0" + (parseInt(m) + 1)).slice(-2);
    }
  }
  //データある日付
  project.calendar.prototype.getDateAjax(y + m)
    .done(function (data) {
      options.dateArray = data['result'];
    })
    .fail(function () {
      options.dateArray = [];
    });
  options.month = m;
}
return $.inArray(ymd, options.dateArray ) !== -1 ? result = [true, ''] : [false, ''];

if (m !== options.month)で、月が変わったときだけやってます。
もっといいやり方いっぱいありそうですね。

表示された全ての日付に対して処理するのは無駄なので上記制限します。
最初に取得したデータを使いまわします。

if (parseInt(d) > 1)は、カレンダーの始まりが前の月の日付かの判定です。
前の月の場合、月に+1したりしてます。

あとはajaxでとってきたデータに、「beforeShowDay」で渡される日付があるかを調べて、あるなら選択可能。なければ選択不可として結果を返してます。

※非同期だとカレンダーに値をセットする前に表示される可能性があるので、同期に設定してます。

async: false


Unity5の教科書 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)

Unity5の教科書 2D&3Dスマートフォンゲーム入門講座 (Entertainment&IDEA)