Проблема с добавлением текста подсказки в поле поиска таблицы данных Jquery - PullRequest
8 голосов
/ 05 декабря 2011

Использование плагина, такого как watermark.js, для добавления серого текста подсказки в поле поиска таблицы данных Jquery не вариант, я должен написать его на заказ.Я почти там, но столкнулся с этой незначительной и странной проблемой, объясненной ниже в следующем фрагменте кода.

function toggleHintText()
{
    // alert("The hint text should show up"); 
    var textSuggest = "Please input search parameter";
    var searchField = $('input:text');

    searchField .attr("value", textSuggest );
    searchField .addClass("activeHint");

    searchField .focus(function() {
    if(searchField .attr("value") == textSuggest)
    {
        searchField .attr("value", "");
    }
    });

    searchField .keyup(function() {             
    if(searchField .attr("value") == "") 
    {
      searchField .addClass("activeHint");
    }
    else
    {
      searchField .removeClass("activeHint");   
    }
    });     

    searchField .blur(function() {
    if(searchField .attr("value") == "")
    {
        searchField .attr("value", hinttext);
        searchField .addClass("activeHint");
    }
    });   

}

Этот метод называется onload, как показано ниже

$(document).ready(function() {
populateTableData();
toggleHintText();
} );

=================================================================================================

Проблема, с которой я сталкиваюсь, заключается в том, что без предупреждения, которое я имею в начале метода,Текст подсказки не отображается в окне поиска.Есть ли предупреждение, как работает в пользу document.ready?Вызывает ли вызов двух методов из document.ready метод toggleHint?Одно из моих требований - сохранить введенный пользователем текст поиска, если он нажимает на строку таблицы после поискового запроса, а затем нажимает пользовательскую кнопку «назад», поэтому мне нужно вызывать ее из document.ready.

Пожалуйста, сообщите и спасибо заранее.

Ответы [ 2 ]

4 голосов
/ 17 мая 2015

Попробуйте использовать .queue(), .delay(), .keyup()

$(document).ready(function() {
  var data = $("#example");
  data.DataTable();
  $("input[type=search]")
    .on("keyup", {
      // if input , delay until no input for 1.2 seconds
      "delay": 1200
    }, function(e) {
      var elem = $(this);
      var update = function update() {
        // wait 1.2 seconds to update `val` with "hint"
        if ($.now() - e.timeStamp > e.data.delay 
            && e.target.value.length > 0 && !/^\s/.test(e.target.value)) {
          var val = e.target.value.toLowerCase();
          // filter `.DataTable().data()`
          // return items where first index matches `val`
          var res = $.grep(data.DataTable().data(), function(value, key) {
              return val === value[0].slice(0, val.length).toLowerCase() 
                     || new RegExp(val, "i").test(value[0])
            })
            // sort returned data
            .sort()
            // filter returned data `res` for match to `val`
            .filter(function(hint) {
              return hint[0].toLowerCase().slice(0, val.length) === val 
                     || new RegExp(val, "i").test(hint) 
            })[0];
          elem.val(res[0])
          .css({
            "color": "grey",
            "fontStyle": "italic"
          });
        } else {
          return elem.queue("update", update)
        }
      };
      var defer = function defer(next) {
        // if input before 1.2 seconds ,
        // empty `"update"` queue , delay calling 
        // update until no input for 1.2 seconds
        elem.queue("update", [])
        elem.delay(e.data.delay, "update")
        .queue("update").push(update);
        return next()
      };
      // if input, do stuff
      if (e.target.value.length > 0) {
          elem
          .queue("update", defer)
          .dequeue("update")
      } else {
        elem
        .queue("update", [])
      }
    }).keyup()
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<link href="https://cdn.datatables.net/1.10.7/css/jquery.dataTables.css" rel="stylesheet" />
<script src="https://cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
<table id="example" class="display" cellspacing="0" width="100%">
  <thead>
    <tr>
      <th>Name</th>
      <th>Position</th>
      <th>Office</th>
      <th>Age</th>
      <th>Start date</th>
      <th>Salary</th>
    </tr>
  </thead>
  <tfoot>
    <tr>
      <th>Name</th>
      <th>Position</th>
      <th>Office</th>
      <th>Age</th>
      <th>Start date</th>
      <th>Salary</th>
    </tr>
  </tfoot>
  <tbody>
    <tr>
      <td>Tiger Nixon</td>
      <td>System Architect</td>
      <td>Edinburgh</td>
      <td>61</td>
      <td>2011/04/25</td>
      <td>$320,800</td>
    </tr>
    <tr>
      <td>Garrett Winters</td>
      <td>Accountant</td>
      <td>Tokyo</td>
      <td>63</td>
      <td>2011/07/25</td>
      <td>$170,750</td>
    </tr>
    <tr>
      <td>Ashton Cox</td>
      <td>Junior Technical Author</td>
      <td>San Francisco</td>
      <td>66</td>
      <td>2009/01/12</td>
      <td>$86,000</td>
    </tr>
    <tr>
      <td>Cedric Kelly</td>
      <td>Senior Javascript Developer</td>
      <td>Edinburgh</td>
      <td>22</td>
      <td>2012/03/29</td>
      <td>$433,060</td>
    </tr>
    <tr>
      <td>Airi Satou</td>
      <td>Accountant</td>
      <td>Tokyo</td>
      <td>33</td>
      <td>2008/11/28</td>
      <td>$162,700</td>
    </tr>
    <tr>
      <td>Brielle Williamson</td>
      <td>Integration Specialist</td>
      <td>New York</td>
      <td>61</td>
      <td>2012/12/02</td>
      <td>$372,000</td>
    </tr>
    <tr>
      <td>Herrod Chandler</td>
      <td>Sales Assistant</td>
      <td>San Francisco</td>
      <td>59</td>
      <td>2012/08/06</td>
      <td>$137,500</td>
    </tr>
    <tr>
      <td>Rhona Davidson</td>
      <td>Integration Specialist</td>
      <td>Tokyo</td>
      <td>55</td>
      <td>2010/10/14</td>
      <td>$327,900</td>
    </tr>
    <tr>
      <td>Colleen Hurst</td>
      <td>Javascript Developer</td>
      <td>San Francisco</td>
      <td>39</td>
      <td>2009/09/15</td>
      <td>$205,500</td>
    </tr>
    <tr>
      <td>Sonya Frost</td>
      <td>Software Engineer</td>
      <td>Edinburgh</td>
      <td>23</td>
      <td>2008/12/13</td>
      <td>$103,600</td>
    </tr>
    <tr>
      <td>Jena Gaines</td>
      <td>Office Manager</td>
      <td>London</td>
      <td>30</td>
      <td>2008/12/19</td>
      <td>$90,560</td>
    </tr>
    <tr>
      <td>Quinn Flynn</td>
      <td>Support Lead</td>
      <td>Edinburgh</td>
      <td>22</td>
      <td>2013/03/03</td>
      <td>$342,000</td>
    </tr>
    <tr>
      <td>Charde Marshall</td>
      <td>Regional Director</td>
      <td>San Francisco</td>
      <td>36</td>
      <td>2008/10/16</td>
      <td>$470,600</td>
    </tr>
    <tr>
      <td>Haley Kennedy</td>
      <td>Senior Marketing Designer</td>
      <td>London</td>
      <td>43</td>
      <td>2012/12/18</td>
      <td>$313,500</td>
    </tr>
    <tr>
      <td>Tatyana Fitzpatrick</td>
      <td>Regional Director</td>
      <td>London</td>
      <td>19</td>
      <td>2010/03/17</td>
      <td>$385,750</td>
    </tr>
    <tr>
      <td>Michael Silva</td>
      <td>Marketing Designer</td>
      <td>London</td>
      <td>66</td>
      <td>2012/11/27</td>
      <td>$198,500</td>
    </tr>
    <tr>
      <td>Paul Byrd</td>
      <td>Chief Financial Officer (CFO)</td>
      <td>New York</td>
      <td>64</td>
      <td>2010/06/09</td>
      <td>$725,000</td>
    </tr>
    <tr>
      <td>Gloria Little</td>
      <td>Systems Administrator</td>
      <td>New York</td>
      <td>59</td>
      <td>2009/04/10</td>
      <td>$237,500</td>
    </tr>
    <tr>
      <td>Bradley Greer</td>
      <td>Software Engineer</td>
      <td>London</td>
      <td>41</td>
      <td>2012/10/13</td>
      <td>$132,000</td>
    </tr>
    <tr>
      <td>Dai Rios</td>
      <td>Personnel Lead</td>
      <td>Edinburgh</td>
      <td>35</td>
      <td>2012/09/26</td>
      <td>$217,500</td>
    </tr>
    <tr>
      <td>Jenette Caldwell</td>
      <td>Development Lead</td>
      <td>New York</td>
      <td>30</td>
      <td>2011/09/03</td>
      <td>$345,000</td>
    </tr>
    <tr>
      <td>Yuri Berry</td>
      <td>Chief Marketing Officer (CMO)</td>
      <td>New York</td>
      <td>40</td>
      <td>2009/06/25</td>
      <td>$675,000</td>
    </tr>
    <tr>
      <td>Caesar Vance</td>
      <td>Pre-Sales Support</td>
      <td>New York</td>
      <td>21</td>
      <td>2011/12/12</td>
      <td>$106,450</td>
    </tr>
    <tr>
      <td>Doris Wilder</td>
      <td>Sales Assistant</td>
      <td>Sidney</td>
      <td>23</td>
      <td>2010/09/20</td>
      <td>$85,600</td>
    </tr>
    <tr>
      <td>Angelica Ramos</td>
      <td>Chief Executive Officer (CEO)</td>
      <td>London</td>
      <td>47</td>
      <td>2009/10/09</td>
      <td>$1,200,000</td>
    </tr>
    <tr>
      <td>Gavin Joyce</td>
      <td>Developer</td>
      <td>Edinburgh</td>
      <td>42</td>
      <td>2010/12/22</td>
      <td>$92,575</td>
    </tr>
    <tr>
      <td>Jennifer Chang</td>
      <td>Regional Director</td>
      <td>Singapore</td>
      <td>28</td>
      <td>2010/11/14</td>
      <td>$357,650</td>
    </tr>
    <tr>
      <td>Brenden Wagner</td>
      <td>Software Engineer</td>
      <td>San Francisco</td>
      <td>28</td>
      <td>2011/06/07</td>
      <td>$206,850</td>
    </tr>
    <tr>
      <td>Fiona Green</td>
      <td>Chief Operating Officer (COO)</td>
      <td>San Francisco</td>
      <td>48</td>
      <td>2010/03/11</td>
      <td>$850,000</td>
    </tr>
    <tr>
      <td>Shou Itou</td>
      <td>Regional Marketing</td>
      <td>Tokyo</td>
      <td>20</td>
      <td>2011/08/14</td>
      <td>$163,000</td>
    </tr>
    <tr>
      <td>Michelle House</td>
      <td>Integration Specialist</td>
      <td>Sidney</td>
      <td>37</td>
      <td>2011/06/02</td>
      <td>$95,400</td>
    </tr>
    <tr>
      <td>Suki Burks</td>
      <td>Developer</td>
      <td>London</td>
      <td>53</td>
      <td>2009/10/22</td>
      <td>$114,500</td>
    </tr>
    <tr>
      <td>Prescott Bartlett</td>
      <td>Technical Author</td>
      <td>London</td>
      <td>27</td>
      <td>2011/05/07</td>
      <td>$145,000</td>
    </tr>
    <tr>
      <td>Gavin Cortez</td>
      <td>Team Leader</td>
      <td>San Francisco</td>
      <td>22</td>
      <td>2008/10/26</td>
      <td>$235,500</td>
    </tr>
    <tr>
      <td>Martena Mccray</td>
      <td>Post-Sales support</td>
      <td>Edinburgh</td>
      <td>46</td>
      <td>2011/03/09</td>
      <td>$324,050</td>
    </tr>
    <tr>
      <td>Unity Butler</td>
      <td>Marketing Designer</td>
      <td>San Francisco</td>
      <td>47</td>
      <td>2009/12/09</td>
      <td>$85,675</td>
    </tr>
    <tr>
      <td>Howard Hatfield</td>
      <td>Office Manager</td>
      <td>San Francisco</td>
      <td>51</td>
      <td>2008/12/16</td>
      <td>$164,500</td>
    </tr>
    <tr>
      <td>Hope Fuentes</td>
      <td>Secretary</td>
      <td>San Francisco</td>
      <td>41</td>
      <td>2010/02/12</td>
      <td>$109,850</td>
    </tr>
    <tr>
      <td>Vivian Harrell</td>
      <td>Financial Controller</td>
      <td>San Francisco</td>
      <td>62</td>
      <td>2009/02/14</td>
      <td>$452,500</td>
    </tr>
    <tr>
      <td>Timothy Mooney</td>
      <td>Office Manager</td>
      <td>London</td>
      <td>37</td>
      <td>2008/12/11</td>
      <td>$136,200</td>
    </tr>
    <tr>
      <td>Jackson Bradshaw</td>
      <td>Director</td>
      <td>New York</td>
      <td>65</td>
      <td>2008/09/26</td>
      <td>$645,750</td>
    </tr>
    <tr>
      <td>Olivia Liang</td>
      <td>Support Engineer</td>
      <td>Singapore</td>
      <td>64</td>
      <td>2011/02/03</td>
      <td>$234,500</td>
    </tr>
    <tr>
      <td>Bruno Nash</td>
      <td>Software Engineer</td>
      <td>London</td>
      <td>38</td>
      <td>2011/05/03</td>
      <td>$163,500</td>
    </tr>
    <tr>
      <td>Sakura Yamamoto</td>
      <td>Support Engineer</td>
      <td>Tokyo</td>
      <td>37</td>
      <td>2009/08/19</td>
      <td>$139,575</td>
    </tr>
    <tr>
      <td>Thor Walton</td>
      <td>Developer</td>
      <td>New York</td>
      <td>61</td>
      <td>2013/08/11</td>
      <td>$98,540</td>
    </tr>
    <tr>
      <td>Finn Camacho</td>
      <td>Support Engineer</td>
      <td>San Francisco</td>
      <td>47</td>
      <td>2009/07/07</td>
      <td>$87,500</td>
    </tr>
    <tr>
      <td>Serge Baldwin</td>
      <td>Data Coordinator</td>
      <td>Singapore</td>
      <td>64</td>
      <td>2012/04/09</td>
      <td>$138,575</td>
    </tr>
    <tr>
      <td>Zenaida Frank</td>
      <td>Software Engineer</td>
      <td>New York</td>
      <td>63</td>
      <td>2010/01/04</td>
      <td>$125,250</td>
    </tr>
    <tr>
      <td>Zorita Serrano</td>
      <td>Software Engineer</td>
      <td>San Francisco</td>
      <td>56</td>
      <td>2012/06/01</td>
      <td>$115,000</td>
    </tr>
    <tr>
      <td>Jennifer Acosta</td>
      <td>Junior Javascript Developer</td>
      <td>Edinburgh</td>
      <td>43</td>
      <td>2013/02/01</td>
      <td>$75,650</td>
    </tr>
    <tr>
      <td>Cara Stevens</td>
      <td>Sales Assistant</td>
      <td>New York</td>
      <td>46</td>
      <td>2011/12/06</td>
      <td>$145,600</td>
    </tr>
    <tr>
      <td>Hermione Butler</td>
      <td>Regional Director</td>
      <td>London</td>
      <td>47</td>
      <td>2011/03/21</td>
      <td>$356,250</td>
    </tr>
    <tr>
      <td>Lael Greer</td>
      <td>Systems Administrator</td>
      <td>London</td>
      <td>21</td>
      <td>2009/02/27</td>
      <td>$103,500</td>
    </tr>
    <tr>
      <td>Jonas Alexander</td>
      <td>Developer</td>
      <td>San Francisco</td>
      <td>30</td>
      <td>2010/07/14</td>
      <td>$86,500</td>
    </tr>
    <tr>
      <td>Shad Decker</td>
      <td>Regional Director</td>
      <td>Edinburgh</td>
      <td>51</td>
      <td>2008/11/13</td>
      <td>$183,000</td>
    </tr>
    <tr>
      <td>Michael Bruce</td>
      <td>Javascript Developer</td>
      <td>Singapore</td>
      <td>29</td>
      <td>2011/06/27</td>
      <td>$183,000</td>
    </tr>
    <tr>
      <td>Donna Snider</td>
      <td>Customer Support</td>
      <td>New York</td>
      <td>27</td>
      <td>2011/01/25</td>
      <td>$112,000</td>
    </tr>
  </tbody>
</table>

jsfiddle http://jsfiddle.net/o98cpxmf/2/

3 голосов
/ 21 мая 2015

«Предупреждает ли кто-нибудь, как работает в пользу document.ready?»

Конечно. Но не в пользу document.ready, а в пользу «динамически загружаемых данных таблицы .ready».

Смотрите ваш второй фрагмент кода:

  • Сначала вы вызываете populateTableData (): я рассчитываю асинхронно прочитать данные, вероятно, с удаленного сервера через Ajax-запрос.

  • И затем вы вызываете toggleHintText () для реализации эффекта переключения над строками таблицы, и я выясняю, что некоторый обратный вызов, реализованный внутри populateTableData (), будет добавляться, как только завершится запрос Ajax (или аналогичная асинхронная операция).

Javascript является однопоточным (что означает, что ваш код выполняется в одном потоке и, следовательно, не содержит параллелизма), но не полностью свободен от параллелизма, поскольку асинхронные операции сопровождаются другими параллельные потоки, работающие или ожидающие завершения необходимых операций, а затем (инициированное событие завершения) помещают задачу в цикл основных задач javascript (обработчик событий, присоединенный к этому элементу).

Вызов alert () останавливает выполнение основного цикла javascript, но не параллельные потоки, посещающие асинхронные задачи.

Таким образом, он может успешно завершить операцию запроса Ajax (даже без сбоя тайм-аута сервера из-за «паузы оповещения») и вызвать событие завершения.

... Но обратный вызов, прикрепленный к этому событию, не будет выполнен, пока не продолжится цикл задач javascript.

Ваша функция toggleHintText () вызывается SURE до того, как данные вашей таблицы заполнены, и без оповещения () остальная часть ее кода НЕ найдет никаких элементов в этой таблице (или, по крайней мере, новых элементов, заполненных populateTableData ()). ).

Таким образом, существует причина, по которой без предупреждения () ваш код не работает.

Но я не уверен, почему это работает даже с предупреждением. Я выяснил, что ваш браузер может реализовать остановку оповещения как «paused nextTick ()» и выполнить, по крайней мере, ожидающие обработчики событий, как можно скорее (но я думаю, что это не совсем правильно в спецификации javascript).

Чтобы избежать этой проблемы, необходимо вызвать toggleHintText (), когда вы уверены , что данные заполнены в таблице. То есть:

  • Вызовите его из обработчика событий, который заполняет данные о (предполагаемом) завершении запроса Ajax.

  • Запустите свой собственный элемент в этот момент и прикрепите toggleHint () в качестве его обработчика события.

Также можно изменить обработчики событий toggleHintText (), которые будут присоединены к самим таблицам (или ко всему документу), а не к более поздним динамически загружаемым элементам, а затем проверить цель события.

Это то, что сделал устаревший метод .live () jquery и что в настоящее время может быть достигнуто просто с помощью .on () и целевого селектора. Например:

В вашем коде:

var searchField = $('input:text');
...
searchField.focus(function() {...});

... последняя строка эквивалентна:

searchField.on("focus", function(){});

Вы можете заменить его (например) на:

$("body").on("focus", 'input:text', function(){...});

Таким образом, обработчик событий присоединяется непосредственно к телу документа, и при каждом событии фокуса он будет проверять, соответствует ли цель указанному селектору (независимо от того, был ли элемент создан перед вложением обработчика событий или нет).

В итоге: вы не можете прикрепить обработчик событий к элементу, который еще не существует.

С другой стороны, у вас есть некоторые элементы управления, такие как добавление классов и атрибутов. Вы не можете сделать это до создания элемента, но, аналогично, вы можете прикрепить обработчик события к его событию "creation".

Но, к сожалению, этого события на самом деле не существует. Но есть методы, чтобы реализовать это через событие dom change. См. этот вопрос о плагине liveQuery.

...