Angular ui-select2 - hide initial drawing/rendering of component - angularjs

I'm evaluating using Angular with ui-select2 and wondered whether someone could provide help on hiding the flicker/conversion of the <select> into the select2 component.
It's only very brief, but users can see the component change styles.
Is there a way of hiding it until the select has been modified by select2?

I came across the same problem and I had a look at the source code. The directive is deliberately initialised later by using a timeout. In the code there is a comment saying "Initialize the plugin late so that the injected DOM does not disrupt the template compiler".
My solution (you can see it in this jsplunker: http://plnkr.co/edit/fXjDxs?p=preview ) is to set the visibility of the select tag to "hidden".
<select ui-select2 ng-model="....." style="visibility: hidden; ">......
When the component is loaded that tag is replaced with a div. In ui-select2.js I have added a line (line 208) to set its visibility to "visible".
elm.prev().css({"visibility": "visible"});

Related

Angular UI Bootstrap tabset with ng-repeat

I'm trying to upgrade my version of bootstrap-ui from 0.14.x to the latest 1.3.2 and I'm encountering some issues regarding the uib-tabset / uib-tab directives.
What I'm trying to do is dynamically create tabs using ng-repeat and have the 'active' tab be handled by expressions or properties of my repeat model.
<uib-tabset type="pills" active="{{activeItem.Id}}" >
<uib-tab class="arrow_box"
ng-repeat="item in myObject.myCollection"
ng-click="SetActiveItem(item)" id="{{$index}}"
index="{{item.Id}}">
The index="{{item.Id}}" binding does not work at all. So I can't seem to set my tab indexes via an expression, which wouldn't be a problem if I could get the uib-tabset to use the active property once the ng-repeat was complete.
activeItem is a property on $scope of the enclosing controller.
Adding this binding results in an error:
Error: [$parse:syntax] Syntax Error: Token '{' invalid key at column 2 of the expression [{{item.Id}}] starting at [{item.Id}}].
If I omit everything (the index attribute on uib-tab and active attribute on uib-tabset) it doesn't throw any errors but it also doesn't select any tabs by default, meaning I need to click one to activate that tab. Even though the documentation states that the defaults are "defaulting to the first tab".
Any reason ng-repeat no longer works properly with this directive set? I'm probably missing something here but I'm stumped.
Thanks
Edit:
Here is a plunkr link showing the issue I'm having.
https://plnkr.co/edit/DWOILq?p=preview
First I tried a lot to fix it but then I decided to search in google. I found this link .
Your problem is a known problem and will not be fixed. "uib-tab won't toggle active class if uib-tab index is set to dynamic key". You have to take some different approach like use of '$index'.
After trying out a few more things I realized I made a mistake and did not have to include the brackets for the expression for either binding (active or index).
It just didn't seem like they were being evaluated but they actually are.
Here is the code that should work:
activeItemId being a property on the parent controller.
<uib-tabset type="pills" active="activeItemId">
<uib-tab class="arrow_box"
ng-repeat="item in myObject.myCollection"
ng-click="SetActiveItem(item)"
index="item.Id">
</uib-tab>
</uib-tabset>

preventing angular to run in non displayed DOM elements

lets say I have a HTML structure like this
<myHandler>
<element_1 ng-controller="..." ng-init="">
content
</element_1>
<element_2 ng-controller="..." ng-init="">
content
</element_2>
</myHandler>
So, my css is saying element_2 has display: none;
how to tell angular not to run on these lements, that are hidden?
and run only (once) when they are visible?
to clarify the case more, the myHandler is handling authorization and is displaying element_1/element_2 depending on the permissions.
so I don't want to initialized element_2 if it has no permissions
Instead of keeping display none ,just keep an attribute ng-if with a flag variable
because if we use ng-if then no element is added into the dom or if no element added then no controller will get instantiated.
<myHandler>
<element_1 ng-controller="..." ng-init="">
content
</element_1>
<sample ng-if="isDisplay">
<element_2 ng-controller="..." ng-init="">
content
</element_2>
</sample>
</myHandler>

Angularjs : Display accolades {{ }} several milliseconds before rendering

I am going to create an application with Angularjs. I have several modals (with the ng-dialog libraries) to create, modify data like an user for example.
When I open it, I can always see during several milliseconds names variables with accolades like {{user.name}}, before it renders the real value.
It is not really beautiful and then if someone has an idea about how to manage this type of display problems, please share it.
Thank you in advance.
There are couple of ways to deal with it, you could either use ng-bind or ng-cloak directives
Check angular ngCloak directive documentation
https://docs.angularjs.org/api/ng/directive/ngCloak
You can use ng-bind. Here is the official documentation on it:
It is preferable to use ngBind instead of {{ expression }} if a template is momentarily displayed >by the browser in its raw state before Angular compiles it. Since ngBind is an element attribute, >it makes the bindings invisible to the user while the page is loading
Usage:
Hello <span ng-bind="name"></span>!

How can I hide a component in AngularJS yet still get an external library to bind to it?

In my code I have something similar to
<div ng-if="variableThatEvaluatesToFalse">
<input id="location">
</div>
What I'm trying to do is hide a component and then show it in response to user input. However, upon my page loading I want Google Maps to attach to my input. Google Maps relies on document.getElementById('location') which is null presumably because AngularJS is 'hiding' it. I can I get document.getElementById('location') to return my input field even if it is initially hidden by the ngIf directive?
The ngIf directive prevents elements from being included in the DOM at all. What you would need in this case is ngHide, which would keep the element in the DOM.
See: https://docs.angularjs.org/api/ng/directive/ngHide

Hide Angular brackets until javascript loaded

I have a few bits of HTML like
<p class="noresults">{{numberOfContacts}} Results Are Available</p>
Is it possible for me to hide {{numberOfContacts}} until Angular has loaded? So it would just say Results Are Available
I've seem some solutions such as hiding the entire body until Angular has loaded, but I'd rather not do that if possible.
Yes, use ng-cloak. Simply add class="ng-cloak" or ng-cloak to an element like this
Using directive <div ng-cloak></div>
Using class <div class="ng-cloak"></div>
It's simply a set of CSS rules with display: none !important and as Angular has rendered your DOM it removes the ng-cloak so an element is visible.
use <span ng-bind="numberOfContacts" /> instead of {{numberOfContacts}}
Sometimes, even if I used the ng-cloak, I could still see the braces for a few seconds. Adding the following style resolved my issue:
[ng-cloak]
{
display: none !important;
}
Please see this link link for more explanation.
Hope it helps :D
This is typically only an issue when working with complex content on really slow devices. In those instances, there can be a brief moment when the browser displays the HTML in the document while AngularJS is parsing the HTML, getting ready, and processing the directives. In this interval of time, any inline template expressions you have defined will be visible to the user. Most devices nowadays have pretty good browsers which are quick enough to prevent this from being an issue. There are two ways to solve the problem.
Avoid using inline template expressions and stick with ng-bind directive.
(Best) Use the ng-cloak directive which will hide the content until Angular has finished processing it. Basically, the ng-cloak directive uses CSS to hide the elements and angular removes the CSS class when the content has been processed, ensuring that the user never sees the {{ and }} characters of a template expression.
One strategy to consider is using the ng-cloak directly to the body element, which will ensure that the user will see an empty browser while AngularJS loads. However, you can be more specific by applying it to parts of the document where there are inline expressions.
I have seen issues with ng-cloak not working when added to an element. In the past, I have worked around this issue by simply adding ng-cloak class to element.
You can use ng-bind instead of expression like
<span ng-bind="data"></span>

Resources