Algolia Instantsearch - add a callback after results are displayed? - algolia

I have an application that allows users to search for artwork and build their own portfolios. I'd like to show whether a piece of artwork that is returned in an algolia search is contained within the users portfolio, but I can't seem to find a way to make a callback once results are displayed to the user.
is it possible to add a callback to the search results?

I suppose you use instantsearch.js library for displaying the results.
Then there are two ways on how to achieve what you want.
1) Use transformData parameter of hits widget
The parameter takes callback and passes results there. So you can modify the results before it gets displayed - you can add a new parameter based on if the record is the one which should be highlighted.
Example:
search.addWidget(
instantsearch.widgets.hits({
container: '#hits-container',
templates: {
item: itemTemplate
},
transformData: {
allItems: function (results) {
console.log(results);
// Modify results
return results;
}
}
})
);
2) Use custom widget to hook a render callback
You can write a simple custom widget where you specify only the render option:
search.addWidget({
render: function(data) {
console.log(data);
}
});
In data parameter you'll get all information about the search, inluding helper, last state and the latest results.
Both approaches you can see live in small jsFiddle: https://jsfiddle.net/JanPetr/g54hzrzp/

Related

Ag Grid Autocomplete in edit cell

I need to implement Autocomplete feature in ag grid cell on the table. Is ag provides any options for that. I am just seeing select with options. But my need is to edit the cell and while start typing the values has to display below based the character.
Like you I could not find this feature. I decided to write an Angular component for this purpose and share it.
It has the ability to filter by starting to type, as well as clicking the selection by mouse. Keyboard arrow up and down navigation is also included.
It's a simple component and should be quite straightforward to edit to your likings, or take the code and implement in JS or a different framework if you are not using Angular. I am having some unfortunate cosmetic issues (primarily on the last column of the grid), which I hopefully can solve soon and then will update the repository.
https://github.com/superman-lopez/ag-grid-auto-complete
Edit:
Since my original post, a new project has started and this is not limited to Angular projects:
https://github.com/avallete/ag-grid-autocomplete-editor
You can use a jQuery autocomplete as part of the cell editor. You have to do it in the afterGuiAttached function of the custom editor so it won't run until after your input has been created.
// function to act as a class
function YourCustomEditor () {}
// gets called once before the renderer is used
YourCustomEditor.prototype.init = function(params) {
this.eInput = document.createElement('input');
this.eInput.setAttribute('class', 'inputClass');
this.eInput.setAttribute('type', 'text');
}
};
YourCustomEditor.prototype.afterGuiAttached = function() {
$('.inputClass').autocomplete({
source: function(request, response) {
// Do your autocomplete filtering here
},
datatype: 'json',
select: function(event, ui) {
// Do Stuff on select
}
});
this.eInput.focus();
};

How to retrieve the rows which are selected in the list report page of smart templates

This is the List Report type of Smart Template application
Here I have selected 2nd and 5th row, I also have a button named Send Requests in the section part which is highlighted. If I click this button it calls a javascript controller function which is defined in the extensions of the application. In this js function how can I retrieve the selected rows that are selected?
I have enabled the checkboxes in this page by mentioning this code
"settings": { "gridTable": false, "multiSelect": true } in the manifest.json
As it was recommended by this link https://sapui5.netweaver.ondemand.com/#docs/guide/116b5d82e8c545e2a56e1b51b8b0a9bd.html
I want to know how can I retrieve the rows which got selected?
There is an API that you can use for your use case. It is described here: https://sapui5.netweaver.ondemand.com/#docs/guide/bd2994b69ef542998becbc69ab093f7e.html
Basically, you just need to call the getSelectedContexts method. Unfortunately you will not be able to really get the items themselves, only the binding contexts (which point to the data entities which are selected). Excerpt from the documentation:
After you have defined a view extension, you can access and modify the
properties of all UI elements defined within these extensions (for
example, change the visibility). However, you cannot access any UI
elements that are not defined within your view extensions.
In this type of table there is way.
var myTable=sap.ui.getCore().byId("your table id");
get all rows:
var myTableRows=myTable.getRows();
now get selected Indices
var selectedIndeices=myTable.getSelectedIndices(); //this will give you array of indeices.
now run loop on indeices array. And get particular row item;
// get binding path
var bindingpath=myTableRows[2].getBindingContext().sPath; // this will return eg:"/ProductCollection/2"
// now get Binding object of that particular row.
var myData=myTableRows[2].getModel().getObject(bindingpath); // this will return binding object at that perticular row.
// once your loop is over in the end you will have all object of selected row. then do whatever you want to do.
If you use smart template create an extension.
This is the standard event befor the table is rebinding:
onBeforeRebindTableExtension: function (oEvent) {
this._table = oEvent.getSource().getTable();
}
In your action function (or where you want) call the table and get the context :
this._table.getSelectedContexts();

How to get ID of layer in feature group on click

I have a feature group containing several markers.
And I have this code to respond to a click on any of the markers:
sampleFeatureGroup.on("click", function(){
alert(this.id); // something like this
});
I want to be able to get the id of the marker which is clicked on from within the function, however "this" refers to the feature group, so I cannot find the id of the marker clicked on, this seems like it should be easy but I can't figure it out.
You must use eachLayer to iterate through the featureGroup, and then bind a function to the click event, like this:
group.eachLayer(function(layer) {
layer.on('click', function(){
alert(this._leaflet_id)
});
});
Here's a working example on Plunker:
http://plnkr.co/edit/4fh7vhVet8N0iD4GE3aN
And here's the reference to eachLayer:
http://leafletjs.com/reference.html#layergroup-eachlayer
Although it is possible to retrieve the ID using this._leaflet_id, this is not best practice because variables prefixed with _ should be treated as private.
Instead, it would be better to use the getLayerId() function like below:
group.eachLayer(function(layer) {
layer.on('click', function(){
alert(group.getLayerId(layer))
});
});

How to reference dynamically added element after DOM loaded without a need to act on any events?

I know there is .on and .live (deprecated) available from JQuery, but those assume you want to attach event handlers to one ore more events of the dynamically added element which I don't. I just need to reference it so I can access some of the attributes of it.
And to be more specific, there are multiple dynamic elements like this all with class="cluster" set and each with a different value for the: title attribute, top attribute, and left attribute.
None of these jquery options work:
var allClusters = $('.cluster');
var allClusters2 = $('#map').children('.cluster');
var allClusters3 = $('#map').find('.cluster');
Again, I don't want to attach any event handlers so .on doesn't seem like the right solution even if I were to hijack it, add a bogus event, a doNothing handler, and then just reference my attributes.
There's got to be a better solution. Any ideas?
UPDATE:
I mis-stated the title as I meant to say that the elements were dynamically added to the DOM, but not through JQuery. Title updated.
I figured it out. The elements weren't showing up because the DOM hadn't been updated yet.
I'm working with Google Maps and MarkerClustererPlus to give some more context, and when I add the map markers using markerclustererplus, they weren't available in the javascript code following the add.
Adding a google maps event listener to my google map fixed the problem:
google.maps.event.addListener(myMarkerClusterer, 'clusteringend', function () {
// access newly added DOM elements here
});
Once I add that listener, all the above JQuery selectors and/or methods work just fine:
var allClusters = $('.cluster');
var allClusters3 = $('#map').find('.cluster');
Although this one didn't, but that's because it only finds direct decendants of parent:
var allClusters2 = $('#map').children('.cluster');
Do what you need to do in the ajax callback:
$.ajax(...).done(function (html) {
//append here
allClusters = $('.cluster');
});
If you want them to be separate, you can always bind handlers after the fact, or use $.when:
jqxhr = $.ajax(...).done(function (html) { /* append html */ });
jqxhr.done(function () { allClusters = $('.cluster') });
$.when(jqxhr).done(function () { /* you get it */ });
If these are being appended without ajax changes, then just move the cluster-finding code to wherever the DOM changes take place.
If that's not an option, then I guess you would just have to check on an interval.

C# - Get textbox value and send to a javascript function

I have a simple form with three textboxes and a <canvas> on the same page and I have to validate these three fields and then get the values (if validated) sent to a javascript function to draw a picture and some text inside the <canvas> element. The form and textboxes wouldn't have to disappear after the values were submitted because the user could try out different results with different values. I've done other forms before but never tried using Ajax. I know I could use a client-side validation and get the textbox values with jQuery but I have more server-side code running that would make use of these three values. How can I do this?
in your controller, create a method to handle the results. I assume that this is for logging only, and does not need to actually return data.
public useResults(string value1, string value2)
{
// ... Do something with the results
return Json(true);
}
In your view, work out a way to construct the url to the above action. Perhaps in a hidden field;
#Html.Hidden("useResultsUrl", Url.Action("useResults", "controllerName"))
Then in your javascript, attach a click event to the button, as you probably have already (to trigger your javascript task) and add in an ajax call.
Note that the following uses JQuery, but you could use microsoft AJAX if you preferred;
$(function () {
$("#button").click(function() {
$.ajax({
url: $("input[name='useResultsUrl']").val(), // Get the url from the hidden field
type: "POST",
dataType: "JSON",
data: $("input[type='text']").serialize() // Get the value of the text inputs and serialise them.
});
});
// ... do other stuff
});
Your View can make an ajax call to the server using JQuery - either using JQuery.post
or JQuery.ajax - you give the Url of the controller action to the JQuery method, and it will handle the AJAX call for you.
Then, in your controller action, you return a JsonResult - which serialize the data for you into JSON format:
e.g. return Json( model );
Finally, implement a success function in the JQuery Ajax call in your view - this wil have the data returned by the controller available for you to do whatever you want with.