twitter bootstrap ketik ajax contoh

280

Saya mencoba menemukan contoh yang berfungsi dari elemen ketikahead bootstrap twitter yang akan membuat panggilan ajax untuk mengisi dropdown itu.

Saya memiliki contoh autocomplete jquery yang sudah ada yang mendefinisikan url ajax dan bagaimana memproses balasannya

<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];
                }
            );
       ..

Apa yang perlu saya ubah untuk mengonversikan ini ke contoh typeahead?

<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];
                }
            );
       ..

Saya akan menunggu masalah ' Tambahkan dukungan sumber jarak jauh untuk typeahead ' diselesaikan.

emeraldjava
sumber
Untuk lebih spesifik saya bertanya-tanya bagaimana opsi autocomplete dan hasil penanganan fungsi peta ke opsi textahead? Apakah ada satu set fungsi penanganan hasil teks yang didefinisikan yang dapat diganti, atau metode yang dinamai diturunkan dari api jquery yang mendasarinya.
emeraldjava
1
Bisakah Anda menandai jawaban Stijn Van Bael sebagai jawaban yang benar sekarang? jawaban bogert hanya berfungsi untuk versi Bootstrap yang sudah ketinggalan zaman.
Giles Roberts

Jawaban:

302

Sunting: typeahead tidak lagi dibundel dalam Bootstrap 3. Periksa:

Mulai dari Bootstrap 2.1.0 hingga 2.3.2, Anda dapat melakukan ini:

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

Untuk mengkonsumsi data JSON seperti ini:

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

Perhatikan bahwa data JSON harus dari tipe mime yang tepat (aplikasi / json) sehingga jQuery mengenalinya sebagai JSON.

Stijn Van Bael
sumber
3
Seperti pada garpu Typeahead, data harus berupa array string JSON dan tipe konten haruslah aplikasi / json.
Stijn Van Bael
9
bisakah 2.1 menggunakan json yang bukan hanya array string? saya perlu memberikan nilai kepada pengguna dan menggunakan id untuk melakukan pemrosesan lebih lanjut. Apakah itu mungkin tanpa mengambil garpu khusus?
Anton
2
@Stijin Apakah ada contoh bagaimana fungsi anonim itu akan digunakan di sini, untuk memproses id untuk opsi yang ditampilkan? Terima kasih!
Acyra
1
Saya ingin menunjukkan bahwa menggunakan metode ini menghasilkan AJAX yang disebut sedang dibuat untuk setiap penekanan tombol pada input. Jika server mengembalikan data statis pada dasarnya (mis. Tidak benar-benar melakukan apa pun dengan kueri), maka ini bisa sangat boros.
Dologan
2
mengapa menggunakan getbukan getJSON? Tampaknya lebih tepat.
greg0ire
119

Anda dapat menggunakan garpu BS Typeahead yang mendukung panggilan ajax. Maka Anda akan dapat menulis:

$('.typeahead').typeahead({
    source: function (typeahead, query) {
        return $.get('/typeahead', { query: query }, function (data) {
            return typeahead.process(data);
        });
    }
});
Bogert
sumber
1
"Tebakan cerdas" jQuery untuk tipe kembali data POST tidak berfungsi ketika saya kembali, misalnya ["aardvark", "apple"],. Saya harus secara eksplisit mengatur dataTypeparameter dalam $.postpanggilan. Lihat jQuery.post () .
Rusty Fausak
1
@rfausak Atau, tetapkan Content-typetajuk keapplication/json
Rusty Fausak
23
saya mendapatkan UnEught TypeError: Tidak dapat memanggil metode 'toLowerCase' dari undefined
Krishnaprasad Varma
Di tautan yang Anda kirim, saya bahkan tidak mendapatkan sourcefungsi untuk dieksekusi.
James
8
Jawaban bagus! Saya akan menggunakan permintaan GET sebagai gantinya, hanya untuk memenuhi standar REST.
Mauro
72

Mulai dari Bootstrap 2.1.0:

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);
            }
        });
    }
});

Sekarang Anda dapat membuat kode terpadu, menempatkan tautan "json-request" dalam kode HTML Anda.

Thantifaxath
sumber
11
Tapi saya akan mengubahnya untuk digunakan $(this)[0].$element.data('link').
Andrew Ellis
atauthis.$element.data('link')
Richard87
51

Semua tanggapan merujuk pada BootStrap 2 typeahead, yang tidak lagi ada di BootStrap 3.

Untuk siapa pun yang diarahkan di sini mencari contoh AJAX menggunakan Twitter postah -Bootstrap typeahead.js baru , inilah contoh yang berfungsi. Sintaksnya sedikit berbeda:

$('#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);
      }
    });
  }
});

Contoh ini menggunakan saran sinkron (panggilan ke processSync ) dan asinkron, sehingga Anda akan melihat beberapa opsi segera muncul, lalu yang lain ditambahkan. Anda bisa menggunakan satu atau yang lain.

Ada banyak acara bindable dan beberapa opsi yang sangat kuat, termasuk bekerja dengan objek daripada string, dalam hal ini Anda akan menggunakan fungsi tampilan kustom Anda sendiri untuk membuat item Anda sebagai teks.

Jonathan Lidbeck
sumber
1
Terima kasih. Satu pertanyaan lagi: dengan processAsync saya mendapatkan "TypeError: advice.slice bukan fungsi." Seperti apa kebutuhan JSON yang dikembalikan? Inilah tebakan terbaik saya: {: Suggest => ["Thing 1", "Thing 2", "Thing 3"]}
user1515295
1
Pastikan Anda mengembalikan string JSON yang valid. Fungsi saran AJAX Anda harus mengembalikan array string, misalnya ["Thing 1","Thing 2"], atau dengan fungsi tampilan kustom, array objek sesuai dengan kebutuhan Anda, misalnya[{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}]
Jonathan Lidbeck
Saya kembali [{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}], Sekarang saya ingin menampilkan dua kolom dalam dropdown typeahead dengan id dan label. Bagaimana saya bisa melakukan itu?
Vishal
2
TUHANKU!!! Saya mencari dari 3 hari terakhir tidak ada yang menyebutkan tentang ini. Saya sedang menguji dengan fungsi sinkronisasi sampai sekarang. TERIMA KASIH BUNG!!
Gilson PJ
Terima kasih! Bekerja dengan bootstrap 4.3, dan jquery 3.4. Tapi, opsi yang tercantum tidak disorot ketika mouse berada di atasnya. Saya pikir itu seharusnya menjadi bagian dari typeahead itu sendiri.
Binita Bharati
25

Saya telah menambahkan plugin Bootstrap typeahead asli dengan kemampuan ajax. Sangat mudah digunakan:

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

Inilah repo github: Ajax-Typeahead

Paul Warelis
sumber
Saya telah melihat kode Gudbergur; terus terang, saya suka yang terbaik ini. Ini sedikit lebih ramah dan menawarkan lebih banyak fungsi. Kerja bagus Paul! Satu-satunya hal yang saya sarankan adalah dalam README Anda mengingatkan pengguna bahwa mereka perlu mengurai data JSON mereka ke dalam JS agar kode Anda dapat menggunakannya dengan benar. Saya berasumsi Anda menguraikannya untuk saya sehingga menggantung saya sebentar. Kalau tidak, cukup bagus, terima kasih! :)
Bane
3
Server Anda mengembalikan string alih-alih objek JSON. jQuery's $ .ajax () digunakan untuk melakukan panggilan, dan menangani penguraian.
Paul Warelis
1
benar sekali, terima kasih atas tangkapannya! :) Plugin ini bekerja dengan sangat baik.
Bane
Halo, bagaimana seharusnya sisi server JSONterlihat? Saya mendapatkan Uncaught TypeError: Cannot read property 'length' of undefined . Saya menggunakan json_encode($array)dan mengirim header kanan ( 'Content-Type: application/json; charset=utf-8'). versi jqueryjQuery v1.9.1
Kyslik
5

Saya melakukan beberapa modifikasi pada jquery-ui.min.js:

//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")`

dan tambahkan css berikut

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

Bekerja dengan sempurna.

penjahat
sumber
versi jquery ui min mana yang Anda gunakan?
emeraldjava
Jika Anda memerlukan ini untuk jQuery 1.7.1 dan jQuery UI 1.8.16 maka saya telah membuat GIST berdasarkan perbaikan di atas yang menunjukkan tempat untuk mengubah File UI jQuery. gist.github.com/1884819 - baris dikomentari dengan // dimodifikasi
Richard Hollis
Ini adalah pertanyaan / jawaban yang cukup lama tetapi saya hanya ingin mengatakan bahwa selalu merupakan praktik yang buruk untuk mengubah kode komponen pihak ke-3. Anda harus meninjau kembali semua perubahan setiap kali Anda memutakhirkannya. Dalam kasus khusus ini, widget jQuery dapat diwarisi yang merupakan cara yang jauh lebih aman untuk menyesuaikannya. Jadi pada dasarnya, buat widget Anda sendiri, mewarisi dari inti (autocomplete dalam hal ini) dan lepaskan imajinasi Anda! :)
AlexCode
3

Saya menggunakan metode ini

$('.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');
    }
});
Krava
sumber
Alangkah baiknya jika Anda bisa menambahkan beberapa penjelasan untuk jawaban Anda. Misalnya, apa perbedaan solusi Anda dibandingkan dengan solusi yang disajikan dalam jawaban yang sudah ada?
membunyikan
2

Seseorang dapat membuat panggilan dengan menggunakan Bootstrap. Versi saat ini tidak memiliki masalah pembaruan sumber. Pemutakhiran yang bermasalah Sumber data bootstrap typeahead dengan respons pos , yaitu sumber bootstrap yang pernah diperbarui dapat dimodifikasi lagi.

Lihat contoh di bawah ini:

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,
});
neoeahit
sumber
2

Bagi mereka yang mencari versi coffeescript dari jawaban yang diterima:

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

Saya telah melalui posting ini dan semuanya tidak ingin bekerja dengan benar dan akhirnya mengumpulkan bit dari beberapa jawaban jadi saya memiliki demo kerja 100% dan akan menempelkannya di sini untuk referensi - tempelkan ini ke dalam file php dan pastikan termasuk dalam tempat yang tepat.

<?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>
l0ft13
sumber
2

Coba ini jika layanan Anda tidak mengembalikan header jenis konten aplikasi / json yang tepat:

$('.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);
        });
    }
});
Andres
sumber
1

PEMBARUAN: Saya memodifikasi kode saya menggunakan garpu ini

juga alih-alih menggunakan $ .each, saya mengubah ke $ .map seperti yang disarankan oleh Tomislav Markovski

$('#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) {

    }
});

Namun saya menghadapi beberapa masalah dengan mendapatkan

UnEught TypeError: Tidak dapat memanggil metode 'toLowerCase' dari undefined

seperti yang Anda lihat pada posting yang lebih baru, saya mencoba mencari tahu di sini

semoga pembaruan ini dapat membantu Anda ...

mmoscosa
sumber
Tidak terkait dengan OP: Saya akan menggunakan Array.mapsebagai gantinya $.eachdan mengganti konten seluruh successfungsi panggilan balik Anda denganvar manufacturers = results.data.manufacturers.map(function (item) { return { id: item.Manufacturer.id, manufacturer: item.Manufacturer.manufacturer } });
Tomislav Markovski
terima kasih @TomislavMarkovski Saya mengubah kode saya seperti yang Anda sarankan.
mmoscosa
0

Saya tidak memiliki contoh yang baik untuk Anda dan saya juga tidak memiliki solusi yang sangat bersih, tetapi izinkan saya memberi tahu Anda apa yang saya temukan.

Jika Anda melihat kode javascript untuk TypeAhead terlihat seperti ini:

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

Kode ini menggunakan metode "grep" jQuery untuk mencocokkan elemen dalam array sumber. Saya tidak melihat tempat yang bisa Anda hubungi dengan panggilan AJAX, jadi tidak ada solusi "bersih" untuk ini.

Namun, satu cara yang bisa Anda lakukan adalah mengambil keuntungan dari cara metode grep bekerja di jQuery. Argumen pertama untuk grep adalah array sumber dan argumen kedua adalah fungsi yang digunakan untuk mencocokkan array sumber (perhatikan Bootstrap memanggil "pencocokan" yang Anda berikan saat menginisialisasi). Apa yang bisa Anda lakukan adalah mengatur sumber ke array satu elemen dummy dan mendefinisikan pencocokan sebagai fungsi dengan panggilan AJAX di dalamnya. Dengan begitu, ia akan menjalankan panggilan AJAX sekali saja (karena array sumber Anda hanya memiliki satu elemen di dalamnya).

Solusi ini bukan hanya peretasan, tetapi akan mengalami masalah kinerja karena kode TypeAhead dirancang untuk melakukan pencarian pada setiap penekanan tombol (panggilan AJAX harus benar-benar hanya terjadi pada setiap beberapa penekanan tombol atau setelah waktu idle tertentu). Saran saya adalah untuk mencobanya, tetapi tetap dengan perpustakaan autocomplete yang berbeda atau hanya gunakan ini untuk situasi non-AJAX jika Anda mengalami masalah.

Aamer Abbas
sumber
0

saat menggunakan ajax, coba $.getJSON()alih-alih $.get()jika Anda memiliki masalah dengan tampilan hasil yang benar.

Dalam kasus saya, saya hanya mendapatkan karakter pertama dari setiap hasil ketika saya menggunakan $.get(), meskipun saya menggunakan json_encode()sisi server.

larsbo
sumber
0

saya gunakan $().one() untuk menyelesaikan ini; Ketika halaman dimuat, saya mengirim ajax ke server dan menunggu untuk selesai. Kemudian berikan hasil ke fungsi. $().one()adalah penting. Karena memaksa typehead.js untuk melampirkan input satu kali. maaf atas tulisan yang buruk.

(($) => {
    
    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 ?">

ali karimi
sumber
-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();

?>

Mohamed Ayed
sumber