ui-bootstrap popover-trigger expression breaks in version 2.0.0 - angularjs

In ui-bootstrap 1.3.3 I had a button with a popover and the following trigger
popover-trigger="click outsideClick"
The trigger opened the popover when I clicked the button and closed it when anything else was clicked
In ui-bootstrap 2.0.0 this popover trigger fails on
Error: $parse:syntax
Syntax Error
Syntax Error: Token 'outsideClick' is an unexpected token at column 7 of the expression [click] starting at [{4}].
Trying both
popover-trigger="click" and
popover-trigger="outsideClick" seems to work but it's not the behavior I require.
Going over their latest change-log I couldn't find any mention of this. How can I correct this?

The docs say that popover-trigger accepts an expression but turns out it also accepts a string, all I had to do to properly concatenate the triggers was to apostrophe them in the expression
bad:
popover-trigger="click outsideClick"
good:
popover-trigger="'click outsideClick'"
And it all works again as it should

Related

Why can't I use interpolation with a directive?

I have searched and found a few articles that address "How does one assign a scoped variable to the value of an html attribute tag". See:
https://docs.angularjs.org/guide/interpolation
How to assign angularjs variable value to html element attribute, such as input elememnt's name attribute
In my controller I have defined the following:
$scope.reportFields = "{'summary.imageID':'Image ID' }";
in my html document I have defined the following:
A TEST EXAMPLE
<button ng-json-eport-excel title="CSV" class="bt btn-md btn-success" separator="," data="mdcData" report-fields="{{reportFields}}" filename="'mySearch'">
when I bring the page into the browser I find that the page reports a parse syntax error on defining {{reportFields}} for my button element.
Error: [$parse:syntax] Syntax error: Token '{' invlaid key at column 2 of the expression [{{reportFields}}] starting at [reportFields}}].
if I forgo using a variable and hardcode the value as in:
<button ng-json-eport-excel title="CSV" class="bt btn-md btn-success" separator="," data="mdcData" report-fields="{'summary.imageID':'Image ID' }" filename="'mySearch'">
it compiles and works correctly. If I add the 'ng-if' it compiles correctly as seen below:
<button ng-json-eport-excel title="CSV" class="bt btn-md btn-success" separator="," data="mdcData" report-fields="{{reportFields}}" ng-if="reportFields.length > 0" filename="'mySearch'">
Furthermore when I examine the generated HTML via the inspector I can see that for the 'ahref' tag that angularjs's interpolation has translated 'reportFields' to '"{'summary.imageID':'Image ID' }"' for the ahref tag but it hasn't translate the value for the report-fields tag specified on the button. I have also tried:
ng-if="1==1" filename="'mySearch'">
for my expression which should always evaluate to true. My questions (and I am new to angularjs and I need help understanding) are:
Why do I get a syntax parse error for using the double curly angles with the second HTML element (button) but not the first (href)??
Why does the parse error go away with the 'ng-if' statement
Why doesn't the interpolation happen in the case for
report-fields="{{reportFields}}"
but occurs just fine for:
A TEST EXAMPLE
Thanks for your help in advance.
Pete
What you probably want is:
<a ng-href="reportFields">A TEST EXAMPLE</a>
Although this doesn't make any sense either given the way you've defined reportFields. Notice the ng-href and lack of interpolation. As it is, you are assigning the reportFields expression to the regular HTML attribute href which is not interpreted by Angular.
Angular treats your HTML like a template rather than trying to render it like a browser would. It takes that template and turns it into browser-readable DOM HTML. This helps explain the behavior you're asking about.
Answers to your questions:
Interpolation (curly braces) is actually a directive with special syntax which the parser has to evaluate along with any other directives such as ng-show, ng-repeat, custom directives, etc. There is no guarantee that an interpolation directive will be processed before another directive that tries to bind to it. And in fact, those other directives such as report-fields will get the raw interpolation markup and not the intended data. This is what throws the error. See the last paragraph in the interpolation documentation
Why mixing interpolation and expressions is bad practice
Since href is not actually a directive-- it's an attribute-- Angular doesn't attempt to treat it as a directive or bind it to the interpolation, so no error is thrown. It just outputs the expected result to the DOM: href="parsed value".
ng-if has no special assistance for this issue except it does get parsed before your report-fields directive and then cancels further parsing on the element if false. If you don't get an error in that situation, it's likely only because the if condition evaluated to false and the report-fields directive was never parsed. (Can't see all your code to confirm.)
The interpolation doesn't happen in the error case because the error is thrown before it has a chance to. Again, this is because it gets processed after other directive linking. (I'm not sure why they made that design choice though I imagine there is a good reason.)

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>

Angular UI Bootstrap Datepicker is-open

I've been working on this for a while now, and am not sure where to go from here.
I am using Jade for my templates inside my app, and am trying to use the UI Bootstrap date picker as well. In UI Bootstrap 0.10.x everything was working fine, but in 0.13.3 I can't get the is-open attribute on the datepicker to work properly. Here is the jade template excerpt:
input(type="text", ng-model="item.exp_date", datepicker-popup="{{datepicker.format}}", min-date="{{datepicker.minDate}}", is-open="{{datepicker.opened}}", close-text="{{datepicker.closeText}}").form-control
span.input-group-btn
button(type="button", ng-click="openDatepicker($event)").btn.btn-default
i.glyphicon.glyphicon-calendar
You can see that for several attributes I'm using angular expressions to get preset values (i.e. datepicker-popup="{{datepicker.format}}". However, that expression does not work when I try to do the same thing with is-open. All the others work fine, and if I just put is-open="true" in for the attribute, the datepicker at least shows up on page load. The problem is you can never open it again.
Here's the pertinent controller code:
$scope.datepicker = {
format: 'MM-dd-yyyy',
minDate: new Date(),
closeText: "Close",
showWeeks: false,
yearRange: 50,
opened: false
}
$scope.openDatepicker = function($event) {
$scope.datepicker.opened = true;
}
and the error in the browser that pops up:
Error: [$parse:syntax] Syntax Error: Token '{' invalid key at column 2 of the expression [{{datepicker.opened}}] starting at [{datepicker.opened}}].
http://errors.angularjs.org/1.4.5/$parse/syntax?p0=%7B&p1=invalid%20key&p2=2&p3=%7B%7Bdatepicker.opened%7D%7D&p4=%7Bdatepicker.opened%7D%7D
at REGEX_STRING_REGEXP (http://localhost:3030/vendor/angular/angular.js:68:12)
at Object.AST.throwError (http://localhost:3030/vendor/angular/angular.js:12967:11)
at Object.AST.object (http://localhost:3030/vendor/angular/angular.js:12954:16)
at Object.AST.primary (http://localhost:3030/vendor/angular/angular.js:12862:22)
at Object.AST.unary (http://localhost:3030/vendor/angular/angular.js:12850:19)
at Object.AST.multiplicative (http://localhost:3030/vendor/angular/angular.js:12837:21)
at Object.AST.additive (http://localhost:3030/vendor/angular/angular.js:12828:21)
at Object.AST.relational (http://localhost:3030/vendor/angular/angular.js:12819:21)
at Object.AST.equality (http://localhost:3030/vendor/angular/angular.js:12810:21)
at Object.AST.logicalAND (http://localhost:3030/vendor/angular/angular.js:12802:21) <div ui-view="locations" class="ng-scope">
Like I said, the is-open attribute is the only one having this issue. If you have any suggestions for fixing the issue or a work around I'd love to hear it. Thanks!
Of course right after I posted the question, I figured out the problem. Apparently for that attribute, the {{ }} is unnecessary. All the other attributes need the curly braces, but that one doesn't. It must be because it assumes you will be adding in a variable to toggle the visibility.
Whatever the reason, I figured it out and got it working again. I'll leave this up in case anyone else gets as stuck as I did and can't get it working again.
For the atribute of angularjs (whatever) the {{ }} is not necesary, in this atribute you are in angularjs, and not needed call to angularjs.

Double curly braces in angularjs avoid w3c validation

I have an html page that uses the following line of code:
... <a href="nolf://{{server.ip}}:{{server.hostport}}/"> ...
When I try to validate the page, I got the following error:
"Bad value nolf://{{server.ip}}:{{server.hostport}}/ for attribute href on element a: Illegal character in scheme data: not a URL code point."
It seems that the validator does not like seeing the curly braces in a URL link. If I remove them, all goes well. They are "unsafe" so they need to be encoded but if I encode them, the AngularJS instructions do not work anymore.
Is there a workaround, a way, to validate this? (original page where this code is can be found here: http://oneoakway.com/nolf/servers/ - there is a validation link in the footer)
Use ng-href instead. This will properly apply the expression to a href attribute.

Errors when upgrading from Angular 1.2.0-rc3 to 1.2.0 or higher

When I upgrade the angular version from 1.2.0-rc3 to 1.2.0 or any higher version, it causes errors which seem to be centered on the use of $parent.$index. There is no error when using 1.2.0-rc3.
Error: [$parse:syntax] Syntax Error: Token '$parent.$index' is unexpected, expecting [:] at column 20 of the expression [setSelectedTable({{$parent.$index}})] starting at [$parent.$index}})].
(Here $parent.$index (of the array) is being passed as the argument to a method)
The corresponding html is
ng-click="setSelectedTable({{$parent.$index}})"
ng-class="{selectedTable:{{$parent.$index}}==event.selectedTable}"
Both the lines, ng-click and the ng-class fail with the above error.
It appears that angular parses the ng-class code line as selectedTable:==event.selectedTable, basically nullifying $parent.$index.
Error: [$parse:syntax] Syntax Error: Token 'event.selectedTable' is unexpected, expecting [}] at column 18 of the expression [{selectedTable:==event.selectedTable}] starting at [event.selectedTable}].
Anyone know why this error? Is there a syntax change between 1.2.0rc3 and 1.2.0? What should be used in place of $parent.$index?
Is that in an ng-click?
setSelectedTable($parent.$index)
Looks to be more what you need. If not can you please paste the line of html.
edit
Based on your edit, it looks like both of those should be like this:
ng-click="setSelectedTable($parent.$index)"
ng-class="{selectedTable:$parent.$index==event.selectedTable}"
What is event though? is that bound to scope?

Resources