Algolia autocomplete js with select2 - autocomplete

I am using aloglia autocomplete.js and followed the tutorial.
I want to use autocomplete text box with others select2 selectbox.
var client = algoliasearch('YourApplicationID','YourSearchOnlyAPIKey')
var index = client.initIndex('YourIndex');
autocomplete('#search-input', { hint: false }, [
{
source: autocomplete.sources.hits(index, { hitsPerPage: 5 }),
displayKey: 'my_attribute',
templates: {
suggestion: function(suggestion) {
return suggestion._highlightResult.my_attribute.value;
}
}
}
]).on('autocomplete:selected', function(event, suggestion, dataset) {
console.log(suggestion, dataset);
$("#search-input").val(suggestion.full_name.name)
});
Problem is when I clicked anywhere beside that autocomplete box autocomplete disappear and it showed only what I typed before.
I don't want it to disappear. How can I implement it? Thanks for helping.
Please see the example below for detail problem.
Assume you have a simple form with one auto complete input field,two select2 boxes and one submit button. After you choose auto complete filed, when you click anywhere, it changed to default text. I mean, you put "piz" and it shows "pizza". Therefore you select pizza and it display "pizza".Then, you try to choose one select2 box or click anywhere. The autocomplete input field changed back to "piz".
I tried autocomplete:closed , $("#search-input").focusout to set the input field but it just changed back to my query.

To prevent it from disappearing, you can use autocomplete.js's debug option:
autocomplete('#search-input', { hint: false, debug: true }, [ /* ... */ ]);
The complete options list is available on GitHub.

Now I have it. When you need to only select and not to do any action, you can safety remove autocomplete:selected. And make sure your display key is value not object.
It saves me for trouble.

Related

Understanding binding and selection in Word Add-in

I'm trying to build an add-in with similar behaviour like the comment system.
I select a part of text.
Press a button in my add-in. A card is created that links to that text.
I do something else, like write text on a different position.
When I press the card in my add-in, I'd like to jump back to the selected text (in point 1).
I studied the API, documentation. And learned that I could do something like that with Bindings. A contentcontrol might also be an option, although I noticed that you can't connect and eventhandler (it's in beta). I might need an eventhandler to track changes later.
Create binding (step 2)
Office.context.document.bindings.addFromSelectionAsync(Office.BindingType.Text, { id: 'MyBinding' }, (asyncResult) => {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
console.log('Action failed. Error: ' + asyncResult.error.message);
} else {
console.log('Added new binding with id: ' + asyncResult.value.id);
}
});
Works. Then I click somewhere else in my document, to continue with step 4.
View binding (step 4).
So I click the card and what to jump back to that text binding, with the binding selected.
I figured there are multiple ways.
Method #1
Use the Office.select function below logs the text contents of the binding. However, it doesn't select that text in the document.
Office.select("bindings#MyBinding").getDataAsync(function (asyncResult) {
if (asyncResult.status == Office.AsyncResultStatus.Failed) {
}
else {
console.log(asyncResult.value);
}
});
Method #2
Use the GoToById function to jump to the binding.
Office.context.document.goToByIdAsync("MyBinding", Office.GoToType.Binding, function (asyncResult) {
let val = asyncResult.value;
console.log(val);
});
This shows like a blue like frame around the text that was previously selected and puts the cursor at the start.
I'd prefer that I don't see that frame (no idea if that's possible) and I would like to the text selected.
There is the Office.GoToByIdOptions interface that mentions:
In Word: Office.SelectionMode.Selected selects all content in the binding.
I don't understand how pass that option in the function call though and I can't find an example. Can I use this interface to get the selection?
https://learn.microsoft.com/en-us/javascript/api/office/office.document?view=common-js-preview#office-office-document-gotobyidasync-member(1)
goToByIdAsync(id, goToType, options, callback)
If there are other ways to do this, I'd like to know that as well.
With some help I could figure it out. I learned that an Interface is just an object.
So in this case:
const options = {
selectionMode: Office.SelectionMode.Selected
};
Office.context.document.goToByIdAsync("MyBinding", Office.GoToType.Binding, options, function (asyncResult) {
console.log(asyncResult);
});
This gives the selected result.
Sure someone can provide a better answer than this, as it's unfamiliar territory for me, but...
When you create a Binding from the Selection in Word, you're going to get a Content Control anyway. So to avoid having something that looks like a content control with the blue box, you either have to modify the control's display or you have to find some other way to reference a region of your document. In the traditional Word Object model, you could use a bookmark, for example. But the office-js APIs do not seem very interested in them.
However, when you create a Binding, which is an Office object, you don't get immediate access to the Content Control's properties (since that's a Word object). So instead of creating the Binding then trying to modify the Content Control, you may be better off creating the Content Control then Binding to it.
Something like this:
async function markTarget() {
Word.run(async (context) => {
const cc = context.document.getSelection().insertContentControl();
// "Hidden" means you don't get the "Bounding Box"
// (blue box with Title), or the Start/End tag view
cc.appearance = "Hidden";
// Provide a Title so we have a Name to bind to
cc.title = "myCC";
// If you don't want users changing the content, you
// could uncomment the following line
//cc.cannotDelete = true;
return context.sync()
.then(
() => {
console.log("Content control inserted");
// Now create a binding using the named item
Office.context.document.bindings.addFromNamedItemAsync("myCC",
Office.BindingType.Text,
{ id: 'MyBinding' });
},
() => console.log("Content control insertion failed")
).then(
() => console.log("Added new binding"),
() => console.log("Binding creation failed")
)
});
}
So why not just create the ContentControl, name it, and then you should be able to select it later using its Title, right? Well, getting the "data" from a control is one thing. Actually selecting it doesn't seem straightforward in the API, whereas Selecting a Binding seems to be.
So this code is pretty similar to your approach, but adds the parameter to select the whole text. The syntax for that is really the same syntax as { id: 'MyBinding' } in the code you already have.
function selectTarget() {
Office.context.document.goToByIdAsync(
"MyBinding",
Office.GoToType.Binding,
{ selectionMode: Office.SelectionMode.Selected },
function(asyncResult) {
let val = asyncResult.value;
console.log(val);
}
);
}
Both the Binding and the ContentControl (and its Title) are persisted when you save/reopen the document. In this case, the Binding is persisted as a piece of XML that stores the type ("text"), name ("MyBinding") and a reference to the internal ID of the content control, which is a 32-bit number, although that is not immediately obvious when you look at the XML - in an example here, the Id Word stores for the ContentControl is -122165626, but "Office" stores the ID for the Binding as 4172801670, but that's because they are using the two different two's complement representations of the same number.

React-Bootstrap-Typeahead: Capture moment before setting selection into box (to allow conditional rejection)

In React-Boostrap-Typeahead, I need to capture the moment after the mouse has been clicked, but before the menu selection gets loaded into the Typeahead's box.
This is because I need to check items being selected, and for some of them, I need to display an alert with a Yes/No warning. Only if Yes is clicked can I proceed with setting that value into the box. Otherwise I need to reject the selection and keep it whatever it was prior to the mouse click.
I can't use onChange because by that point the selection is already in the box.
I can't use onInputChange because that is for typing rather than for menu selection. I need the post-menu-select, pre-box change.
If there are any workarounds please let me know.
You should be able to achieve what you're after using onChange:
const ref = useRef();
const [selected, setSelected] = useState([]);
return (
<Typeahead
id="example"
onChange={(selections) => {
if (!selections.length || window.confirm('Are you sure?')) {
return setSelected(selections);
}
ref.current.clear();
}}
options={options}
ref={ref}
selected={selected}
/>
);
Working example: https://codesandbox.io/s/objective-colden-w7ko9

Accordion dropdown filtering through ion search bar

Hi I just created the ionic accordion dropdowns by following a tutorial blog link which used widgets for creating an accordion dropdowns, Below is the link of that blog.
http://masteringionic.com/blog/2019-01-27-creating-a-simple-accordion-widget-in-ionic-4/
updated: here is the my project demo link https://stackblitz.com/github/dSaif/search-accordion
Everything is working perfect, but i want to add Ion-searchbar at the top of the accordions sothat the dropdowns gets filter by inputing text.
please assist me how can i do that. Thank you.
You are going to have to create a variable in your homepage to store your filtered results. Then you need to have a filter function that will take the input from the search bar and filter your master list. Keep in mind you should not set the new variable to the master list, this could cause issues due to object referencing.
So you should have something like
in your html
<ion-searchbar placeholder="Search a name." [(ngModel)]="searchValue" (ionChange)="filterList()"></ion-searchbar>
In your ts file
searchValue: string = '';
filteredList: Array<{ name: string, description: string, image: string }> = this.technologies;
// function called in the html whenever you change the ion searchbar value
private filterList(){
//Make a variable so as to avoid any flashing on the screen if you set it to an empty array
const localFilteredList = []
this.technologies.forEach(currentItem => {
//here goes your search criteria, in the if statement
if(currentItem.name && currentItem.name.toLowerCase().includes(this.searchValue.toLowerCase())) {
localFilteredList.push(currentItem);
}
});
//finally set the global filter list to your newly filtered list
this.filteredList = localFilteredList;
}
You also need to make sure to reference the filterList variable instead of the current one you are referencing.

How to enable auto focus on SAPUI5 input suggestion field

I'm currently developing a sapui5 mobile application and am using an sap.m.Input with suggestions bound by a model like this:
new Page('page', {
showNavButton: true,
content: [
new sap.m.Input({
id: "input",
type: 'Text',
showSuggestion: true,
suggestionItemSelected: function(event) {
event.getParameters().selectedItem.mProperties.text;
},
liveChange: function() {
// some stuff
}
})
]
});
The Model is created and bound like the following:
var model = new sap.ui.model.json.JSONModel();
// model is filled
sap.ui.getCore().byId('input').setModel(model);
sap.ui.getCore().byId('input').bindAggregation('suggestionItems', '/', new sap.ui.core.Item({
text: "{someField}"
}));
When I now click into the input field on a mobile device, kind of a new screen opens with a new input field, which the user has to manually focus again, what seems like a usability flaw to me.
Is there a nice possibility to enable auto focusing the input field on this new screen, so that the user doesn't has to do it again? Or can this screen be disabled at all on mobile devices?
sap.m.input doesn't seem to have a own method for focusing, or at least I'm not finding one - I already tried using jquery's .focus() on the new input field, but without success.
edit: for clarification, the suggestion works troublefree - only the absence of the auto focus on the appearing new screen is what bothers me.
Here is a workaround to "fix" this behavior: https://jsbin.com/lukozaq
Note 1: The above snippet relies on internal implementation of how the popup works. Use it with caution as there are currently no public APIs to access the corresponding internal controls.
Note 2: I put the word fix in quotes because it seems to be the intended behavior that the user has to click on the second input field explicitly, according to the comment in the source code:
Setting focus to DOM Element, which can open the on screen keyboard on mobile device, doesn't work consistently across devices. Therefore, setting focus to those elements are disabled on mobile devices and the keyboard should be opened by the user explicitly.
That comment is from the module sap.m.Dialog. On a mobile device, when the user clicks on the source input field, a stretched Dialog opens up as a "popup" which has the second input field in its sub header.
Please check the API documentation of sap.m.Input, it has a method focus. You can call:
this.byId("input").focus()
to set the focus into the input field.
Try this:
jQuery.sap.delayedCall(0, this, function() {
this.byId("input").focus()
});
About how to detect when the user presses the input field: maybe something like this? Only problem is that I think you probably don't know the id of the new input field which is shown.
var domId = this.byId("input").getId();
$( "#"+domId ).click(function() {
jQuery.sap.delayedCall(0, this, function() {
this.byId("input").focus()
});
});
I am pretty sure that the first piece of code is how to put focus on an input. I'm not sure about the second part, but it's something to try.
in onAfterRendering() do the below..
onAfterRendering : function() {
$('document').ready(function(){
sap.ui.getCore().byId('input').focus();
});
}
I didnĀ“t have the exactly same problem, but It was similiar.
My problem was that I needed focus into suggestion input when the view had been rendered. My solution was to put following code into "hanldeRouteMatched" function:
var myInput = this.byId("inputName");
var viewName = this.getView().getId();
var selector1 = viewName + "--inputName-inner";
var selector2 = viewName + "--inputName-popup-input-inner";
jQuery.sap.delayedCall(1000, this, function() {
myInput.focus();
if($("#" + selector1)){
$("#" + selector1).click();
jQuery.sap.delayedCall(500, this, function() {
if($("#" + selector2)){
$("#" + selector2).focus();
}
});
}
});
If you see that suggestion input catch focus, but It lose it after, or It never catched it, try increasing the time in delayedCalls. The needed time depends on your connection speed.

Ajax Auto Suggest v.2 suggestion depends on radio button?

I am using auto suggest v.2.1.3 from brandspankingnew.
I have a form with two radio button and a text field and would like to know how to make the auto suggest script pointing to a different php file if one of the radio button is checked.
I tried this but it doesnt work, its always point to the same php file even if second button is checked
Could you please assist?
Many thanks in advance.
My code is as follows:
function targetvalue()
{
for (i=0;i
/>Business Street
var options = {
script:"autosuggest.php?json=true&limit=6&",
varname:"input",
json:true,
shownoresults:false,
maxresults:10,
callback: function (obj) { document.getElementById('name').value = obj.id; }
};
var as_json = new bsn.AutoSuggest('business', options);
var options_xml = {
script: function (input) { return "autosuggest.php?input="+input+"&testid="+document.getElementById('testid').value; },
varname:"input"
};
var as_xml = new bsn.AutoSuggest('business', options_xml);
As for me, the easiest solution is to pass the the button state to the one script eg only one script but can return different results depending on button state. Otherwise you need to rewrite options each time someone clicks on the radio button. The second solution an lead to unpredictable behavior of auto suggest component.
Sample script:
var selectedValue = getRadioSelectedValue("radioGroupName");
var options_xml = { script: function (input) { return "autosuggest.php?input="+input+"&testid="+document.getElementById('testid').value+"&mode="+selectedValue; },
Write getRadioSelectedValue by yourself to get selected radio button value or set some flag on click. Mode param in GET request will indicates the state of the button, so you can return proper response.