I am building a service that uses Algolia instantsearch.js to display search results.
Starting the project I created a template where I displayed our customers in a table. Then I wanted to add the functionality that the contents of the table change while a user is typing for a specific customer info (ex. mobile number). This is why I used Algolia and instantsearch.js to achieve this.
I managed to have it working but I have a problem with styling the whole thing:
The searchbox and hits widgets (where the results are displayed) are added to the DOM with a specific HTML/CSS structure:
Searchbox:
<!- Input field -->
<input autocapitalize="off" autocomplete="off" autocorrect="off" placeholder="Search for customers.." role="textbox" spellcheck="false" type="text" value="" class="ais-search-box--input">
<!- Algolia Powered by logo -->
<span class="">
<div class="ais-search-box--powered-by">
...
<a class="ais-search-box--powered-by-link">...</a>
</div>
</span>
<!- Search magnifier icon -->
<span class="ais-search-box--magnifier-wrapper">
<div class="ais-search-box--magnifier">...</div>
</span>
<!- Clear search icon -->
<span class="ais-search-box--reset-wrapper" style="display: none;">
<button type="reset" title="Clear" class="ais-search-box--reset">...</button>
</span>
Hits:
<div class="ais-hits">
<div class="ais-hits--item">
First customer data (all of them)
</div>
<div class="ais-hits--item">
Second customer data (all of them)
</div>
<div class="ais-hits--item">
Third customer data (all of them)
</div>
<div class="ais-hits--item">
First customer data (all of them)
</div>
</div>
Trying to work with these results it's frustrating since I have my HTML/CSS code ready (search field and table for results is designed to match the look and feel of the rest of the website).
What i want to get back from search is a response that i can use and add data in the correct place. For example now i am trying to populate the with the customer's data but i can't:
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Surname</th>
<th>Email</th>
<th>Mobile</th>
</tr>
</thead>
<tbody>
<tr id="hits"></tr>
</tbody>
</table>
Below is the template I use:
<script type="text/html" id="hit-template">
<td>#{{ name }}</td>
<td>#{{ surname }}</td>
<td>#{{ email }}</td>
<td>#{{ mobile }}</td>
</script>
I am adding # in front of the value since I am using Laravel and blade template.
What i get is a table with all data from all customers in the first . Only one table row is created.
In JS code I use the following:
var search = instantsearch({
appId: 'my-app-id',
apiKey: 'my-search-only-api-key',
indexName: 'my-indices',
urlSync: false,
searchParameters: {
hitsPerPage: 10
}
});
search.addWidget(
instantsearch.widgets.searchBox({
container: '#searchbox',
placeholder: 'Search for customers..',
poweredBy: true,
wrapInput: false
})
);
search.addWidget(
instantsearch.widgets.hits({
container: '#hits',
templates: {
item: document.getElementById('hit-template').innerHTML,
empty: "We didn't find any results for the search <em>\"{{query}}\"</em>"
}
})
);
search.start();
Is there a way to just get a JSON response from instantsearch instead of a widget? I dont want to go down the server site route, since this is the whole point of instantsearch.js.
If I cant get back simple JSON response, what do I have to do to change the layout of the widgets. Override all ais classes?
Thanks in advance!
You can't have a full control of what is render with the widget API. But there is another API called connectors. This one lets you create a custom rendering without reimplementing the core logic of the widget. You can take a look at this API on the documentation.
Related
I am fetching list of posts with sort order from Database and binding with table using ng-repeat of rows. I set them up so you can reorder them with drag-and-drop using Angular Dragula. This works fine.
After dragging, Whenever I click on save button I should get Updated Sort Order, So that I can update it on Database.
Before Drag:
Let Suppose post_sort_order:1,2,3,5
After Drag :
post_sort_order: 4,2,3,1
HTML:
<tbody md-body ui-sortable >
<tr md-row>
<td>
<div dragula-model="vm.GroupData.groups" class="drag-container" dragula='"drag-container"' layout="column" layout-xs="column" layout-align="space-between" layout-margin>
<tri-widget ng-repeat="order in vm.GroupData.groups" flex title="{{::order.group_name | triTranslate}}" title-position="top" palette-background="blue-grey:600" background="primary"></tri-widget>
</div>
</td>
</tr>
</tbody>
Javascript:
Result: vm.GroupsData.groups:
Now, Once I click on Save button, I should get updated sort list like here 4,3,2,1.
Actual post_sort_order: 1,2,3,5
Expected post_sort_order:3,1,5,2
Is there a way to get updated list ?If yes, Please let me know.
Thanks in advance.
I am in the process of learning with this framework (Vuejs) and I need to find a way to add a page in a table, by which, it should be expanded as more objects are added and then list them in the table and limit the number of items to show by tab.
The table used is the following.
<table class="table table-responsive">
<thead>
<tr>
<th>Título</th>
<th>Tipo</th>
<th>Categoría</th>
<th>Fecha creación</th>
<th>Acción</th>
</tr>
</thead>
<tbody>
<tr :key="post.IDEN_PUBLICACION" v-for="post in posts" v-if="!post.FLAG_VALIDADO && !post.FLAG_BAN">
<td>{{post.NOMB_PUBLICACION}}</td>
<td>{{post.CODI_TIPO_PUBLICACION == 'P' ? 'Producto' : 'Servicio' }}</td>
<td>{{post.categoria.NOMB_CATEGORIA}}</td>
<td>{{post.FECH_CREACION | dateFormat}}</td>
<td>
<a class="btn btn-success" #click="acceptPost(post)" title="Aceptar"><icon name="check"></icon></a>
<a class="btn btn-danger" #click="ban(post)" title="Rechazar"><icon name="times"></icon></a>
</td>
</tr>
</tbody>
</table>
Searching, I found that there are plugins that can help this time, but if I manage to implement it visually, I do not know how to start developing the behavior I need.
I try with 'vue-paginate'.
<!--Paginación de tabla -->
<template>
<paginate
:page-count="5"
:page-range="1"
:margin-pages="1"
:click-handler="recorrerTabla"
:prev-text="'Anterior'"
:next-text="'Siguiente'"
:container-class="'pagination'"
:page-class="'page-item'">
</paginate>
</template>
this method I only used it to check functionality
methods: {
acceptPost (post) {
controller.acceptPost(this, post)
},
recorrerTabla: function (pageNum) {
console.log(pageNum)
},
n summary, I would like that the table shows 5 items per tab of the table and that the pager allows me to see in another tab the following 5 items. If this is possible, add that the number of pages fits the total of items, it would be great.
Image from the view
Technologies used:
Vuejs 2.4 Node 8+ Nuxt 1.0.0 - RC11 Nuxt / Axios 4.5.0 JWT-Decode 2.2.0 Js-Cookie Vee-Validate
In advance, thanks for your answers and any documentation or example of help.
I'm trying to learn some AngularJS. I have a small page hosted locally which looks up information in MySQL. The fields are [user_ID, comment, user_Name].
Here is the webpage's code:
AngularJS Test
<div id="container" ng-app='two_way' ng-controller='two_way_control'>
<input ng-model="name_filter" placeholder="filter names">
<p>{{name_filter}}</p>
<div class="row" ng-repeat="data in profile_pictures | filter:{data.user_Name:name_filter}">
<div class=".col-sm-6 .col-md-5 .col-lg-6" style="background-color:#eee;height:125px;width:500px;margin-left:240px;margin-top:20px;">
<h4 style="padding:10px;">{{data.user_Name}} says:</h4><hr>
<p style="padding:10px;">
{{data.comment}}
</p>
<img src="{{data.profile_picture}}" class="img-circle" style="width:100px;height:100px;margin-left:-140px;margin-top:-130px;">
</div>
</div>
</div>
Now the problem I am having is regarding the filter for "data in profile_pictures"
I'm trying to filter just by the user_Name field. When I type anything into the input box on the site, no data is displayed (everything disappears). I have tried hardcoding the filter to be a name I know is in the data, but that just shows no data when I load the page.
Any ideas?
Thanks for the help
You have invalid syntax in your filter. You need to provide the key name of the object as the filter object, do not use dot notation for the object key #filter:{data.user_Name:name_filter}"
i.e try
ng-repeat="data in profile_pictures | filter:{user_Name:name_filter}"
I am new to angularJS i have an object of which contains nearly 4000 records which i am showing them using ng-repeat
<div infinite-scroll='loadMore()' infinite-scroll-distance='2'>
<li ng-repeat="outlet in outlets | filter:searchText" >
<table>
<tr>
<td>
<div clss="title">{{outlet.name}}</div>
<div class="discription">{{outlet.address}},{{outlet.cityName}},{{outlet.countyName}}</div>
</td>
</tr>
</table>
</li>
</div>
now i wanted to use endless list by using ng-infinitescroll but the problem is the filter is happening only which are visible not in total 4000 records so what do i have to implement to get the search functionality to be done in total 4000 records and endless list
searchText filter would only work on in-memory data. In order to search things that havent been loaded yet you would need to implement a server-side search api.
I'm using Angular UI - Bootstrap, specifically the Typeahead directive. http://angular-ui.github.io/bootstrap/#/typeahead
I'm attempting to use the 'typeahead-template-url' to create custom html templates for my suggestion boxes. After trying multiple techniques, unsuccessfully, I discovered that by purposely messing up my quotation marks 'solved' the display issues. I would love to understand why this is breaking and get it working properly.
For example: this works
<table class="> <!--see class quote error -->
<tr>
<td>
<div ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)">
<a>ID{{ match.model.id }} - {{ match.model.text }}</a>
</div>
</td>
</tr>
</table>
This DOESN'T WORK
<table class="">
<tr>
<td>
<div ng-mouseenter="selectActive($index)" ng-click="selectMatch($index)">
<a>ID{{ match.model.id }} - {{ match.model.text }}</a>
</div>
</td>
</tr>
</table>
FIDDLE is here: http://jsfiddle.net/nicktest222/JXtaZ/24/
Additionally, when you select an item in the results list, it returns the entire object. How can I get it to return a specific property in the object?
Any help would be greatly appreciated.
Thanks
I think it is the way you add your template (columnTwo.html) in JSFiddle.
Look at my demo (which is based on yours): http://jsbin.com/aMOrOra/1/edit?html,js,output
As for the typeahead property:
<input type="text" ng-model="monkey" typeahead-template-url="columnTwo.html" typeahead="suggestion as suggestion.text for suggestion in sample_data | filter: $viewValue" />
Here it means that the suggestion object is used as the selected value, but I want to display only the suggestion.text property in the box. But monkey will still be set to the selected suggestion object.
Just so you know, your current filter will look for the query on every properties of the suggestion object, not only text.
EDIT: To filter only the text property, use the filter like this:
filter:{'text':$viewValue}