A semantic search engine for source code https://bitshift.benkurtovic.com/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.advanced-search-form.js 5.1 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. /*
  2. * @file Manages all advanced search form logic.
  3. */
  4. var searchGroups = $("div#search-groups");
  5. /*
  6. * Load all advanced search form libraries.
  7. */
  8. (function loadInputFieldWidgets(){
  9. $(".search-group input#date-last-modified").datepicker();
  10. $(".search-group input#date-created").datepicker();
  11. $("#autocomplete").autocomplete({
  12. source: function(request, response){
  13. var matcher = new RegExp(
  14. $.ui.autocomplete.escapeRegex(request.term), "i");
  15. response($.grep(AUTOCOMPLETE_LANGUAGES, function(item){
  16. return matcher.test(item);
  17. }));
  18. }
  19. });
  20. }());
  21. /*
  22. * Set all advanced search form button callbacks.
  23. */
  24. (function setSearchFormCallbacks(){
  25. // Create a new search group, and update the `#sidebar` checklist.
  26. $("button#add-group").click(function(){
  27. $("div#sidebar input[type=checkbox]").prop("checked", false);
  28. searchGroups.children("#selected").removeAttr("id");
  29. var searchGroup = $("<div/>", {class : "search-group", id : "selected"});
  30. searchGroups.append(
  31. searchGroup.append(createSearchGroupInput("language")));
  32. $("div#sidebar input[type=checkbox]#language").prop("checked", true);
  33. });
  34. // Remove the currently selected group if it's not the only one, and mark
  35. // one of its siblings as selected.
  36. $("button#remove-group").click(function(){
  37. var currentGroup = $("div.search-group#selected");
  38. if($("div.search-group").length == 1)
  39. return;
  40. else {
  41. var nextGroup = currentGroup.prev();
  42. if(nextGroup.size() == 0)
  43. nextGroup = currentGroup.next();
  44. }
  45. currentGroup.remove();
  46. nextGroup.click();
  47. });
  48. // Select a search group, and update the `#sidebar` checklist accordingly.
  49. $(document).on("click", "div.search-group", function(){
  50. searchGroups.children("#selected").removeAttr("id");
  51. $(this).attr("id", "selected");
  52. $("div#sidebar input[type=checkbox]").prop("checked", false);
  53. $(this).find("input[type=text]").each(function(){
  54. var checkBoxSelector = "div#sidebar input[type=checkbox]";
  55. $(checkBoxSelector + "#" + $(this).attr("class").split(" ")[0]).
  56. prop("checked", true);
  57. })
  58. });
  59. // Add an input field to the currently selected search group.
  60. $("div#sidebar input[type=checkbox]").click(function(){
  61. var fieldId = $(this).prop("id");
  62. if($(this).is(":checked")){
  63. $("div.search-group#selected").append(
  64. $.parseHTML(createSearchGroupInput(fieldId)));
  65. if(fieldId.slice(0, 4) == "date")
  66. $(".search-group#selected ." + fieldId).datepicker();
  67. }
  68. else
  69. $("div.search-group#selected #" + fieldId).remove()
  70. });
  71. }());
  72. /*
  73. * Return an HTML string representing a new input field div in a search group.
  74. *
  75. * @param fieldId The id of the input field div, and its child elements.
  76. */
  77. function createSearchGroupInput(fieldId){
  78. return [
  79. "<div id='" + fieldId + "'>",
  80. "<div class='name'>" + fieldId.replace(/-/g, " ") + "</div>",
  81. "<input class='" + fieldId + "' name='" + fieldId + "'type='text'>",
  82. "<input type='checkbox' name='regex'><span>Regex</span>",
  83. "</div>"
  84. ].join("");
  85. }
  86. /*
  87. * Create a query from advanced-search groups.
  88. */
  89. function assembleQuery(){
  90. var groups = searchGroups.children(".search-group");
  91. var groupQueries = [];
  92. for(var group = 0; group < groups.length; group++){
  93. var inputFields = groups[group].querySelectorAll("input[type=text]");
  94. var regexCheckbox = groups[group].querySelectorAll("input[name=regex]");
  95. var groupQuery = [];
  96. for(var field = 0; field < inputFields.length; field++)
  97. if(inputFields[field].value.length > 0)
  98. groupQuery.push(genFieldQueryString(
  99. inputFields[field], regexCheckbox[field].checked));
  100. groupQueries.push(groupQuery.join(" AND "));
  101. }
  102. console.log(groupQueries.join(" OR "));
  103. }
  104. /*
  105. * Generate a processed query string for an input field's value.
  106. *
  107. * @param field (DOM element) An `input[type=text]` element.
  108. * @param hasRegex (boolean) Whether or not the field's value has regex.
  109. */
  110. function genFieldQueryString(field, hasRegex){
  111. var terms = field.value.replace(/\\/g, "\\\\").replace(/\"/g, "\\\"");
  112. var query = field.getAttribute("name") + ":" + ((hasRegex)?"re:":"") + terms;
  113. if(field.value.indexOf('"') >= 0){
  114. // ['"', field.getAttribute("name"), ":", regex?"re:":"", terms, '"']
  115. return '"' + query + '"';
  116. }
  117. return query;
  118. }
  119. (function testQueryStringGeneration(){
  120. var sampleStrings = [
  121. "A B",
  122. "A \\ B",
  123. '"A \\" B"',
  124. '"A \\" B" C D "A B"',
  125. ];
  126. for(var string = 0; string < sampleStrings.length; string++)
  127. console.log([
  128. (sampleStrings[string] + " ").slice(0, 12),
  129. ":",
  130. " " + genFieldQueryString($("<input>").val(sampleStrings[string])[0])
  131. ].join(""));
  132. })();