I have a UI in which I'm adding angucomplete as dynamic html. I have a directive that that compiles the html on add like this :
.directive('dynamic', function ($compile) {
return {
restrict: 'A',
replace: true,
link: function (scope, ele, attrs) {
scope.$watch(attrs.dynamic, function (html) {
console.log('dynamic watch');
ele.html(html);
$compile(ele.contents())(scope);
});
}
};
})
Now I have an add button which appends angucompletes text-boxes to the existing html which is in directive 'dynamic'. When I add an angucomplete all my previous selected values also get cleared. I don't understand why. I tried debugging angucomplete-alt.js but couldn't find the cause.
I have also used ng-tagsinput in the similar scenario and works great, when I add a new row the previous tags-input doesn't loose its selected value.
function recommendationHtml(recommedCount) {
var men = 'men';
var women = 'women';
var tblRecommend = ' <table id="tblid'+recommedCount+'" style="padding:5px;border-bottom:solid 1px;"> '
+ ' <tr> '
+ ' <td class="td-recommendation"><i class="icon fa-inr fa-2x"></i> '
+ ' </td> '
+ ' <td> '
+ '<div class="item range range-positive"> '
+ '<label id="spanprice_' + recommedCount + '" name="spanprice_' + recommedCount + '">1000</label> '
+ '<input id="slider_' + recommedCount + '" type="range" step="500" name="slider_' + recommedCount + '" min="1000" max="50000" value="1000" '
+ ' onchange="angular.element(document.querySelector(\'#spanprice_0\')).val(this.value);"/> '
+ ' </div> '
+ ' </td> '
+ ' </tr> '
+ ' <tr> '
+ ' <td class="td-recommendation"><i class="icon ion-bag fa-2x"></i> '
+ ' </td> '
+ ' <td> '
+ ' <tags-input ng-model="vendors' + recommedCount + '" id="vendors' + recommedCount + '" '
+ ' display-property="name" '
+ ' key-property="id" '
+ ' on-tag-added="storeTagAdded($tag)" '
+ ' on-tag-removing="storeTagRemoved($tag)" '
+ ' max-tags="1" '
+ ' placeholder="store"> '
+ ' <auto-complete source="loadVendors($query)"></auto-complete> '
+ ' </tags-input> '
+ ' </td> '
+ ' </tr> '
+ ' <tr> '
+ ' <td class="td-recommendation"><i class="icon ion-bag fa-2x"></i></td> '
+ ' <td> '
+ '<div angucomplete-alt id="vendor' + recommedCount + '" placeholder="Search Store" '
+ 'pause="300" selected-object="selectedVendorPost" local-data="vendorData"'
+ ' search-fields="name" title-field="name" description-field="email"'
+ ' image-field="image" minlength="1" remote-url-data-field="name"'
+ ' input-class="form-control form-control-small"'
+ ' match-class="highlight" style="border-bottom: 1px solid;"'
+ ' ng-keydown="removedVendorPost($event,' + recommedCount + ')" >'
+ '</div>'
+ ' </td> '
+ ' </tr> '
+ ' <tr> '
+ ' <td class="td-recommendation"><i class="icon ion-tshirt-outline fa-2x"></i></td> '
+ ' <td> '
+ '<div angucomplete-alt id="apparel_' + recommedCount + '" placeholder="Search apparel" '
+ 'pause="300" selected-object="selectedApparel" local-data="apparelData"'
+ ' search-fields="tagname" title-field="tagname" description-field=""'
+ ' image-field="" minlength="1" remote-url-data-field=""'
+ ' input-class="form-control form-control-small"'
+ ' match-class="highlight" style="border-bottom: 1px solid;"'
+ ' ng-keydown="removedApparel($event,' + recommedCount + ')" >'
//+ ' onkeydown="javascript:console.log(event:' + 'event.which' + 'value:' + ' this.value' + 'index:' + recommedCount + ');"'
+ '</div>'
+ ' </td> '
+ ' </tr> '
+ ' </table>';
return tblRecommend;
};
$scope.addRecommend = function() {
$scope.html = $scope.html + recommendationHtml($scope.recommedCount);
$scope.recommedCount = $scope.recommedCount + 1;
//$compile(recommendationHtml(0).contents())($scope);
};
.directive('dynamic', function($compile) {
return {
restrict: 'A',
replace: true,
link: function(scope, ele, attrs) {
scope.$watch(attrs.dynamic, function(html) {
console.log('dynamic watch');
ele.html(html);
$compile(ele.contents())(scope);
});
}
};
})
<div dynamic="html"></div>
Related
This is what I append to my modal on load, and it's working fine, except the checkbox row.
//$scope.items is retrieved by an api, and looks something like this.
$scope.items[0] = ['delivered' : true, 'status': 'delivered']
$scope.items[1] = ['delivered': false, 'status': 'pending']
angular.element('.row-modal').empty();
request.success(function(response) {
$scope.paymentTransactionServices = response;
angular.forEach($scope.paymentTransactionServices, function(value, index) {
var deliveredBy = value.deliveredBy ? value.deliveredBy.email : null;
angular.element('#table-services').append('<tr class = "row-modal">' +
'<td>' + value.title + '</td>' +
'<td>' + deliveredBy + '</td>' +
'<td>' + '<label class="checkbox-inline">' +
' <input type="checkbox" ng-model=' + $scope.paymentTransactionServices[index].delivered + ' ng-change="print()" />' + value.status + '</label> </td>' +
'<td>' + value.delivery_date + '</td>' +
'</tr>'
);
})
What I expect is that if "delivered" is false, the checkbox should notbe checked and if true then it should be checked. And on click, i want to fire a function but it's not working...
You should never alter the dom like that, as this may result in unexpected errors and memory leaks in you application.
You should always use directives & components for this kind of stuff.
What you should do, in your template, is:
<table id="table-services">
<tr>
<th>Title</th>
<th>Delivered by</th>
<th>Status</th>
<th>Delivery date</th>
</tr>
<tr ng-repeat="service in paymentTransactionServices" class="row-modal">
<td>{{ service.title }}</td>
<td>{{ service.deliveredBy.email || null }}</td>
<td>
<label class="checkbox-inline">
<input type="checkbox" ng-model="service.delivered" ng-change="print()" />
{{ service.status }}
</label>
</td>
<td>{{ service.delivery_date | date }}</td>
</tr>
</table>
If you need to check a checkbox, you must add checked attribute to your HTML element. In the above case, there is no checked attributed on that element.
On the other hand, I have a doubt if click event exists on checkbox. Kindly use change instead.
Check if the below works
input type="checkbox" checked={{value.delivered}} (change)=print()
Is there any way to put a condition in the following:
<h3 ng-show="ctrl.loggedIn">
{{ctrl.loggedInUser.FirstName + " " + ctrl.loggedInUser.LastName + " is logged in."}}
</h3>
that is if the ctrl.loggedInUser.FirstName is undefined or null then it wouldn't print.
Click here to visit the project on github.
yes you can. use ng-if to add conditions in DOM
<h3 ng-show="ctrl.loggedIn" ng-if="ctrl.loggedInUser.FirstName">
{{ctrl.loggedInUser.FirstName + " " + ctrl.loggedInUser.LastName + " is logged in."}}
</h3>
h3 will only show if ctrl.loggedInUser.FirstName have some value
<h3 ng-show="ctrl.loggedIn && ( ctrl.loggedInUser.FirstName!=null || (ctrl.loggedInUser.FirstName!='undefined')")>
{{ctrl.loggedInUser.FirstName + " " + ctrl.loggedInUser.LastName + " is logged in."}}
</h3>
you can also do like
<h3 ng-hide="!ctrl.loggedIn && (ctrl.loggedInUser.FirstName==null || (ctrl.loggedInUser.FirstName=='undefined')")>
{{ctrl.loggedInUser.FirstName + " " + ctrl.loggedInUser.LastName + " is logged in."}}
</h3>
You can use ng-show
<h3 ng-show="ctrl.loggedInUser.FirstName!=undefined || ctrl.loggedInUser.FirstName!=null">
{{ctrl.loggedInUser.FirstName + " " + ctrl.loggedInUser.LastName + " is logged in."}}
</h3>
<div ng-switch on="ctrl.loggedInUser.FirstName == null || ctrl.loggedInUser.FirstName == undefined || ctrl.loggedInUser.FirstName == ''">
<h3 ng-switch-when="true">Please log in.</h3>
<h3 ng-switch-when="false">{{ctrl.loggedInUser.FirstName + " " + ctrl.loggedInUser.LastName + " is logged in."}}</h3>
</div>
this worked for me.
thanks all for the ideas.
This should be a really simple question.
Is it possible to get a property value dynamically like this:
<div tabset>
<div tab ng-repeat="item in teamController.range track by $index">
<div tab-heading>
<div class="selected-colour" ng-class="{ 'no-colour-selected': !controller.kit['colour' + $index + 1] }" ng-style="{ 'background-color' : '#' + controller.kit['colour' + $index + 1] }"></div> {{ controller.kit['colour' + $index + 1] }}
</div>
<div class="picker colour-picker">
<ul class="picker-dropdown list-inline">
<li ng-repeat="colour in teamController.colours" ng-class="{ 'active': controller.kit['colour' + $index + 1] === colour.hex }">
<a href style="background-color: #{{ colour.hex }};" ng-click="teamController.setColour(controller.kit['colour' + $index + 1], colour)"></a>
</li>
</ul>
</div>
</div>
</div>
hopefully you can see that my model has 3 properties:
Colour1
Colour2
Colour3
And in my repeat I am trying to get each of them by doing
controller.kit['colour' + $index + 1]
Update
So I have changed my view to this:
<div tabset>
<div tab ng-repeat="item in teamController.range track by $index">
<div tab-heading>
<div class="selected-colour" ng-class="{ 'no-colour-selected': !controller.kit['colour' + ($index + 1)] }" ng-style="{ 'background-color' : '#' + controller.kit['colour' + ($index + 1)] }"></div> {{ controller.kit['colour' + ($index + 1)] }}
</div>
<div class="picker colour-picker">
<ul class="picker-dropdown list-inline">
<li ng-repeat="colour in teamController.colours" ng-class="{ 'active': controller.kit['colour' + ($index + 1)] === colour.hex }">
<a href style="background-color: #{{ colour.hex }};" ng-click="teamController.setColour(controller.kit['colour' + ($parent.$index + 1)], colour)"></a>
</li>
</ul>
</div>
</div>
</div>
In my controller I have this:
// Set our colours
self.setColour = function (item, colour) {
// Set the colour
item = colour.hex;
console.log(item);
console.log(kit);
// Store our model in the session
configuratorService.saveToSession(kit);
};
It doesn't update the kit.
But if I change the setColour invocation to
teamController.setColour(controller.kit['colour' + ($parent.$index + 1)], colour)
and then change my controller function to this:
// Set our colours
self.setColour = function (item, colour) {
// Set the colour
item.colour1 = colour.hex;
console.log(item);
console.log(kit);
// Store our model in the session
configuratorService.saveToSession(kit);
};
everything works fine.
I have also tried using teamController.setColour(controller.kit['colour' + ($index + 1)], colour) and this didn't work.
Does anyone know why?
You need to wrap $index + 1 inside round brackets to evaluate it first before concatenating the string.
Additionally You need to use $parent notation while you wanted to access the $index of parent ng-repeat
ng-click="teamController.setColour(controller.kit['colour' + ($parent.$index + 1)], colour)"
This was a weird one to solve.
I had to change the way my function worked. I changed my function to this:
// Set our colours
self.setColour = function (propertyName, colour) {
// Set the colour
kit[propertyName] = colour.hex;
// Store our model in the session
configuratorService.saveToSession(kit);
};
and my HTML to this:
<div class="picker colour-picker">
<ul class="picker-dropdown list-inline">
<li ng-repeat="colour in teamController.colours" ng-class="{ 'active': controller.kit['colour' + ($index + 1)] === colour.hex }">
<a href style="background-color: #{{ colour.hex }};" ng-click="teamController.setColour('colour' + ($parent.$index + 1), colour)"></a>
</li>
</ul>
</div>
For some reason I found that if I tried to pass the actual property, although it updated the property it did not update all references (as if dynamic properties in views are always treated as copies). Doing it this new way fixed the problem.
I want to add new type class button in my datepicker.
Example:
Button blue colour for range date from Jan 8, 2014 until Jan 18, 2014
or, button red colour for date Feb 2, 2014.
I already try to ovveride datepicker directive, but it doesn't work. Here my codes:
angular.module('App').directive('NewDatepickerPopup',function(){
return{
restrict: 'EA',
replace: true,
require: ['datepicker'],
templateUrl: 'template/datepicker/datepicker.html',
controller: function($scope){
console.log('controller NewDatepickerPopup');
},
link: function(scope, element, attrs, requiredControllers){
console.log('requiredControllers',requiredControllers);
console.log('link NewDatepickerPopup');
element.on('click',function(){
console.log('on click nya disini');
});
}
};
});
angular.module("template/datepicker/datepicker.html", []).run(["$templateCache",
function($templateCache) {
$templateCache.put("template/datepicker/datepicker.html",
"<table class=\"zor-datepicker\" >\n" +
" <thead>\n" +
" <tr>\n" +
" <th><button type=\"button\" class=\"btn btn-cal btn-sm pull-left\" ng-click=\"move(-1)\"><i class=\"fa fa-angle-left fa-lg\"></i></button></th>\n" +
" <th colspan=\"{{rows[0].length - 2 + showWeekNumbers}}\"><button type=\"button\" class=\"btn btn-cal btn-sm btn-block\" ng-click=\"toggleMode()\">{{title}}</button></th>\n" +
" <th><button type=\"button\" class=\"btn btn-cal btn-sm pull-right\" ng-click=\"move(1)\"><i class=\"fa fa-angle-right fa-lg\"></i></button></th>\n" +
" </tr>\n" +
" <tr ng-show=\"labels.length > 0\" class=\"h6\">\n" +
" <th ng-show=\"false\" class=\"text-center ng-hide\">#</th>\n" +
" <th ng-repeat=\"label in labels\" class=\"text-center\">{{label}}</th>\n" +
" </tr>\n" +
" </thead>\n" +
" <tbody>\n" +
" <tr ng-repeat=\"row in rows\">\n" +
" <td ng-show=\"false\" class=\"text-center ng-hide\"><em>{{ getWeekNumber(row) }}</em></td>\n" +
" <td ng-repeat=\"dt in row\" class=\"text-center\">\n" +
" <button type=\"button\" style=\"width:100%;\" class=\"btn btn-default btn-sm\" ng-class=\"{'btn-info': dt.selected}\" ng-click=\"select(dt.date)\" ng-disabled=\"dt.disabled\"><span ng-class=\"{'text-muted': dt.secondary}\">{{dt.label}}</span></button>\n" +
" </td>\n" +
" </tr>\n" +
" </tbody>\n" +
"</table>\n" +
"");
}
]);
<input id="ph" ng-click="openCheckin($event)" name="in" type="text" class="form-control search home" new-datepicker-popup datepicker-popup="{{format}}" ng-model="check_in" ng-change="changeCheckinDate()" is-open="openedCheckin" min="minCheckInDate" ng-required="false" show-weeks="false" show-button-bar="false" close-text="Close" placeholder=""/>
Anybody could help me?
Thank you so much
*Sorry my english so bad.
Take a look on this post: https://github.com/angular-ui/bootstrap/issues/743
You could use decorator in the config phase to override the templateUrl
My team are wanting to use this feature of ng-grid. However it does not seem to be documented anywhere. What we would like to do is to put a "plus" icon into the last column of the header area of a ng-grid.
Has anyone found a good way to do this?
Just modify the headerCellTemplate for the last column in your grid (see https://github.com/angular-ui/ng-grid/wiki/Templating).
Here is an example (note <img src="PLUS-ICON.png" /> in the second line):
var myHeaderCellTemplate = '<div class="ngHeaderSortColumn {{col.headerClass}}" ng-style="{\'cursor\': col.cursor}" ng-class="{ \'ngSorted\': !noSortVisible }">' +
'<div ng-click="col.sort($event)" ng-class="\'colt\' + col.index" class="ngHeaderText">{{col.displayName}} <img src="PLUS-ICON.png" /></div>' +
'<div class="ngSortButtonDown" ng-show="col.showSortButtonDown()"></div>' +
'<div class="ngSortButtonUp" ng-show="col.showSortButtonUp()"></div>' +
'<div class="ngSortPriority">{{col.sortPriority}}</div>' +
'<div ng-class="{ ngPinnedIcon: col.pinned, ngUnPinnedIcon: !col.pinned }" ng-click="togglePin(col)" ng-show="col.pinnable"></div>' +
'</div>' +
'<div ng-show="col.resizable" class="ngHeaderGrip" ng-click="col.gripClick($event)" ng-mousedown="col.gripOnMouseDown($event)"></div>';
$scope.gridOptions = {
data: self.myData,
columnDefs: [
{ field: 'firstField', displayName: 'First Column' },
{ field: 'secondField', displayName: 'Second Column' },
...
{ field: 'lastField', displayName: 'Last Column', headerCellTemplate: myHeaderCellTemplate }
]
};