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.
Related
I just started using kendo-ui grid and have created my columns and everything works with data coming back. I tried adding in a template value to my column definitions and the kendo docs say that I should be able to use {{dataItem.something}} to access the value in a template. This does NOT work. However doing <span ng-bind='dataItem.something'></span> works fine. Why is this, and how can I get the curly braces binding working? Thanks.
Here is a snippet of pseudo code for what I'm doing:
in my html and controller ( I am omitting all the other options like datasources etc..):
this.gridOptions = {
columns: [
{
field: 'valueOne',
template: "<span ng-bind='dataItem.valueOne'></span>" // THIS WORKS
},
{
field: 'valueTwo',
template: "{{dataItem.valueTwo}}" // THIS DOES NOT WORKS
}
]
};
<div ng-controller="gridController as vm">
<div kendo-grid k-options="vm.gridOptions"></div>
</div>
What I'm attempting is right from the kendo documentation and demos:
http://docs.telerik.com/kendo-ui/AngularJS/the-grid-widget#templates
http://dojo.telerik.com/ikEKIr
TL;DR;
By removing kendo-angular.js the binding is working as expected.
kendo-angular.js library was still being included in our build and was conflicting with kendo.all.js
More:
The kendo-angular.js library was deprecated and support was moved to kendo professional. The angular functionality was moved into kendo.all.js. The docs are very specific about including libraries in a specific order. The include order must be JQuery, Angular, then Kendo. I checked this and made sure to try the latest versions of all scripts, also tried using the specific versions used in the demos. However after digging a bit further into our scripts it turns out that our build scripts were still including kendo-angular.js farther down the list. Removing this fixed my issue.
You cannot use angular templates after app was initialized, when you inserting new HTML angular will ignore it.
Kendo have own templating tags for it:
There are three ways to use the hash syntax:
Render values as HTML: #= #.
Use HTML encoding to display values: #: #.
Execute arbitrary JavaScript code: # if (true) { # ... non-script content here ... # } #.
Also you can use functions as templates:
template:
function (e) {
if (e.type !== 1)
return "";
return '<input type="checkbox"' + (e.canExecute ? 'checked="checked"' : '') + 'disabled="disabled" />';
}
You also can check out docs for more info
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>
I had a bit of code in my view that would only show up when a particular value was true. Lt looked like this:
button type="button" ng-click="attachBarCode('enter')" ng-show="barcodeAllowed.status">Foo</button>
This was working until recently. My controller had some logic where, based on Ajax data, it would set $scope.barcodeAllowed.status to true. All of a sudden though, the button was always showing up. To help debug the issue, I added some additional tests to my view:
first test, <span ng-show="!barcodeAllowed.status">DONT SHOW</span><br/>
second test, <span ng-show="barcodeAllowed.status">DONT SHOW</span><br/>
test -{{barcodeAllowed.status}}-end -{{!barcodeAllowed.status}}- -{{barcodeAllowed | json}}-<br/>
test if <span ng-if="barcodeAllowed.status"> if was true</span><p>
Here is where things got crazy. Both "DONT SHOWS" rendered in my view, even though it seems as if that would be impossible. When I output the values in the third line, I saw false and true, as I expected.
Finally - the ng-if? It worked perfectly! The value did not show up.
I've heard folks mention that ngShow can have scope issues inside a ngif, but my code isn't inside an ngif.
So, you won't believe what it was. I was using a Content Security policy in my app and on a whim, I disabled it. As soon as I did, it began working. I played around a bit and discovered that I needed to add 'unsafe-eval' to the to the script-src area of my CSP in order for Angular to be able to apply the styles.
The Ng-show/Ng-hide directives needs a css-class to show/hide, since it just adds a class to your element when the scope-variable is truthy/falsy.
Ref: https://docs.angularjs.org/api/ng/directive/ngShow
I am using the sliders in the ionic framework and everything is working great. This is my html:
<ion-slide-box on-slide-changed="slideHasChanged($index)" show-pager={{showPager}}>
Pretty straightforward, notice that i am using showPager to dynamically show and hide the pager.
And in the controller:
$scope.showPager = true
$scope.slideHasChanged = ($index) ->
if $index == 4
$scope.$apply ->
$scope.showPager = false
It does as expected sets showPager value to false when the index of the slide is 4 in the web console.
BUT it does not really hide it on the web page. IF i explicitly set showPager to false, it does not display in the browser as expected, but if i try the above stuff to dynamically hide it, it does not work.
What am i missing?
<ion-slide-box> directive does not observe show-pager attribute. So it will consider only the value which was at the time of directive initialization.
For your use-case, you can show/hide pager by putting ng-class directive on <ion-slide-box> directive and based on that class you can write css to show/hide the pager.
Check this example codepen for working example.
I have the following code:
<form class="form"
data-ng-submit="modalSubmit(modal.data)"
id="modal-body"
name="modalForm"
novalidate>
This works and when I click on a button of type submit then the modalSubmit function is called.
However I would like to do this in my controller:
$scope.modalForm.$setPristine();
But it gives an error saying:
has no method '$setPristine'
How I can I set the form to pristine? I did try adding data-ng-form="modalForm" but then I get
a message saying something to the effect of duplicate directive names.
I tried changing the form element to a DIV but then the clicking on the submit button does not call
the function
Here's an example (modified from another user) that shows what I am trying to do which is set values to pristine:
plnkr.co/edit/LNanJdAggMLIgxii0cfv?p=preview
You're not doing anything wrong there, only problem is you're referencing an old version of angular in which $setPristine() was not a feature. $setPristine() was added in 1.1.+, so reference a newer version of angular and you're good to go. See it working in this plunk, using 1.2.+.
If you can't upgrade, then a dirty workaround would be to loop through all inputs in the form and set their $dirty and $pristine values manually:
$scope.mp = function() {
$scope.mainForm.$pristine=true;//clean main form
$scope.mainForm.$dirty=false;
angular.forEach($scope.mainForm,function(input){//clean all input controls
if (input !== undefined && input.$dirty !== undefined) {
input.$dirty=false;
input.$pristine=true;
}
});
}
First, your version of angular was old, 1.2.12 is the latest stable on the CDN. But even it wouldn't allow $setPristine because of the HTML5 validation that was going on.
The biggest problem was you used required on the fields instead of ng-required. The browser was doing the form validation for you instead of angular. You could also add the novalidate attribute to the form tag.
http://plnkr.co/edit/l1mUCceSFMFFZWgGgL6u?p=preview
it has already been implemented in this link you can use it this was as it has been demonstrated in the plnkr link.
As you can see from the above description, $setPristine only changes the state of the form (and thereby resets the css applied to each control in the form).
If you want to clear the values of each control, then you need to do for each in code.