I have almost finished my own website, and I am wondering how simple I can implement search function in current page. It's static and only need to show list items which include users' input. Some answers from stackoverflow advise Google API, but it will show Google logo in the search box, that's not work for me.
Is there any 3rd party API or some simple code can satisfy my requirement?
It's not easy to create your own search library, and also you don't need Google Search API if you only require search function in static website.
You can consider to use Angular JS to excute.
1.1 Defined ng-app & ng-controller to main body function
<body ng-app="instantSearch" ng-controller="InstantSearchController">
1.2 Add ng-model to search box function
<input ng-model="searchString">
1.3 Add ng-repeat to div or li function to show the data based on search from input box
<div ng--repeat="i in items | searchFor: searchString">
2.1 Define a new module for your app
var app = angular.module("instantSearch", []);
2.2 Create the instant search filter
app.filter('searchFor', function() {
return function(arr, searchString) {
if(!searchString){
return arr;
}
var result = [];
searchString = searchString.toLowerCase();
angular.forEach(arr, function(item) {
if(item.title.toLowerCase().indexOf(searchString) !== -1){
result.push(item);
}
});
return result;
};
});
2.3 Edit your controller
function InstantSearchController($scope) {
$scope.items = [
{
title1:'abc',
title2:'def'
},
{
title1:'ghi',
title2:'jkl'
}
];
}
And now you can display the items which has the same result in your search box.
Related
Currently I have an HTML page that has a list of items and for each item, there is a button.
See my HTML here (example of an item followed by a button): https://pastebin.com/Ne4yrC7D
I am using the function as follows:
basePage.js
this.listAndClick = function(optionList, foundText) {
optionList.filter(function(elm, index) {
return elm.getText().then(function(text) {
console.log(text);
return text === foundText;
});
}).first().element(by.css('.ui-button')).click();
};
this.clientsList = element.all(by.css('.ui-cell-data'));
mySpec.js
basePage.listAndClick(basePage.clientsList, 'client zero');
So far my function is filtering all the items on the page, but the problem is that the click on the button corresponding to the text is not working.
Can anyone help with this please?
Please try the below logic.
As per the html you shared all the elements are with class with CSS of span.ui-cell-data which is the "ArrayElement" used below.
selectElement(text: String) : any {
for(int i=o;i< ArrayElement.length();i++)
{
if(ArrayElement.get(i).toEqual(text)){
ArrayElement.get(i).click()
}}
Now just pass the selectElement('client zero') from you spec file.
Note: Used typescript in the solution provided.
Background: There's a table from which I can choose employees. I want to filter these employees by name.(I know name is not a good way to filter, this is just an example)
Basically I have a drop down from which I choose one of the filters.
My declaration: $scope.filters = null;.
I also have this deceleration to choose my filter $scope.chosenFilter= null;.
I use the following to retrieve the different filters I have $scope.filters = retrieveFilters(info.Names);
retrieveFilters looks like the following:
var retrieveFilters = function(rows) {
var filterWrapper = document.querySelector(".filterWrapper");
var datasetOptions = [];
$scope.predicate = 'Name';
if (rows) {
//Add Default option
datasetOptions.push({
name: $scope.data.Fnames.defaultFilterOptionLabel,
value: ''
});
$scope.chosenFilter = datasetOptions[0];
_.forEach(rows, function(ele) {
datasetOptions.push({
name: ele,
value: ele
});
});
} else {
filterWrapper.style.display = "none";
}
return datasetOptions;
};
I use the following to choose my filter:
$scope.$watch('chosenFilter', function() {
var filterSearchInput = document.querySelector(".filterWrapper input");
ng.element(filterSearchInput).triggerHandler('input');
});
Everything is fine and the display works on first load as I have set the default with
//Add Default option
datasetOptions.push({
name: $scope.data.Fnames.defaultFilterOptionLabel,
value: ''
});
From the default table whenever I click on an employees name hes details are displayed. However whenever I filter and click on the employees name, nothing is displayed. Whenever I click on a specific employees name at the default table and then filter in the same name the information also shows up, as I cache it each time.
I assume that you're displaying this data somewhere in your GUI using ng-repeat. Angular has a lot of great built-in features for this. Check out the answer here: AngularJS custom search data by writing custom filter for a way to approach this more from an Angular direction. You also might want to check out this question and answer: "Thinking in AngularJS" if I have a jQuery background?.
I'm trying to figure out how to display up to 10 options from a suggestions array and then give the user the ability to select the option, with that option now becoming the search query?
Html and AngularJS:
<ul class="suggestions" ng-show="showAutocomplete">
<li ng-repeat="suggestion in autocomplete.suggestions" ng-show="suggestion.options.length > 0" ng-mousedown="searchForSuggestion()"><small>Searching —</small>
{{suggestion.options[0].text}}//how to display up to 10 options
</li>
</ul>
Suggestions array
$scope.autocomplete = {
suggestions: []
};
$scope.showAutocomplete = false;
JS:
$scope.searchForSuggestion = function() {
$scope.searchTerms = $scope.autocomplete.suggestions[0].options[0].text;
$scope.search();
$scope.showAutocomplete = false;
};
More JS:
var getSuggestions = function(query) {
searchService.getSuggestions(query).then(function(es_return) {
var suggestions = es_return.suggest.phraseSuggestion;
if (suggestions.length > 0) {
$scope.autocomplete.suggestions = suggestions;
}
else {
$scope.autocomplete.suggestions = [];
}
if (suggestions.length > 0) {
$scope.showAutocomplete = true;
}
else {
$scope.showAutocomplete = false;
}
});
};
Suggestions is an array mapped to the $scope.autocomplete object.
I'm using PhraseSuggestion from ES and options is an array within the PhraseSuggestion object. Text is the actual option from the options array within the PhraseSuggestion object.
I hope that makes it a bit clearer - I'm a bit new to AngularJS and still learning it.
UPDATE:
I should be able to include the functionality that I'm seeking in the getSuggestions function, right? Just adjusting the if statements a bit... then all it really comes down to is the display, how to display up to 10 suggestions in the options array
I think you might be looking to use a nested ng-repeat with a limitTo filter placed on it.
I've put together a plunker showing how you can use limitTo with an ng-click on your populated options here http://plnkr.co/edit/8Mh....
If selecting an option alters suggestions, that should be fine and update the view accordingly.
Hope that helps you out!
I'm trying to make a web app that allows (student) users to see all possible class schedules that they can have. Right now, I've got a list of classes that fit certain constraints (users desired classes). I want to create all possible schedules that can be made with combinations of these classes. It seems like FullCalendar might be what I want to display these schedules (just in a week view or something) but i'm not sure if I can make FullCalendar just display a possible schedule and then allow the user to click through the possible schedules without assigning all the classes dates or something on the back end.
In a nutshell:
Is FullCalendar what I want to use for this? Or is there something else better suited to my goal?
Below is the code I have so far (still figuring out how to get lists of all possible schedules from this list)
<!DOCTYPE html>
<html>
<head>
<script src='../lib/jquery.min.js'></script>
<script src='../lib/jquery-ui.custom.min.js'></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<h2 id="search_results"></h2>
<div id="morning_results_container">
<h5>Morning Courses</h5>
<ul id="morning_results_list">
</ul>
</div>
<script>
$(document).ready(function() {
$.getJSON("http://vazzak2.ci.northwestern.edu/courses/?term=4540&subject=EECS", function(result) {
var earlyCourses = [];
$(result).each(function (index, item) {
$('#search_results').text((index+1) + " total courses");
if (item.start_time > '10:00:00') {
if (item.meeting_days === 'We'){
console.log(item);
$('#morning_results_list').append('<li>' + item.title + '</li>');
}
}
});
});
});
</script>
</head>
<body>
<div id="resultarea"></div>
</body>
</html>
Thanks for any experiential advice you can offer!
Yes, I think you can achieve what you like to do with jquery FullCalendar plugin you are using. I'm not sure whether there is a better plugin for your purpose. FullCalendar pretty much provides a very good user interface for a interactive calendar for any type of web app.
However it's up to you to implement what it should do in your web app based on the UI interactions of a user. Could you provide a example of a JSON output with all the schedules? As I understood your question, maybe you can allow the user to select a schedule from a drop-down list and then show the classes in the calendar for a selected schedule.
[Update]
function load_all_classes()
{
$.getJSON("http://vazzak2.ci.northwestern.edu/courses/?term=4540&subject=EECS", function(data) {
window.all_classes = data;
});
}
function update_calendar(classes)
{
//update calendar to display the given classes
}
function get_classes_before_10_am()
{
var results = [];
$(window.all_classes).each(function (index, the_class) {
if (the_class.start_time <= '10:00:00') {
results.push(the_class);
}
});
return results;
}
$(document).ready(function() {
load_all_classes();
$('#select_schedule').change(function(){
if ($(this).val = 'Before 10 am')
{
update_calendar(get_classes_before_10_am());
}
else if ($(this).val = 'After 10 am')
{
update_calendar(get_classes_after_10_am());
}
//...etc
});
});
I'm looking for tutorial or example on how to implement a simple input text for searching
in the grid.
My attempt (but ng-keyup require angularjs > 1.1.3 and I've got
1.0.7)
<input type="text" ng-keyup="mySearch()" ng-model="searchText">
$scope.getPagedDataAsync = function (pageSize, page, searchText) {
setTimeout(function () {
var data;
if (searchText) {
var ft = searchText.toLowerCase();
$http.get('largeLoad.json?q='+encodeURIComponent(ft)).success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
} else {
$http.get('largeLoad.json').success(function (largeLoad) {
$scope.setPagingData(largeLoad,page,pageSize);
});
}
}, 100);
};
$scope.mySearch = function(){
console.log($scope.searchText);
$scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage,$scope.searchText);
}
Bye
NB its a fake request against a json file just to make the example.
Update: I'm using ng-grid-1.3.2
Basically to solve this problem I think you can use a solution similar to what I've done below where I'm just watching the property of the model for changes and firing a function to do the filtering on the data set at that point.
The HTML for the text input
<input type="text" placeholder="Type to filter" ng-model="gardenModel.externalFilterText"/>
The JavaScript that filters the data set (also included the part I had a watch on a service to update the data in the first place too or if the data is refreshed to reapply the filter).
//This function is called every time the data is updated from the service or the filter text changes
$scope.filterGardens = function(filterText) {
//Basically everything in this function is custom filtering specific
//to the data set I was looking at if you want something closer to the
//real implementation you'll probably have to dig through the source (I believe they separated the search filter code into it's own file in the original project)
//Creating a temporary array so changes don't cause a bunch of firing of watchers
var tempToShow = [];
//doing case insensitive search so lower case the filter text
filterText = filterText.toLowerCase();
//If the filter text is blank just use the whole data set
if(!filterText || filterText == "")
{
$scope.gardenModel.shownGardens = $scope.gardenModel.gardens;
return;
}
//step through each entry in the main list and add any gardens that match
for (var i = 0; i < $scope.gardenModel.gardens.length; i++) {
var curEntry = $scope.gardenModel.gardens[i];
var curGarden = curEntry.curGarden;
if(curGarden["Garden Name"] && curGarden["Garden Name"].answer.toString().toLowerCase().indexOf(filterText)!=-1)
tempToShow.push(curEntry);
else if(curGarden["Address"] && curGarden["Address"].answer.toString().toLowerCase().indexOf(filterText)!=-1)
tempToShow.push(curEntry);
else if(curGarden["Ownership"] && curGarden["Ownership"].answer.toString().toLowerCase().indexOf(filterText)!=-1)
tempToShow.push(curEntry);
else if(curGarden.gardenId && curGarden.gardenId == filterText)
tempToShow.push(curEntry);
};
$scope.gardenModel.shownGardens = tempToShow;
}
//Watch for any changes to the filter text (this is bound to the input in the HTML)
$scope.$watch('gardenModel.externalFilterText', function(value) {
$scope.filterGardens(value);
});
//Watch for any changes on the service (this way if addition/edit are made and
//refresh happens in the service things stay up to date in this view, and the filter stays)
$scope.$watch( function () { return gardenService.gardens; }, function ( gardens ) {
$scope.gardenModel.gardens = gardens;
$scope.filterGardens($scope.gardenModel.externalFilterText);
});
Edit Cleaned up the code formatting a bit and added some comments.