.btn-groupにtooltipを使うとデザインがズレる
環境
- Mac OS X 10.10.2
- Google Chrome 41.0.2272.101 (64-bit)
- Bootstrap 3.3.4
.btn-groupにtooltipを使うとデザインがズレる
.btn-group
内のbutton
にtooltip
を使用すると、
tooltip
が発動した時に1px程度ズレが生じてしまいます。
<div class="btn-group" role="group"> <button type="button" class="btn btn-default" data-toggle="tooltip" title="Tooltip"> Left </button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div>
何故ズレが生じているのか?
Bootstrapのソースコードを見てみると、隣接している.btn
にmargin-left: -1px;
が指定されているようです。
.btn-group { .btn + .btn, .btn + .btn-group, .btn-group + .btn, .btn-group + .btn-group { margin-left: -1px; } }
しかし、tooltip
を使用するとtooltip
の対象となっている.btn
の後にDOMが追加されてしまい、.btn
同士が隣接している状態ではなくなってしまいます。
そうすると、上記cssが適応されないのでレイアウトがズレてしまっているようです。
ズレが生じないようにする
対処法としてはdata-container
をbody
等に設定してあげればOKです。
<div class="btn-group" role="group"> <button type="button" class="btn btn-default" data-toggle="tooltip" data-container="body" title="Tooltip"> Left </button> <button type="button" class="btn btn-default">Middle</button> <button type="button" class="btn btn-default">Right</button> </div>
参考
Bootstrapの公式サイトにもdata-container
を指定するよう載っていますね。
When using tooltips on elements within a .btn-group or an .input-group, you'll have to specify the option container: 'body' (documented below) to avoid unwanted side effects (such as the element growing wider and/or losing its rounded corners when the tooltip is triggered).
Drawableに設置したpngファイルのオリジナルサイズを取得する
AndroidにてDrawableに設置したpngファイルのサイズを取得しようとしたら、ちょっとはまったのでメモ。
前提
drawableに 50 * 50 px の画像ファイルを設置。
res/drawable/sample.png
画像サイズを取得
リソースIDからBitmap
を生成して#getWidth, #getHeight
でサイズを取得したら、
実際のサイズとは異なる値が取得される。。。
Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.sample); int w = b.getWidth(); int h = b.getHeight(); // w => 150; h => 150;
そんな時はBitmapFactory.Options
から値を取得してあげれば、
オリジナルの画像サイズが取得出来ました( ´ー`)フゥー...
BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(getResources(), R.drawable.sample, options); int w = options.outWidth; int h = options.outHeight; // w => 50; h => 50;
参考
http://stackoverflow.com/questions/8855036/incorrect-image-dimensions-in-android-when-using-bitmap
Enumerable#map and Array#flatten vs Enumerable#flat_map
目的
- Enumerable#map, Array#flatten と Enumerable#flat_map でどちらがパフォーマンスに優れているかを調べる。
環境
Enumerable#flat_map
flat_map (Enumerable) - APIdock : http://apidock.com/ruby/Enumerable/flat_map
ベンチマーク
require 'benchmark' n = 1000 array = Array.new(100) { |i| Array.new(i) { |j| j } } Benchmark::CAPTION Benchmark.bm do |x| x.report('flat_map') { n.times { array.flat_map { |a| a } } } x.report('flat map') { n.times { array.map { |a| a }.flatten(1) } } end
user system total real flat_map 0.030000 0.010000 0.040000 ( 0.036725) flat map 0.260000 0.020000 0.280000 ( 0.271837)
まとめ
map
, flatten
ではなくflat_map
を使ったほうが速くなっていますね。
ただ、flat_map
では1段階までしか平坦化されないで使用する際には注意が必要かもしれないです。
irb(main):055:0> [[1, 2], [[3, 4, 5]]].flat_map { |x| x } => [1, 2, [3, 4, 5]]
Railsで独自クラスにバリデーションを実装してみる
環境
独自クラスにValidationを実装
独自クラスでRailsのValidationを実装したい場合はActiveModel::Validations
をincludeしてあげればよいらしい。
class Hoge include ActiveModel::Validations validates :hoge_id, presence: true def initialize(attributes = {}) attributes.each do |name, value| send("#{name}=", value) end end end
これで、大丈夫かと思ったがNoMethodError
が出てしまった。
[1] pry(main)> Hoge.new(hoge_id: 100) NoMethodError: undefined method `hoge_id=' for #<Hoge:0x007fc71ce47bf0> from /path/to/hoge.rb:8:in `block in initialize'
なので、attr_accessor :hoge_id
を指定してあげればエラーは消えた.
class Hoge include ActiveModel::Validations attr_accessor :hoge_id # 追加 validates :hoge_id, presence: true def initialize(attributes = {}) attributes.each do |name, value| send("#{name}=", value) end end end
これで、ひとまず独自クラスでもバリデーションを行うことが出来るようになりました。
[5] pry(main)> hoge = Hoge.new(hoge_id: nil) [6] pry(main)> hoge.valid? => false [7] pry(main)> hoge.errors.full_messages => ["Hogeを入力してください。"]
参考
CoffeeScriptのファットアローって何だ?
ファットアロー
jQueryのコールバック関数で呼ばれた関数でthis
を使うと関数内のjQueryオブジェクトを指しているため、
that = @
等と関数外で別の変数に置き換えて使用することがあると思います。
coffee
class User constructor: (first_name, last_name) -> @full_name = "#{first_name} #{last_name}" that = @ $("#action-hello").click -> alert "My name is #{that.full_name}."
js
var User; User = (function() { function User(first_name, last_name) { var that; this.full_name = "" + first_name + " " + last_name; that = this; $("#action-hello").click(function() { return alert("My name is " + that.full_name + "."); }); } return User; })();
そんな時、アロー->
ではなくファットアロー=>
を使ってあげると
@
に対してスコープ外のthis
へと自動的に置き換えを行ってくれます。
coffee
class User constructor: (first_name, last_name) -> @full_name = "#{first_name} #{last_name}" $("#action-hello").click => alert "My name is #{@full_name}."
js
var User; User = (function() { function User(first_name, last_name) { this.full_name = "" + first_name + " " + last_name; $("#action-hello").click((function(_this) { return function() { return alert("My name is " + _this.full_name + "."); }; })(this)); } return User; })();
感想
ファットアローなんてものがあったんですね、知らなかった自分が情けないです。。。
Railsでf.selectにclassが設定できない時
環境
f.select
<%= form_for @user do |f| %>
...
<%= f.select :job, { engineer: "Engineer", ... }, class: "myclass" %>
...
<% end %>
ここでセレクトタグに.myclass
が設定されていることが期待されるが、
実際に生成されるHTMLは下記のようになる。
<select id="user_job" name="user[job]">
<option selected="selected" value="engineer">Engineer</option>
...
</select>
classが設定できない時の対処法
<%= form_for @user do |f| %>
...
<%= f.select :job, { engineer: "Engineer", ... }, {}, { class: "myclass" } %>
...
<% end %>
これでclassが設定されたHTMLが出力されるはずです。
<select class="myclass" id="user_job" name="user[job]">
<option selected="selected" value="engineer">Engineer</option>
...
</select>
参考
Railsでdefault_scopeの解除方法
環境
default_scopeの設定方法
order
やwhere
文などをdefault_scope
メソッドに渡してあげればおk
class User < ActiveRecord::Base ... default_scope { order(email: :asc) } default_scope { where(deleted_at: nil) } ... end
orderの解除方法
reorder
でorder
のみ解除できる。
User.all #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL ORDER BY `users`.`email` ASC" User.reorder(nil) #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL User.reorder(id: :desc) #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL ORDER BY `users`.`id` DESC"
特定のscopeの解除方法
except
またはunscope
で解除することが出来る。
unscope
の方はexcept
よりも細かい設定をすることが出来るようです。
User.all #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL ORDER BY `users`.`email` ASC" User.except(:order) User.unscope(:order) #=> "SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL User.except(:where) User.unscope(:where) User.unscope(where: :deleted_at) #=> "SELECT `users`.* FROM `users` ORDER BY `users`.`id` DESC"
感想
今回は環境がRails4だったのでRails3などでは結果が違うかもしれないですね。