[{"data":1,"prerenderedAt":891},["ShallowReactive",2],{"post:\u002F2017\u002F10\u002F28\u002Fruby-on-rails-part-5-searching-for-love":3},{"id":4,"title":5,"body":6,"date":883,"description":12,"extension":884,"meta":885,"navigation":287,"path":886,"seo":887,"stem":888,"subtitle":889,"__hash__":890},"posts\u002F2017\u002F10\u002F28\u002Fruby-on-rails-part-5-searching-for-love.md","Ruby on Rails: Part 5 - searching for love",{"type":7,"value":8,"toc":881},"minimark",[9,13,16,33,36,59,62,78,81,104,111,335,348,351,354,357,530,544,547,621,624,774,783,851,858,861,867,870,877],[10,11,12],"p",{},"I wasn't sure what to do this time around, but I'm currently on the way to Belfast nuts deep in a spice bag, so lets begin.",[10,14,15],{},"Having a site that has loads of pictures is no good unless there's some form of search functionality. so that's today's job. I kinda did this backwards, but its my site, and nobody reads this so sue me.",[10,17,18,19,26,27,32],{},"I started this section on a whim looking through nice input fields and came across ",[20,21,25],"a",{"href":22,"rel":23},"https:\u002F\u002Fsemantic-ui.com\u002F",[24],"nofollow","semantic UI"," and their lovely ",[20,28,31],{"href":29,"rel":30},"https:\u002F\u002Fsemantic-ui.com\u002Fmodules\u002Fdropdown.html#multiple-search-selection",[24],"multiple select"," dropdown menus, so, against all logic this is where this post begins.",[10,34,35],{},"Lets go head and integrate Semantic UI into out project:",[37,38,43],"pre",{"className":39,"code":40,"language":41,"meta":42,"style":42},"language-ruby shiki shiki-themes github-dark","gem 'semantic-ui-sass'\n","ruby","",[44,45,46],"code",{"__ignoreMap":42},[47,48,51,55],"span",{"class":49,"line":50},"line",1,[47,52,54],{"class":53},"s95oV","gem ",[47,56,58],{"class":57},"sU2Wk","'semantic-ui-sass'\n",[10,60,61],{},"And then in both our application css and js files respectively:",[37,63,65],{"className":39,"code":64,"language":41,"meta":42,"style":42},"@import \"semantic-ui\";\n",[44,66,67],{"__ignoreMap":42},[47,68,69,72,75],{"class":49,"line":50},[47,70,71],{"class":53},"@import ",[47,73,74],{"class":57},"\"semantic-ui\"",[47,76,77],{"class":53},";\n",[10,79,80],{},"and",[37,82,84],{"className":39,"code":83,"language":41,"meta":42,"style":42},"\u002F\u002F= require semantic-ui\n\n",[44,85,86],{"__ignoreMap":42},[47,87,88,92,95,98,101],{"class":49,"line":50},[47,89,91],{"class":90},"snl16","\u002F\u002F=",[47,93,94],{"class":90}," require",[47,96,97],{"class":53}," semantic",[47,99,100],{"class":90},"-",[47,102,103],{"class":53},"ui\n",[10,105,106,107,110],{},"And then we just go ahead and create a ",[44,108,109],{},"\u003Cselect>"," tag with the styling and elements required by semantic UI and then add it it in, piece of cake.",[37,112,116],{"className":113,"code":114,"language":115,"meta":42,"style":42},"language-html shiki shiki-themes github-dark","\u003Cselect id=\"MultipleSelect\" multiple=\"\" name=\"skills\" class=\"ui fluid search dropdown form-control\">\n  \u003Coption value='aww'>aww\u003C\u002Foption>\n  \u003Coption value='funny'>funny\u003C\u002Foption>\n  \u003Coption value='memes'>memes\u003C\u002Foption>\n  \u003Coption value='pics'>pics\u003C\u002Foption>\n  \u003Coption value='birdswitharms'>birdswitharms\u003C\u002Foption>\n\u003C\u002Fselect>\n\n\u003Cscript>\n$('.ui.dropdown')\n  .dropdown();\n\u003C\u002Fscript>\n","html",[44,117,118,164,188,209,230,251,272,282,289,299,314,326],{"__ignoreMap":42},[47,119,120,123,127,131,134,137,140,142,145,148,150,153,156,158,161],{"class":49,"line":50},[47,121,122],{"class":53},"\u003C",[47,124,126],{"class":125},"s4JwU","select",[47,128,130],{"class":129},"svObZ"," id",[47,132,133],{"class":53},"=",[47,135,136],{"class":57},"\"MultipleSelect\"",[47,138,139],{"class":129}," multiple",[47,141,133],{"class":53},[47,143,144],{"class":57},"\"\"",[47,146,147],{"class":129}," name",[47,149,133],{"class":53},[47,151,152],{"class":57},"\"skills\"",[47,154,155],{"class":129}," class",[47,157,133],{"class":53},[47,159,160],{"class":57},"\"ui fluid search dropdown form-control\"",[47,162,163],{"class":53},">\n",[47,165,167,170,173,176,178,181,184,186],{"class":49,"line":166},2,[47,168,169],{"class":53},"  \u003C",[47,171,172],{"class":125},"option",[47,174,175],{"class":129}," value",[47,177,133],{"class":53},[47,179,180],{"class":57},"'aww'",[47,182,183],{"class":53},">aww\u003C\u002F",[47,185,172],{"class":125},[47,187,163],{"class":53},[47,189,191,193,195,197,199,202,205,207],{"class":49,"line":190},3,[47,192,169],{"class":53},[47,194,172],{"class":125},[47,196,175],{"class":129},[47,198,133],{"class":53},[47,200,201],{"class":57},"'funny'",[47,203,204],{"class":53},">funny\u003C\u002F",[47,206,172],{"class":125},[47,208,163],{"class":53},[47,210,212,214,216,218,220,223,226,228],{"class":49,"line":211},4,[47,213,169],{"class":53},[47,215,172],{"class":125},[47,217,175],{"class":129},[47,219,133],{"class":53},[47,221,222],{"class":57},"'memes'",[47,224,225],{"class":53},">memes\u003C\u002F",[47,227,172],{"class":125},[47,229,163],{"class":53},[47,231,233,235,237,239,241,244,247,249],{"class":49,"line":232},5,[47,234,169],{"class":53},[47,236,172],{"class":125},[47,238,175],{"class":129},[47,240,133],{"class":53},[47,242,243],{"class":57},"'pics'",[47,245,246],{"class":53},">pics\u003C\u002F",[47,248,172],{"class":125},[47,250,163],{"class":53},[47,252,254,256,258,260,262,265,268,270],{"class":49,"line":253},6,[47,255,169],{"class":53},[47,257,172],{"class":125},[47,259,175],{"class":129},[47,261,133],{"class":53},[47,263,264],{"class":57},"'birdswitharms'",[47,266,267],{"class":53},">birdswitharms\u003C\u002F",[47,269,172],{"class":125},[47,271,163],{"class":53},[47,273,275,278,280],{"class":49,"line":274},7,[47,276,277],{"class":53},"\u003C\u002F",[47,279,126],{"class":125},[47,281,163],{"class":53},[47,283,285],{"class":49,"line":284},8,[47,286,288],{"emptyLinePlaceholder":287},true,"\n",[47,290,292,294,297],{"class":49,"line":291},9,[47,293,122],{"class":53},[47,295,296],{"class":125},"script",[47,298,163],{"class":53},[47,300,302,305,308,311],{"class":49,"line":301},10,[47,303,304],{"class":129},"$",[47,306,307],{"class":53},"(",[47,309,310],{"class":57},"'.ui.dropdown'",[47,312,313],{"class":53},")\n",[47,315,317,320,323],{"class":49,"line":316},11,[47,318,319],{"class":53},"  .",[47,321,322],{"class":129},"dropdown",[47,324,325],{"class":53},"();\n",[47,327,329,331,333],{"class":49,"line":328},12,[47,330,277],{"class":53},[47,332,296],{"class":125},[47,334,163],{"class":53},[10,336,337,338,341,342,347],{},"Life's too short to go through each ",[44,339,340],{},"\u003Coption>"," tag and writing in the content and value so I wrote ",[20,343,346],{"href":344,"rel":345},"https:\u002F\u002Fgist.github.com\u002Fconorbr\u002Fa09ba9662a7cd19154ba0da728a38b96",[24],"this",". As the saying goes, why stand when you can sit.",[10,349,350],{},"And just like that we have a nifty little dropdown menu that had both search functionality and the capacity for multiple selections, nice.",[10,352,353],{},"Having a nice dropdown menu is all well and good but I've kinda shot myself in the foot, with a cannon, while standing on a bag of salt, in mass, during communion. Reading this you can begin to imagine the hacky way I went about this, and to be honest its probably worse than that. So lets see how I shoe-horned a search feature around a dropdown menu.",[10,355,356],{},"well first we need to go ahead and consult the controller, because that is whats going to parse the url that comes in when a search is made.",[37,358,360],{"className":39,"code":359,"language":41,"meta":42,"style":42},"def get_url_params\n    url_params = request.fullpath.split(\"?\")\n    tidy_params = url_params.map { |word| word.gsub('\u002F','') }\n    if url_params == ['\u002F']\n      tidy_params = [\"aww\"]\n    else\n    return tidy_params\n  end\nend\n\n  def index\n    @pictures = Pic.all\n    @params = get_url_params\n  end\n",[44,361,362,370,398,432,451,465,470,478,483,488,492,500,515,525],{"__ignoreMap":42},[47,363,364,367],{"class":49,"line":50},[47,365,366],{"class":90},"def",[47,368,369],{"class":129}," get_url_params\n",[47,371,372,376,379,382,385,388,391,393,396],{"class":49,"line":166},[47,373,375],{"class":374},"s9osk","    url_params",[47,377,378],{"class":90}," =",[47,380,381],{"class":53}," request.",[47,383,384],{"class":129},"fullpath",[47,386,387],{"class":53},".",[47,389,390],{"class":129},"split",[47,392,307],{"class":53},[47,394,395],{"class":57},"\"?\"",[47,397,313],{"class":53},[47,399,400,403,405,408,411,414,418,420,423,426,429],{"class":49,"line":190},[47,401,402],{"class":374},"    tidy_params",[47,404,378],{"class":90},[47,406,407],{"class":53}," url_params.",[47,409,410],{"class":129},"map",[47,412,413],{"class":53}," { |word| word.",[47,415,417],{"class":416},"sDLfK","gsub",[47,419,307],{"class":53},[47,421,422],{"class":57},"'\u002F'",[47,424,425],{"class":53},",",[47,427,428],{"class":57},"''",[47,430,431],{"class":53},") }\n",[47,433,434,437,440,443,446,448],{"class":49,"line":211},[47,435,436],{"class":90},"    if",[47,438,439],{"class":53}," url_params ",[47,441,442],{"class":90},"==",[47,444,445],{"class":53}," [",[47,447,422],{"class":57},[47,449,450],{"class":53},"]\n",[47,452,453,456,458,460,463],{"class":49,"line":232},[47,454,455],{"class":374},"      tidy_params",[47,457,378],{"class":90},[47,459,445],{"class":53},[47,461,462],{"class":57},"\"aww\"",[47,464,450],{"class":53},[47,466,467],{"class":49,"line":253},[47,468,469],{"class":90},"    else\n",[47,471,472,475],{"class":49,"line":274},[47,473,474],{"class":90},"    return",[47,476,477],{"class":53}," tidy_params\n",[47,479,480],{"class":49,"line":284},[47,481,482],{"class":90},"  end\n",[47,484,485],{"class":49,"line":291},[47,486,487],{"class":90},"end\n",[47,489,490],{"class":49,"line":301},[47,491,288],{"emptyLinePlaceholder":287},[47,493,494,497],{"class":49,"line":316},[47,495,496],{"class":90},"  def",[47,498,499],{"class":129}," index\n",[47,501,502,505,507,510,512],{"class":49,"line":328},[47,503,504],{"class":53},"    @pictures ",[47,506,133],{"class":90},[47,508,509],{"class":416}," Pic",[47,511,387],{"class":53},[47,513,514],{"class":129},"all\n",[47,516,518,521,523],{"class":49,"line":517},13,[47,519,520],{"class":53},"    @params ",[47,522,133],{"class":90},[47,524,369],{"class":53},[47,526,528],{"class":49,"line":527},14,[47,529,482],{"class":90},[10,531,532,533,536,537,540,541],{},"So I created a method that will look at the incoming url, find the path and split it into an array every time the ",[44,534,535],{},"?"," deliminator occurs. And if there is nothing just default to the 'aww' category. Now we're getting places because with that we can now pass the ",[44,538,539],{},"get_url_params"," variable into our ",[44,542,543],{},"index.html.erb",[10,545,546],{},"I went ahead and updated the ruby code in the index page to accept this new array and grab each of the categories requested:",[37,548,550],{"className":39,"code":549,"language":41,"meta":42,"style":42},"\u003C% @pictures.where(category: @params).limit(200).each do |data|%>\n  \u003C%= image_tag data.link, :data => { :caption => data.title} %>\n\u003C%end%>\n",[44,551,552,594,616],{"__ignoreMap":42},[47,553,554,557,560,563,565,568,571,574,576,579,582,585,588,591],{"class":49,"line":50},[47,555,556],{"class":90},"\u003C%",[47,558,559],{"class":53}," @pictures.",[47,561,562],{"class":129},"where",[47,564,307],{"class":53},[47,566,567],{"class":416},"category:",[47,569,570],{"class":53}," @params).",[47,572,573],{"class":129},"limit",[47,575,307],{"class":53},[47,577,578],{"class":416},"200",[47,580,581],{"class":53},").",[47,583,584],{"class":129},"each",[47,586,587],{"class":90}," do",[47,589,590],{"class":53}," |data|",[47,592,593],{"class":57},"%>\n",[47,595,596,599,602,605,608,611,614],{"class":49,"line":166},[47,597,598],{"class":57},"  \u003C%= image_tag data.link, :data =>",[47,600,601],{"class":53}," { ",[47,603,604],{"class":416},":caption",[47,606,607],{"class":53}," => data.",[47,609,610],{"class":129},"title",[47,612,613],{"class":53},"} ",[47,615,593],{"class":57},[47,617,618],{"class":49,"line":190},[47,619,620],{"class":57},"\u003C%end%>\n",[10,622,623],{},"now, we just need to be able to search our categories. So coming back full circle now we need to actually get the values the user selects when choosing a category, and for that, what else but JavaScript.",[37,625,629],{"className":626,"code":627,"language":628,"meta":42,"style":42},"language-erb shiki shiki-themes github-dark","  \u003Cscript>\n  $(\"#MultipleSelect\").change(function(getUserSearch){\n      var category_array = []\n      value = $('#MultipleSelect').val().join(\"?\");\n      root = window.location.host\n      search_result_url = \"\u002F?\"+ value\n      document.getElementById(\"burl\").href = search_result_url;\n  });\n  \u003C\u002Fscript>\n","erb",[44,630,631,639,667,680,713,723,739,760,765],{"__ignoreMap":42},[47,632,633,635,637],{"class":49,"line":50},[47,634,169],{"class":53},[47,636,296],{"class":125},[47,638,163],{"class":53},[47,640,641,644,646,649,651,654,656,659,661,664],{"class":49,"line":166},[47,642,643],{"class":129},"  $",[47,645,307],{"class":53},[47,647,648],{"class":57},"\"#MultipleSelect\"",[47,650,581],{"class":53},[47,652,653],{"class":129},"change",[47,655,307],{"class":53},[47,657,658],{"class":90},"function",[47,660,307],{"class":53},[47,662,663],{"class":374},"getUserSearch",[47,665,666],{"class":53},"){\n",[47,668,669,672,675,677],{"class":49,"line":190},[47,670,671],{"class":90},"      var",[47,673,674],{"class":53}," category_array ",[47,676,133],{"class":90},[47,678,679],{"class":53}," []\n",[47,681,682,685,687,690,692,695,697,700,703,706,708,710],{"class":49,"line":211},[47,683,684],{"class":53},"      value ",[47,686,133],{"class":90},[47,688,689],{"class":129}," $",[47,691,307],{"class":53},[47,693,694],{"class":57},"'#MultipleSelect'",[47,696,581],{"class":53},[47,698,699],{"class":129},"val",[47,701,702],{"class":53},"().",[47,704,705],{"class":129},"join",[47,707,307],{"class":53},[47,709,395],{"class":57},[47,711,712],{"class":53},");\n",[47,714,715,718,720],{"class":49,"line":232},[47,716,717],{"class":53},"      root ",[47,719,133],{"class":90},[47,721,722],{"class":53}," window.location.host\n",[47,724,725,728,730,733,736],{"class":49,"line":253},[47,726,727],{"class":53},"      search_result_url ",[47,729,133],{"class":90},[47,731,732],{"class":57}," \"\u002F?\"",[47,734,735],{"class":90},"+",[47,737,738],{"class":53}," value\n",[47,740,741,744,747,749,752,755,757],{"class":49,"line":274},[47,742,743],{"class":53},"      document.",[47,745,746],{"class":129},"getElementById",[47,748,307],{"class":53},[47,750,751],{"class":57},"\"burl\"",[47,753,754],{"class":53},").href ",[47,756,133],{"class":90},[47,758,759],{"class":53}," search_result_url;\n",[47,761,762],{"class":49,"line":284},[47,763,764],{"class":53},"  });\n",[47,766,767,770,772],{"class":49,"line":291},[47,768,769],{"class":53},"  \u003C\u002F",[47,771,296],{"class":125},[47,773,163],{"class":53},[10,775,776,777,779,780],{},"so what's happening above is im grabbing the users input, pusing them into an array, the splitting them up with a ",[44,778,535],{},". Then i go ahead and assign this value to the button i created with the id of ",[44,781,782],{},"burl",[37,784,786],{"className":626,"code":785,"language":628,"meta":42,"style":42},"\u003Ca href=\"?aww\" id=\"burl\" onclick=\"window.location.reload(true);\" class=\"btn btn-default\">Search\u003C\u002Fa>\n",[44,787,788],{"__ignoreMap":42},[47,789,790,792,794,797,799,802,804,806,808,811,813,816,819,821,824,826,829,831,834,837,839,841,844,847,849],{"class":49,"line":50},[47,791,122],{"class":53},[47,793,20],{"class":125},[47,795,796],{"class":129}," href",[47,798,133],{"class":53},[47,800,801],{"class":57},"\"?aww\"",[47,803,130],{"class":129},[47,805,133],{"class":53},[47,807,751],{"class":57},[47,809,810],{"class":129}," onclick",[47,812,133],{"class":53},[47,814,815],{"class":57},"\"",[47,817,818],{"class":53},"window",[47,820,387],{"class":57},[47,822,823],{"class":53},"location",[47,825,387],{"class":57},[47,827,828],{"class":129},"reload",[47,830,307],{"class":57},[47,832,833],{"class":416},"true",[47,835,836],{"class":57},");\"",[47,838,155],{"class":129},[47,840,133],{"class":53},[47,842,843],{"class":57},"\"btn btn-default\"",[47,845,846],{"class":53},">Search\u003C\u002F",[47,848,20],{"class":125},[47,850,163],{"class":53},[10,852,853,854,857],{},"Just a side note, I added a ",[44,855,856],{},"window.location.reload()"," function to this button to refresh the page just to avoid anything weird going on when reloading the DOM. It works without it but having this means that nothing weird will happen when doing multiple searches in a row.",[10,859,860],{},"now lets take a gander and see what this abomination looks like",[10,862,863],{},[864,865],"img",{"alt":42,"src":866},"\u002Fimages\u002Fposts\u002F2017\u002F10\u002FScreen-Shot-2017-10-27-at-09.23.23.png",[10,868,869],{},"Aaaaaaand thats it really, it works a treat to my surprise, but the points of failure on this are pretty high. but hey, it's not stupid if it works!",[10,871,872,873],{},"next: ",[20,874,876],{"href":875},"\u002F2017\u002F12\u002F28\u002Fruby-on-rails-part-6-f-ck-it-well-do-it-live","Ruby on Rails - part 6: F*ck it we'll do it live",[878,879,880],"style",{},"html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}",{"title":42,"searchDepth":166,"depth":166,"links":882},[],"2017-10-28 21:54","md",{},"\u002F2017\u002F10\u002F28\u002Fruby-on-rails-part-5-searching-for-love",{"title":5,"description":12},"2017\u002F10\u002F28\u002Fruby-on-rails-part-5-searching-for-love",null,"pJdXk1Eo4HUqfXvTIXOjARX-0pleckBrVxzKsQVQ3Ww",1791634646178]