I got this code from a tutorial that I am following for Elasticsearch and AngularJS.
Trying to figure out how to have the autocomplete function form a list of sugggestions in a dropdown as user input is typed instead of displaying links as suggestions.
Here is the html markup:
<ul class="suggestions" ng-show="showAutocomplete">
<li ng-repeat="suggestion in autocomplete.suggestions" ng-show="suggestion.options.length > 0">
<small>Search for —</small> {{suggestion.options[0].text}}
<li ng-repeat="result in autocomplete.results">
{{result._source.title}}
</li>
Here is the js:
//Autocomplete
$scope.autocomplete = {
suggestions: []
};
$scope.showAutocomplete = false;
$scope.evaluateTerms = function(event) {
var inputTerms = $scope.searchTerms ? $scope.searchTerms.toLowerCase() : null;
if (event.keycode === 13) {
return;
}
if (inputTerms && inputTerms.length > 3) {
getSuggestions(inputTerms);
}
else if (!inputTerms) {
$scope.autocomplete = {};
$scope.showAutocomplete = false;
}
};
$scope.searchForSuggestion = function() {
$scope.searchTerms = $scope.autocomplete.suggestions[0].options[0].text;
$scope.search();
$scope.showAutocomplete = false;
};
var getSuggestions = function(query) {
searchService.getSuggestions(query).then(function(es_return) {
var suggestions = es_return.suggest.phraseSuggestion;
var results = es_return.hits.hits;
if (suggestions.length > 0) {
$scope.autocomplete.suggestions = suggestions;
}
else {
$scope.autocomplete.suggestions = [];
}
if (suggestions.length > 0) {
$scope.showAutocomplete = true;
}
else {
$scope.showAutocomplete = false;
}
});
};
The first list item in the html markup gives 1 suggestion (in the form of a link) and the second list item gives a list of links as suggestions. I like the list idea of multiple suggestions, but just want text phrases instead of links that the user can select. Any ideas?
Something like this should work, but I don't' have you object structure so I had to guess in a few places.
<select class="" style="font-size: 12px"
ng-options="suggestion.options[0].text as suggestion for suggestion in autocomplete.suggestions"
ng-change="searchForSuggestion()"
ng-show="suggestion.options.length > 0">
</select>
Related
Hi there I am working on a search bar I would like the search box to display p, li and h3 elements of various pages using XMLHttpRequest() ? and how?
I am converting all these elements into an array but I don't know how to make sure that the array displays in the search box so that the user can click and be redirected to the element's page.
I am trying to learn javascript so please vanilla javascript only.
Thank you for your time, hope that makes sense.
const search = document.getElementById("myInput");
const list = document.getElementById("list");
const sections = document.querySelectorAll("li, h3, p");
const filter = Array.prototype.filter;
function setlist(group) {
for (const item of group) {
const it = document.createElement("li");
const text = document.createTextNode(item.name);
it.appendChild(text);
list.appendChild(it);
}
if (group.length === 0) {}
}
function clearList() {
while (list.firstChild) {
list.removeChild(list.firstChild);
}
}
function setNoResults() {
const it = document.createElement("li");
it.classList.add("list-group-item");
const text = document.createTextNode("no results found");
it.appendChild(text);
list.appendChild(it);
}
function getRelevancy(value, searchTerm) {
if (value === searchTerm) {
return 2;
} else if (value.startWith(searchTerm)) {
return 1;
} else if (value.includes(searchTerm)) {
return 0;
} else {
return -1;
}
}
search.addEventListener("input", event => {
let value = event.target.value;
if (value && value.length > 0) {
value = value.toLowerCase();
setlist(
sections
.filter(item => {
return item.name.includes(value);
})
.sort((itemA, itemB) => {
return (
getRelevancy(itemB.name, value) - getRelevancy(itemA.name, value)
);
})
);
} else {
clearList();
}
});
<div class="navbar">
<ul class="navSection">
<li class="collection-item">
Speakers</li>
<li class="collection-item">Headphones</li>
<li class="collection-item">Accessories</li>
<li class="collection-item">Earphones</li>
<li class="collection-item">All</li>
</ul>
</div>
<div class="basketSearch">
<div class="searchBar">
<input type="text" name="search" value="" autocomplete="off" id="myInput" placeholder="" />
</div>
<ul class="listGroup" id="list"></ul>
You should have a Database with the data or use an API to fetch some.
The second option is to have a JSON file locally that will contain the data.
let request = new XMLHttpRequest();
request.open('GET', 'URL*', true);
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
let data = JSON.parse(request.responseText)
}
};
request.send(null);
- Example of data -
[
{name: 'something', ...othervalues},
]
OR
['something', 'item1', 'item2', ...]
*URL = The path to a php file, or url to an API.
After that you can use your
search.addEventListener("input", event => {...})
to filter the data array results.
Have in mind that Ajax requests have an asynchronous nature and you have to handle them properly. You might consider using async functions or promises. Otherwise if you fire the input event before the result is set, the data will be undefined.
An other way is to set your search.addEventListener("input", event => {...}) after the ajax request is finished
request.onreadystatechange = function() {
if (request.readyState === 4 && request.status === 200) {
let data = JSON.parse(request.responseText);
search.addEventListener("input", event => {...})
}
};
So you can have direct access to the data variable.
Also an other option for the dropdown menu for the suggestions is HTML Datalists.
Cheers.
Okay guys, I am trying to use JavaScript to validate a form, and then display a "Thank you" message after its all been validated with correct information. I've got it working to validate the first name, email address, and a radio selection, however I can't seem to get it to validate the state selection, or display the thank you message, but I've also used my browser's(Firefox) Dev Console to dig for syntax errors. None are displayed. Any help?
A small snip of the code is below, and a jsfiddle link to the whole code, plus the HTML is below that.
function validForm() { // reference point
/* first name, email, comments and phone */
var fname = document.form1.fname;
var email = document.form1.email;
var comments = document.form1.comments;
var phone1 = document.form1.phone1;
var phone2 = document.form1.phone2;
var phone3 = document.form1.phone3;
/* collecting the error spans for later use */
var fnErr = document.getElementById('fnErr');
var lnErr = document.getElementById('lnErr');
var emErr = document.getElementById('emErr');
var phErr = document.getElementById('phErr');
var cmErr = document.getElementById('cmErr');
var state = document.getElementById('stErr');
if(fname.value=="") {
fnErr.innerHTML = "We need your name, please.";
fname.focus();
return false;
} else {
fnErr.innerHTML = "";
}
if(email.value=="") {
emErr.innerHTML = "We need your email, please.";
email.focus();
return false;
} else {
emErr.innerHTML = "";
}
if(state.value=="none") {
fnErr.innerHTML = "Please select your state.";
state.focus();
return false;
} else {
fnErr.innerHTML = "";
}
/[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}/i;
if(isNaN(phone1.value) || isNaN(phone2.value) ||
isNaN(phone3.value)) {
phErr.innerHTML = "If you include a phone number it should be numbers only.";
phone1.select();
return false;
} else {
phErr.innerHTML = "";
}
var notices = document.form1.notices;
var selected;
for(var i=0;i<notices.length;i++) {
if(notices[i].checked) {
selected = notices[i].value;
}
}
/* set up a message for a advert recipient */
var msg = "Thank you, <b>"+fname.value
+"!</b> Your message has been received and one of our representatives will reply to <a href='"
+email.value+"'>"+email.value+"</a> within a day or two. Relax, and enjoy the rest of the site!";
if(selected != undefined) {
document.getElementById('notePref').innerHTML = "";
if (selected == "yes") { // here's where we test the contents of "selected"
document.getElementById('fnlMsg').innerHTML = msg;
} else {
document.getElementById('fnlMsg').innerHTML = "<strong>"+fname.value+"</strong>, thank you for your feedback!";
}
var contactForm = document.getElementById('registerForm').setAttribute('class','hide');
var loseSep = document.getElementsByClassName('spec');
loseSep[0].setAttribute('class', 'hide');
} else {
document.getElementById('notePref').innerHTML = "Please make a selection:";
}
} // reference point
https://jsfiddle.net/xp5e099y/2/
first: you dont have place(div/span/etc) with id ="fnlMsg"
second: you dont have place(div/span/etc) with id ="contactForm"
then change your html
<select name="state">
with
<select id="state">
and your script from this
var state = document.getElementById('stErr');
to
var state = document.getElementById('state');
Here is your culprit 'fnlMsg' element is not defined
if (selected == "yes") { // here's where we test the contents of "selected"
document.getElementById('fnlMsg').innerHTML = msg;
} else {
document.getElementById('fnlMsg').innerHTML = "<strong>"+fname.value+"</strong>, thank you for your feedback!";
}
I am trying to search through the list by search box. This is my HTML:
<input type="text" id="query" value=""/>
<ol id="abbreviations" >
<li>Cars</li>
<li>bars</li>
.
.
<ol>
And this is the jQuery code I have:
<script>
var abbrs = {};
$('ol#abbreviations li').each(function(i){
abbrs[this.firstChild.nodeValue] = i;
});
$('#query').focus().keyup(function(e){
if(this.value.length >= 2){
$('ol#abbreviations li').hide();
var filterBy = this.value;
for (var abbr in abbrs) {
if (abbr.indexOf(filterBy) !== -1) {
var li = abbrs[abbr];
$('ol#abbreviations li:eq('+li+')').show();
}
}
} else {
$('ol#abbreviations li').show();
}
if(e.keyCode == 13) {
$(this).val('');
$('ol#abbreviations li').show();
}
});
</script>
My code is working perfectly, but it's case sensitive. For example if I type "Cars" it will filter the list, but if I type "cars" it doesn't work. So how can I make this jQuery search insesitive? I tried to changing var filterBy = this.value.toLowerCase();, but it won't match upper case letters. How can I make it work?
You need to convert to lowercase both the filterValue and abbr:
var filterBy = this.value.toLowerCase();
...
if (abbr.toLowerCase().indexOf(filterBy) !== -1) {
...
Also see this SO question
I use pdf.js library to generate html5 page from pdf but some capabilities not working. I try to get value for input radio but still abortively:(
For example, in core.js script there are a few lines of code that take type of field:
var fieldType = getInheritableProperty(annotation, 'FT');
if (!isName(fieldType))
break;
item.fieldType = fieldType.name;
How I can get feild value?
I found the solution that work form me!
Add this code around line 260 of core.js file:
function setRadioButton(annotation, item) {
var ap = annotation.get('AP');
var nVal = ap.get('N');
var i = 0;
nVal.forEach(function(key, value){
i++;
if(i == 1 || i == 2) {
if(key != 'Off')
item.value = key;
}
});
}
And this code around line 370 of core.js file:
if (item.fieldType == 'Btn') {
if (item.flags & 32768) {
setRadioButton(annotation, item);
}
}
Also, if you want to get values from select input, you can use this code:
if(item.fieldType == 'Ch') {
item.value = annotation.get('Opt') || []; //return array of values
}
i used to use jquery validation plugin but because of lack of this plugin with wysiwyg plugins i wrote a simple script to validate my form
i tried to do it like this
function validateArticle(formData, jqForm, options) {
$('#errors').empty();
if ($('#editor').val() == 0) {
$('#errors').show();
$('#errors').append('<li>please enter your article body</li>');
return false;
}
if ($('#ArticleTitle').val() == 0) {
$('#errors').show();
$('#errors').append('<li>please enter your article title</li>');
return false;
}
$('#errors').hide();
return true ;
}
i found to 1 problem when it validate the form it's validating it field by field so the errors messages doesn't appear at once
i tried to do something like
var errors = [];
function validateArticle(formData, jqForm, options) {
$('#errors').empty();
if ($('#editor').val() == 0) {
errors.push('<li>please enter your article body</li>');
var invalid = 1 ;
return false;
}
if ($('#ArticleTitle').val() == 0) {
errors.push('<li>please enter your article title</li>');
var invalid = 1 ;
return false;
}
if(invalid == 1){
$.each(errors , function(i, val) {
$('#errors').append(errors [i]);
});
}
$('#errors').hide();
return true ;
}
i tried to push errors as array elements and loop through them in case of invalid is true
bu this one doesn't work at it all ?
is there any way to make it work ?
if ($('#editor').val() == 0) // This is checking if value is 0
This does not make sense..
Try
if ($('#editor').val() == '') //Instead check for empty string
EDIT
Also you seem to be hiding the error's div in the end.
$('#errors').hide();
Try this code Instead
$('#validate').on('click', function() {
var errors = [];
var html = '<ul>' ;
valid = true;
$('#errors').empty();
if ($('#editor').val() == '') {
errors.push('<li>please enter your article body</li>');
valid = false;
}
if ($('#ArticleTitle').val() == '') {
errors.push('<li>please enter your article title</li>');
valid = false;
}
if (!valid) {
html += errors.join('') + '</ul>'
$('#errors').append(html);
}
else{
$('#errors').hide();
}
return valid;
});
DEMO