How to add algolia image to to the bottom of autocomplete results - html

I am using algolia autocomplete service and would like to add an image
to the bottom of the autocomplete results like it is shown in their examples here:
This is how my autocomplete.js looks like:
autocomplete('#search-input', {}, [
{
source: autocomplete.sources.hits(players, { hitsPerPage: 5 }),
displayKey: 'first_name',
templates: {
header: '<div class="aa-suggestions-category">Players</div>',
suggestion: function(suggestion) {
return '<span>'
+ '<a href="/player/' + suggestion.id + '">'
+ '<div class="media">'
+ '<div class="media-left">'
+ '<img class="media-object" src="/imagecache/small/' + suggestion.image_filename + '">'
+ '</div>'
+ '<div class="media-body">'
+ '<p>' + suggestion._highlightResult.first_name.value + " " + suggestion._highlightResult.last_name.value + '<small> ' + old + ' years</small>' + '</p>'
+ '<small> ' + suggestion.nationality + ' '+ suggestion.position + '</small>'
+ '</div>'
+ '</div>'
+ '</a>'
+'</span>';
}
}
},
{
source: autocomplete.sources.hits(videos, { hitsPerPage: 5 }),
displayKey: 'title',
templates: {
header: '<div class="aa-suggestions-category">Videos</div>',
suggestion: function(suggestion) {
timeAgo();
return '<span>'
+ '<a href="/player/video/' + suggestion.uid + '">'
+ '<div class="media">'
+ '<div class="media-left">'
+ '<img class="media-object" src="https://s3.eu-central-1.amazonaws.com/videos.football-talents.com/' + suggestion.video_id + '_1.jpg">'
+ '</div>'
+ '<div class="media-body">'
+ '<p>' + suggestion._highlightResult.title.value + ' <small class="timeago" title="' + suggestion.created_at + '">' + suggestion.created_at + '</small>' + '</p>'
+ '<small> ' + suggestion._highlightResult.player_name.value + " " + suggestion._highlightResult.player_surname.value + '</small>'
+ '</div>'
+ '</div>'
+ '</a>'
+'</span>';
}
}
}
]).on('autocomplete:updated', function(event, suggestion, dataset) {
var timeagoTimeout;
clearTimeout(timeagoTimeout);
timeAgo();
timeagoTimeout = setTimeout(timeAgo, 60000);
});
Where should I add an image so that it is at the bottom of the result, like it is on the image I have posted?

You can use the footer template option like described here.
$('#search-input').autocomplete({
templates: {
footer: '<div class="branding">Powered by <img src="https://www.algolia.com/assets/algolia128x40.png" /></div>'
}
}, [
/// here your sources
]
);

Related

DataTable search filter, sorting and pagination not working after fetching JSON data using Promise.fetch

I have a DataTable that display JSON data from Promise fetch. It uses loops over the JSON data and displays it in the tbody. The problem I'm having now is that, all the rows of the JSON data fetched appears in the table with no pagination, and the search filter and column sorting aren't working as well.
Here is my code snippet:
<table class="table table-striped table-hover" id="tierlist">
<thead>
<tr>
<th></th>
<th>Card Image</th>
<th>Rarity</th>
<th>Character</th>
<th>Attribute</th>
<th>R Factor Scene</th>
<th>Overall STR</th>
<th>HP</th>
<th>SP</th>
<th>ATK</th>
<th>DEF</th>
<th>HIT</th>
<th>AVO</th>
<th>LUK</th>
</tr>
</thead>
<tbody id="datarows">
</tbody>
</table>
<script type="text/javascript">
var table = $('#tierlist').DataTable({
responsive: true,
initComplete: function () {
$('.dataTables_filter input[type="search"]').css({ 'width': '50px', 'display': 'inline-block' });
}
});
// Data URL
const URL = "https://somedomain/data.json";
// Promise fetch the data and display it
fetch(URL)
.then((response) => response.json())
.then((cards) => datarows.innerHTML = displayCards(cards))
.then(table.clear().draw());
const displayCards = (cards) => {
var out = "";
var i;
for(i = 0; i<cards.length; i++) {
out += '<tr><td><img height="35" src="' + cards[i].skill + '" /></td>' +
'<td><img height="70" src="' + cards[i].cardImage + '" /></td>' +
'<td>' + cards[i].rarity + '</td>' +
'<td>' + cards[i].character + '</td>' +
'<td><img height="35" src="' + cards[i].attribute + '" /></td>' +
'<td>' + cards[i].rFactorScene + '</td>' +
'<td>' + cards[i].STR + '</td>' +
'<td>' + cards[i].HP + '</td>' +
'<td>' + cards[i].SP + '</td>' +
'<td>' + cards[i].ATK + '</td>' +
'<td>' + cards[i].DEF + '</td>' +
'<td>' + cards[i].HIT + '</td>' +
'<td>' + cards[i].AVO + '</td>' +
'<td>' + cards[i].LUK + '</td></tr>' ;
}
return out;
};
</script>
Any help would be greatly appreciated.
The data you are adding to the table in HTML is not added to the DataTable object.
The following jsfiddle solves your issue by instead of adding the fetched data to the HTML table, adding it to the DataTable object and redrawing it.
The important difference is displayed here (addData replaces displayCards):
function addData(cards){
cards.forEach(card => {
table.row.add([
'<img height="35" src="' + card.skill + '" />',
'<img height="70" src="' + card.cardImage + '" />',
card.rarity,
card.character,
'<img height="35" src="' + card.attribute + '" />',
card.rFactorScene,
card.STR,
card.HP,
card.SP,
card.ATK,
card.DEF,
card.HIT,
card.AVO,
card.LUK
]);
});
}
https://jsfiddle.net/ja03o65r/30/

$.each only the last element is shown

I'm trying to filter a list with AJAX, I have an issue where the html only shows the last element. I have read a lot of similar SO questions and to no avail. I have variables, so I don't know whats the issue.
$("#programme").change(function () {
event.preventDefault();
var selected_programme = $(this).val();
$.ajax({
url: '{% url "gps_list" %}',
data: {
"selected_programme": selected_programme,
},
dataType: 'json',
success: function(response) {
var json = $.parseJSON(response);
$.each( json, function( key, values ) {
var valname = values.fields.name;
var valco = values.fields.country;
var valpro = values.fields.programme_type;
var valwhat = values.fields.what;
console.log(valname, key);
console.log(valco);
console.log(valpro);
console.log(valwhat);
$("#names").html(valname);
$("#country").html(valco);
$("#pro_types").html(valpro);
$("#whats").html(valwhat);
});
},
error: function(response) {
alert("oh no!");
}
});
});
HTML
<div class="row">
<div class="col-md-12">
<h2 class="my-4" id="names">
<small id="country"></small>
</h2>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="card mb-4">
<div class="card-body">
<h2 class="card-title" id="pro_types"></h2>
<p class="card-text" id="whats"></p>
</div>
</div>
</div>
</div>
When you do this:
$("#names").html(valname);
$("#country").html(valco);
$("#pro_types").html(valpro);
$("#whats").html(valwhat);
you're overwriting whatever those elements had in them before. Since you're doing that in a loop, naturally you only see the result of the last write.
You'll need to either:
Write to different elements, or
Append rather than replacing (via append)
The specifics will depend on your HTML structure.
(Now that you've added your HTML.) I would structure it differently. Don't have any row at all (or have a placeholder "loading" row) to start with. Then build rows and append them when you have a response. Something along these lines:
var entryTemplate =
'<div>' +
'<div class="row">' +
'<div class="col-md-12">' +
'<h2 class="my-4">' +
'<span class="names"></span>' + // *** Made it a span inside the h2
'<small class="country"></small>' +
'</h2>' +
'</div>' +
'</div>' +
'<div class="row">' +
'<div class="col-md-12">' +
'<div class="card mb-4">' +
'<div class="card-body">' +
'<h2 class="card-title pro_types"></h2>' +
'<p class="card-text whats"></p>' +
'</div>' +
'</div>' +
'</div>' +
'</div>' +
'</div>';
function success(response) {
var json = $.parseJSON(response);
var container = $("#container");
container.empty(); // Removes any previous rows
$.each( json, function( key, values ) {
var fields = values.fields;
var entry = $(entryTemplate);
entry.find(".names").text(fields.name);
entry.find(".country").text(fields.country);
entry.find(".pro_types").text(fields.programme_type);
entry.find(".whats").text(fields.what);
container.append(entry.children());
});
}
success(
'[' +
'{"fields": {' +
'"name": "Name 1",' +
'"country": "Country 1",' +
'"programme_type": "PT 1",' +
'"what": "What 1"' +
'}},' +
'{"fields": {' +
'"name": "Name 2",' +
'"country": "Country 2",' +
'"programme_type": "PT 2",' +
'"what": "What 2"' +
'}},' +
'{"fields": {' +
'"name": "Name 3",' +
'"country": "Country 3",' +
'"programme_type": "PT 3",' +
'"what": "What 3"' +
'}}' +
']'
);
setTimeout(function() {
success(
'[' +
'{"fields": {' +
'"name": "Name 4",' +
'"country": "Country 4",' +
'"programme_type": "PT 4",' +
'"what": "What 4"' +
'}},' +
'{"fields": {' +
'"name": "Name 5",' +
'"country": "Country 5",' +
'"programme_type": "PT 5",' +
'"what": "What 5"' +
'}},' +
'{"fields": {' +
'"name": "Name 6",' +
'"country": "Country 6",' +
'"programme_type": "PT 6",' +
'"what": "What 6"' +
'}}' +
']'
);
}, 2000);
<div id="container"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

click button from template Angular 6

I have this function:
windowInfo_(marker, i, data) {
'<div style="' + this.content_ + '">' +
'<div>' +
'<img [src]="' + "'" + this.image + "'" + '"' + ' style="' + this.image_ + '" alt="avatar">' +
'</div>' +
'<div style="' + this.details_ + '">' +
'<div>' +
'<h5 style="' + this.company_name + '">' + data.company_name + '</h5>' +
'<i class="fa fa-map-marker" id="' + this.country_city + '">' + data.country + ',' + data.city + '</i>' +
'</div>' +
'</div>' +
'</div>' +
'<button class="' + this.footerListing + '" type="button" (click)="details(data.id_listing)">Explore Trips</button>'
}
details(id) {
console.log(id)
}
As you can see, I have a button inside this template, and I want when I click it, details function to be triggered. But when I click it, nothing is happening. What do I need to modify in order to trigger the function? Thank you for your time!
You can do this by using HostListener:-
Just assign id to your button (i.e. <button id="your_button_id">Click</button>)
Now use HostListener to detect click event:-
#HostListener('click', ['$event'])
onClick(event) {
if (event.target.id === 'your_button_id') {
details(id);
}
}

Bootbox message box doesn't fit content

bootbox.confirm({
title: "請輸入綁定手機號碼",
message:
'<div class="col-xs-12">'
+ '<form class="form-horizontal">'
+ '<div class="form-group">'
+ '<label class="col-xs-12" style="text-align: left">帳號(您的手機號碼):</label>'
+ '<div class="col-xs-5">'
+ '<select class="form-control" id="countryCode-bootbox" name="countryCode-bootbox">'
+ '<option value="+93">Afghanistan +93</option>'
+ '<option value="+355">Albania +355</option>'
+ '<option value="+213">Algeria +213</option>'
+ '<option value="+1684">American Samoa +1684</option>'
+ '<option value="+263">Zimbabwe +263</option>'
+ '</select>'
+ '</div>'
+ '<div class="col-xs-7">'
+ '<input type="text" class="form-control" id="cellphone-bootbox" name="cellphone-bootbox">'
+ '</div>'
+ '</div>'
+ '</form>'
+ '</div>',
callback:
function(result) {
if(result == false) {
return;
}
register3rdPartyUser(flag, $('#countryCode-bootbox').val(), $('#cellphone-bootbox').val());
}
});
As you can see, there are two horizontal lines inside the overall box which I believe are the boundaries of the message content. The bottom line doesn't come after the message content when I'm using HTML for my string. How can I fix this issue? Is it a bug?

Grails JSON from controller to GSP formatting html tag

I am trying to send the following JSON from my controller to the GSP:
[
"message": errorList + '<br/>' + '<br/>' +
'Rows loaded: ' + rows + '<br/>' +
'<img src="${resource(dir: ''images'', file: ''twc-logo-002.png'')}" alt="logo" />'
+ 'Errors: ' + errors + '<br/>' +
'Yellow Issues: ' + yellowFlags + '<br/>' +
'Red Issues: ' + redFlags
]
I am having a hard time with compiler errors on the line containing the image tag. I don't think I am escaping the inner quotes correctly. Any advice? Thanks.
[
"message": errorList + '<br/>' + '<br/>' +
'Rows loaded: ' + rows + '<br/> \'<img src=\"${resource(dir: \'images\',file: \'twc-logo-002.png\')}\" alt=\"logo\" />'
+ 'Errors: ' + errors + '<br/>' +
'Yellow Issues: ' + yellowFlags + '<br/>' +
'Red Issues: ' + redFlags
]