Guia de início rápido: adicionando pesquisa a um aplicativo (HTML)
[ Este artigo destina-se aos desenvolvedores do Windows 8.x e do Windows Phone 8.x que escrevem aplicativos do Windows Runtime. Se você estiver desenvolvendo para o Windows 10, consulte documentação mais recente]
Muitos usuários contam com a pesquisa para encontrar o que procuram. Por exemplo, se seu aplicativo reproduzir arquivos de mídia, os usuários vão esperar que possam procurar uma música ou um vídeo específico. Se o seu aplicativo for um aplicativo de receitas, os usuários vão esperar que possam procurar receitas ou ingredientes específicos.
Com um pouco de planejamento, não é muito difícil adicionar pesquisa ao seu aplicativo. Eis o que você precisa:
- Uma fonte de dados para pesquisa. Você precisa de um tipo de catálogo ou inventário de itens que os usuários possam querer procurar. Quanto mais descritivo você puder tornar esse inventário, melhores serão os resultados da pesquisa.
- Um controle para inserir consultas de pesquisa. O Windows fornece um controle SearchBox que o seu aplicativo pode usar. O SearchBox fornece uma área de entrada para inserir consultas, um botão de pesquisa para a execução da pesquisa e eventos para lidar com consultas de pesquisa. Ele fornece até mesmo sugestões de pesquisa automaticamente.
- Uma página de exibição dos resultados da pesquisa. O Microsoft Visual Studio fornece um modelo de Página de resultados da pesquisa que cria grande parte do código que você precisa para lidar com consultas de pesquisa e resultados de exibição.
Este guia de início rápido ensina como usar esses itens para adicionar a funcionalidade de pesquisa ao seu aplicativo.
Veja este recurso em ação como parte da nossa série sobre recursos para aplicativos, do início ao fim: Interface do usuário de aplicativo da Windows Store, do início ao fim
Pré-requisitos
- Presumimos que você possa adicionar controles para um aplicativo básico da Windows Store em JavaScript. Para obter instruções sobre como adicionar controles, consulte Guia de início rápido: adicionando controles e manipulando eventos e Guia de início rápido: adicionando controles e estilos WinJS.
- Você deve saber como trabalhar com fontes de dados e vinculação de dados. Para obter instruções, consulte Como personalizar dados de modelos do Visual Studio.
Configurar seus dados
Quando o usuário insere uma consulta de pesquisa, seu aplicativo procura por itens que o usuário pode estar procurando. Os dados de pesquisas do aplicativo podem assumir várias formas: podem ser um arquivo XML, JSON (JavaScript Object Notation), um banco de dados, um serviço da Web ou arquivos no sistema de arquivos.
Os exemplos neste guia de início rápido usam os dados de exemplo gerados pelo Microsoft Visual Studio quando você cria um novo projeto no Visual Studio.
Quando você usa o Visual Studio para criar um novo Aplicativo de Grade, Aplicativo de Hub ou Aplicativo Dividido, ele cria um arquivo denominado data.js na pasta de seu aplicativo js. Esse arquivo inclui dados estáticos que você pode substituir por seus próprios dados. Por exemplo, se o aplicativo fizer uma única solicitação de xhr para obter dados RSS ou JSON, talvez você queira adicionar esse código no data.js. A inclusão do código permite que você use com facilidade seus próprios dados, sem modificar o modelo de dados usado pela Página de Resultados da Pesquisa.
Aqui está um exemplo da aparência dos dados de exemplo:
function generateSampleData() {
// . . .
var sampleGroups = [
{ key: "group1", title: "Group Title: 1", // . . .
// . . .
];
var sampleItems = [
{ group: sampleGroups[0], title: "Item Title: 1", // . . .
// . . .
];
return sampleItems;
}
Para tornar esses dados acessíveis para seus arquivos, o arquivo data.js
define um namespace de Data
que expõe esses membros:
items
: um WinJS.Binding.List que contém os itens de dados. Isso é um List agrupado.groups
: um WinJS.Binding.List que contém os grupos aos quais pertencem os itens de dados. (Você também pode obter os grupos, chamando items.groups.)- getItemReference: recupera um objeto que contém a chave de grupo e o título do item especificado.
- getItemsFromGroup: recupera um FilteredListProjection que contém os itens que pertencem ao grupo com a chave especificada.
- resolveGroupReference: recupera um objeto que representa o grupo que possui a chave especificada.
- resolveItemReference: esse método usa uma matriz que contém duas cadeias de caracteres, uma chave de grupo e um título. Esse método recupera o item que tem a chave de grupo e o título especificados.
Não é necessário usar esse namespace ou esses membros para conter seus dados, mas ao fazer isso ficará mais fácil usar o modelo de Página de Resultados da Pesquisa.
(Para saber mais sobre como trabalhar com os dados gerados pelo modelo, consulte Como personalizar dados de modelos do Visual Studio.)
Adicionar uma Página de resultados da pesquisa
A Página de resultados da pesquisa processa consultas de pesquisa e exibe o resultado. Vamos adicionar uma ao seu projeto. (Essas instruções presumem que seu projeto tenha sido criado do modelo de Hub, Grade ou Dividido. )
Adicionar o item Página de Resultados de Pesquisa
Na pasta do projeto pages do Gerenciador de Soluções, adicione uma nova pasta nomeada search.
Abra o menu de atalho para a pasta search e selecione Adicionar > Novo Item.
No painel central da caixa de diálogo Adicionar Novo Item, selecione Página de Resultados de Pesquisa. Neste exemplo, mantenha o nome padrão searchResults.html que aparece na caixa Nome.
Selecione Adicionar.
O Visual Studio adiciona searchResults.html, searchResults.css e searchResults.js ao projeto na pasta de pesquisa.
Adicionar SearchBox
Ainda temos trabalho a fazer na página de resultados de pesquisa, mas, primeiro, vamos adicionar uma SearchBox ao seu aplicativo. Ter uma SearchBox vai facilitar o nosso teste da página de resultados de pesquisa à medida que o implementamos.
Uma SearchBox permite ao usuário inserir consultas. Ela também pode exibir sugestões. Para adicionar uma SearchBoxao seu aplicativo, basta adicionar essa marcação a uma página HTML:
<div class="searchBox"
data-win-control="WinJS.UI.SearchBox"
data-win-options="{placeholderText: 'Search'}">
</div>
(Também é necessário registrar-se para o evento onquerysubmitted; faremos isso em uma etapa posterior).
Onde você deve colocar sua caixa de pesquisa? Recomendamos colocar uma caixa de pesquisa em cada página do seu aplicativo para que os usuários possam pesquisar facilmente sempre que quiserem. Se o espaço for um problema, você pode colocar a caixa de pesquisa no topo de uma barra de aplicativos.
Adicionar uma SearchBox a sua página
Vamos adicionar uma SearchBox a uma das páginas do aplicativo. Essas instruções funcionarão para qualquer página baseada em um controle Page.
Normalmente, o melhor local para colocar a sua SearchBox é o canto superior direito da página. A maioria das páginas que você cria a partir de um modelo do Visual Studio (como o modelo Controle de Página) tem um elemento header que contém o título da página e um botão de voltar:
<header aria-label="Header content" role="banner"> <button data-win-control="WinJS.UI.BackButton"></button> <h1 class="titlearea win-type-ellipsis"> <span class="pagetitle"></span> </h1> </header>
Simplesmente adicione sua SearchBox depois do elemento h1:
<header aria-label="Header content" role="banner"> <button data-win-control="WinJS.UI.BackButton"></button> <h1 class="titlearea win-type-ellipsis"> <span class="pagetitle">Welcome to basicPage</span> </h1> <div class="searchBox" data-win-control="WinJS.UI.SearchBox" data-win-options="{placeholderText: 'Search'}"> </div> </header>
(Recomendado) Convém permitir que os usuários pesquisem conteúdo em seu aplicativo simplesmente digitando pelo teclado.
Muitas pessoas usarão um teclado para manipular o Windows 8. Ao permitir que os usuários pesquisem digitando, você possibilita um uso eficiente da manipulação por teclado e torna a experiência de pesquisa do seu aplicativo consistente com a tela inicial.
Defina a propriedade focusOnKeyboardInput do controle SearchBox como true para que a caixa de pesquisa receba a entrada quando o usuário digitar.
<div class="searchBox" data-win-control="WinJS.UI.SearchBox" data-win-options="{placeholderText: 'Search', focusOnKeyboardInput: true }"> </div>
A folha de estilos do default.css que o Visual Studio cria para você dão um layout -ms-grid aos elementos do cabeçalho. Para colocar sua SearchBox no canto superior direito da página, simplesmente adicione esse estilo ao arquivo CSS (Folhas de Estilo em Cascata) de sua página:
.searchBox { -ms-grid-column: 4; margin-top: 57px; margin-right: 29px; }
Manipular o evento onquerysubmitted
Provavelmente seu aplicativo terá vários controles SearchBox. Vamos definir um único manipulador do evento onquerysubmitted que todos possam usar.
Abra o arquivo default.js de seu aplicativo.
Crie um manipulador do evento onquerysubmitted denominado "querySubmittedHandler" que usa um único argumento denominado "args". (Você pode colocar essa definição de método em qualquer lugar dentro da função anônima que envolve o código default.js existente).
function querySubmittedHandler(args) { }
Use o manipulador de eventos para navegar para a sua nova página de resultados da pesquisa chamando WinJS.Navigation.navigate. A propriedade
args.details
contém um objeto que fornece informações sobre o evento que a nossa página de resultados da pesquisa precisará, portanto, passe esse objeto quando chamar WinJS.Navigation.navigate.function querySubmittedHandler(args) { WinJS.Navigation.navigate('/pages/search/searchResults.html', args.detail); }
Aviso Se você tiver criado seu aplicativo usando o modelo Aplicativo em Branco, também precisará adicionar suporte à navegação ao seu aplicativo para que a pesquisa funcione. Você pode oferecer suporte à navegação da mesma maneira que os modelos Aplicativo de Grade, Aplicativo Dividido e Aplicativo de Navegação oferecem adicionando ao seu aplicativo um controle personalizado chamado
PageControlNavigator
. Veja como esse controle personalizado oferece suporte à navegação em Guia de início rápido: usando a navegação de página única. Se você preferir oferecer suporte à navegação sem usar um controle personalizado, precisará criar um código próprio que ouve e responde a eventos de navegação como WinJS.Navigation.navigated. Veja um exemplo de como oferecer suporte à navegação sem usar um controle personalizado comoPageControlNavigator
no Exemplo de navegação e histórico de navegação.Agora precisamos expor publicamente esse manipulador de eventos definindo um namespace e fazendo desse manipulador um membro. Vamos chamar o namespace "SearchUtils". Também precisamos usar o método WinJS.UI.eventHandler assim podemos definir o manipulador de eventos declarativamente (para obter mais informações sobre como isso funciona, veja Como definir manipuladores de eventos declarativamente).
WinJS.Namespace.define("SearchUtils", { querySubmittedHandler: WinJS.UI.eventHandler(querySubmittedHandler) } );
Abra a página HTML que contém seu SearchBox. Use a propriedade data-win-options para definir o evento onquerysubmitted para
SampleUtils.querySubmittedHandler
.<div class="searchBox" data-win-control="WinJS.UI.SearchBox" data-win-options="{placeholderText: 'Search', focusOnKeyboardInput: true, onquerysubmitted: SearchUtils.querySubmittedHandler}"> </div>
Experimente. Execute o aplicativo e digite uma consulta de teste na SearchBox e pressione Enter. Se estiver usando dados de exemplo fornecidos pelo Visual Studio, tente usar "1" como sua consulta de teste.
O manipulador de eventos onquerysubmittedque você criou navega para a página de resultados de pesquisa, passando a consulta que você digitou.
Se você usou os dados de exemplo, deverá ver as correspondências para sua consulta de teste. Se estiver usando seus próprios dados, poderá não receber resultados ainda; será necessário atualizar a página de resultados da pesquisa primeiro. Faremos isso numa etapa posterior.
Pesquisar seus dados
É hora de voltar à página de resultados de pesquisa. Quando seu aplicativo navega para a página de resultados da pesquisa, um dos primeiro métodos que ele chama é o método _handleQuery
. O _handleQuery
chama diversos métodos que nós devemos modificar:
_generateFilters
Gera a lista de filtros que o usuário pode clicar para filtrar resultados.
_searchData
Pesquisa seus dados para obter itens correspondentes e os armazena em um List denominado
originalResults
._populateFilterBar
Exibe os filtros em nossa lista de filtros.
Vamos atualizar esses métodos para personalizá-los para seus dados.
Atualizar os filtros
O método _generateFilters
gera a lista de filtros que o usuário pode clicar para filtrar resultados. O método gerado pelo modelo cria três filtros: um filtro "Todos" para mostrar todos os resultados, um filtro para mostrar os itens no grupo 1 e um filtro para mostrar tudo mais. Iremos substituir o código gerado pelo modelo pelo código que gera a lista de filtros dinamicamente. Dessa forma, se você alterar os dados de exemplo, seus novos filtros aparecerão na página. Atualizaremos o código _generateFilters
e criaremos dois métodos auxiliares. Mas primeiro, será necessário atualizar nosso arquivo data.js para podermos acessar a lista de grupos; usaremos esses grupos para definir nossos filtros.
Atualizar o método _generateFilters
No searchResults.js, localize o método
_generateFilters
e exclua o código que ele contém.Inicialize a matriz
_filters
. (A matriz_filters
é uma variável de membro definida pela página de resultados da pesquisa.)_generateFilters: function () { this._filters = [];
Agora crie um filtro. Um filtro é um objeto que possui três propriedades:
results
: um List dos itens a exibir. Definiremos para null por enquanto.text
: o texto de exibição no filtro.predicate
: uma função que utiliza um item. Se o item atender aos critérios do filtro (se ele deve ser exibido quando esse filtro é selecionado), essa função retorna true; caso contrário, ela retorna false.
Primeiro, criaremos o filtro "Todos". O filtro Todos sempre exibe itens, portanto seu
predicate
sempre retorna true.this._filters.push({ results: null, text: "All", predicate: function (item) { return true; } });
Agora criaremos um filtro para cada grupo em nossos dados. Nossos grupos são armazenados como List denominada
Data.groups
. Use o método forEach para iterar em cada grupo no List. O método forEach assume uma função como seu parâmetro; essa função é chamada para cada item na lista. Passemos a ele uma função de membro denominada_createFiltersForGroups
; criaremos a função na etapa seguinte.if (window.Data) { Data.groups.forEach(this._createFiltersForGroups.bind(this)); } },
Agora vamos criar a função
_createFiltersForGroups
.Crie uma função de membro chamada
_createFiltersForGroups
que use três parâmetros: element, index e array._createFiltersForGroups: function (element, index, array){
O parâmetro element contém nosso objeto de grupo. Crie um novo objeto de filtro e use o método por push para adicioná-lo à matriz
_filters
. Defina a propriedaderesults
do filtro como null, sua propriedadetext
como element.title
e sua propriedadepredicate
como uma função chamada_filterPredicate
. Você definirá o método_filterPredicate
na próxima etapa.this._filters.push( { results: null, text: element.title, predicate: this._filterPredicate.bind(element)} ); },
Crie uma função de membro chamada
_filterPredicate
que use um único parâmetro chamado item. Retorne true se a propriedadegroup
do parâmetro item for igual ao objeto de grupo atual._filterPredicate: function (item) { return item.group === this; },
Este é o código completo para os três métodos que acabamos de criar:
_generateFilters: function () {
this._filters = [];
this._filters.push({ results: null, text: "All", predicate: function (item) { return true; } });
if (window.Data) {
Data.groups.forEach(this._createFiltersForGroups.bind(this));
}
},
_createFiltersForGroups: function (element, index, array){
this._filters.push(
{ results: null, text: element.title, predicate: this._filterPredicate.bind(element)}
);
},
_filterPredicate: function (item) {
return item.group === this;
},
Execute o aplicativo e faça uma pesquisa; você deve ver seus novos filtros na barra de filtro.
Se estiver usando os dados de exemplo gerados pelo modelo, poderá observar que alguns dos grupos estão cortados. Você pode corrigir o problema fazendo alguns ajustes no arquivo CSS de sua página de resultados da pesquisa.
Atualizar o CSS da página de resultados da pesquisa
Abra searchResults.css.
Localize o estilo
.searchResults section[role=main]
e altere o valor da propriedade -ms-grid-rows para "auto 1fr"..searchResults section[role=main] { /* Define a grid with rows for the filters and results */ -ms-grid-columns: 1fr; -ms-grid-rows: auto 1fr; -ms-grid-row: 1; -ms-grid-row-span: 2; display: -ms-grid; }
Localize o estilo
.searchResults section[role=main] .filterbar
e altere o valor da propriedade word-wrap para "normal" e defina margin-bottom para "20px"..searchResults section[role=main] .filterbar { -ms-font-feature-settings: "case" 1; -ms-grid-row: 1; list-style-type: none; margin-left: 60px; margin-right: 60px; margin-top: 133px; max-width: calc(100% - 120px); position: relative; white-space: normal; z-index: 1; margin-bottom: 20px; }
Localize o estilo
.searchResults section[role=main] .filterbar li
e altere o valor da propriedade display para "inline-block"..searchResults section[role=main] .filterbar li { display: inline-block; margin-left: 20px; margin-right: 20px; margin-top: 5px; opacity: 0.6; }
Localize o estilo
.searchResults section[role=main] .resultslist
e altere o valor da propriedade -ms-grid-row para "2" e defina -ms-grid-row-span para "1"..searchResults section[role=main] .resultslist { -ms-grid-row: 2; -ms-grid-row-span: 1; height: 100%; position: relative; width: 100%; z-index: 0; }
Execute o aplicativo e faça outra pesquisa. Você deve ver todos os filtros agora.
Atualizar o algoritmo da pesquisa
O método _searchData
pesquisa dados de itens que correspondem à consulta da pesquisa. O código gerado pelo modelo pesquisa o título, subtítulo e descrição de cada item. Vamos gravar nosso próprio código de pesquisa que classifica os resultados por relevância.
Atualize o método _searchData
Abra searchResults.js, localize o método
_searchData
e exclua o código que ele contém.Crie uma variável denominada
originalResults
; isso será nosso valor de retorno.// This function populates a WinJS.Binding.List with search results for the // provided query. _searchData: function (queryText) { // Create a variable for the results list. var originalResults;
Vamos deixar nossa pesquisa sensível a maiúsculas e minúsculas convertendo o texto da consulta e o texto que estamos procurando em letras minúsculas. Iniciemos convertendo a consulta em letras minúsculas e armazenando-a como uma variável denominada
lowercaseQueryText
.// Convert the query to lowercase. var lowercaseQueryText = queryText.toLocaleLowerCase();
Antes de tentarmos acessar nossos dados, precisamos ter certeza de que os dados existem.
if (window.Data) {
Se estiver usando os dados de exemplo fornecidos em data.js, nossos itens serão armazenados em
Data.items
, um objeto WinJS.Binding.List. Use o método createFiltered para filtrar itens que não satisfazem a consulta da pesquisa.O método createFiltered assume uma função de filtragem como seu parâmetro. Essa função de filtragem usa um único parâmetro, item. A List chama essa função em cada item na lista para determinar se ele deve estar na lista filtrada. A função retorna true se o item deve ser incluído e false se ele deve ser omitido.
originalResults = Data.items.createFiltered( function (item) {
Em JavaScript, você pode anexar novas propriedades aos objetos existentes. Adicione uma propriedade
ranking
a item e defina seu valor para "-1".// A ranking < 0 means that a match wasn't found. item.ranking = -1;
Primeiro, vamos verificar se o título do item contém o texto da consulta. Se tiver, dê ao item 10 pontos.
if (item.title.toLocaleLowerCase().indexOf(lowercaseQueryText) >= 0) { item.ranking += 10; }
Em seguida, verifiquemos as ocorrências no campo de subtítulo. Se encontrarmos uma correspondência, dê ao item 5 pontos.
if (item.subtitle.toLocaleLowerCase().indexOf(lowercaseQueryText) >= 0) { item.ranking += 5; }
Finalmente, verifiquemos o campo de descrição. Se encontrarmos uma correspondência, dê ao item 1 ponto.
if (item.description.toLocaleLowerCase().indexOf(lowercaseQueryText) >= 0) { item.ranking += 1; }
Se o item tiver uma classificação de -1, isso significa que ele não correspondia à nossa consulta de pesquisa. Para nosso valor de retorno, retorne true se o item tiver uma classificação de 0 ou superior.
return (item.ranking >= 0); } );
Até agora, filtramos a lista para apenas os itens que correspondem à consulta da pesquisa e adicionamos informações de classificação. Agora, usaremos o método createSorted para classificar nossa lista de resultados, de forma que os itens com maiores pontos apareçam primeiro.
// Sort the results by the ranking info we added. originalResults = originalResults.createSorted(function (firstItem, secondItem){ if (firstItem.ranking == secondItem.ranking) { return 0; } else if (firstItem.ranking < secondItem.ranking) return 1; else return -1; }); }
Se nossos dados estiverem ausentes, crie uma lista vazia.
else { // For some reason, the Data namespace is null, so we // create an empty list to return. originalResults = new WinJS.Binding.List(); }
Finalmente, retorne os resultados.
return originalResults; }
Este é o código completo do método _searchData
atualizado.
_searchData: function (queryText) {
// Create a variable for the results list.
var originalResults;
// Convert the query to lowercase.
var lowercaseQueryText = queryText.toLocaleLowerCase();
if (window.Data)
{
originalResults = Data.items.createFiltered(
function (item) {
// A ranking < 0 means that a match wasn't found.
item.ranking = -1;
if (item.title.toLocaleLowerCase().indexOf(lowercaseQueryText) >= 0) {
item.ranking += 10;
}
if (item.subtitle.toLocaleLowerCase().indexOf(lowercaseQueryText) >= 0) {
item.ranking += 5;
}
if (item.description.toLocaleLowerCase().indexOf(lowercaseQueryText) >= 0) {
item.ranking += 1;
}
return (item.ranking >= 0);
}
);
// Sort the results by the ranking info we added.
originalResults = originalResults.createSorted(function (firstItem, secondItem){
if (firstItem.ranking == secondItem.ranking) {
return 0;
}
else if (firstItem.ranking < secondItem.ranking)
return 1;
else
return -1;
});
}
else {
// For some reason, the Data namespace is null, so we
// create an empty list to return.
originalResults = new WinJS.Binding.List();
}
return originalResults;
}
Fornecer navegação para os itens retornados pela pesquisa
Quando você executa seu aplicativo e faz uma pesquisa, a página de resultados da pesquisa exibe os resultados em um controle ListView. Agora, clicando em um desses itens do resultado da pesquisa não acontece nada. Vamos adicionar algum código para exibir o item quando o usuário clicar nele.
Quando o usuário clica em um item em um ListView, o ListView dispara o evento oniteminvoked. O código gerado pelo modelo de nossa página de resultados da pesquisa define um manipulador de eventos oniteminvoked denominado _itemInvoked
. Atualizemos o código para navegar até o item chamado.
Para adicionar navegação aos itens
Abra searchResults.js e adicione código à função
_itemInvoked
para navegar para a página correta. Cuidado O URI mostrado aqui é para o modelo de Hub. Para o modelo de Grade, o URI deve ser: /pages/itemDetail/itemDetail.html. Para o modelo Dividido, o URI deve ser: /pages/items/items.html._itemInvoked: function (args) { args.detail.itemPromise.done(function itemInvoked(item) { // TODO: Navigate to the item that was invoked. var itemData = [item.groupKey, item.data.title]; WinJS.Navigation.navigate("/pages/item/item.html", { item: itemData }); }); },
(Opcional) Atualizar o itemTemplate do controle ListView
A página de resultados da pesquisa gerada pelo modelo define um itemTemplate projetado para funcionar com a fonte de dados de exemplo que o Visual Studio cria para você, e espera os seguintes campos em cada item de dados: "imagem", "título", "legenda" e "descrição".
Se os itens de dados tiverem diferentes campos, será necessário modificar o itemTemplate. Para saber mais, veja Guia de início rápido: adicionando um ListView.
(Opcional) Adicionar sugestões de pesquisa
As sugestões de pesquisa são exibidas na caixa de pesquisa no painel de pesquisa. As sugestões são importantes porque elas poupam o tempo dos usuários e dão dicas valiosas sobre os tipos de coisas que os usuários podem pesquisar em seu aplicativo.
Você obtém sugestões de várias fontes:
- Você mesmo pode defini-las. Por exemplo, crie uma lista de fabricantes automobilísticas.
- Você pode acessá-las do Windows quando o seu aplicativo pesquisa arquivos locais.
- Você pode acessá-las de um serviço ou servidor Web.
Para ver diretrizes de experiência do usuário para exibir sugestões, veja Diretrizes e lista de verificação para pesquisa.
Você pode usar o LocalContentSuggestionSettings para adicionar sugestões baseadas em arquivos locais do Windows, usando apenas algumas linhas de código. Alternativamente, você pode se registrar para o evento onsuggestionsrequested do controle de caixa de pesquisa e criar sua própria lista de sugestões que é composta por sugestões que você obteve de outra fonte (como uma lista definida localmente ou um serviço da Web). Este guia de início rápido mostra como lidar com o evento onsuggestionsrequested.
Para ver exemplos de código adicionais que mostram como adicionar sugestões de pesquisa, baixe o Exemplo de controle SearchBox. O exemplo demonstra como adicionar sugestões de pesquisa, usando todas as três fontes possíveis, e como adicionar sugestões para idiomas do leste asiático, usando formas alternativas do texto da consulta gerado por um IME (Editor de Método de Entrada). (Recomendamos usar textos de consulta alternativos se o seu aplicativo for usado por usuários japoneses ou chineses).
Manipular o evento SuggestionsRequested
É provável que seu aplicativo tenha vários controles SearchBox; vamos definir um único manipulador de eventos em seu arquivo default.js que todos possam usar. Adicione esse código depois do método
querySubmittedHandler
que você criou em uma etapa anterior.function suggestionsRequestedHandler(args) {
Converta o texto da consulta de SearchBox para letras minúsculas.
var query = args.detail.queryText.toLocaleLowerCase();
O sistema fornece automaticamente algumas sugestões de pesquisa, como as pesquisas anteriores que o usuário realizou. Vamos adicionar nossas sugestões de pesquisa a qualquer coisa que o sistema fornecer.
// Retrieve the system-supplied suggestions. var suggestionCollection = args.detail.searchSuggestionCollection;
Verifique se a consulta contém pelo menos um caractere e se temos acesso aos nossos dados.
if (query.length > 0 && window.Data) {
Itere por cada item em seus dados e verifique se há correspondências. Quando encontramos uma correspondência, anexe o título do item correspondente à coleta de sugestões de pesquisa.
Data.items.forEach( function (element, index, array) { if (element.title.substr(0, query.length).toLocaleLowerCase() === query) { suggestionCollection.appendQuerySuggestion(element.title); } });
A propriedade
args.detail.linguisticDetails.queryTextAlternatives
fornece sugestões adicionais para os usuários que digitam texto em um IME. Usar essas sugestões melhora a experiência de pesquisa para os usuários dos idiomas do leste asiático. Vamos verificar as alternativas de texto de consulta para cadeias de caracteres que contêm a consulta original e adicioná-las à nossa lista de sugestões de pesquisa.args.detail.linguisticDetails.queryTextAlternatives.forEach( function (element, index, array) { if (element.substr(0, query.length).toLocaleLowerCase() === query) { suggestionCollection.appendQuerySuggestion(element); } }); } }
Só precisamos desse código para o nosso manipulador de eventos procurar sugestões. Aqui está o método completo
suggestionsRequestedHandler
:function suggestionsRequestedHandler(args) { var query = args.detail.queryText.toLocaleLowerCase(); // Retrieve the system-supplied suggestions. var suggestionCollection = args.detail.searchSuggestionCollection; if (query.length > 0 && window.Data) { Data.items.forEach( function (element, index, array) { if (element.title.substr(0, query.length).toLocaleLowerCase() === query) { suggestionCollection.appendQuerySuggestion(element.title); } }); args.detail.linguisticDetails.queryTextAlternatives.forEach( function (element, index, array) { if (element.substr(0, query.length).toLocaleLowerCase() === query) { suggestionCollection.appendQuerySuggestion(element); } }); } }
Observação Se sua fonte de dados for assíncrona, você deve dividir as atualizações para a coleção de sugestões de pesquisa em um Promise. O código de exemplo usa uma List, que é uma fonte de dados assíncrona, mas aqui está como o método ficaria se a List fosse uma fonte de dados assíncrona.
function suggestionsRequestedHandler(args) { var query = args.detail.queryText.toLocaleLowerCase(); // Retrieve the system-supplied suggestions. var suggestionCollection = args.detail.searchSuggestionCollection; if (query.length > 0 && window.Data) { args.detail.setPromise(WinJS.Promise.then(null, function () { Data.items.forEach( function (element, index, array) { if (element.title.substr(0, query.length).toLocaleLowerCase() === query) { suggestionCollection.appendQuerySuggestion(element.title); } }); args.detail.linguisticDetails.queryTextAlternatives.forEach( function (element, index, array) { if (element.substr(0, query.length).toLocaleLowerCase() === query) { suggestionCollection.appendQuerySuggestion(element); } }); }) ); } }
Só precisamos desse código para o nosso manipulador de eventos procurar sugestões. Vamos torná-la acessível expondo-a por meio do namespace
SearchUtils
que definimos em uma etapa anterior:WinJS.Namespace.define("SearchUtils", { querySubmittedHandler: WinJS.UI.eventHandler(querySubmittedHandler), suggestionsRequestedHandler: WinJS.UI.eventHandler(suggestionsRequestedHandler) } );
Agora vamos registrar o evento com a nossa SearchBox. Abra a página HTML que contém seu SearchBox e defina o evento onsuggestionsrequested para
SearchUtils.suggestionsRequestedHandler
.<div class="searchBox" data-win-control="WinJS.UI.SearchBox" data-win-options="{placeholderText: 'Search', focusOnKeyboardInput: true, onquerysubmitted: SearchUtils.querySubmittedHandler, onsuggestionsrequested: SearchUtils.suggestionsRequestedHandler}"> </div>
Implementando o contrato de Pesquisa (para versões anteriores do Windows)
Antes do Windows 8.1, os aplicativos usavam o botão Pesquisar para fornecer pesquisa dentro deles. Os desenvolvedores implementavam o contrato de Pesquisa e usavam a API SearchPane para lidar com consultas e obter sugestões e resultados.
Embora continuemos oferecendo suporte total ao contrato de Pesquisa do Windows 8 e à API SearchPane, a partir do Windows 8.1, recomendamos o uso do controleSearchBox em vez do SearchPane. Aplicativos que usam a SearchBox não precisam implementar o contrato de Pesquisa.
Um aplicativo deve usar o SearchPane e o contrato de Pesquisa? Se você não espera que os usuários pesquisem seu aplicativo com frequência, use o SearchPane e o contrato de Pesquisa. Recomendamos que você use um botão com o glifo Pesquisa (Segoe UI Símbolo 0xE0094 em 15pt) no seu aplicativo em que os usuários possam clicar para ativar o painel de pesquisa. Para ver o código que implementa o SearchPane e o contrato de Pesquisa, veja a Amostra do contrato de Pesquisa.
Resumo e próximas etapas
Você usou o controle SearchBox e a Página de Resultados da Pesquisa para adicionar pesquisa ao seu aplicativo.
Para orientações para ajudar você a projetar e criar uma boa experiência de pesquisa para seus usuários, veja Diretrizes e lista de verificação para pesquisa.