スタイルシートだけで文字が長い時に...と表示する方法

最近咳が止まらない現象に悩まされているおいらです。
今まで枠に収まらない文字はレイアウトを崩したくないので「...」とjQuery使って処理してたんだけど、
CSSだけで処理を出来る事を知りました。今知りました。ついさっき知りました。

.hoge {
  width: 125px;
  font-size: 14px;
  white-space: nowrap;
  text-overflow: ellipsis;
  -webkit-text-overflow: ellipsis;
}

とこんな風にwhite-spaceとtext-overflowをスタイルシートに定義してあげましょう。
そうすると枠を超えると「...」と表示されるようになります。

ここで気をつけなければいけないのが、
white-spaceとtext-overflowは必ずセットで記述しましょう。
いやぁこりゃ便利だ。何で今まで知らなかったんだろう。

jquery.validate.jsでajax使用時の入力チェックをしてみた

最近の内容はjQueryjavascript絡みばかりになってるけど一番書きやすい事が分かりました。
これでSymfony2がまた遠ざかってしまう。。。

というわけでまたjquery.validate.jsのお出ましですけど、
以前id:amidaike:20130318はエラーメッセージを変更してみましたけど、
今回はajaxを使った時の入力チェックてどうするんだとふと思ったのでやってみますたノシ

どういうことかというと、ページ遷移がある画面なら

$(function() {
  $("#login-form").validate({
    rules: {
      'email': {
        required: true
      }
    }
  });
});

とこれだけ書けばsubmitされてもエラーがあれば処理を中断してくれるんだけど、
画面遷移をしない画面でajaxを使った場合、こんな感じで処理をしようとしたら、、、

$(function() {
  $("#login-form").validate({
    rules: {
      'email': {
        required: true
      }
    }
  });

  $("#login-btn").click(function() {
    $.ajax({
      url: "/hoge.php"
      type: 'post'
      dataType: 'json',
      data: {
        'email': email,
      }
      success: function(data) {
      }
    });
  });
});

エラーがあってもhoge.phpが実行されてしまいます。
そんな時はどうするかというと、valid()関数というのがjquery.validateに用意されているのでそれを使って処理を中断させます。

で、上記のコードを修正したajaxを使った入力チェックはこんな感じ

$(function() {
  $("#login-btn").click(function() {
    $("#login-form").validate({
      rules: {
        'email': {
          required: true
        }
      }
    });

    if (!$("#login-form").valid()) {
      return false;
    }

    $.ajax({
      url: "/hoge.php"
      type: 'post'
      dataType: 'json',
      data: {
        'email': email,
      }
      success: function(data) {
      }
    });
  });
});


上記にあるとおりvalidateを使う箇所はclick関数へ含め、valid関数を

if (!$("#login-form").valid()) {
  return false;
}

というようにチェックすると入力エラーがあってもhoge.phpへ処理されなくなります。
これできちんとエラーメッセージも表示されますよっと。



こんな事書かなくてもみんな知ってるか。
他にもいい方法があるのか知らないけど今回のプロジェクトではこの方法でチェックしてますよノシ

Stupid jQuery Table Sortプラグインに矢印をつけてみた

jQueryプラグインを導入しすぎて何を使ってて、何を使っていないのか分からなくなってきましたよっと。

というわけでテーブルのソートをするのにサーバ通信するまでもなかったので、
jQuery Table Sortプラグインとやらを使ってます。
これね jQuery Table Sort | The Stupid Table Plugin by JoeQuery


このstupidtable関数は標準だとどの項目がソートされているのかが分かりません。
サイトを見るとCallbacksの説明で矢印のつけ方がのってるんだけどベージ毎にこれを書くのはめんどくさい。
というわけでライブラリの中身をちょこっといじってみました。


使っているバージョンはソース上に明記されてないので本日時点の最新です。

後、twitter bootstrapを対象にしてるので、bootstrapを使っていない方も似たようなやり方でやれば動く筈です。
では早速変更した箇所を載せてみます。

// ==================================================== //
//                  Begin execution!                    //
// ==================================================== //
// Do sorting when THs are clicked
table.delegate("th", "click", function(){
  var trs = table.find("tbody tr");


  var i = $(this).index();
  var classes = $(this).attr("class");
  var type = null;
  if (classes){
    classes = classes.split(/\s+/);

    for(var j=0; j<classes.length; j++){
      if(classes[j].search("type-") != -1){
        type = classes[j];
        break;
      }
    }
    if(type){
      type = type.split('-')[1];
    }
  }
  if(type){

    var icon = $("th").not(this).find('i');
    $(icon).remove();

    var iconup = $(this).find('.icon-arrow-up');
    var icondown = $(this).find('.icon-arrow-down');
    if (iconup.length != 0) {
      $(iconup).remove();
      $(this).append(" <i class='icon-arrow-down'></i>");
    } else {
      $(icondown).remove();
      $(this).append(" <i class='icon-arrow-up'></i>");
    }

    var sortMethod = sortFns[type];

    // Gather the elements for this column
    column = [];

    // Push either the value of the 'data-order-by' attribute if specified
    // or just the text() value in this column to column[] for comparison.
    trs.each(function(index,tr){
      var e = $(tr).children().eq(i);
      var order_by = e.attr('data-order-by') || e.text();
      column.push(order_by);
    });

    // If the column is already sorted, just reverse the order. The sort
    // map is just reversing the indexes.
    if(is_sorted_array(column, sortMethod)){
      column.reverse();
      var theMap = [];
      for(var i=column.length-1; i>=0; i--){
        theMap.push(i);
      }
    }
    else{
      // Get a sort map and apply to all rows
      theMap = sort_map(column, sortMethod);
    }

    var sortedTRs = $(apply_sort_map(trs, theMap));

    // Replace the content of tbody with the sortedTRs. Strangely (and
    // conveniently!) enough, .append accomplishes this for us.
    table.find("tbody").append(sortedTRs);
  }
});

このtable.delegate関数の中にある以下の内容が追加したソースどすえ。

var icon = $("th").not(this).find('i');
$(icon).remove();

var iconup = $(this).find('.icon-arrow-up');
var icondown = $(this).find('.icon-arrow-down');
if (iconup.length != 0) {
  $(iconup).remove();
  $(this).append(" <i class='icon-arrow-down'></i>");
} else {
  $(icondown).remove();
  $(this).append(" <i class='icon-arrow-up'></i>");
}

これでソートが分かりやすくなりますたよっとノシ

ただこのライブラリはライセンスが不明のため改造しても良いのかどうかが気になりますが。。。

JavascriptでURLの正規表現チェック2

前回id:amidaike:20130405の正規表現ではhoge.hogeとか
訳の分からないドメインでもURLとしてみなされてしまうので、
トップレベルドメインも指定してみる事にしますたノシ

トップレベルドメインWikipediaトップレベルドメイン一覧を参考にしています。
こんなにも必要なければcomとかjpとか必要な物だけ記入してください。

function isUrl(str) {
  var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+(aero|asia|biz|cat|com|coop|edu|gov|info|int|jobs|mil|mobi|museum|name|net|org|pro|tel|travel|xxx|ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|ax|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|dd|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gb|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|rs|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|ss|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|za|zm|zw)|'+ // domain name
    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
    '(\\#[-a-z\\d_]*)?$','i'); // fragment locator

  if(!pattern.test(str)) {
    return false;
  } else {
    return true;
  }
}


おそらくtwitterはここまでチェックしている筈なんだけど、
よくよく考えたら今回のプロジェクトでここまでチェックする必要があるのかが疑問だ。。。

JavascriptでURLの正規表現チェック

週末は凄い暴風雨がくるということですが、いつも通り大阪はまた影響などないのでしょうね。。。

てなわけで以前、phpでURLの正規表現id:amidaike:20130306を書いてみたんだけども、
イマイチだったのとjavascriptでも使いたかったのでこんな風にしてみますたノシ

function isUrl(str) {
  var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
    '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
    '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
    '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
    '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
    '(\\#[-a-z\\d_]*)?$','i'); // fragment locator

  if(!pattern.test(str)) {
    return false;
  } else {
    return true;
  }
}

ちなにみこれはstackoverflowで見かけたコードなんだけどurlを失念してしまいました。

javacscriptでのhtmlエスケープシーケンス

新社会人をチラホラ見るようになってあんな初々しさがおいらにもあったのかと思う季節になってきましたね。

今日は特に書く事ないのでjavascript内でのhtmlエスケープシーケンスの関数でも載せときます。

function htmlEscape(s) {
	return s.replace(/&/g, '&amp;')
		.replace(/</g, '&lt;')
		.replace(/>/g, '&gt;')
		.replace(/'/g, '&#039;')
		.replace(/"/g, '&quot;')
		.replace(/\n/g, '<br />');
}


ちょっと最近忙しいので最近は手抜きなんですけど、少し時間に余裕ができればSymfony2の続きを書いていく予定です。
誰も期待はしてないと思いますけどね。

googlemapapiのGroundOverlayをiPhoneで使うときの注意点

今日から新年度ということですが相変わらずダメ人間のまま今年度も乗り切ろうと思います。

それで今googlemapapiでGroundOverlayを使ってある画像をおいてるんだけども、
PCで見たら表示されるのにiPhoneだと表示されなかったのです。

ソースはこんなの。

function initialize() {
  var initLatLng = new google.maps.LatLng(緯度, 経度);
  var mapOptions = {
    center: initLatLng,
    mapTypeControl: false,
    streetViewControl: false,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };

  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);

  var sw = new google.maps.LatLng(緯度, 経度);
  var ne = new google.maps.LatLng(緯度, 経度);
  var imageBounds = new google.maps.LatLngBounds(sw, ne);

  var mapOverlay = new google.maps.GroundOverlay(
    "/img/hoge.png",
    imageBounds
  );
  mapOverlay.setMap(map);
}

google.maps.event.addDomListener(window, 'load', initialize);

よくありがちなソースですね。

で、このhoge.pngiPhoneだと表示されないという現象に悩まされました。
最初は画像のファイル容量だと思って100kbから50kbにしたけどそれでも表示されない。
じゃあpngが悪いのかと思ってjpgやgifにしたけどそうでもないし、そもそもpngのせいじゃない。


で、あーだこーだしているうちに結局画像サイズが原因だと判明しました。
最初は2000px以上の画像サイズを使っていたんだけど、それを1900pxにすると無事に表示されるようになりました。


時間がないのでとりあえずこれでよしとするけど本当の原因て何なんだろうか。
もしかするとドキュメントに載っているのかもしれないけどね。