Im trying to build an autocomplete search with Semantic UI but i dont know how to show my data...
<script type="text/javascript">
$(document).ready(function () {
$('.ui.search').search({
apiSettings: {
url: '/autocomplete/{query}',
minCharacters : 3,
},
});
});
</script>
CONTROLLER
public function autocomplete($query)
{
$search = "%$query%";
$data = Tag::where("name","LIKE",$search)->get();
return response()->json($data);
}
JSON DATA
"id":3,"name":"Argentina","description":"Argentina","status":"1","created_at":"2016-07-11 02:36:37","updated_at":"2016-07-11 02:36:37"},{"id":4,"name":"Argelia","description":"argelia","status":"1","created_at":"2016-07-11 02:36:48","updated_at":"2016-07-11 02:36:48"}]
Based on their documentation, I believe you're looking for something like this (note, I've never used this library - and didn't test). Check out the onResponse method:
<script type="text/javascript">
$(document).ready(function () {
$('.ui.search').search({
apiSettings: {
url: '/autocomplete/{query}',
minCharacters : 3,
onResponse: function(results) {
var response = {
results : []
};
$.each(results, function(index, item) {
response.results.push({
title : item.name,
description : item.description
//url : item.html_url
});
});
return response;
},
},
});
});
</script>
Related
Could someone determine how to authenticate myself asynchronously on the Google Drive API using AngularJS and HTML?
I am getting stuck on the call to gapi.auth.authorize because the callback function never gets called:
Here is the AngularJS--HTML5 code excerpt which does not work currently,
var app = angular.module('myApp', []);
app.service('googleService', ['$http', '$rootScope', '$q', function ($http, $rootScope, $q) {
this.login = function () {
gapi.auth.authorize(
{ client_id: '1009536034660-armd84ckoemm3jan35ceupjhdsmo0fa1.apps.googleusercontent.com', scope: 'https://www.googleapis.com/auth/plus.login https://www.googleapis.com/auth/userinfo.email' , immediate: true },
this.handleAuthResult);
return deferred.promise;
}
this.handleClientLoad = function {
gapi.client.setApiKey(apiKey);
gapi.auth.init(function () { });
window.setTimeout(checkAuth, 1);
};
this.checkAuth = function () {
gapi.auth.authorize({
client_id: clientId,
scope: scopes,
immediate: true,
hd: domain
}, this.handleAuthResult);
};
this.handleAuthResult = function (authResult) {
if (authResult && !authResult.error) {
var data = {};
gapi.client.load('oauth2', 'v2', function () {
var request = gapi.client.oauth2.userinfo.get();
request.execute(function (resp) {
data.email = resp.email;
deferred.resolve(data);
});
});
} else {
deferred.reject('error');
}
};
this.handleAuthClick = function (event) {
gapi.auth.authorize({
client_id: clientId,
scope: scopes,
immediate: false,
hd: domain
}, this.handleAuthResult);
return false;
};
}]);
app.controller('myController', ['$scope', 'googleService', function ($scope, googleService) {
$scope.login = function () {
$scope.login = function () {
googleService.login().then(function (greeting) {
console.log('Success: ' + greeting);
}, function (reason) {
console.log('Failed: ' + reason);
}, function (update) {
console.log('Got notification: ' + update);
});
};
};
}]);
} else {
deferred.reject('error');
}
};
});
Why is the gapi.auth.authorize failing to call the callback?
First I checked this hypothesis stackoverflow.com/questions/20036893/… and it was incorrect. Next I checked this hypothesis : stackoverflow.com/questions/31659414/… and it was also wrong.
I even tried using Brendan's SetTimeout workaround in this URL, https://groups.google.com/forum/#!topic/google-api-javascript-client/GuFxPzqQ9-0 and it did not function properly.
In addition, I requested and obtained a new OAuth2 client id with the correct javascript origin. Evidently , the onload callback is only called after successful loading of the script. Or, is there a timeout possibility for the callback to be invoked?
Here is Windows 7 ASP.NET program written entirely in Javascript and HTML which works properly :
<html>
<head>
<title>Google+ Sign-in button demo: rendering with JavaScript</title>
<style type="text/css">
html, body { margin: 0; padding:0;}
#signin-button {
padding: 5px;
}
#oauth2-results pre { margin: 0; padding:0; width: 600px;}
.hide { display: none;}
.show { display: block;}
</style>
<script src="https://apis.google.com/js/client:platform.js" type="text/javascript"></script>
<script type="text/javascript">
var loginFinished = function (authResult) {
if (authResult) {
console.log(authResult);
}
gapi.client.load('oauth2', 'v2', function () {
gapi.client.oauth2.userinfo.get()
.execute(function (resp) {
// Shows user email
console.log(resp.email);
});
});
};
var options = {
'callback': loginFinished,
'approvalprompt': 'force',
'clientid': '375218714272ao7690jhv6sk7jphi0jf3l5t500sajvt.apps.googleusercontent.com',
'scopes': ['https://www.googleapis.com/auth/drive.metadata.readonly', 'https://www.googleapis.com/auth/drive.readonly'],
'requestvisibleactions': 'http://schemas.google.com/CommentActivity http://schemas.google.com/ReviewActivity',
'cookiepolicy': 'single_host_origin'
};
var renderBtn = function () {
gapi.signin.render('renderMe', options);
}
</script>
</head>
<body onload ="renderBtn()">
<div id="renderMe"></div>
</body>
</html>
Could I ask why the Windows 7 ASP.NET Javascript code works okay but not the AngularJS code version?
You have to point $window.location.href at a file in the Windows filesytem which conforms to JavaScript origin naming convention.
I am trying to display nested JSON in a page. I'm not sure how to drill down into it.
In my app js file I have an parameter called initialData that I want to call a function getProducts() when the view is called...
'use strict';
var quoteApp = angular.module('quoteApp', ['ui.router']);
quoteApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'ng-views/choose.html',
controller: "quoteBuilderController",
resolve: {
initialData: ['quoteApi', function (quoteApi) {
return quoteApi.getProducts();
}]
}
})
});
my quoteApi looks like this in case you want to see it...
(function () {
'use strict';
angular.module('quoteApp').factory('quoteApi', quoteApi);
quoteApi.$inject = ['$http'];
function quoteApi($http) {
var service = {
getProducts: getProducts,
getPrices: getPrices
};
var baseUrl = 'http://www.website.com/api/Pricing';
return service;
function getProducts() {
return httpGet('/GetProductCatalogue');
}
function getPrices() {
return httpGet('/GetPrices');
}
/** Private Methods **/
function httpExecute(requestUrl, method, data){
return $http({
url: baseUrl + requestUrl,
method: method,
data: data,
headers: requestConfig.headers }).then(function(response){
return response.data;
});
}
function httpGet(url){
return httpExecute(url, 'GET');
}
}
})();
So quoteApi.getProducts() returns JSON that looks like this...
{
"Cat1": [
{
"product_id": 1,
"product_name": "Prod1"
},
{
"product_id": 2,
"product_name": "Prod2"
}
],
"Cat2": [
{
...
}
]
}
My controller for the view looks like this...
(function () {
'use strict';
angular.module('quoteApp').controller('quoteController', ['$scope', '$http', '$timeout', quoteController]);
quoteController.$inject = ['initialData', 'quoteApi'];
function quoteController($scope, initialData) {
$scope.cat1Products = initialData;
};
})();
So my question is, how can I get 'initialData' to load products from Cat1 only? Should I try to do this from the html? It seems like it should be straight forward enough but I can seem to get it. Thank you.
You need to transform your response from your http request further so you only return the piece you require, and you may also want to consider using the .then() approach:
$http.get('/someUrl').then(function(response) {
//Do something with response.data.Cat1 here
}, function(errResponse) {
console.error('Error while fetching data');
});
Just take out cat1 from your initialData object
function quoteController($scope, initialData) {
$scope.cat1Products = initialData['Cat1'];
};
Okay, im going slightly insane trying to display data from a json file in 2 seperate views/collections.
I will paste my entire code here and try to explain where i am now, and what i need done.
Its probably a very small thing i just need to do in order for it to work, but i cant see it..
Here is a screen shot of how my page looks like now, as you can see the data is being loaded, i just cant get it into the views properly..
In my Collection class i call parse:
parse:function(response, options) {
return options.parseField ? response[options.parseField] : response;
},
i call sync: (not sure its needed at all)
sync: function(method, model, options) {
options.contentType = "application/json";
options.cache = false;
options.dataType = "json";
return Backbone.sync(method, model, options);
},
Then near the bottom, i create 2 new collections and use fetch to get the specific json data i need for each collection like so:
var links = new App.Collections.Links();
links.fetch({
parseField: 'links_1',
success: function () {
console.log(links.toJSON());
return links.toJSON();
}
});
var links2 = new App.Collections.Links();
links2.fetch({
parseField: 'links_2',
success: function () {
console.log(links2.toJSON());
return links2.toJSON();
}
});
I do console.log and can see that my json data is getting loaded just fine, but its not getting rendered ?
What am i doing wrong here..
For sake of debugging and understanding i have included my entire js file below.
(function() {
// Helper functions
// Defining namespacing rules
window.App = {
Models: {},
Collections: {},
Views: {}
};
// Setting global template function, for simpel declaration later on by setting template('name'); for the built in template function.
window.template = function(id) {
return _.template( $('.' + id).html() );
};
// Capitalize first letter in a link by adding .capitalize(); to the string.
String.prototype.capitalize = function() {
return this.charAt(0).toUpperCase() + this.slice(1);
};
// Extending Backbone
//Modellen
App.Models.Link = Backbone.Model.extend({
defaults: {
navn : 'i haz a name!',
link : 'http://www.lolcats.com/',
counter : 0
}
});
//Collection
App.Collections.Links = Backbone.Collection.extend({
model: App.Models.Link,
url: 'data1.json',
parse:function(response, options) {
return options.parseField ? response[options.parseField] : response;
},
sync: function(method, model, options) {
options.contentType = "application/json";
options.cache = false;
options.dataType = "json";
return Backbone.sync(method, model, options);
},
// Sort the models 'highest first'
comparator: function(link) {
return -link.get('counter');
}
});
//Singel view
App.Views.LinkView = Backbone.View.extend({
tagnavn: 'li',
template: template('Links'),
initialize: function() {
this.model.on('change', this.render, this);
this.model.on('destroy', this.remove, this);
},
events: {
'click .edit' : 'retLink',
'click .delete' : 'destroy',
'click .LinkUrl' : 'addCounter'
},
retLink: function() {
var newLinkNavn = prompt('What should the new name be?', this.model.get('navn'));
if ( !newLinkNavn ) return;
newLinkNavn = newLinkNavn.capitalize();
this.model.set('navn', newLinkNavn);
var newLinkUrl = prompt('What should the new url be?', this.model.get('link'));
if ( !newLinkUrl ) return;
this.model.set('link', newLinkUrl);
},
destroy: function() {
this.model.destroy();
},
// Increment the counter then user clicks it
addCounter: function(e) {
e.preventDefault();
var newCounter = this.model.get('counter');
this.model.set('counter', newCounter + 1);
},
remove: function() {
this.$el.remove();
},
render: function() {
this.$el.html(this.template(this.model.toJSON()) );
return this;
}
});
//Collection View
App.Views.LinksView = Backbone.View.extend({
tagName: 'ul',
className: 'liste',
initialize: function() {
_.bindAll(this);
this.collection.on('add', this.addOne, this);
this.collection.on('reset', this.render);
// Render view when a user has changed a model
this.collection.bind('change', this.render, this);
$('.navnClass').focus();
this.load();
this.render();
},
load: function() {
this.collection.fetch({
add: true,
success: this.loadCompleteHandler,
error: this.errorHandler
});
},
loadCompleteHandler : function(){
this.render();
},
errorHandler : function(){
throw "Error loading JSON file";
},
render: function() {
// Empty the UL before populating it with the new models and sorting it.
this.$el.empty();
this.collection.sort();
this.collection.each(this.addOne, this);
return this;
},
addOne: function(link) {
var linkView = new App.Views.LinkView({ model: link });
this.$el.append(linkView.render().el);
}
});
// Create link view
App.Views.AddLink = Backbone.View.extend({
el: '#addLink',
events: {
'submit' : 'submit'
},
submit: function(e) {
e.preventDefault();
var linkNavn = $(e.currentTarget).find('.navnClass').val(),
linkNum = $(e.currentTarget).find('.linkClass').val();
// Tildel link navn en værdi, hvis det er tomt
if ( ! $.trim(linkNavn)) {
linkNavn = 'I haz a name!';
}
// Tildel link url en værdi, hvis det er tomt
if( ! $.trim(linkNum)) {
linkNum = 'http://www.lolcats.com/';
}
// Tilføj http:// foran værdi, hvis den ikke indeholder det i forvejen.
if( linkNum.indexOf( "http://" ) == -1 ) {
addedValue = 'http://',
linkNum = addedValue + linkNum;
}
// nulstil og sæt fokus på link navn feltet.
$(e.currentTarget).find('.navnClass').val('').focus();
$(e.currentTarget).find('.linkClass').val('');
this.collection.add({ navn:linkNavn, link: linkNum });
}
});
// new links collection
// populate collection from external JSON file
// change navn to match the link heading
var links = new App.Collections.Links();
links.fetch({
parseField: 'links_1',
success: function () {
console.log(links.toJSON());
return links.toJSON();
}
});
var links2 = new App.Collections.Links();
links2.fetch({
parseField: 'links_2',
success: function () {
console.log(links2.toJSON());
return links2.toJSON();
}
});
// new collection view (add)
var addLinkView = new App.Views.AddLink({ collection: links });
// new collection view
var linksView = new App.Views.LinksView({ collection: links });
$('.links').html(linksView.el);
// new collection view
var linksView2 = new App.Views.LinksView({ collection: links2 });
$('.links2').html(linksView2.el);
})();
Could you try this:
var links2 = new App.Collections.Links();
links2.on("reset", function(collection){
console.log("reset event", collection);
}
links2.fetch({
parseField: 'links_2',
wait:true, #wait for the server to respond
success: function (collection, response) {
console.log(collection, response);
}
});
a return in the success call doesn't do anything (it would return to the $.ajax object). I've added a wait because it would call the successcall instantly if it passes the clientside validation (you have none, so it would always call success first).
You say it doesn't render anything. But to render something you need a View. I don't see a view in your code.
Here's a quick example of the view:
var Link = new Backbone.View.extends({
el: $('body'),
initialize: function(){
this.listenTo(this.collection, 'reset', this.render, this)
},
render: function(){
this.$el.empty();
this.collection.each(function(item){
this.$el.append(item.get('id') + '<br />');
});
}
})
var view = new Link({collection: links2});
Im very new to Backbone.js and have been following a couple tutorials to come up with the script below. What I am trying to achieve is retrieving JSON data from a rest api when my routes are used. If you look at the people function for the friends route you can see where im going with this. Where am i going wrong?
<!DOCTYPE html>
<html>
<head>
<title>I have a back bone</title>
</head>
<body>
<button id="add-friend">Add Friend</button>
<ul id="friends-list">
</ul>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js"></script>
<script>
Friend = Backbone.Model.extend({
name: null,
age: null,
});
FriendDetailModel = Backbone.Model.extend();
FriendDetailCollection = Backbone.Collection.extend({
url: 'slim/index.php/friends/',
model: FriendDetailModel
});
Friends = Backbone.Collection.extend({
initialize: function(models, options) {
this.bind("add",options.view.addFriendLi);
}
});
AppView = Backbone.View.extend({
el: $("body"),
initialize: function() {
this.friends= new Friends(null, {view:this});
},
events: {
"click #add-friend": "showPrompt",
},
showPrompt: function () {
var friend_name = prompt("Who is your friend?");
var friend_age = prompt("What is your friends age?");
var friend_model = new Friend({name: friend_name, age: friend_age});
this.friends.add(friend_model);
},
addFriendLi: function(model) {
$("#friends-list").append("<li>" + model.get('name') + " " + model.get('age') + "</li>");
}
});
var appview = new AppView;
AppRouter = Backbone.Router.extend({
routes: {
"friends":"people",
"person/:name":"personDetail"
},
people: function() {
console.log('all the people');
var people = new FriendDetailCollection;
people.fetch({
success: function(data) {
console.log(data);
}
},
personDetail: function(name) {
console.log('one person named ' + name);
}
});
var approuter = new AppRouter;
Backbone.history.start();
</script>
</body>
</html>
after running people.fetch Console.log shows
d
_byCid: Object
_byId: Object
length: 4
models: Array[4]
__proto__: x
If i do console.log(data.toJSON()); it returns
[]
I ended up resolving the problem by doing the following:
I created a new collection outside of the router:
var people = new FriendDetailCollection;
When I created the view I specified the collection I previously created.
friendview = new FriendView({collection: people});
I had a typo in my FriendView. Previously I had _.bind(this, 'render'). It need to be
_.bindAll(this,'render');
Also, i put my console.log in the render() function within my FriendView.
FriendView = Backbone.View.extend({
el: $("body"),
initialize: function() {
_.bindAll(this,'render');
this.collection.bind('reset', this.render);
},
render: function() {
console.log(this.collection.toJSON());
}
});
All,
I've moved on to using the ui autocomplete rather than the plugin, took me a while to figure out extra params based on an example I found here, but that part works.
I'm having problems with dealing with the return data. In the code below I can alert out the title being returned, but I get a drop down of 'UNDEFINED' in the browser.
Thanks in advance.
$('#DocTitle').autocomplete({
source: function(request, response) {
$.ajax({
url: "index.pl",
dataType: "json",
data: {
Title: request.term,
maxRows: 10
},
success: function(data) {
response($.map(data, function(item) {
alert(item.TITLE);
return {
TITLE: item.TITLE
}
}))
}
})
}
});
I am using jquery UI autocomplete as follows and it is working quite fine for me. You may try on the similar lines.
$('input[type=text][name=City]').autocomplete({
source: function(request, response) {
$.getJSON($('input#CitySuggestionsLink').val(), {
term: request.term,
stateId: $('select#StateName option:selected').attr('value')
}, response);
},
search: function() {
// custom minLength
var term = this.value;
if (term.length < 1) {
return false;
}
},
delay: 200,
focus: function() {
// prevent value inserted on focus
return false;
},
select: function(event, ui) {
return false;
}
});