twitter bootstrap typeahead ví dụ ajax


280

Tôi đang cố gắng tìm một ví dụ hoạt động của phần tử kiểu chữ bootstrap twitter sẽ thực hiện một cuộc gọi ajax để đưa vào danh sách thả xuống.

Tôi có một ví dụ tự động hoàn thành jquery đang hoạt động xác định url ajax và cách xử lý trả lời

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

Tôi cần thay đổi gì để chuyển đổi nó thành ví dụ về kiểu chữ?

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

Tôi sẽ chờ đợi ' Thêm hỗ trợ nguồn từ xa cho vấn đề kiểu chữ ' được giải quyết.


Để cụ thể hơn, tôi tự hỏi làm thế nào các tùy chọn tự động hoàn thành và chức năng xử lý kết quả ánh xạ tới các tùy chọn textahead? Có một tập hợp các hàm xử lý kết quả textalert được xác định có thể bị ghi đè, hoặc là phương thức có tên được kế thừa từ api jquery cơ bản.
emeraldjava

1
Bạn có thể đánh dấu câu trả lời của Stijn Van Bael là đúng không? Câu trả lời của bogert chỉ hoạt động đối với các phiên bản lỗi thời của Bootstrap.
Giles Roberts

Câu trả lời:


302

Chỉnh sửa: typeahead không còn được đóng gói trong Bootstrap 3. Kiểm tra:

Kể từ Bootstrap 2.1.0 cho đến 2.3.2, bạn có thể làm điều này:

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

Để sử dụng dữ liệu JSON như thế này:

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

Lưu ý rằng dữ liệu JSON phải đúng loại mime (application / json) để jQuery nhận ra nó là JSON.


3
Như trong ngã ba typeahead, dữ liệu phải là một chuỗi JSON của chuỗi và loại nội dung phải là application / json.
Stijn Van Bael

9
2.1 có thể sử dụng json không chỉ là một chuỗi chuỗi? Tôi cần một giá trị cho người dùng và sử dụng id để xử lý thêm. Có thể mà không cần lấy một ngã ba tùy chỉnh?
Anton

2
@Stijin Có bất kỳ ví dụ nào về cách sử dụng chức năng ẩn danh đó ở đây để xử lý id cho một tùy chọn được hiển thị không? Cảm ơn!
Acyra

1
Tôi muốn chỉ ra rằng việc sử dụng phương pháp này dẫn đến một AJAX được gọi là được tạo cho mỗi lần nhấn phím trên đầu vào. Nếu máy chủ đang trả về dữ liệu tĩnh (nghĩa là không thực sự làm gì với truy vấn), thì điều này có thể khá lãng phí.
Dologan

2
Tại sao sử dụng getthay vì getJSON? Có vẻ phù hợp hơn.
greg0ire

119

Bạn có thể sử dụng ngã ba BS typeahead hỗ trợ các cuộc gọi ajax. Sau đó, bạn sẽ có thể viết:

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

1
"Dự đoán thông minh" của jQuery cho kiểu trả về của dữ liệu POST không hoạt động khi tôi trả về, chẳng hạn , ["aardvark", "apple"]. Tôi đã phải thiết lập rõ ràng dataTypetham số trong $.postcuộc gọi. Xem jQuery.post () .
Rusty Fausak

1
@rfausak Hoặc, đặt Content-typetiêu đề thànhapplication/json
Rusty Fausak

23
Tôi đang nhận Uncaught TypeError: Không thể gọi phương thức 'toLowerCase' không xác định
Krishnaprasad Varma

Trong liên kết bạn đã gửi, tôi thậm chí không nhận được sourcechức năng để thực thi.
James

8
Câu trả lời tốt đẹp! Tôi sẽ sử dụng một yêu cầu GET thay thế, chỉ để đáp ứng các tiêu chuẩn REST.
Mauro

72

Bắt đầu từ 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);
            }
        });
    }
});

Bây giờ bạn có thể tạo một mã thống nhất, đặt các liên kết "json-request" trong mã HTML của bạn.


11
Nhưng tôi sẽ thay đổi nó để sử dụng $(this)[0].$element.data('link').
Andrew Ellis

hoặcthis.$element.data('link')
Richard87

51

Tất cả các phản hồi đề cập đến kiểu chữ BootStrap 2, không còn xuất hiện trong BootStrap 3.

Đối với bất kỳ ai khác được hướng dẫn ở đây đang tìm kiếm một ví dụ AJAX bằng cách sử dụng typeahead.js sau Bootstrap mới , đây là một ví dụ hoạt động. Cú pháp hơi khác một chút:

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

Ví dụ này sử dụng cả đề xuất đồng bộ (cuộc gọi đến processSync ) và đề xuất không đồng bộ, vì vậy bạn sẽ thấy một số tùy chọn xuất hiện ngay lập tức, sau đó các tùy chọn khác được thêm vào. Bạn chỉ có thể sử dụng cái này hay cái khác.

Có rất nhiều sự kiện có thể ràng buộc và một số tùy chọn rất mạnh mẽ, bao gồm làm việc với các đối tượng thay vì chuỗi, trong trường hợp đó, bạn sử dụng chức năng hiển thị tùy chỉnh của riêng mình để hiển thị các mục của bạn dưới dạng văn bản.


1
Cảm ơn bạn. Thêm một câu hỏi nữa: với processAsync tôi đang nhận được "TypeError: suggest.slice không phải là một chức năng." JSON được trả về sẽ cần trông như thế nào? Đây là dự đoán tốt nhất của tôi: {: gợi ý => ["Điều 1", "Điều 2", "Điều 3"]}
user1515295

1
Hãy chắc chắn rằng bạn trả về một chuỗi JSON hợp lệ. Chức năng AJAX đề nghị của bạn nên trả về một mảng các chuỗi, ví dụ ["Thing 1","Thing 2"], hoặc với một chức năng hiển thị tùy chỉnh, một mảng của các đối tượng theo yêu cầu của bạn, ví dụ:[{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}]
Jonathan Lidbeck

Tôi trở lại [{"id":1,"label":"Foo"},{"id":2,"label":"Bar"}], Bây giờ tôi muốn hiển thị hai cột trong trình đơn thả xuống kiểu chữ với id và nhãn. Làm thế nào tôi có thể làm điều đó?
Vishal

2
CHÚA TÔI!!! Tôi đã tìm kiếm từ 3 ngày qua không ai đề cập đến điều này. Tôi đã thử nghiệm với chức năng đồng bộ cho đến bây giờ. CẢM ƠN !!
Gilson PJ

Cảm ơn ! Hoạt động tuyệt vời với bootstrap 4.3 và jquery 3.4. Nhưng, các tùy chọn được liệt kê không được tô sáng khi chuột di chuyển qua nó. Tôi nghĩ rằng nó được cho là một phần của chính typeahead.
Binita Bharati

25

Tôi đã tăng cường plugin Bootstrap typeahead ban đầu với khả năng ajax. Rất dễ sử dụng:

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

Đây là repo github: Ajax-typeahead


Tôi đã xem mã của Gudbergur; thẳng thắn, tôi thích cái này nhất Nó thân thiện hơn một chút và cung cấp nhiều chức năng hơn. Làm tốt lắm Paul! Điều duy nhất tôi muốn đề xuất là trong README của bạn nhắc nhở người dùng rằng họ cần phân tích dữ liệu JSON của họ thành JS để mã của bạn có thể sử dụng chính xác. Tôi cho rằng bạn đã phân tích nó cho tôi để tôi gác máy một chút. Nếu không, khá đẹp, cảm ơn bạn! :)
Bane

3
Máy chủ của bạn trả về một chuỗi thay vì một đối tượng JSON. $ .ajax () của jQuery được sử dụng để thực hiện cuộc gọi và nó đảm nhiệm việc phân tích cú pháp.
Paul Warelis

1
Hoàn toàn chính xác, cảm ơn bạn đã bắt! :) Plugin này hoạt động rất tốt.
Bane

Xin chào, phía máy chủ nên JSONnhư thế nào? Tôi đang nhận được Uncaught TypeError: Cannot read property 'length' of undefined . Tôi đang sử dụng json_encode($array)và gửi đúng tiêu đề ( 'Content-Type: application/json; charset=utf-8'). phiên bản jqueryjQuery v1.9.1
Kyslik

5

Tôi đã thực hiện một số sửa đổi trên 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")`

và thêm css sau

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

Hoạt động hoàn hảo.


Phiên bản nào của jquery ui min bạn đang sử dụng?
emeraldjava

Nếu bạn cần điều này cho jQuery 1.7.1 và jQuery UI 1.8.16 thì tôi đã tạo GIST dựa trên bản sửa lỗi ở trên cho biết nơi cần thay đổi Tệp UI UI. gist.github.com/1884819 - các dòng được nhận xét với // đã sửa đổi
Richard Hollis

Đây là một câu hỏi / câu trả lời khá cũ nhưng tôi chỉ muốn nói rằng luôn luôn thay đổi mã thành phần của bên thứ 3. Bạn sẽ phải xem lại tất cả các thay đổi mỗi khi bạn nâng cấp chúng. Trong trường hợp cụ thể này, các widget jQuery có thể được kế thừa, đó là cách an toàn hơn nhiều để tùy chỉnh chúng. Vì vậy, về cơ bản, hãy tạo widget của riêng bạn, kế thừa từ lõi (tự động hoàn thành trong trường hợp này) và giải phóng trí tưởng tượng của bạn! :)
AlexCode

3

Tôi đang sử dụng phương pháp này

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

Sẽ thật tốt nếu bạn có thể thêm một số lời giải thích cho câu trả lời của mình. Ví dụ, sự khác biệt của giải pháp của bạn so với các giải pháp được trình bày trong các câu trả lời đã có là gì?
bấm còi

2

Người ta có thể thực hiện cuộc gọi bằng cách sử dụng Bootstrap. Phiên bản hiện tại không có bất kỳ vấn đề cập nhật nguồn nào Sự cố khi cập nhật nguồn dữ liệu kiểu chữ của Bootstrap với phản hồi bài đăng , tức là nguồn bootstrap sau khi cập nhật có thể được sửa đổi một lần nữa.

Vui lòng tham khảo dưới đây để biết ví dụ:

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

Đối với những người tìm kiếm một phiên bản cà phê của câu trả lời được chấp nhận:

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

2

Tôi đã xem qua bài đăng này và mọi thứ không muốn hoạt động chính xác và cuối cùng ghép các bit lại với nhau từ một vài câu trả lời để tôi có bản demo hoạt động 100% và sẽ dán nó vào đây để tham khảo - dán tệp này vào tệp php và đảm bảo bao gồm trong đúng địa chỉ.

<?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

Hãy thử điều này nếu dịch vụ của bạn không trả lại đúng tiêu đề loại nội dung / ứng dụng json:

$('.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

CẬP NHẬT: Tôi đã sửa đổi mã của mình bằng cách sử dụng ngã ba này

ngoài ra thay vì sử dụng $ .each, tôi đã đổi thành $ .map theo đề xuất của 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) {

    }
});

Tuy nhiên tôi đang gặp một số vấn đề bằng cách nhận được

Uncaught TypeError: Không thể gọi phương thức 'toLowerCase' không xác định

như bạn có thể thấy trên một bài đăng mới hơn, tôi đang cố gắng tìm hiểu ở đây

hy vọng bản cập nhật này sẽ giúp ích cho bạn ...


Không liên quan đến OP: Tôi sẽ sử dụng Array.mapthay thế $.eachvà thay thế nội dung của toàn bộ successchức năng gọi lại của bạn bằngvar manufacturers = results.data.manufacturers.map(function (item) { return { id: item.Manufacturer.id, manufacturer: item.Manufacturer.manufacturer } });
Tomislav Markovski

cảm ơn bạn @TomislavMarkovski Tôi đã sửa đổi mã của mình như bạn đề xuất.
mmoscosa

0

Tôi không có một ví dụ làm việc cho bạn cũng như tôi không có một giải pháp rất sạch sẽ, nhưng hãy để tôi nói cho bạn biết những gì tôi đã tìm thấy.

Nếu bạn nhìn vào mã javascript cho TypeAhead, nó sẽ trông như thế này:

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

Mã này sử dụng phương thức "grep" của jQuery để khớp với một phần tử trong mảng nguồn. Tôi không thấy bất kỳ nơi nào bạn có thể thực hiện cuộc gọi AJAX, vì vậy không có giải pháp "sạch" nào cho vấn đề này.

Tuy nhiên, một cách hơi khó mà bạn có thể làm là tận dụng lợi thế của phương thức grep hoạt động trong jQuery. Đối số đầu tiên cho grep là mảng nguồn và đối số thứ hai là một hàm được sử dụng để khớp với mảng nguồn (chú ý Bootstrap gọi "đối sánh" bạn đã cung cấp khi bạn khởi tạo nó). Những gì bạn có thể làm là đặt nguồn thành một mảng một phần tử giả và định nghĩa trình so khớp là một hàm có lệnh gọi AJAX trong đó. Bằng cách đó, nó sẽ chạy cuộc gọi AJAX chỉ một lần (vì mảng nguồn của bạn chỉ có một phần tử trong đó).

Giải pháp này không chỉ bị hack mà còn gặp phải các vấn đề về hiệu năng do mã TypeAhead được thiết kế để thực hiện tra cứu trên mỗi lần nhấn phím (các cuộc gọi AJAX chỉ thực sự xảy ra trên mỗi vài lần nhấn phím hoặc sau một khoảng thời gian nhàn rỗi nhất định). Lời khuyên của tôi là hãy dùng thử, nhưng hãy gắn bó với một thư viện tự động hoàn thành khác hoặc chỉ sử dụng điều này cho các tình huống không phải là AJAX nếu bạn gặp phải bất kỳ vấn đề nào.


0

khi sử dụng ajax, hãy thử $.getJSON()thay vì $.get()nếu bạn gặp vấn đề với việc hiển thị kết quả chính xác.

Trong trường hợp của tôi, tôi chỉ nhận được ký tự đầu tiên của mọi kết quả khi tôi sử dụng $.get(), mặc dù tôi đã sử dụng json_encode()phía máy chủ.


0

tôi sử dụng $().one() để giải quyết điều này; Khi tải trang, tôi gửi ajax đến máy chủ và chờ đợi để hoàn thành. Sau đó chuyển kết quả cho chức năng. $().one()là quan trọng. Bởi vì buộc typehead.js phải gắn vào đầu vào một lần. xin lỗi vì viết xấu

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

?>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.