I'm having trouble with focusing element programmatically.
I have a ul which looks like this :
<ul className="text-left">
{Object.keys(props.characters).map((char, i) => {
return (
<li key={props.characters[char].key}>
<button type="button" className={"btn align-middle bg_" + props.characters[char].character}>
<div className={"label text-left float-left " + getFontColorFromCharacter(props.characters[char].character)}>
<img alt="" className="char-img" src={"/images/characters/" + props.characters[char].character + "_xs.png"}/>
<input className="align-middle d-none" id={props.characters[char].key + "_input"} type="text" placeholder="Nom joueur" value={props.characters[char].player_name} onChange={e => props.changePlayerNameHandler(props.characters[char],e)} onBlur={e => toggleDNone(props.characters[char].key)} onKeyDown={e => tabToNext(e)}/>
<span className="align-middle" id={props.characters[char].key + "_span"} onClick={e => toggleDNone(props.characters[char].key)} > {props.characters[char].player_name}</span>
</div>
<div className={"actions " + getFontColorFromCharacter(props.characters[char].character)}>
<span className="action">
<FontAwesomeIcon icon="times-circle" title="Supprimer" onClick={() => props.removeCharacterHandler(props.characters[char].key)}/>
</span>
</div>
</button>
</li>
);
})}
</ul>
Javascript :
//Toggle d-none class on input & span for player name edition
function toggleDNone(key) {
document.getElementById(key + "_input").classList.toggle("d-none");
document.getElementById(key + "_span").classList.toggle("d-none");
if (!document.getElementById(key + "_input").classList.contains("d-none")) {
document.getElementById(key + "_input").focus();
}
}
//When the user hit tab key, navigate to next input
function tabToNext(event){
if(event.key === "Tab")
{
var allInput = document.querySelectorAll("[id$='_input']");
var indexOfCurrent = Array.from(allInput).indexOf(event.target);
var id;
if (indexOfCurrent + 1 === Array.from(allInput).length)
{
id = allInput[0].id;
}
else
{
id = allInput[indexOfCurrent + 1].id;
}
toggleDNone(allInput[indexOfCurrent].id.replace("_input", ""));
toggleDNone(id.replace("_input",""));
}
}
When the users click on the span, the input is displayed and the focus is working. When the users hit the tab key to get to the next input, the input is displayed but the focus is not working.
I tried setting the tabIndex to -1 as I saw on a post but it didn't work.
Any ideas?
Found the solution.
The issue was that the second toggleDNone call started before the first one finished.
I just added a setTimeOut of 100ms on the second call and it worked.
Thanks all
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>
I have the following data:
$scope.AcctHistList = "[{"AcctHistID":13,"AcctID":6,"TranAmount":444,"TranDSC":"IncomeBill","UserDSC":"423142341","TXID":"ec9a8fb7-9f76-4671-f7c7-75a77c2a7a04","Created_D":"2015-09-14","Created_T":"08:00","Created_DT":"2015-09-14 08:00","Created_YM":"2015-09","Created_W":"37","Created_Y":"2015","Created_w":"Mo","AcctCurrency":"AED"}
,{"AcctHistID":12,"AcctID":6,"TranAmount":444,"TranDSC":"IncomeBill","UserDSC":"undefined","TXID":"eaec26e6-4dc1-41a3-e987-d27843cefed8","Created_D":"2015-09-14","Created_T":"08:00","Created_DT":"2015-09-14 08:00","Created_YM":"2015-09","Created_W":"37","Created_Y":"2015","Created_w":"Mo","AcctCurrency":"AED"}
,{"AcctHistID":11,"AcctID":6,"TranAmount":444,"TranDSC":"IncomeBill","UserDSC":"undefined","TXID":"16a323b3-0f11-4a18-e753-e4f262ace2ca","Created_D":"2015-09-14","Created_T":"08:00","Created_DT":"2015-09-14 08:00","Created_YM":"2015-09","Created_W":"37","Created_Y":"2015","Created_w":"Mo","AcctCurrency":"AED"}
,{"AcctHistID":10,"AcctID":6,"TranAmount":44,"TranDSC":"IncomeBill","UserDSC":"423141234","TXID":"bc5b4a80-0322-4e04-9bb4-5a82973c99a7","Created_D":"2015-10-11","Created_T":"09:12","Created_DT":"2015-10-11 09:12","Created_YM":"2015-10","Created_W":"40","Created_Y":"2015","Created_w":"Su","AcctCurrency":"AED"}
,{"AcctHistID":9,"AcctID":6,"TranAmount":44,"TranDSC":"IncomeBill","UserDSC":"423141234","TXID":"e8ba0ec2-e007-4925-94af-7cc038937aa3","Created_D":"2015-10-11","Created_T":"09:12","Created_DT":"2015-10-11 09:12","Created_YM":"2015-10","Created_W":"40","Created_Y":"2015","Created_w":"Su","AcctCurrency":"AED"}
,{"AcctHistID":8,"AcctID":6,"TranAmount":44,"TranDSC":"IncomeBill","UserDSC":"423141234","TXID":"d516756f-afc6-454b-c7d1-db55c474397f","Created_D":"2015-10-11","Created_T":"09:12","Created_DT":"2015-10-11 09:12","Created_YM":"2015-10","Created_W":"40","Created_Y":"2015","Created_w":"Su","AcctCurrency":"AED"}
]"
in the view i iterate through these data and group it using the user input(Day,Month,Week,Year,...).
<div class="panel panel-info" ng-repeat="group in AcctHistList | groupBy:AcctHistGropuBy | toArray:true | orderBy:'-$key'">
<div class="panel-heading">
<strong data-i18n={{group.$key}}>{{group.$key}}</strong>
<span class="label pull-right" ng-model="SumAmount = SumTranAmount(group)">
<span class="badge">{{SumAmount.In}}</span>
<span class="badge">-{{SumAmount.Out}}</span>
<span class="badge">={{SumAmount.Total}}{{SumAmount.Currency}}</span>
</span>
</div>
<div class="panel-body">
<ul class="list-group" ng-repeat="item in group">
<li class="list-group-item">
<h4 class="list-group-item-heading" data-i18n={{item.TranDSC}}>
{{item.TranDSC}}
</h4>
<span class="badge">{{item.Created_DT}}</span>
<span class="badge">{{item.TranAmount}} {{item.AcctCurrency}}</span>
<p class="list-group-item-text">{{item.UserDSC}}</p>
</li>
</ul>
</div>
The main problem is that, i want to summarize each group (to calculate TotalIn, TotalOut, and In-Out), So i wrote the function SumTranAmount for this.
$scope.SumTranAmount = function (group) {
var Total = 0, In = 0, Out = 0;
for (var i = 0; i < group.length; i++) {
Total = Total + group[i].TranAmount
if (group[i].TranAmount >= 0) {
In = In + group[i].TranAmount;
}
else {
Out = Out - group[i].TranAmount;
}
}
//return (In + " " + Out + " = " + Total + " " + group[0].AcctCurrency);
return { In: In, Out: Out, Total: Total, Currency: group[0].AcctCurrency };
}
Problem, an exception occured ng-model="SumAmount = SumTranAmount(group)"
So, my question is, how can i assign the output of the function to a variable and use this variable in the current loop??
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