Chips autocomplete for Angular 1.6. No angular-material - angularjs

I would need to add an autocomplete chips component in our Angular 1.6 application. We are using Typescript, Webpack 2. As we are already using angular-ui-bootstrap, we do not want to introduce also angular-material in order to avoid style conflicts. However the wished result is exactly what material chips provide.
Is there a directive or component that i can use in my case? I found this library but it runs endless exceptions when I import it.
unfortunately I could find only partial solutions with bootstrap typehead, but then I would need to implement all the "chips" part, making me think of re-inventing the wheel.

Stack Newb here. I have an identical problem as yours. Here's how I resolved this:
1. Resolve the ReferenceError: error is not defined within the angular-chips library
The library you used (angular-chips) wasn't designed with typescript in mind. So, you'll first need to resolve the following error ReferenceError: error is not defined by defining it for them in the line above with var error;. This should prepare angular-chips for your webpack useage.
The second issue you'll find is how to add your typeahead-template-url with webpack in the mix. Rather than referring to a separate html file, use an inline template as referenced here: Bootstrap-UI Typeahead display more than one property in results list?.
If you're lazy like me and don't want to follow that hyperlink, use this as example:
2. Template to be added before the <chips> tag:
<script type="text/ng-template" id="yourTemplate.html">
<a tabindex="-1">
<i ng-class="'icon-'+match.model.type"></i>
<span ng-bind-html-unsafe="match.model.title | typeaheadHighlight:query"></span>
</a>
</scrip>
3. Include template in your directive:
typeahead-template-url:"yourTemplate.html"
Worked like a charm for me.

Related

Angular UI bootstrap Modal is not working with AEM and sightly

In my application, I am using Angular UI bootstrap with AEM and having the sightly parameters in the same.
The issue is, when I try to access the sightly parameters inside the script tag of UI modal It is not rendenring the sightly parameters.
< script type="text/ng-template" id="/view2.tpl" data-sly-include="template.html">
${properties.title}
< /script >
This specific problem is there with Sightly with AEM and angular. Can anyone suggest how to make a Modal work for Angular+AEM+sightly?
Help will be highly appreciated.
As per the specification, using data-sly-include will cause the content of the <script> tag to be replaced with the content of the included script.
If you want to use HTL/Sightly templates from template.html you should instead write data-sly-use.tpl="template.html"
First, for using templates, use the data-sly-use instead of data-sly-include.
Second, HTL (Sightly) escapes the expressions by default depending on the context where they are used. You can explicitly specify the context using the context option as shown below.
<script type="text/ng-template" id="/view2.tpl">
<!--/* Use scriptString if you are using the value as a string */-->
${properties.title # context='scriptString'}
<!--/* In case you are trying to output an entire function or javascript,
there is no context specifically available for that. So, you can use the
unsafe option to disable escaping completely */-->
${properties.title # context='unsafe'}
</script>
More information on Display Context can be found here and information on Template and Call here.

Angular Material md-grid-list overlaps on page refresh

I am working on a angular material application. i have a page where i need to list number of languages. i am using md-grid-list instead of conventional ul and li.
However when the page loads/refreshes the list gets overlapped for a fraction of second before it gets displayed properly.
Code
<md-grid-list md-cols-md="3" md-cols-lg="3" md-cols-sm="3" md-cols-xs="2" md-row-height-gt-sm="6:1" md-row-height="7:1" md-gutter="33px">
<md-grid-tile ng-repeat="language in vm.languages" class="language">
<a data-ng-click="vm.changeLanguage(language.key)"><span ng-bind="language.language | humanize"></span></a>
</md-grid-tile>
</md-grid-list>
it would be great if anyone can share a solution for this.
Try to put ng-cloack as an attribute of the "md-grid-list".
<md-grid-list md-cols-md="3" md-cols-lg="3" md-cols-sm="3" md-cols-xs="2" md-row-height-gt-sm="6:1" md-row-height="7:1" md-gutter="33px">
<md-grid-tile ng-repeat="language in vm.languages" class="language">
<a data-ng-click="vm.changeLanguage(language.key)"><span ng-bind="language.language | humanize"></span></a>
</md-grid-tile>
</md-grid-list>
The order in which you are loading your css,js dependencies could be causing this problem.
If you can move your material library dependency closer to the initial loading of the page, it may fix this. You could test this by putting jquery and material libraries inside your html head as one of your first dependencies to load. These dependencies being global to your app or just on your component can also cause this to happen. Again, you can test that with the previously mentioned approach.
I have also fixed a flavor of this problem naturally by using *ngIf in a div container wrapper around my html and that seemed to allow the dependencies for the site to load prior to showing any content. I would still try rearranging my dependencies, though.

Bootstrap Select Plugin does not render in Angular ui router ng-view

I use the Bootstrap Select Plugin to create an extended select with input field and multiple selectable options. I use it in an Angular 1.5.3 application set up with ui-router. It does not work in the view where I need it. The code I include in that view:
<select name="jobdomainTeamId"
class="form-control selectpicker"
data-live-search="true"
multiple=""
style="display: none;"
ng-model="data.detailView.jobDomain.teams"
ng-options="team.id as team.displayName for team in data.detailView.teams"
>
<option value="">No selection</option>
</select>
The attributes 'selectpicker' and 'data-live-search' should trigger Bootstrap to dynamically create a node that provides the extra functionality. But nothing happens when I add this to the Angular view - the select is not visible (style="display: none;").
But when I add the exact same code to index.html, commenting out the ng-view
<!--<div ui-view="body"></div>-->
Here the select works - extra DOM nodes are generated and functionality is as expected.
I included all necessary stuff - Boostrap.css, bootstrap-select.css,jquery-2.1.1.,bootstrap.js and bootstrap.select.js
It occurred to me there might be a conflict between angular dependencies and Bootstrap - I include
angular.module('app',[angular-storage','ui.bootstrap','ui.router','ui.router.modal','xeditable','angular-confirm'])
Does anyone have a clue what might block Bootstrap css / js here??
Turns out that mixing JQuery + Bootstrap.js with Angular.js is asking for trouble.
Bootstrap (via JQuery) works by 'grabbing an element and modifying it'. Angular also modifies the DOM element - is an Angular directive (as well as an browser-native DOM element). What I tried to achieve is impossible this way and i ended up using an Angular library (ui-select) that does what I want.
you defined style='display:none' in your select so it's working as expected. if you want to hide it use the directive ng-hide instead, in some case you should use angular UI for specific actions
I was struggling with the same issue. This methods helped me. Hope it help someone else also
Install jquery on your angular project.
npm i --save-dev #types/jquery
import jquery to the component.
declare var $: any;
run the below code on ngOnInit
ngOnInit(): void {
$('.selectpicker').selectpicker('refresh');
}

How to select an element by classname using jqLite?

I'm trying to remove jquery from my Angular.js app in order to make it lighter, and put Angular's jqLite instead. But the app makes heavy use of find('#id') and find ('.classname'), which are not supported by jqLite, only 'tag names' (as per documentation)
wondered what do u feel would be the best approach to change it. One approach I thought about is to create custom HTML tags. for example:
change
<span class="btn btn-large" id="add-to-bag">Add to bag</span>
to
<a2b style="display:none;"><span class="btn btn-large" >Add to bag</span></a2b>
and
$element.find('#add-to-bag')
to
$element.find('a2b')
Any thoughts? other ideas?
thanks
Lior
Essentially, and as-noted by #kevin-b:
// find('#id')
angular.element(document.querySelector('#id'))
//find('.classname'), assumes you already have the starting elem to search from
angular.element(elem.querySelector('.classname'))
Note: If you're looking to do this from your controllers you may want to have a look at the "Using Controllers Correctly" section in the developers guide and refactor your presentation logic into appropriate directives (such as <a2b ...>).
angualr uses the lighter version of jquery called as jqlite which means it doesnt have all the features of jQuery. here is a reference in angularjs docs about what you can use from jquery.
Angular Element docs
In your case you need to find a div with ID or class name.
for class name you can use
var elems =$element.find('div') //returns all the div's in the $elements
angular.forEach(elems,function(v,k)){
if(angular.element(v).hasClass('class-name')){
console.log(angular.element(v));
}}
or you can use much simpler way by query selector
angular.element(document.querySelector('#id'))
angular.element(elem.querySelector('.classname'))
it is not as flexible as jQuery but what
If elem.find() is not working for you, check that you are including JQuery script before angular script....

ng-click as a class in AngularJS

I'm trying to work out why this doesn't work:
<a class="ng-click: loadSomeDatas();">Click here to load some datas</a>
But this does:
<a ng-click="loadSomeDatas()">Click here to load some datas</a>
Why are you using classes?
Well ng-* attributes don't play nice on some of the clients I have to support, thus rather than shimming them I'd rather just use good ol' safe classes.
This looks like a documentation error. According to the source code, it can only be used as an attribute. The link function does not use restrict so the default is "attribute only".
Can you try using "data-ng-click"? Angular will still work with data- appended before it's attribute names and this should be valid syntax in older browsers.
<a data-ng-click="loadSomeDatas()" href="#">Click here to load some datas</a>

Resources