JS学習 文字が入力されるたびに検索できるようにする(インクリメンタルサーチ)
インクリメンタルサーチ学習に向けて
文字が入力されるたびに検索できるようにする
・main.js
// 入力されたものと比較される値の配列 var fruits = ['apple', 'apricot', 'avocado', 'blueberry', 'cherry', 'coconut', 'cranberry', 'dragonfruit', 'durian', 'grape', 'grapefruit', 'guava', 'kiwi fruit', 'lemon', 'lime', 'lychee', 'mango', 'melon', 'watermelon', 'miracle fruit', 'orange', 'bloodorange','clementine','mandarine','tangerine','papaya','passionfruit','peach','pear','persimmon','physalis','plum/prune','pineapple','pomegranate','raspberry','rambutan','star fruit','strawberry']; $(function() { // 変数listにid listの場所を代入する var list = $("#list"); var preWord; // 9,検索結果を表示するlistに追加する処理 function appendList(word) { // 変数itemに<li class="list">を新規に作成し、そこに引数wordを追加する var item = $('<li class="list">').append(word); // 変数listに変数itemの中身を挿入 list.append(item); } // 5,前方一致に対応するためには、^を検索する言葉の前につける必要がある。今回は、splitで作成した配列要素の前に^をつければ前方一致ができる。配列の要素を加工した新しい配列を作成するには、map()を使用する。map()の引数に要素の頭に^をつける処理をする、関数editElementを渡す。map()によって作成された新しい配列をnewInputsという変数に入れる。 function editElement(element) { var result = "^" + element; return result; } // 1,#keywordにワードが入力された時の処理 $("#keyword").on("keyup", function() { // 2,変数inputに、#keywordに入力された値を取得し、代入する var input = $("#keyword").val(); // 3,変数inputに入った複数の文字列をsplit()で分割する。split()で空文字で区切った配列から空文字を削除している。引数のeには、配列の要素が代入されている。eに文字が代入されている場合はtrueになるので、配列に格納される。反対に空文字の場合はfalseになるので、配列には格納されない。このようにすることで、スペースが入力された時に配列の要素がすべて表示されなくなった。 var inputs = input.split(" ").filter(function(e) { return e; }); // 4,変数inputsに入った配列から要素を1つずつ取り出し、引数に与えられた関数の処理を行った結果から新しい配列を作る。map()は、配列から要素を1つずつ取り出し、引数に与えられた関数の処理を行った結果から新しい配列を作る。 var newInputs = inputs.map(editElement); // 6,変数wordに変数newinputsの中身の要素を|でつないだ配列を代入する var word = newInputs.join("|"); // 7,変数wordの中身を正規表現化したものを代入する。 var reg = RegExp(word); // 8,2回目以降の検索時に前の検索結果をremove()を使って.list(検索結果を表す変数itemで作っているliのこと)を削除する $(".list").remove(); // 9,変数wordと変数prewordがイコールでない場合、さらに入力されたワードが0でない場合に、配列から1つずつ取り出して変数regと比較する。マッチしたのをappendlistに加える。 if (word != preWord && input.length !== 0) { $.each(fruits, function(i, fruit) { if (fruit.match(reg)) { appendList(fruit); } }); if ($(".list").length === 0) { appendList("一致する果物はありませんでした"); } } // 変数prewordに変数wordの中身を代入する。これによって次の検索の準備をする。入力されたもの=>word これと同じ値のpreword.wordが違う値になったらまた検索をスタートさせる。 // preWord = word; }); });
・index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script src="main.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div class="form-group"> <input type='text' id="keyword" class="form-control" placeholder="好きなフルーツを入力してください"> <button type="button" id="submit" class="btn">検索</button> </div> <ul id="list"></ul> </body> </html>
JS学習 複数のワードで検索できるようにする
インクリメンタルサーチの学習に向けて
複数のワードで検索できるようにする
・main.js
// 入力されたものと比較される値の配列 var fruits = ['apple', 'apricot', 'avocado', 'blueberry', 'cherry', 'coconut', 'cranberry', 'dragonfruit', 'durian', 'grape', 'grapefruit', 'guava', 'kiwi fruit', 'lemon', 'lime', 'lychee', 'mango', 'melon', 'watermelon', 'miracle fruit', 'orange', 'bloodorange','clementine','mandarine','tangerine','papaya','passionfruit','peach','pear','persimmon','physalis','plum/prune','pineapple','pomegranate','raspberry','rambutan','star fruit','strawberry']; $(function() { // 変数listにid listの場所を代入する var list = $("#list"); // 9,検索結果を表示するlistに追加する処理 function appendList(word) { // 変数itemに<li class="list">を新規に作成し、そこに引数wordを追加する var item = $('<li class="list">').append(word); // 変数listに変数itemの中身を挿入 list.append(item); } // 5,前方一致に対応するためには、^を検索する言葉の前につける必要がある。今回は、splitで作成した配列要素の前に^をつければ前方一致ができる。配列の要素を加工した新しい配列を作成するには、map()を使用する。map()の引数に要素の頭に^をつける処理をする、関数editElementを渡す。map()によって作成された新しい配列をnewInputsという変数に入れる。 function editElement(element) { var result = "^" + element; return result; } // 1,id submitがクリックされた時の処理 $("#submit").on("click", function() { // 2,変数inputに、#keywordに入力された値を取得し、代入する var input = $("#keyword").val(); // 3,変数inputに入った複数の文字列をsplit()で分割する。split()は、文字列を複数の部分文字列に区切り、文字列の配列に分割する。引数には文字列を区切るための文字を指定する。 var inputs = input.split(" "); // 4,変数inputsに入った配列から要素を1つずつ取り出し、引数に与えられた関数の処理を行った結果から新しい配列を作る。map()は、配列から要素を1つずつ取り出し、引数に与えられた関数の処理を行った結果から新しい配列を作る。 var newInputs = inputs.map(editElement); // 6,変数regに変数newinputsの中身の要素を|でつないで、さらに正規表現化したものを代入する。join()は、配列のすべての要素をつないだ文字列を作成する。引数に文字列を渡すと、その文字列で文字と文字をつなげる。join()の引数に|を渡すことでnewInputsの要素を|でつなぐ。その結果をRegExpの引数に渡すことで正規表現を作成する。 var reg = RegExp(newInputs.join("|")); // 7,2回目以降の検索時に前の検索結果をremove()を使って.list(検索結果を表す変数itemで作っているliのこと)を削除する $(".list").remove(); // 8,配列から1つずつ取り出して変数regと比較する。マッチしたのをappendlistに加える。 $.each(fruits, function(i, fruit) { if (fruit.match(reg)) { appendList(fruit); } }); // マッチしなかった場合の処理 if ($(".list").length === 0) { appendList("一致する果物はありませんでした"); } }); });
・index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script src="main.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div class="form-group"> <input type='text' id="keyword" class="form-control" placeholder="好きなフルーツを入力してください"> <button type="button" id="submit" class="btn">検索</button> </div> <ul id="list"></ul> </body> </html>
JS学習 入力された値を前方一致で検索する
インクリメンタルサーチの学習に向けて
入力された値を前方一致で検索する
・index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> <script src="main.js"></script> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> <link rel="stylesheet" type="text/css" href="style.css"> </head> <body> <div class="form-group"> <input type='text' id="keyword" class="form-control" placeholder="好きなフルーツを入力してください"> <button type="button" id="submit" class="btn">検索</button> </div> <ul id="list"></ul> </body> </html>
・main.js
// 入力されたものと比較される値の配列 var fruits = ['apple', 'apricot', 'avocado', 'blueberry', 'cherry', 'coconut', 'cranberry', 'dragonfruit', 'durian', 'grape', 'grapefruit', 'guava', 'kiwi fruit', 'lemon', 'lime', 'lychee', 'mango', 'melon', 'watermelon', 'miracle fruit', 'orange', 'bloodorange','clementine','mandarine','tangerine','papaya','passionfruit','peach','pear','persimmon','physalis','plum/prune','pineapple','pomegranate','raspberry','rambutan','star fruit','strawberry']; $(function() { // 変数listにid listの場所を代入する var list = $("#list"); // listに追加する処理 function appendList(word) { // 変数itemに<li class="list">を新規に作成し、そこに引数wordを追加する var item = $('<li class="list">').append(word); // 変数listに変数itemの中身を代入 list.append(item); } // id submitがクリックされた時の処理 $("#submit").on("click", function() { // 変数inputにid keywordに入力された値を取得し、代入する var input = $("#keyword").val(); // 入力された値をRegExp()を使って正規表現として使用できるようにしています。^を使うことで前方一致で検索できるようになります。この時regという変数に格納しています。 var reg = new RegExp("^" + input); // 2回目以降の検索時に前の検索結果をremove()を使って.list(検索結果を表す変数itemで作っているliのこと)を削除する $(".list").remove(); // 配列から1つずつ取り出して変数regと比較する。マッチものをlistに加える。 $.each(fruits, function(i, fruit) { if (fruit.match(reg)) { appendList(fruit); } }); // マッチしなかった場合の処理 if ($(".list").length === 0) { appendList("一致する果物はありませんでした"); } }); });
レビューの反省 2017年1月10日
・jQueryオブジェクトを格納する変数名には先頭に$を付けましょう。
var $textField = $('.js-form__text-area')
・開発用のconsole.logは消しましょう。
rails ajaxを使って非同期通信をするための学習メモ
現在、railsでチャットアプリを作っている。チャットメッセージの送信、グループの追加機能にajaxを使った非同期通信を使いたい。
しかし、いろいろ調べてみたが全然わからない。ほとんどすべてがわからない。
なので、わからない部分を整理するためにここにメモを残す。
・respond_toとは
respond_to do |format| format.html { render ... } # この中はHTMLリクエストの場合に呼ばれる format.json { render ... } # この中はJSONリクエストの場合に呼ばれる end
リクエストがHTMLを求めているのか、もしくはJSONを求めているのかを拡張子やヘッダー情報を利用して、自動的に条件分岐する。
・JSONとは
JSONとはJavaScript Object Notationの略で、XMLなどと同様のテキストベースのデータフォーマット。
・on()とは
on()は、HTML要素に対してイベントを設定。on()の引数としてはイベントの種類と設定したイベントが起きた時にどのような処理を行うかを指定。
$(function() { $("セレクタ").on("イベント", function() { イベントが起きた時に行う処理 }); });
・append()とは
引数で指定したHTML要素を追加できる。
$("セレクタ").append("追加したいHTML要素");
・attr()とは
attr()を使用すると、HTML要素の属性値を取得・変更できる。取得したい場合には、第一引数に取得したい属性を指定する。変更したい場合には第一引数に変更したい属性を、第二引数に変更したい属性値を指定する。
// 属性の取得 $("セレクタ").attr("取得したい属性名"); // 属性の変更 $("セレクタ").attr("変更したい属性名", "変更したい属性値");
・val()とは
val()を使用すると、フォームに入力された値を取得することができる。
RSpec 外部キーを使っているモデルをテストする際の手順(factory_girl使用)
やり方まとめ
・外部キーを使っている場合、外部キーの先のレコードが存在しないと、テストで弾かれる。だから必要なレコードを定義する。
具体的に
messageテーブルに外部キーでuserとgroupを設定しているとする。
「messageが投稿できるかどうか」というテストを行うにあたっては、messageに紐づくべきuserとgroupのレコードが必要になる。
factory_girlにて、messageのテスト用インスタンスだけでなく、userとgroupのものも設定する必要がある。
手順
1、spec/factories にgroup.rb user.rb message.rb を作成する。
2、それぞれにテスト用のインスタンスを定義する。
EX
user.rb
FactoryGirl.define do factory :user do name "hoge" email "hogehoge@hogehoge" password "hogehogehoge" end end
3つにそれぞれ定義する。
3、messageが投稿できるかどうかのテストコードを書く。
spec/models/message_spec.rb
require 'rails_helper' describe Message do #Messageモデルのテストであることの宣言 describe '#create' do it "is valid with a message" do #messageが存在していたら投稿できる user = create(:user) group = create(:group) message = build(:message, user_id: user.id, group_id: group.id) expect(message).to be_valid end end end
userとgroupをcreateしてDBに入れる→それをmessageで引っ張るという流れ。
Rspec コードメモ
・通常の書き方(factory-girlなし) user_spec.rb
require 'rails_helper' describe User do describe '#create' do it "is invalid without a email" do #ここはテストの条件式。今回の条件はemailがないと無効になるか user = User.new(nickname: "abe", email: "", password: "00000000", password_confirmation: "00000000") #インスタンスの生成。emailはからの設定 user.valid? #インスタンスを保存する際に「バリデーションにより保存ができない状態であるか」を確かめる expect(user.errors[:email]).to include("can't be blank") #errorsメソッドを利用すると、バリデーションにより保存ができない状態である場合なぜできないのかを確認することができる end end end
・factory-girlあり
require 'rails_helper' describe User do describe '#create' do it "is invalid without a email" do #ここはテストの条件式。今回の条件はemailがないと無効になるか user = User.build(:user, nickname: "") #factory-girlを使い、buildメソッドで記述を省略 user.valid? #インスタンスを保存する際に「バリデーションにより保存ができない状態であるか」を確かめる expect(user.errors[:nickname]).to include("can't be blank") #errorsメソッドを利用すると、バリデーションにより保存ができない状態である場合なぜできないのかを確認することができる end end end