Typeahead.js with angular ui-router - angularjs

I have built a multi step form following this tutorial: http://scotch.io/tutorials/javascript/angularjs-multi-step-form-using-ui-router Everything is working well.
I now want to use Twitter's typeahead.js on those forms. So I need to make the typeahead call on the input being loaded with angular-ui-router.
I noticed angular-ui-router provides a onEnter callback that gets called when the state becomes active. Making the call to the typeahead function from in there doesn't seem to work, it seems the call is made before the view is loaded (not 100% sure of that).
How can I initialize typeahead on my input field loaded with angular-ui-router?
What I tried:
.state('questionnaire.relationship', {
url: '/relationship',
templateUrl: 'questionnaire/relationship.html',
onEnter: function(){
var relationshipList = ['brother', 'sister', 'father', 'mother'];
var relationships = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
local: $.map(relationshipList, function(relationship) { return { name: relationship }; })
});
relationships.initialize();
$('#bloodhound .typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'relationships',
displayKey: 'name',## Heading ##
source: relationships.ttAdapter()
});
alert('finished');
}
})
When entering the questionnaire.relationship state, I see the alert popup before the view. Then the view with my input loads properly, but typeahead isn't working. There are no js error in the console.
I also made sure the typeahead call is working when used outside of angular-ui-router.

Have you tried using angular ui bootstrap's typeahead? It was built for angular without the dependency on JQuery
http://angular-ui.github.io/bootstrap/

Related

Why getting provider error when trying to inject resolved property in controller using ui-router?

I am unable to inject resolve property of ui-routing in controller.
It is giving
Error: $injector:unpr
Unknown Provider
When I'm using controller property in state definition object as following
.state('widget', {
url: '/widgets',
template: '<h1>{{name}}</h1>',
controller: function(widget, $scope) {
$scope.name = widget.name;
},
resolve: {
// standard resolve value promise definition
widget: function() {
return {
name: 'myWidget'
};
},
// resolve promise injects sibling promise
features: function(widget) {
return ['featureA', 'featureB'].map(function(feature) {
return widget.name+':'+feature;
});
}
}
});
Then it is working fine and I'm able to get the widget in controller and able to use in html.
Please see the fiddle for code.
http://jsfiddle.net/sunilmadaan07/ugsx6c1w/8/
Might be I'm making a silly mistake.
Before posting this question I have tried returning with simple object, promise object to the property.
Thanks In Advance.
You can not get resolved data in the directive with the code you did. Basically, you are trying to implement component based structure with an older version of angular 1.3.x.
You have two options to achieve this.
Create route controller then you can access resolve to the controller as local dependency then use that dependency as binding to the directive.
Here is example - http://plnkr.co/edit/TOPMLUXc7GhXTeYL0IFj?p=preview
Upgrade angular version to 1.5.x and use "ui-router-route-to-components": "^0.1.0"
Here working example of your code - http://jsfiddle.net/ugsx6c1w/25/
In order for the controller to be able to use resolvers, it should be route component (only in UI Router 1.x) or route controller.
widget and features are local dependencies, they aren't registered in the injector and aren't available anywhere in the application except route controller/component.
As explained here, resolvers can be passed to nested components in UI Router 0.3.x and injected directly to route components in 1.x.

Resolve with $state throws unknown provider

I'm using ui-router to handle my apps states. I need to use resolve to ensure that a settings value is there when the controller is loaded. I started by making a very simple dummy:
.state('dashboard', {
url: '/dashboard',
resolve: {
simpleObj: function(){
return {value: 'simple!'};
}
},
controller: 'DashboardController',
template: '<dashboard></dashboard>',
});
In the controller I inject this like I would any other dependency:
angular
.module('flowlens')
.controller('DashboardController', DashboardController);
DashboardController.$inject = ['simpleObj'];
function DashboardController(simpleObj){
var vm = this;
activate();
function activate(){}
}
However this throws an unknown provider error on the simpleObj This code is based on the example code on the ui-router git repo so it should work.
According to others this typically happens when you use ng-controller on your template but my template contains no such thing:
%h2 Dashboard
%hr
%pre {{ $root.currentUser | json }}
.card.card-block
%my-input{type: "contact", model: "selected_contact", placeholder: "Choose Contact", allow-new: "true"}
Selected:
%pre {{ selected_contact | json }}
%h2 Settings {{ $root.settings }}
There should be no need to use deferred to resolve this promise as it's just returning a simple value - correct?
What's the issue here?
EDIT Heres a plunkr detailing what's going on.
Thanks to imbalind for the help. Here's an updated plunkr of it working. Check the console to see the value getting printed.
The problem is that you referenced the DashboardController twice in two different places:
inside the $stateProvider, where you add a resolve for simpleObj.
inside dashboard directive, where it cannot have a clue about what simpleObj is.
The error (IMHO) is having the same controller used for different things. You should have two different controllers.
If you need to access simpleObj from both of them you should think about making a service out of it.
EDIT: Here's your plunker edited so to avoid the error. Logic is missing.

Angular js not working on chrome extension

I need Angular Js framework for a chrome extension.
what i already done its injected AJS script via background page.
But when i use angular directives in content script it just not working.
I also tried initializing Angular js Manually using Bootstrap command but that also didn't work.
any help would be appreciated.
Actually i am trying to convert an existing extension developed in pure JS into Ajs framework.
I injected AJs script in chrome tab from background page as below.
chrome.extension.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.Arg == 'INIT') {
$.when(
$.ajax({
url: server + '/Cscript.js',// Content Script
dataType: 'text'
}),
$.ajax({
url: server +'/util.js',// Jquery and other 3drparty
dataType: 'text'
}),
$.ajax({
url: server +'/angular.js',
dataType: 'text'
})
).then(function(Cscript,Ujs,ang) {
chrome.tabs.executeScript(sender.tab.id, {code: Ujs[0]+ang[0]+Cscript[0], allFrames:true});
sendResponse(config);
});
}
In content script i created a sidebar div which have a top root div with properties
$("#SidePan").attr('ng-app','TApp');
$("#SidePan").attr("ng-csp", "true");
i created two controllers Ctrl1 and Ctrl2 for TApp.
And i added a Div as below in #SidePan
$("#SidePan").html('<div ng-controller="Ctrl1">{{2+3}}</div>)
This works as expected, But when i changed the #SidePan html on a buttonclick as below
$("#SidePan").html('<div ng-controller="Ctrl2">{{4+5}}</div>)
this wont evaluates the expression.Am i doing anything wrong with Ajs
$("#SidePan").html('<div ng-controller="Ctrl2">{{4+5}}</div>) won't work. AngularJS does not monitor the DOM so that it would know you manipulated it from outside.
Stop mixing up jQuery and AngularJS. You need to use $scopes, ng-click and possible some custom directive to achieve this.

Angular - UI Router - state reentrance

How to config UI Router to reenter or reload the state by default?
E.g. user wants to refresh page, so he clicks the link that follows to that page. But currently the link isn't clickable, as it goes to the same page and the state doesn't change. Refreshing with browser button does work, so it reloads entire SPA again - isn't desirable.
This question - Reloading current state - refresh data - describes similar effect. Is it possible to change this solution - https://stackoverflow.com/a/23198743/404099 - to define the default behavior?
By the way, probably my approach is incorrect and I'm missing some basic idea in UI Router. Please point out if this is the case.
I second what #Sabacc said, but if you still instead, here you go:
angular.module('app')
.config(function($provide) {
$provide.decorator('$state', function($delegate)
{
$delegate.go = function(to, params, options)
{
return $delegate.transitionTo(to, params, angular.extend(
{
reload: true,
inherit: true,
relative: $delegate.$current
}, options));
};
return $delegate;
});
});

kendo ui angular js grid ng-repeat

I m trying to use Kendo grid in my angular js app. I m creating a directive so I can use it in different tables among the application. Once the ng-repeat renders the dom I want to call:
element.kendogrid().
Since there is no post-render callback for ng-repeat, some people suggest using two directives:
1-
angular.module('app')
.directive('rowDirective', function () {
return function(scope, element){
if (scope.$last){
scope.$emit('LastElementMessage');
}
};
});
2-
angular.module('app')
.directive('tableDirective', function () {
return function(scope, element){
scope.$on('LastElementMessage', function(event){
$(element).kendoGrid({
scrollable: true,
sortable: true,
});
});
}
});
This approach works fine and everything is executed in the order it should. The ng-repeat works fine by it self, which means it renders the items in the right order but when I use the kendo-grid, it renders this: {{customer.CustomerID}} inside the grid. Has anyone gone through something like this ?
Well, perhaps you should take a look at Angular Kendo UI project at http://kendo-labs.github.io/angular-kendo/ - it does rather good job of "marrying" Kendo UI with AngularJS.
See http://demos.telerik.com/kendo-ui/grid/angular.
There are specific custom directives that enable kendo ui to play nicely with angular js. E.G. k-data-source, k-columns, k-selectable, k-pageable. These should be included in the latest version of kendo ui. Just make sure to include "kendo.directives" as a dependency on your top level-module :
var MyModule = angular.module('MyModule', ["ngRoute", "kendo.directives"]);

Resources