Angularjs issue with ng-click on mobile - javascript

i've got a big performance issue.
I'm in a ng-repeat block (and i'm using track by id to improve performances).
In this block i'm generating the following dom:
1)button1A button1B
2)button2A button2B
3)button3A button3B
4)button4A button4B
5)button5A button5B
6)button6A button6B
There are some ng-show and ng-disabled in that page, on a variable that is set by ng-click on those buttons.
Performances are very poor.
On mobile we are using ng-mobile and\or fastclick for 300ms delay removing, but it seems that it tooks a lot of time to "update variables and the dom" after clicking on a button.
How can i improve performances?
Thanks a lot!
Edit: here is some code:
<div class="row" ng-repeat="date in dateRanges track by date.value">
<div ng-show="!date.custom" class="col-xs-14 col-sm-15 date-filter no-rel">
<div class="button-container button-radio"><button data-ng-class="{'radiob disabled': getDate() != date,'radiob active': getDate() == date}" ng-click="setDate(date)"></button></div>
<div class="button-container button-text">
<button class="select-date" ng-click="setDate(date)">{{date.title}} {{date.noDetails ? '' : date.start | date:'dd/MM/yyyy'}} {{date.noDetails ? '' : '-'}} {{date.noDetails ? '' : date.end | date:'dd/MM/yyyy'}}</button>
</div>
</div>
<div ng-if="date.custom" class="col-xs-2 col-sm-1 date-filter">
<button data-ng-class="{'radiob disabled':getDate() != date,'radiob active':getDate() == date}" ng-click="setDate(date)"></button>
</div>
<div ng-if="date.custom" class="col-xs-14 col-sm-15 date-filter no-rel">
<div class="row" data-ng-class="{'has-error': hasErrorComune && criteriRicerca_DateRange.custom}">
</div>
<div class="col-md-16 mrg-t-10 text-center">
<button id="Undo" ng-click="Undo()" class="btn btn-esci mrg-r-10">Undo</button>
<button type="submit" id="dropdownMovimentiConferma" ng-click="Operation()" data-ng-disabled="criteriRicerca_DateRange.custom && (hasErrorComune || hasErrorStart || hasErrorEnd)" class="btn btn-primary">OK</button>
</div>

You're testing on real mobile (harware) or emulator?
If on real, check task manager and cpu utilization.

Related

Angular JS dynamically set tabindex attribute

I'm fairly new to Angular, and I'm working on a simple flashcard website. Here's my current relevant HTML:
<div id="flashcards" class="row">
<div class="flashcard col-sm-6 col-md-4 col-lg-3"
ng-repeat="card in cards">
<div class="flashcard-inside"
ng-class="{'flipped' : card.flipped}">
<div class="flashcard-btns">
<button ng-click="flip(card)" class="btn btn-secondary">
<i class="fas fa-sync-alt"></i>
</button>
<button ng-click="remove(card)" class="btn btn-danger">
<i class="fas fa-trash"></i>
</button>
</div>
<div class="flashcard-front">
<textarea ng-model="card.front"
class="form-control
flashcard-content"
ng-tabindex="{-1 : card.flipped}">
</textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back"
class="form-control flashcard-content"
tabindex="card.flipped ? 0 : -1">
</textarea>
</div>
</div>
</div>
</div>
I'm making a flashcard for each card in cards.
My remove and flip functions are fairly simple:
$scope.flip = (card) =>
card.flipped = !card.flipped;
$scope.remove = (card)=>
$scope.cards = $scope.cards.filter(obj=> obj.front!=card.front || obj.back!=card.back);
As you can see above, I've tried ng-tabindex="{-1 : card.flipped}" and I've tried tabindex="card.flipped ? 0 : -1" and several other combinations with no luck. I was hoping someone more experienced in Angular could point me in the right direction. It seems my problems would be solved if I could get a hold of the DOM element from the card variable in my flip scrips, and set its tabindex attribute with jQuery, however I can't seem to access the element for the textarea (which would be nice because I'd also like to focus it later).
There is no need to use ng-attr-tabindex, it can simply be done with interpolation:
<div class="flashcard-front">
<textarea ng-model="card.front" class="form-control flashcard-content"
tabindex="{{card.flipped ? -1 : 0}}"></textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back" class="form-control flashcard-content"
tabindex="{{!card.flipped ? -1 : 0}}"></textarea>
</div>
The problem with the code in the question is that the interpolation needs double curly brackets ({{ }}).
The ng-attr-* syntax is only necessary in exotic situations.
For more information, see
AngularJS Developer Guide - Interpolation
AngularJS Developer Guide - ngAttr for binding to arbitrary attributes
Credit to #Phix for the suggestion to use ng-attr.
The relevant part is ng-attr-tabindex="{{card.flipped ? -1 : 0}}" and the same but with !card.flipped instead of card.flipped.
My full code is:
<div class="flashcard-front">
<textarea ng-model="card.front" class="form-control flashcard-content"
ng-attr-tabindex="{{card.flipped ? -1 : 0}}"></textarea>
</div>
<div class="flashcard-back">
<textarea ng-model="card.back" class="form-control flashcard-content"
ng-attr-tabindex="{{!card.flipped ? -1 : 0}}"></textarea>
</div>
Angular Docs

How to enable only active tab and disable all other tabs by default in Angularjs?

I have four tabs as "Tab1, Tab2, Tab3, Tab4".
By default all tabs should be disabled and active tab should be enabled.
If I click on submit button in active tab then I should automatically navigate to next tab by enabling the next tab and setting it as active and disabling the previous tab.
<li class="myli" ng-repeat="tab in tabs track by $index" ng-class="{active:isSelected($index)}"><a href ng-click="displaySelectedtab(tab, $index)">{{tab}}</a></li>
<div class="panel-body newPanelBody" ng-if="displaytab1 && !displaytab2 && !displaytab3 && !displaytab4">
<form name="actForm" role="form" data-ng-init="resp()" ng-submit="save()" novalidate>
<h4>Tab1</h4>
<br>
<button class="btn save sbmt" type="submit" id="submit">SAVE & CONTINUE</button>
</form>
</div>
<div class="panel-body newPanelBody" ng-if="displaytab2 && !displaytab1 && !displaytab3 && !displaytab4">
<form name="actForm" role="form" data-ng-init="resp()" ng-submit="save()" novalidate>
<h4>Tab2</h4>
<br>
<button class="btn save sbmt" type="submit" id="submit">SAVE & CONTINUE</button>
</form>
</div>
<div class="panel-body newPanelBody" ng-if="displaytab3 && !displaytab1 && !displaytab2 && !displaytab4">
<form name="actForm" role="form" data-ng-init="resp()" ng-submit="save()" novalidate>
<h4>Tab3</h4>
<br>
<button class="btn save sbmt" type="submit" id="submit">SAVE & CONTINUE</button>
</form>
</div>
<div class="panel-body newPanelBody" ng-if="displaytab4 && !displaytab1 && !displaytab2 && !displaytab3">
<form name="actForm" role="form" data-ng-init="resp()" ng-submit="save()" novalidate>
<h4>Tab4</h4>
<br>
<button class="btn save sbmt" type="submit" id="submit">SAVE & CONTINUE</button>
</form>
</div>
First off, your use of .panel-body and .btn has me assuming you use bootstrap, so have a look here: https://angular-ui.github.io/bootstrap/
There's a tabs component on that page made for use with angular and bootstrap.
Secondly, instead of using booleans to control which tab should show, it is much easier to use an integer to control the currently selected tab. That will also allow you to work with a variable amount of tabs.
<li class="myli" ng-repeat="tab in tabs track by $index" ng-class="{active: selectedIndex == $index}"><a href ng-click="displaySelectedtab(tab, $index)">{{tab}}</a></li>
<div class="panel-body newPanelBody" ng-repeat="tab in tabs track by $index" ng-if="selectedIndex == $index">
<h4>Tab {{$index + 1}}</h4>
<!-- If you need different content for each tab you can include an angular template as well -->
<ng-include src="'path/to/template.tpl.html'"></ng-include>
</div>
It will require you to think about how to store your tab content a little. The easiest way is probably to use templates. In that case you could devise a strategy where your tabs array contains objects that contain both the tab title as well as the content template url, like so:
$scope.tabs = [
{
"title": "Tab 1",
"templateUrl": "path/to/template.tpl.html"
}
];
Your ng-include would then look like like:
<ng-include src="tab.templateUrl"></ng-include>
Making your form's submit action go to a different tab then becomes a simple matter of changing the $scope.selectedIndex variable to the index of the tab you want opened.
Change ng-if="displaytab1 && !displaytab2 && !displaytab3 && !displaytab4" to ng-if="$index==selected"
In your button submit function add index like this ng-submit="save($index)"
In controller method:
`$scope.selected=1; $scope.save= function(index){selected=index+1;}`

Ui-router, ng-repeat and ui state

I m developping an application in which I need to redirect the current user to a different state after a ressource creation.
Actually, I have a list of demands, and I need to show or create a quotation based on that demand.
Here's the view code :
<div class="landing-diags">
<div class="current-projects">
<div class="row project-summary" ng-repeat="demand in landingdiag.demandsList">
<div class="col-md-2 project-block first-block {{project.projectType}}">
<p class="project-strong">{{demand.user.firstname}} {{demand.user.lastname}}</p>
</div>
<div class="col-md-2 project-block">
<p class="project-strong">{{demand.creationDate | date:"dd/MM/yyyy"}}</p>
</div>
<div class="col-md-4">
</div>
<div class="col-md-2">
<div ng-if="!demand.quotation">
<button ng-click="landingdiag.createQuotation(demand)" class="btn btn-primary pull-right bar-btn">Create</button>
</div>
<div ng-if="demand.quotation">
<button ui-sref="app.state.concerned({id: demand._id})" class="btn btn-primary pull-right bar-btn">Show</button>
</div>
</div>
</div>
</div>
</div>
And here's the controller methods implied :
createQuotation (demand) {
this.DemandsService.createQuotation(demand).$promise.then((response) => {
this.redirectToQuote(demand);
});
}
redirectToQuote (demand) {
this.$state.transitionTo('app.state.concerned', {id: demand._id});
}
Problem
My problem is that I m never redirected when creating a quotation. If I console log the redirectToQuote method, I pass inside of it. So it seems that my problem is on the $state.go call.
However, when I try to redirect directly using the redirectToQuote method inside of my view on the "show" button like following :
<div ng-if="demand.quotation">
<button ng-click="landingdiag.redirectToQuote(demand)" class="btn btn-primary pull-right bar-btn">Accéder au devis</button>
</div>
I m well redirected to the concerned state
I am concerned about the this.redirectToQuote within createQuotation() which is called by then() as a callback. So the this object will definitely not be your controller.
Look at the first code snippet from todd: https://toddmotto.com/resolve-promises-in-angular-routes/
He is using bind.
You can also look at https://github.com/getify/You-Dont-Know-JS/tree/master/this%20%26%20object%20prototypes from awesome Kyle Simpson
or shorter from myself: http://blog.monkey-development.com/javascript/java/2015/12/18/javascript-this.html

kibana 4 search place out of iframe

kibana 4 search code looks like following
<form name="queryInput" class="fill inline-form ng-valid ng-dirty" ng-submit="filterResults()">
<div class="typeahead ng-isolate-scope" kbn-typeahead="dashboard">
<div class="input-group" ng-class="queryInput.$invalid ? 'has-error' : ''">
<input input-focus="" placeholder="Filter..." class="form-control ng-isolate-scope ng-valid ng-valid-query-input ng-dirty" ng-model="state.query" kbn-typeahead-input="" validate-query="" type="text"><i style="display: none;" class="fa fa-ban input-error"></i>
<button type="submit" class="btn btn-default" ng-disabled="queryInput.$invalid">
<span class="fa fa-search"></span>
</button>
</div>
<div ng-show="typeahead.isVisible()" ng-mouseenter="typeahead.setMouseover(true);" ng-mouseleave="typeahead.setMouseover(false);" class="typeahead-items ng-hide">
<!-- ngRepeat: item in typeahead.getItems() --><div ng-repeat="item in typeahead.getItems()" ng-class="{active: item === typeahead.active}" ng-click="typeahead.selectItem(item, $event);" ng-mouseenter="typeahead.activateItem(item);" class="typeahead-item ng-binding ng-scope">
*
</div><!-- end ngRepeat: item in typeahead.getItems() -->
</div>
</div>
</form>
I have kibana dashboard in iframe in my page.
I want to have following code out of that iframe and want it to have functionality same as above code.
<input id="logsSearch" name="logsSearch" type="text"/>
to achieve this i have tried following options.
'keypress #logsSearch' : function(e){
if (e.keyCode == 13) {
var strSearch = $("#logsSearch").val();
$("#kibana").contents().find('form[name=queryInput]').find('input').val(strSearch);
var e = jQuery.Event("keydown");
e.which = 13; // # Some key code value
$("#kibana").contents().find('form[name=queryInput]').find('input').trigger(e);
$("#kibana").contents().find('form[name=queryInput]').find('button').click();
}
}
but it doesn't work. it calls /kibana4/elasticsearch/_msearch
but it doesn't call __kibanaQueryValidator.
in other solution i tried to trigger keyup, keydown events as well. but it also doesn't work
I don't know how should I do it. Any ideas or pointers or guidance to solve this problem will be a great help.

Add class based on a condiiton in angularjs?

I want to add classes based on a condition in angularJs, I am following below method and it is working fine, Is there any best practice?
<div ng-if="client.status != 2" class="list-primary">
<span class="pull-right amount">{{client.receivables|number:2}}</span>
<div class="name">{{client.name}}</div>
</div>
<div ng-if="client.status == 2" class="list-primary text-muted">
<span class="pull-right amount">{{client.receivables|number:2}}</span>
<div class="name">{{client.name}}</div>
</div>
You can use ng-class for this:
<!-- apply class 'text-muted' when client.status == 2 -->
<div class="list-primary" ng-class="{ 'text-muted': client.status == 2 }">
<span class="pull-right amount">{{client.receivables|number:2}}</span>
<div class="name">{{client.name}}</div>
</div>
In angular 1.1.5+ you can use javascript ternary operator.
<div ng-class="client.status == 2 ? 'text-muted' : 'other-class'" class="list-primary ">
<span class="pull-right amount">{{client.receivables|number:2}}</span>
<div class="name">{{client.name}}</div>
</div>
I hope this helps
Have a look at ng-class which is provided in AngularJS. Documentation here:
https://docs.angularjs.org/api/ng/directive/ngClass

Categories

Resources