2015-07-27 3 views
0

Я пытаюсь добавить параметр автозаполнения в поле заголовка в Wordpress. Заголовки одного из моих типов документов часто (но не всегда) имеют стандартное имя.Почему мой элемент ajax сразу теряет фокус?

Я зацепил в Wordpress, чтобы добавить div с идентификатором suggestions ниже title и добавьте яваскрипт onKeyUp события заголовок говорит это, чтобы сделать запрос Ajax на страницу, которая предлагает имена, основанные на том, что набрано до сих пор. Все это прекрасно работает.

В настоящее время, однако, я могу только выбрать предложения через mouseclick (который затем использует val для обновления значения #title.Я также хотел бы, чтобы пользователи могли использовать клавиши со стрелками, чтобы выбрать предложение ., а-ля Google

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

Это работает на долю секунды - ожидаемый элемент получает фокус - но потом он сразу теряет его, возвращаясь к body. Почему это происходит?

Код для gethint.php:

<?php 

$sofar = stripslashes($_GET['sofar']); // This is important as otherwise the url gets confused and won't work on anything with an apostrophe in it. 

$common_file_names = array(
    "Here's suggestion 1", 
    "This is suggestion 2", 
    "Suggestion 3"); 
if(strlen($_GET['sofar'])>1) { //Ignores single letters 
    echo '<ul id="autocomplete">'; 
    $tabindex=0; 
    foreach ($common_file_names as $suggestion) { 
     if(false !== stripos($suggestion, $sofar)) : ?> 
      <li 
      tabindex="<?=$tabindex?>" 
      onClick="acceptSuggestion('<?=addslashes($suggestion)?>')" 
      onBlur="console.log('Lost focus!'); console.log(document.activeElement);"; 
      ><?=$suggestion?></li> 
     <?php $tabindex++; endif; 

    } 
    echo '</ul>'; 
} 
?> 

JS код:

$.ajaxSetup({ cache: false }); 

window.onload = function() { 
    $("<div id='suggestions'></div>").insertAfter("#title"); 

    $(document).on('keydown', '#title', function(){ 
      var hint_slash = this.value; 
      showHint(hint_slash); 
      checkKey(event); 
    }); 



    $(document).on('focus', '#acf-field-extranet_client_area', function(){ 
     clearSuggestions(); 
    }); 
    $(document).on('focus', '#acf-field-extranet_document_type', function(){ 
     clearSuggestions(); 
    }); 
    $(document).on('focus', '#acf-date_picker', function(){ 
     clearSuggestions(); 
    }); 
    $(document).on('focus', '#acf-file-value', function(){ 
     clearSuggestions(); 
    }); 


    console.log("Scripts loaded successfully"); 
} 

function showHint(str) { //If the user has typed 2 or more characters, this function looks for possible matches among common document names to speed up data entry. 
    var xmlhttp = new XMLHttpRequest(); 
     xmlhttp.onreadystatechange = function() { 
      if (xmlhttp.readyState == 4 && xmlhttp.status == 200) { 
       document.getElementById("suggestions").innerHTML = xmlhttp.responseText; 
      } 
     } 
     xmlhttp.open("GET", "/gethint.php?sofar=" + str, true); 
     xmlhttp.send(); 
} 


function acceptSuggestion(str) { 
    $('#title').val(str); //Puts the clicked suggestion into the title box. 
    clearSuggestions(); 
} 

function clearSuggestions() { 
    showHint(""); //Clears suggestions. 
} 

function checkKey(event) { 
    console.log('Key press: ' + event.keyCode); 
    if(40 == event.keyCode) { 
     event.preventDefault(); // Stops scrolling. 
     var autocomplete = $("#autocomplete"); 
     $(autocomplete.children('li:nth-child(' + 2 + ')')).focus() ; 
     console.log(document.activeElement); 
     } 

    } 

Это просто тестовый код в настоящее время, следовательно, всегда устанавливая фокус на 3-й дочерний элемент.

ответ

0

Опираясь на ответ @ evilunix, я понял, что каждый нажатие клавиши сбросило #suggestions div, что означало, что он никогда не сможет удерживать фокус (или сохранить добавленный класс и т. д.).

Итак, написал новую функцию под названием checkKey:

function checkKey(e) { 
    if(e.which == 38) { 
     // up key 
     e.preventDefault(); //Stops scrolling and cursor movement. 
     var active = $('#suggestions li.active'); 
     if(active.length) { 
      active.removeClass('active'); 
      active.prev().addClass('active'); 
     } else { 
      $('#suggestions li:last').addClass('active'); 
     } 
    } else if(e.which == 40) { 
     // down key 
     e.preventDefault(); //Stops scrolling and cursor movement. 
     var active = $('#suggestions li.active'); 
     if(active.length) { 
      active.removeClass('active'); 
      active.next().addClass('active'); 
     } else { 
      $('#suggestions li:first').addClass('active'); 
     } 
    } else if(e.which == 13) { 
     //Return key 
     e.preventDefault(); //Stops form submission. 
     acceptSuggestion(document.getElementsByClassName('active')[0].innerHTML); 
    } else { 
     console.log(e.which); 
     showHint($('#title').val());  
    } 
} 

и изменил #title «s OnKeyDown событие:

$(document).on('keydown', '#title', function(){ 
     checkKey(event); 
}); 

Теперь #suggestions только освежает, если нажатие клавиши не стрелка вверх, вниз стрелка или возврат, а также с возвратом acceptSuggestion на какой бы то ни было li класс active.

1

Я бы не стал фокусироваться на предложениях. В этом случае вам нужно будет добавить код проверки ключей для каждого предложения, потому что вход потеряет фокус. Вместо этого можно создать класс CSS для «сфокусированного» предложение, удалить класс на клавишу вверх/вниз и добавить его к предыдущему/следующему предложению ...

$input.keyup(function(e) { 

    if(e.which == 38) { 
     // up key 
     var active = $('.suggestions li.active'); 
     if(active.length) { 
      active.removeClass('active'); 
      active.prev().addClass('active'); 
     } else { 
      $('.suggestions li:last').addClass('active'); 
     } 
    } else if(e.which == 40) { 
     // down key 
     var active = $('.suggestions li.active'); 
     if(active.length) { 
      active.removeClass('active'); 
      active.next().addClass('active'); 
     } else { 
      $('.suggestions li:first').addClass('active'); 
     } 

    } 
}); 
+0

У этой проблемы все еще есть та же проблема: элемент получает класс «активен» на долю секунды, а затем теряет его. Я подозреваю, что showHint - это освежающие предложения даже при нажатии клавиши со стрелкой вниз. – BFWebAdmin

+1

А, да, это будет так. Самое простое решение - проверить, что вы никогда не отправляете один и тот же запрос два раза подряд, сохраняя последний запрос, к которому у вас успешно были предложения. Вы должны использовать этот код вместо фокусировки, иначе ваш вход потеряет фокус. – evilunix