searchbase 4.0.0 copy "searchbase: ^4.0.0" to clipboard
searchbase: ^4.0.0 copied to clipboard

Searchbase allows building search UIs for ReactiveSearch, powered by Elasticsearch or OpenSearch

example/README.md

Entry file for basic example #

// /example/basic/main.dart
import 'dart:html';
import 'package:searchbase/searchbase.dart';

class DefaultUriPolicy implements UriPolicy {
  DefaultUriPolicy();
  @override
  bool allowsUri(String uri) {
    return true;
  }
}

void main() {
  final index = 'gitxplore-app';
  final url = 'https://@appbase-demo-ansible-abxiydt-arc.searchbase.io';
  final credentials = 'a03a1cb71321:75b6603d-9456-4a5a-af6b-a487b309eb61';

  final searchbase = SearchBase(index, url, credentials,
      appbaseConfig: AppbaseSettings(recordAnalytics: true));
  // Register search widget => To render the suggestions
  final searchController = searchbase.register('search-widget', {
    'enablePopularSuggestions': true,
    'dataField': [
      'name',
      'description',
      'name.raw',
      'fullname',
      'owner',
      'topics'
    ]
  });

// Register filter widget with dependency on search widget
  final filterWidget = searchbase.register('language-filter', {
    'type': QueryType.term,
    'dataField': 'language.keyword',
    'react': {'and': 'search-widget'},
    'value': []
  });

// Register result widget with react dependency on search and filter widget => To render the results
  final resultWidget = searchbase.register('result-widget', {
    'dataField': 'name',
    'react': {
      'and': ['search-widget', 'language-filter']
    },
    'defaultQuery': (SearchController controller) =>
        ({'track_total_hits': true})
  });

  // Render results
  querySelector('#output')!.innerHtml = '''
    <div id="root">
      <h2 class="text-center">Searchbase Demo with Facet</h2>
      <div id="autocomplete" class="autocomplete">
        <input class="autocomplete-input" id="input" />
        <ul class="autocomplete-result-list"></ul>
      </div>
      <div class="row">
        <div class="col">
          <div class="filter" id="language-filter"></div>
        </div>
        <div class="col">
          <div id="results">
            <div class="loading">Loading results... </div>
          </div>
        </div>
      </div>
    </div>
  ''';
  final input = querySelector('#input');
  void handleInput(e) {
    // Set the value to fetch the suggestions
    searchController.setValue(e.target.value,
        options: Options(triggerDefaultQuery: true));
  }

  input!.addEventListener('input', handleInput);

  void handleKeyPress(e) {
    // Fetch the results
    if (e.key == 'Enter') {
      e.preventDefault();
      searchController.triggerCustomQuery();
    }
  }

  input.addEventListener('keydown', handleKeyPress);

  final resultElement = querySelector('#results');
  // Fetch initial results
  resultWidget.triggerDefaultQuery();

  resultWidget.subscribeToStateChanges((change) {
    final results = change.Results!.next;
    final items = results!.data.map((i) {
      return """
    <div id=${i['_id']} class="result-set">
      <div class="image">
        <img src=${i['avatar']} alt=${i['name']} />
      </div>
      <div class="details">
        <h4>${i['name']}</h4>
        <p>${i['description']}</p>
      </div>
    </div>""";
    });
    final resultStats = '''<p class="results-stats">
                          Showing ${results.numberOfResults} in ${results.time}ms
                        <p>''';
    resultElement!.setInnerHtml("$resultStats${items.join('')}",
        validator: NodeValidatorBuilder.common()
          ..allowHtml5()
          ..allowElement('img',
              attributes: ['src'], uriPolicy: DefaultUriPolicy()));
  }, [KeysToSubscribe.Results]);

  // Fetch initial filter options
  filterWidget.triggerDefaultQuery();

  filterWidget.subscribeToStateChanges((change) {
    final aggregations = change.AggregationData!.next;
    final container = document.getElementById('language-filter');
    container!.setInnerHtml('');
    aggregations?.data?.forEach((i) {
      if (i['_key'] != null) {
        final checkbox = document.createElement('input');
        checkbox.setAttribute('type', 'checkbox');
        checkbox.setAttribute('name', i['_key']);
        checkbox.setAttribute('value', i['_key']);
        checkbox.id = i['_key'];
        checkbox.addEventListener('click', (event) {
          final List values = filterWidget.value ?? [];
          if (values.contains(i['_key'])) {
            values.remove(i['_key']);
          } else {
            values.add(i['_key']);
          }
          // Set filter value and trigger custom query
          filterWidget.setValue(values,
              options: Options(stateChanges: true, triggerCustomQuery: true));
        });
        final label = document.createElement('label');
        label.setAttribute('htmlFor', 'i._key');
        label.setInnerHtml("${i['_key']}(${i['_doc_count']})");
        final div = document.createElement('div');
        div.append(checkbox);
        div.append(label);
        container.append(div);
      }
    });
  }, [KeysToSubscribe.AggregationData]);

  searchController.subscribeToStateChanges((change) {
    print('Track State Updates');
    print('Search Suggestions');
    window.console.log(searchController.suggestions);
  }, [KeysToSubscribe.Results]);
}

6
likes
150
pub points
54%
popularity

Publisher

verified publisherappbase.io

Searchbase allows building search UIs for ReactiveSearch, powered by Elasticsearch or OpenSearch

Repository (GitHub)
View/report issues

Documentation

API reference

License

Apache-2.0 (license)

Dependencies

collection, http

More

Packages that depend on searchbase