twitter bootstrap typeahead ajax örneği


280

Açılışını doldurmak için ajax çağrısı yapacak twitter bootstrap typeahead öğesinin çalışan bir örneğini bulmaya çalışıyorum .

Ajax url ve nasıl yanıt işleme tanımlayan varolan bir çalışma jquery otomatik tamamlama örneği var

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
    var options = { minChars:3, max:20 };
    $("#runnerquery").autocomplete('./index/runnerfilter/format/html',options).result(
            function(event, data, formatted)
                {
                    window.location = "./runner/index/id/"+data[1];
                }
            );
       ..

Bunu typeahead örneğine dönüştürmek için neye ihtiyacım var?

<script type="text/javascript">
//<![CDATA[
$(document).ready(function() {
    var options = { source:'/index/runnerfilter/format/html', items:5 };
    $("#runnerquery").typeahead(options).result(
            function(event, data, formatted)
                {
                    window.location = "./runner/index/id/"+data[1];
                }
            );
       ..

' Yazı tipine uzaktan kaynak desteği ekle ' sorununun çözülmesini bekleyeceğim .


Daha spesifik olmak gerekirse, otomatik tamamlama seçenekleri ve sonuç işleme işlevinin textahead seçenekleriyle nasıl eşleştiğini merak ediyorum? Geçersiz kılınabilecek bir dizi tanımlanmış textalert sonuç işleme fonksiyonu var mı yoksa alttaki jquery api'den miras alınan yöntem var mı?
emeraldjava

1
Stijn Van Bael'in cevabını şimdi doğru olarak işaretleyebilir misiniz? bogert'ın yanıtı sadece Bootstrap'ın eski sürümleri için geçerlidir.
Giles Roberts

Yanıtlar:


302

Düzenleme: typeahead artık Bootstrap 3'te bulunmuyor.

Bootstrap 2.1.0'dan 2.3.2'ye kadar şunları yapabilirsiniz:

$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('/typeahead', { query: query }, function (data) {
            return process(data.options);
        });
    }
});

JSON verilerini şöyle kullanmak için:

{
    "options": [
        "Option 1",
        "Option 2",
        "Option 3",
        "Option 4",
        "Option 5"
    ]
}

JSON verilerinin doğru mime türünde (application / json) olması gerektiğine dikkat edin, böylece jQuery bu verileri JSON olarak tanır.


3
Typeahead çatalında olduğu gibi, veriler JSON dizeler dizisi olmalı ve içerik türü application / json olmalıdır.
Stijn Van Bael

9
2.1 sadece bir dize dizi değil json kullanabilirsiniz? kullanıcı için bir değer ve daha fazla işlem yapmak için bir kimlik kullanmanız gerekir. Özel bir çatal almadan bu mümkün mü?
Anton

2
@Stijin Görüntülenen bir seçeneğin kimliğini işlemek için bu anonim işlevin burada nasıl kullanılacağına dair örnekler var mı? Teşekkürler!
Acyra

1
Bu yöntemi kullanmanın , girişteki her tuş vuruşu için yapılan AJAX ile sonuçlandığını belirtmek isterim . Sunucu temel olarak statik veriler döndürüyorsa (yani sorgu ile hiçbir şey yapmıyorsa), bu oldukça israf olabilir.
Dologan

2
neden kullanmak getyerine getJSON? Daha uygun görünüyor.
greg0ire

119

Sen kullanabilirsiniz BS typeahead çatal ajax çağrıları destekler. Sonra şunları yazabileceksiniz:

$('.typeahead').typeahead({
    source: function (typeahead, query) {
        return $.get('/typeahead', { query: query }, function (data) {
            return typeahead.process(data);
        });
    }
});

1
Örneğin, döndüğümde POST verilerinin dönüş türü için jQuery "akıllı tahmin" çalışma değildi ["aardvark", "apple"]. Ben açıkça çağrı dataTypeparametre ayarlamak zorunda kaldı $.post. Bkz. JQuery.post () .
Rusty Fausak

1
@rfausak Alternatif olarak, Content-typebaşlığıapplication/json
Rusty Fausak

23
Yakalanmamış TypeError alıyorum: undefined 'toLowerCase' yöntemi çağrılamıyor
Krishnaprasad Varma

Gönderdiğiniz bağlantıda, sourceişlevin yürütülmesini bile almıyorum .
James

8
Güzel cevap! Bunun yerine, sadece REST standartlarını karşılamak için bir GET isteği kullanırdım.
Mauro

72

Bootstrap 2.1.0'dan itibaren:

HTML:

<input type='text' class='ajax-typeahead' data-link='your-json-link' />

JavaScript:

$('.ajax-typeahead').typeahead({
    source: function(query, process) {
        return $.ajax({
            url: $(this)[0].$element[0].dataset.link,
            type: 'get',
            data: {query: query},
            dataType: 'json',
            success: function(json) {
                return typeof json.options == 'undefined' ? false : process(json.options);
            }
        });
    }
});

Artık, HTML kodunuza "json-request" bağlantıları yerleştirerek birleşik bir kod oluşturabilirsiniz.


11
Ama kullanmak için değiştirirdim $(this)[0].$element.data('link').
Andrew Ellis

veyathis.$element.data('link')
Richard87

51

Tüm yanıtlar, artık BootStrap 3'te bulunmayan BootStrap 2 yazım tipine başvuruyor.

Burada yeni Bootstrap sonrası Twitter typeahead.js kullanarak AJAX örneği arayan herkes için işte çalışan bir örnek. Sözdizimi biraz farklıdır:

$('#mytextquery').typeahead({
  hint: true,
  highlight: true,
  minLength: 1
},
{
  limit: 12,
  async: true,
  source: function (query, processSync, processAsync) {
    processSync(['This suggestion appears immediately', 'This one too']);
    return $.ajax({
      url: "/ajax/myfilter.php", 
      type: 'GET',
      data: {query: query},
      dataType: 'json',
      success: function (json) {
        // in this example, json is simply an array of strings
        return processAsync(json);
      }
    });
  }
});

Bu örnek hem eşzamanlı ( processSync çağrısı ) hem de eşzamansız öneri kullanır, böylece bazı seçeneklerin hemen göründüğünü görürsünüz, diğerleri eklenir. Sadece birini veya diğerini kullanabilirsiniz.

Dizeler yerine nesnelerle çalışma da dahil olmak üzere çok sayıda düzenlenebilir etkinlik ve bazı çok güçlü seçenekler vardır; bu durumda öğelerinizi metin olarak oluşturmak için kendi özel görüntüleme işlevinizi kullanırsınız.


1
Teşekkür ederim. Bir soru daha: processAsync ile "TypeError: suggestions.slice bir işlev değil." Döndürülen JSON'un da neye ihtiyacı var? İşte benim en iyi tahminim: {: suggestions => ["Şey 1", "Şey 2", "Şey 3"]}
user1515295 26:15

1
Geçerli bir JSON dizesi döndürdüğünüzden emin olun. AJAX öneri işleviniz bir dizi dizeyi, örneğin ["Thing 1","Thing 2"], özel bir görüntüleme işleviyle, ihtiyaçlarınıza göre bir nesne dizisi [{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}]
döndürmelidir

Geri [{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}]dönüyorum, şimdi id ve etiketli typeahead açılır menüsünde iki sütun göstermek istiyorum. Bunu nasıl yapabilirim?
Vishal

2
TANRIM!!! Son 3 gün içinde hiç kimse bundan bahsetmedi. Şimdiye kadar senkronizasyon fonksiyonu ile test yapıyordum. TESEKKURLER DOSTUM!!
Gilson PJ

Teşekkürler ! Bootstrap 4.3 ve jquery 3.4 ile harika çalışıyor. Ancak, fare üzerine geldiğinde listelenen seçenekler vurgulanmaz. Daktilo başının bir parçası olması gerektiğini düşündüm.
Binita Bharati

25

Ajax yetenekleri ile orijinal typeahead Bootstrap eklentisini artırdım. Kullanımı çok kolay:

$("#ajax-typeahead").typeahead({
     ajax: "/path/to/source"
});

İşte github repo: Ajax-Typeahead


Gudbergur'un koduna baktım; Açıkçası, bunu en çok sevdim. Biraz daha arkadaş canlısı ve daha fazla işlevsellik sunuyor. İyi iş Paul! Önerebileceğim tek şey README'nizde, kodunuzun doğru bir şekilde kullanabilmesi için kullanıcıya JSON verilerini JS'ye ayrıştırmaları gerektiğini hatırlatır. Benim için ayrıştırdığını varsaymıştım, bu yüzden beni biraz kapattı. Aksi takdirde, çok güzel, teşekkür ederim! :)
Bane

3
Sunucunuz JSON nesnesi yerine bir dize döndürür. jQuery'nin $ .ajax () yöntemi çağrı yapmak için kullanılır ve ayrıştırma işlemiyle ilgilenir.
Paul Warelis

1
kesinlikle doğru, yakalamak için teşekkür ederim! :) Bu eklenti çok iyi çalışıyor.
Bane

Merhaba, sunucu tarafı nasıl olmalı JSON? Ben alıyorum Uncaught TypeError: Cannot read property 'length' of undefined . json_encode($array)Doğru başlıkları ( 'Content-Type: application/json; charset=utf-8') kullanıyorum ve gönderiyorum . jquery sürümüjQuery v1.9.1
Kyslik

5

Jquery-ui.min.js üzerinde bazı değişiklikler yaptım:

//Line 319 ORIG:
this.menu=d("<ul></ul>").addClass("ui-autocomplete").appendTo(d(...
// NEW:
this.menu=d("<ul></ul>").addClass("ui-autocomplete").addClass("typeahead").addClass("dropdown-menu").appendTo(d(...

// Line 328 ORIG:
this.element.addClass("ui-menu ui-widget ui-widget-content ui-corner-all").attr...
// NEW:this.element.attr....

// Line 329 ORIG:
this.active=a.eq(0).children("a")
this.active.children("a")
// NEW:
this.active=a.eq(0).addClass("active").children("a")
this.active.removeClass("active").children("a")`

ve aşağıdaki css'i ekleyin

.dropdown-menu {
    max-width: 920px;
}
.ui-menu-item {
    cursor: pointer;        
}

Mükemmel çalışıyor.


jquery ui min'in hangi sürümünü kullanıyorsunuz?
emeraldjava

JQuery 1.7.1 ve jQuery UI 1.8.16 için buna ihtiyacınız varsa, jQuery UI Dosyasının nerede değiştirileceğini gösteren yukarıdaki düzeltmeye dayalı bir GIST oluşturdum. gist.github.com/1884819 - satırlar // değiştirildi ile yorumlandı
Richard Hollis

Bu oldukça eski bir soru / cevap ama sadece 3. taraf bileşenleri kodunu değiştirmek her zaman kötü bir uygulama olduğunu söylemek istiyorum. Her yükseltişinizde tüm değişiklikleri tekrar gözden geçirmeniz gerekir. Bu özel durumda, jQuery widget'ları miras alınabilir, bu da onları özelleştirmenin çok daha güvenli bir yoludur. Temel olarak, kendi widget'ınızı oluşturun, çekirdek olandan (bu durumda otomatik tamamlama) miras alın ve hayal gücünüzü serbest bırakın! :)
AlexCode

3

Bu yöntemi kullanıyorum

$('.typeahead').typeahead({
    hint: true,
    highlight: true,
    minLength: 1
},
    {
    name: 'options',
    displayKey: 'value',
    source: function (query, process) {
        return $.get('/weather/searchCity/?q=%QUERY', { query: query }, function (data) {
            var matches = [];
            $.each(data, function(i, str) {
                matches.push({ value: str });
            });
            return process(matches);

        },'json');
    }
});

Cevabınıza biraz açıklama ekleyebilmeniz iyi olur. Örneğin, halihazırda var olan cevaplarda sunulan çözümlere kıyasla çözümünüzün farkı nedir?
korna

2

Bootstrap kullanarak arama yapabilirsiniz. Geçerli sürümde herhangi bir kaynak güncelleme sorunu yok Bootstrap'ın daktilo veri veri kaynağını post yanıtı ile güncellemekle ilgili sorun , yani güncellendikten sonra bootstrap kaynağı tekrar değiştirilebilir.

Bir örnek için lütfen aşağıya bakın:

jQuery('#help').typeahead({
    source : function(query, process) {
        jQuery.ajax({
            url : "urltobefetched",
            type : 'GET',
            data : {
                "query" : query
            },
            dataType : 'json',
            success : function(json) {
                process(json);
            }
        });
    },
    minLength : 1,
});

2

Kabul edilen cevabın kahve versiyonunu arayanlara:

$(".typeahead").typeahead source: (query, process) ->
  $.get "/typeahead",
    query: query
  , (data) ->
    process data.options

2

Bu yazıyı inceledim ve her şey doğru çalışmak istemedi ve sonunda birkaç cevaptan bitleri birleştirdi, böylece% 100 çalışan bir demo var ve referans için buraya yapıştırın - bunu bir php dosyasına yapıştırın ve içerdiğinden emin olun Doğru yer.

<?php if (isset($_GET['typeahead'])){
    die(json_encode(array('options' => array('like','spike','dike','ikelalcdass'))));
}
?>
<link href="bootstrap.css" rel="stylesheet">
<input type="text" class='typeahead'>
<script src="jquery-1.10.2.js"></script>
<script src="bootstrap.min.js"></script>
<script>
$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('index.php?typeahead', { query: query }, function (data) {
            return process(JSON.parse(data).options);
        });
    }
});
</script>

2

Hizmetiniz doğru uygulama / json içerik türü başlığını döndürmüyorsa bunu deneyin:

$('.typeahead').typeahead({
    source: function (query, process) {
        return $.get('/typeahead', { query: query }, function (data) {
            var json = JSON.parse(data); // string to json
            return process(json.options);
        });
    }
});

1

GÜNCELLEME: Kodumu bu çatalla değiştirdim

Ayrıca $ .each kullanmak yerine Tomislav Markovski'nin önerdiği gibi $ .map olarak değiştirdim

$('#manufacturer').typeahead({
    source: function(typeahead, query){
        $.ajax({
            url: window.location.origin+"/bows/get_manufacturers.json",
            type: "POST",
            data: "",
            dataType: "JSON",
            async: false,
            success: function(results){
                var manufacturers = new Array;
                $.map(results.data.manufacturers, function(data, item){
                    var group;
                    group = {
                        manufacturer_id: data.Manufacturer.id,
                        manufacturer: data.Manufacturer.manufacturer
                    };
                    manufacturers.push(group);
                });
                typeahead.process(manufacturers);
            }
        });
    },
    property: 'name',
    items:11,
    onselect: function (obj) {

    }
});

Ancak bazı problemlerle karşılaşıyorum

Yakalanmamış TypeError: undefined öğesinin 'toLowerCase' yöntemi çağrılamıyor

daha yeni bir yayında görebileceğiniz gibi burada anlamaya çalışıyorum

Umarım bu güncelleme size yardımcı olur ...


OP ile ilgisi yok: Bunun Array.mapyerine $.eachtüm successgeri arama işlevinizin içeriğinivar manufacturers = results.data.manufacturers.map(function (item) { return { id: item.Manufacturer.id, manufacturer: item.Manufacturer.manufacturer } });
Tomislav Markovski ile değiştiririm

thank you @TomislavMarkovski Önerdiğim gibi kodumu değiştirdim.
mmoscosa

0

Senin için çalışan bir örneğim yok, ne de çok temiz bir çözümüm yok, ama sana ne bulduğumu söyleyeyim.

TypeAhead için javascript koduna bakarsanız şöyle görünür:

items = $.grep(this.source, function (item) {
    if (that.matcher(item)) return item
  })

Bu kod, kaynak dizideki bir öğeyi eşleştirmek için jQuery "grep" yöntemini kullanır. Bir AJAX çağrısında kanca herhangi bir yer görmedim, bu yüzden bu "temiz" bir çözüm yoktur.

Ancak, bunu yapabilmeniz için biraz hileli bir yol, grep yönteminin jQuery'de çalışma şeklinden yararlanmaktır. Grep için ilk argüman kaynak dizisidir ve ikinci argüman kaynak dizisiyle eşleşmek için kullanılan bir işlevdir (Bootstrap başlattığınızda sağladığınız "eşleştiriciyi çağırır" uyarısı). Yapabileceğiniz şey, kaynağı kukla bir tek öğeli diziye ayarlamak ve eşleştiriciyi içinde AJAX çağrısı olan bir işlev olarak tanımlamaktır. Bu şekilde, AJAX çağrısını yalnızca bir kez çalıştıracaktır (kaynak dizininizde yalnızca bir öğe olduğu için).

Bu çözüm sadece çirkin olmakla kalmaz, aynı zamanda TypeAhead kodu her tuşa basmak için tasarlandığından performans sorunlarından muzdarip olacaktır (AJAX aramaları gerçekten sadece birkaç tuş vuruşunda veya belirli bir boşta kalma süresinden sonra gerçekleşmelidir). Benim tavsiyem denemek, ama farklı bir otomatik tamamlama kitaplığı ile sopa veya herhangi bir sorunla karşılaşırsanız sadece AJAX olmayan durumlar için kullanın.


0

ajax kullanırken , sonuçların doğru görüntülenmesi konusunda sorun yaşıyorsanız $.getJSON()bunun yerine deneyin $.get().

Benim durumumda $.get(), json_encode()sunucu tarafı kullansam da, kullandığımda her sonucun sadece ilk karakterini aldım .


0

$().one() Bunu çözmek için kullanıyorum ; Sayfa yüklendiğinde sunucuya ajax gönderiyorum ve işlemin tamamlanmasını bekliyorum. Ardından sonucu işleve iletin. $().one()Önemli .çünkü güçtür typehead.js girişine bir kez takmak için. Kötü yazı için özür dilerim.

(($) => {
    
    var substringMatcher = function(strs) {
        return function findMatches(q, cb) {
          var matches, substringRegex;
          // an array that will be populated with substring matches
          matches = [];
      
          // regex used to determine if a string contains the substring `q`
          substrRegex = new RegExp(q, 'i');
      
          // iterate through the pool of strings and for any string that
          // contains the substring `q`, add it to the `matches` array
          $.each(strs, function(i, str) {
            if (substrRegex.test(str)) {
              matches.push(str);
            }
          });
          cb(matches);
        };
      };
      
      var states = [];
      $.ajax({
          url: 'https://baconipsum.com/api/?type=meat-and-filler',
          type: 'get'
      }).done(function(data) {
        $('.typeahead').one().typeahead({
            hint: true,
            highlight: true,
            minLength: 1
          },
          {
            name: 'states',
            source: substringMatcher(data)
          });
      })
      

})(jQuery);
.tt-query, /* UPDATE: newer versions use tt-input instead of tt-query */
.tt-hint {
    width: 396px;
    height: 30px;
    padding: 8px 12px;
    font-size: 24px;
    line-height: 30px;
    border: 2px solid #ccc;
    border-radius: 8px;
    outline: none;
}

.tt-query { /* UPDATE: newer versions use tt-input instead of tt-query */
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
}

.tt-hint {
    color: #999;
}

.tt-menu { /* UPDATE: newer versions use tt-menu instead of tt-dropdown-menu */
    width: 422px;
    margin-top: 12px;
    padding: 8px 0;
    background-color: #fff;
    border: 1px solid #ccc;
    border: 1px solid rgba(0, 0, 0, 0.2);
    border-radius: 8px;
    box-shadow: 0 5px 10px rgba(0,0,0,.2);
}

.tt-suggestion {
    padding: 3px 20px;
    font-size: 18px;
    line-height: 24px;
    cursor: pointer;
}

.tt-suggestion:hover {
    color: #f0f0f0;
    background-color: #0097cf;
}

.tt-suggestion p {
    margin: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>

<input class="typeahead" type="text" placeholder="where ?">


-1
 $('#runnerquery').typeahead({
        source: function (query, result) {
            $.ajax({
                url: "db.php",
                data: 'query=' + query,            
                dataType: "json",
                type: "POST",
                success: function (data) {
                    result($.map(data, function (item) {
                        return item;
                    }));
                }
            });
        },
        updater: function (item) {
        //selectedState = map[item].stateCode;

       // Here u can obtain the selected suggestion from the list


        alert(item);
            }

    }); 

 //Db.php file
<?php       
$keyword = strval($_POST['query']);
$search_param = "{$keyword}%";
$conn =new mysqli('localhost', 'root', '' , 'TableName');

$sql = $conn->prepare("SELECT * FROM TableName WHERE name LIKE ?");
$sql->bind_param("s",$search_param);            
$sql->execute();
$result = $sql->get_result();
if ($result->num_rows > 0) {
    while($row = $result->fetch_assoc()) {
    $Resut[] = $row["name"];
    }
    echo json_encode($Result);
}
$conn->close();

?>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.