2012-06-01 3 views
25

У меня есть выпадающее меню, которое инициализируется одним единственным значением. Когда пользователь нажимает на него, удаляется один элемент и добавляется новый элемент, говорящий «Загрузка», затем на сервер выдается вызов AJAX, а при возврате новые значения добавляются в элемент управления.Закройте раскрывающийся список SELECT программно с помощью Javascript/jQuery

Проблема в том, что элемент управления остается открытым во время обновления, и я хотел бы закрыть его.

Это пример: http://jsfiddle.net/vtortola/CGuBk/2/

AJAX На примере в не получает данные, вероятно, потому, что что-то не так, что я делаю при вызове jsfiddle апи, но он показывает, как ВЫБРАТЬ остается открытым во время обновления.

Я хочу знать, как закрыть выпадающий список программно без фокуса на другом входе.

Cheers.

ответ

12

Я не уверен ни о ком другом, но я использую самую последнюю стабильную сборку Chrome, и ни один из других ответов, связанных с .blur(), не работает для меня.

Этот вопрос задает обратное: Programmatically open a drop-down menu

вывод, что, казалось, получается, что это не представляется возможным из-за тем, как браузер обрабатывает щелчки поле элемента.

Лучшим решением было бы заменить выпадающий текст на чистый HTML-код и спрятать его при необходимости с помощью простой команды .hide().

+0

при смене текстового поля я открываю окно «подсказка». Если это изменение происходит при нажатии кнопки выбора, я избегаю теперь тревожного выпадающего списка, скрывая выбранные перед тем, как будет показано ниже, и показывается снова после подсказки. visibleselects = $ ('select: visible'). hide(); ... visibleselects.show(); –

12

Просто добавьте эту строку в конец вашего закрытия в пределах click.

$(this).blur(); 

Так это будет выглядеть

$select.click(function(e){ 

    $select.html('<option value="-1">Loading</option>'); 

    $(this).blur(); 
    ...... 
    ... 
}); 

DEMO

Хах! Если у нас есть проблемы с Chrome новой версии, то:

Возьмите фальшивый select как следующее:

<select class="fake" style="display: none"> 
    <option value="-1">Loading</option> 
</select> 

и сделать что-то вроде:

$select.click(function(e) { 
    $(this).hide(0); // hide current select box 

    //$select.html('<option value="-1">Loading</option>'); 

    $('select.fake').show(0); // show the fake slide 

    $.ajax({ 
      // your code 
     }).done(function(data) { 

      $('select.fake').hide(0); 
      $select.show(0); 

     }) 
     ...... 
    }): 

DEMO

+1

** + 1 ** первый, чтобы ответить, и с демо! – gdoron

+0

@gdoron большое спасибо – thecodeparadox

+1

Если намерение закрыть раскрывающийся список, то это не работает в Chrome 19 (последний), и поэтому не следует полагаться. – Death

5

Я думаю, что все, что вам нужно сделать, это цель что-то еще, или я должен сказать, теряет фокус на выбор (размойте)

<select> 
    <option value="0">Initial Value</option> 
</select> 

var $select = $('select'); 
$select.click(function(e){ 

    $select.html('<option value="-1">Loading</option>'); 

    $.ajax({ 
     url: '/echo/json/', 
     method:'post', 
     dataType: "json", 
     contentType: "application/json; charset=utf-8", 
     data: { json: JSON.stringify([1, 2, 3]), delay:1 } 
    }).done(function(data){ 

     $.each($.map(data, function (item, i) { 
        return "<option value='" + item +"' >" + item + "</option>"; 

       }), function (i, item) { 
        $element.append(item); 
       }); 

    }).fail(function(){ 
     alert('error'); 
    }); 

    e.preventDefault(); 
    e.stopPropagation(); 
    $(this).blur();  
}); 
6

После ...

$select.html('<option value="-1">Loading</option>'); 

Попробуйте добавить ...

2

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

Вы можете имитировать замыкание выбора путем его повторного рендеринга. В JQuery вы можете реализовать простой плагин для достижения этой цели:

$.fn.closeSelect = function() { 
    if($(this).is("select")){ 
     var fakeSelect = $(this).clone(); 
     $(this).replaceWith(fakeSelect); 
    } 
}; 

и использовать его таким образом:

$("#mySelect").closeSelect(); 
+0

Это хорошая идея. Интересно, как это работает со связыванием. – vtortola

0

Старый пост я знаю, но у меня есть очень простое решение.

$(someSelectElement).on('change', function(e) { 
    e.target.size = 0  
} 

Это приведет к смене элемента select, если вы нажмете на любой элемент в списке.

0

В случае, если кто-то там используется Angular2, раствор, который работал там для меня, чтобы добавить (фокус) событие, которое вызывает $($event.srcElement).attr("disabled","disabled");

Я затем добавить тайм-аут, чтобы повторно включить элемент, когда я хочу он снова станет активным.

1

РЕШЕНИЕ 1 Я нашел очень легкое решение.

select.style.display = "none"; 
setTimeout(function() { 
    select.style.display = "block"; 
}, 10); 

Этот скрыть элемент в DOM, эта причина, что выпадающая будет закрыта, а затем с 10мс задержки (без задержек он не работает) вернуть его в DOM.

РЕШЕНИЕ 2: Немного сложнее, но без задержки полностью удалить элемент из DOM, а затем немедленно вернуть его обратно.

var parent = select.parentElement; 
var anchor = document.createElement("div"); 
parent.insertBefore(anchor, select); 
parent.removeChild(select); 
parent.insertBefore(select, anchor); 
parent.removeChild(anchor); 

Это хранит элемент изображения, а затем привожу якорь перед выбором. Якорь там для восстановления выбора в том же положении в DOM, а затем. Конечно, он может быть реализован для функции select element.

HTMLSelectElement.prototype.closeDropdown = function() { 
    var parent = this.parentElement; 
    var anchor = document.createElement("div"); 
    parent.insertBefore(anchor, this); 
    parent.removeChild(this); 
    parent.insertBefore(this, anchor); 
    parent.removeChild(anchor); 
} 

, а затем просто позвонить

select.closeDropdown(); 

Example

Смежные вопросы