Optimize / Speed Up AngularJS HTML rendering - Performance Issue - javascript

This is probably not the first question on this topic, but since it took me hours finding out I couldn't find a good solution, I still want to ask you guys here.
I would like to optimize following code, because the page needs a few seconds to load right now. If I take that part out of the page (it is only one part of it), the page loads in max 1 second.
FYI: I only have 4 routes for the student that I test my application with.
<tr ng-repeat="route in student.itin">
<td>
<select ng-options="airline._id as airline.code for airline in ::airlines | orderBy: 'code'" ng-model="route.airline" class="form-control"/>
</td>
<td>
<input type="text" ng-model="route.flight_number" maxlength="4" size="4" class="form-control"/>
</td>
<td>
<input type="text" ng-model="route.class" maxlength="1" size="1" class="form-control"/>
</td>
<td>
<select ng-options="airport._id as airport.code for airport in ::airports | orderBy: 'code'" ng-model="route.departure.airport" class="form-control"/>
</td>
<td>
<div class="form-group has-feedback" ng-class="{'has-error': route.arrival.date < route.departure.date}">
<input type="text" class="form-control" is-open="datepickers['departure_date' + $index]" max-date="route.arrival.date" timepicker-options="timepicker_options" ng-focus="open($event, 'departure_date'+$index)" datetime-picker="{{ ::datetimepicker_format }}" ng-model="route.departure.date" />
<span ng-if="route.arrival.date < route.departure.date" tooltip-placement="right" tooltip="Arrival Date cannot be before Departure Date" tooltip-trigger="mouseenter" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
</div>
</td>
<td>
<select ng-options="airport._id as airport.code for airport in ::airports | orderBy: 'code'" ng-model="route.arrival.airport" class="form-control"/>
</td>
<td>
<div class="form-group has-feedback" ng-class="{'has-error': route.arrival.date < route.departure.date}">
<input type="text" class="form-control" is-open="datepickers['arrival_date' + $index]" min-date="route.departure.date" timepicker-options="timepicker_options" ng-focus="open($event, 'arrival_date'+$index)" datetime-picker="{{ ::datetimepicker_format }}" ng-model="route.arrival.date" />
<span ng-if="route.arrival.date < route.departure.date" tooltip-placement="right" tooltip="Arrival Date cannot be before Departure Date" tooltip-trigger="mouseenter" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
</div>
</td>
<td>
<input type="text" ng-model="route.filekey" class="form-control"/>
</td>
<td class="text-right">
<a class="btn btn-danger" ng-click="deleteRoute($index)" tooltip-placement="top" tooltip="Delete route" tooltip-trigger="mouseenter">
<i class="fa fa-trash-o"></i>
</a>
</td>
</tr>
What I have learned from my research is pretty much that I shouldn't use too much ng-repeat, try to minimize data-binding and filters. But after applying everything I have learned, I came up with the code above and don't know how to go on optimizing, since this is not enough.
Thank you

add track by to your ng-repeat
remove filters where it is possible
use one time binding with ::
Or switch to ReactJS.

Try to improve ng-repeat if your AngularJS is above 1.4.1: https://docs.angularjs.org/api/ng/directive/ngRepeat#tracking-and-duplicates

You can try to use sly-repeat directive instead ng-repeat: http://blog.scalyr.com/2013/10/angularjs-1200ms-to-35ms/

Related

Store the total and have it cumulate on submit

How do you store the total and have it cumulate each time a user hits submit?
For instance, Cumulative Total = # would add up the total of column 3 each time a user submits their info.
<body ng-app="Test">
<section style="margin-top:80px">
<h3>Plastic Calculator Form</h3>
<div ng-controller="TestController as test" >
<p>To date, <strong><u># of people who pledged</u></strong> Earthlings have pledged to reduce their single-use plastic waste from <strong><u>{{ test.approve | sumByColumn: 'amount' }}</u></strong> Items per year to <strong><u>{{(test.approve | sumByColumn: 'amount') - (test.approve | sumByColumn4: 'reducedTotal')}}</u></strong>. That's a reduction of <strong><u>{{ test.approve | sumByColumn4: 'reducedTotal' }}</u></strong> per year! Do your part. Make a pledge!</p>
<table class="table">
<tr>
<th>Single-Use Plastic Items</th>
<th>Enter the Number You Use Per Week</th>
<th>The Number You Use Per Year is:</th>
<th>How Many Less Can You Use Per Week?</th>
<th>Your Reduced Usage Per Year Would Be:</th>
</tr>
<tr ng-repeat="x in test.approve">
<td> {{ x.name }} </td>
<td> <input class="qty form-control" type="number" ng-model="x.number" ng-change="sumByColumn3()" min="0" restrict-to="[0-9]"/> </td>
<td> {{ x.number*x.amount }} </td>
<td> <input class="qty form-control" type="number" ng-model="x.reducedAmount" ng-change="sumByColumn2()" min="0" restrict-to="[0-9]"/> </td>
<td> {{ x.reducedAmount*x.reducedTotal }} </td>
</tr>
<tr>
<td>TOTALS</td>
<td>{{ test.approve | sumByColumn3: 'number' }}</td>
<td>{{ test.approve | sumByColumn: 'amount' }}</td>
<td>{{ test.approve | sumByColumn2: 'reducedAmount' }}</td>
<td>{{ test.approve | sumByColumn4: 'reducedTotal' }}</td>
</tr>
<tr>
<td colspan="2">Total difference = {{(test.approve | sumByColumn: 'amount') - (test.approve | sumByColumn4: 'reducedTotal')}}</td>
<td colspan="3">
<strong>Cumulative Total = #</strong>
</td>
</tr>
</table>
<form>
<div class="col-sm-4">
<div class="form-group">
<label for="full-name">Name</label>
<input type="text" class="form-control" id="full-name" placeholder="Enter Full Name">
</div>
</div>
<div class="col-sm-4">
<div class="form-group">
<label for="email-address">Email</label>
<input type="email" class="form-control" id="email-address" aria-describedby="emailHelp" placeholder="Enter email">
</div>
</div>
<div class="col-sm-4">
<button type="submit" class="btn btn-primary" style="margin-top:25px">Submit</button>
</div>
</form>
</div>
</section>
</body>
Link to Pen
I am not really sure if its best to do with window.localStorage or sessionStorage or perhaps do it with PHP. I'm experimenting with this now.
Your help will be golden.
I am not really sure if its best to do with window.localStorage or
sessionStorage or perhaps do it with PHP. I'm experimenting with this
now.
Its simple to figure this out. Here is how:
1.) Have these numbers (summation) somehow got anything to do with your backend data? Do you need some kind of server code or functionalities to do this? if yes: use php.
2.) If 1 was false for you, do you want your users to be able to get the numbers or summation back again when they come back again? do you want it to be persistent? then use: localStorage
3.) If 2 was false, use sessionStorage. it is not persistent and is cleared out as soon as the current session is terminated. ie: user closes the tab or browser.
Now if you need some help with code, then modify your question to include those details or open a new question or simply post a comment on this answer of mine. I would try my best to help you out. Happy Coding!

Angular JS ng-click does not work on search icon

Can someone please lead me into the right direction regarding my search icon? I need to make my search icon clickable within the input field to display results.
Please see the following code listed below.
<div class="search-input">
<div class="inner-addon right-addon">
<i class="glyphicon glyphicon-search"></i> <input
placeholder="{{'SEARCH_HELP' | translate}}"
type="text" class="input-sm form-control"
ng-model="searchLocation" ng-enter="runUserSearch()" />
</div>
</div>
Use ng-click instead of ng-enter
<div class="search-input">
<div class="inner-addon right-addon">
<i class="glyphicon glyphicon-search"></i> <input
placeholder="{{'SEARCH_HELP' | translate}}"
type="text" class="input-sm form-control"
ng-model="searchLocation" ng-click="runUserSearch()" />
</div>
</div>

angularJS update inline script with model

I need to update datetimepicker[i] script inside ng-repeat but I do not know how to do that.
<div class='input-group date' id='datetimepicker{{$index+1}}'>
work successfully and made list of
<div class='input-group date' id='datetimepicker1'>
<div class='input-group date' id='datetimepicker2'>
but problem is script not update from model data
$('#datetimepicker{{$index+1}}').datetimepicker();
result is
$('#datetimepicker{{$index+1}}').datetimepicker();
I want to '#datetimepicker{{$index+1}}' change to'#datetimepicker1'
<tr data-ng-repeat="row in game.result">
<td>{{$index+1}}</td>
<td ng-bind="row.host"></td>
#*<td>
<input class="form-control text-center" data-ng-model="row.dateStart" />
</td>*#
<td ng-controller="DatepickerDemoCtrl">
<div class="input-group w-360">
<div class='input-group date' id='datetimepicker{{$index+1}}'>
<input data-format="yyyy/MM/dd hh:mm:ss" ng-model="row.dateStart" type='text' class="form-control" ng-required="true" />
<span class="input-group-addon">
<span class="fa fa-calendar"></span>
</span>
</div>
<script type="text/javascript">
$(function () {
$('#datetimepicker{{$index+1}}').datetimepicker();
});
</script>
</div>
</td>
<td>
<select ng-model="row.gameState"
ng-options="c.Value as c.Text for c in game.states" class="form-control" required></select>
</td>
<td>
<input class="form-control text-center" data-ng-model="row.hostGoals" type="number" required />
</td>
<td>
<input class="form-control text-center" data-ng-model="row.guestGoals" type="number" required />
</td>
<td ng-bind="row.guest"></td>
</tr>
Update
I move my code inside controller and make html in controller
Controller - MVC
onlineResult.dateHtml = #"<script type=""text/javascript"">$(function () {$('#datetimepicker"+(i + 1).ToString()+ "').datetimepicker({format: 'YYYY/MM/DD HH:mm:ss'});});</script>";
and update view to
<p compile data-ng-bind-html="to_trusted(row.dateHtml)"></p>
My new problem is model bind in Get but not changed in Post.
When i submit form my Get data sent to controller not changed data
I used angularjs directive datetimepicker
https://material.angularjs.org/latest/demo/datepicker

ng-form with $setPristine()

<tr ng-form="fbForm_{{$index}}">
<td><center><p ng-hide="fb.editMode">{{fb.clientId}}</p>
<input type="text" class="form-control" name="clientId" ng-show="fb.editMode" required
ng-model="fb.clientId"/></center>
<span ng-show="fbForm_{{$index}}.clientId.$dirty && fbForm_{{$index}}.clientId.$error.required">Client Id is required.</span>
</td>
<td><center><p ng-hide="fb.editMode">{{fb.clientSecret}}</p>
<input type="text" class="form-control" name="clientSecret" ng-show="fb.editMode" required
ng-model="fb.clientSecret"/></center>
<span ng-show="fbForm_{{$index}}.clientSecret.$dirty && fbForm_{{$index}}.clientSecret.$error.required">Client secret is required.</span>
</td>
<td style="width:10%">
<p ng-hide="fb.editMode"><a ng-click="toggleEdit()" href="javascript:;">Edit</a> | <a ng-click="deletefacebook()" href="javascript:;">Delete</a></p>
<p ng-show="fb.editMode"><a class="btn btn-primary simple_button" ng-disabled="fbForm_{{$index}}.$pristine || fbForm_{{$index}}.$invalid" data-ng-click="save($index); fbForm_{{$index}}.$setPristine()" href="javascript:;">Save</a> | <a class="btn btn-primary simple_button" ng-click="cancel($index,fb.fbConfigId)" href="javascript:;">Cancel</a></p>
</td>
</tr>
http://plnkr.co/edit/LnnJQj1WwQaxLjlIWXq2?p=preview
for ng-disabled I am able to use {{$index}}
Getting syntax error in pristine function form name.
ngDisabled and ngClick directives expect expressions, so it should be something like this:
ng-disabled="this['fbForm_' + $index].$pristine || this['fbForm_' + $index].$invalid"
ng-click="save($index); this['fbForm_' + $index].$setPristine()"

jquery how to detect current input id

i have a table that generated from yii2, i want to make a tabular input but before sending submit, there are a client validation to the input field. Consider i dont know the input id, because it is generated by yii2. Here's the code snippet of first row
<tr class="kv-tabform-row" data-key="4">
<td class="kv-align-center kv-align-middle">1</td>
<td class="kv-grid-hide kv-align-top">
<div class="form-group field-kegbulan-4-id">
<input type="hidden" id="kegbulan-4-id" class="form-control" name="KegBulan[4][id]" value="4">
<div class="help-block"></div>
</div>
</td>
<td class="kv-grid-hide kv-align-top">
<div class="form-group field-kegbulan-4-id_keg_ta_uk required">
<input type="hidden" id="kegbulan-4-id_keg_ta_uk" class="form-control" name="KegBulan[4][id_keg_ta_uk]" value="6">
<div class="help-block"></div>
</div>
</td>
<td class="kv-align-middle" style="width:300px;">Pengadaan Barang Kuasi, Buku Uji, Plat Uji dan Stiker Uji</td>
<td class="kv-align-middle">
<input type="text" id="kegbulan-4-anggaran" class="anggaran" name="KegBulan-[4][anggaran]" value="300,000,000" disabled="disabled" style="width:100px;"></td>
<td class="kv-align-top">
<div class="form-group field-kegbulan-4-sp2d required">
<input type="text" id="kegbulan-4-sp2d" class="form-control sp2d" name="KegBulan[4][sp2d]" value="680000" onchange="tesbos()">
<div class="help-block"></div>
</div>
</td>
<td class="kv-align-top" style="width:70px;">
<div class="form-group field-kegbulan-4-persen_sp2d required">
<input type="text" id="kegbulan-4-persen_sp2d" class="form-control" name="KegBulan[4][persen_sp2d]" value="2">
<div class="help-block"></div>
</div>
</td>
<td class="kv-align-top">
<div class="form-group field-kegbulan-4-spj required">
<input type="text" id="kegbulan-4-spj" class="form-control" name="KegBulan[4][spj]" value="680000">
<div class="help-block"></div>
</div>
</td>
<td class="kv-align-top" style="width:70px;">
<div class="form-group field-kegbulan-4-persen_spj required">
<input type="text" id="kegbulan-4-persen_spj" class="form-control" name="KegBulan[4][persen_spj]" value="2">
<div class="help-block"></div>
</div>
</td>
<td class="kv-align-top" style="width:70px;">
<div class="form-group field-kegbulan-4-target required">
<input type="text" id="kegbulan-4-target" class="form-control" name="KegBulan[4][target]" value="0">
<div class="help-block"></div>
</div>
</td>
<td class="kv-align-top" style="width:70px;">
<div class="form-group field-kegbulan-4-pfisik required">
<input type="text" id="kegbulan-4-pfisik" class="form-control" name="KegBulan[4][pfisik]" value="10">
<div class="help-block"></div>
</div>
</td>
<td class="skip-export kv-align-center kv-align-middle" style="width:60px;"><a href="/yii2/yii-application/frontend/web/keg-bulan/view?id=4" title="View" data-pjax="0">
<span class="glyphicon glyphicon-eye-open"></span></a> <a href="/yii2/yii-application/frontend/web/keg-bulan/update?id=4" title="Update" data-pjax="0" style="display:none;">
<span class="glyphicon glyphicon-pencil"></span></a> <a href="/yii2/yii-application/frontend/web/keg-bulan/delete?id=4" title="Delete" data-confirm="Are you sure to delete this item?" data-method="post" data-pjax="0">
<span class="glyphicon glyphicon-trash"></span></a></td>
<td class="skip-export kv-align-center kv-align-middle kv-row-select" style="width:50px;">
<input type="checkbox" name="selection[]" value="4"></td>
</tr>
screenshoot : http://www.imagebam.com/image/569de2398154258
the input sp2d will check input anggaran and do some validation if (sp2d > anggaran) then "sp2d exceed anggaran limit"
Here the initial javascript function to check that function is triggered via onchange
function tesbos(){
var sp2d = $(".sp2d").attr("id");
console.log(sp2d);
}
when i go to row no 2 in sp2d input, still when i check my console log, it still print the sp2d input id of row #1, how to get my input id automatically/dynamically when i go to any row? any help would be appreciated
Assuming you can change the markup, you need to pass the element refernce to the click handler
<input type="text" id="kegbulan-4-sp2d" class="form-control sp2d" name="KegBulan[4][sp2d]" value="680000" onchange="tesbos(this)">
then
function tesbos(el) {
alert(el.id)
}
But I would recommend using jQuery event handlers instead of inlined one, so remove onchange="" from the markup
<input type="text" id="kegbulan-4-sp2d" class="form-control sp2d" name="KegBulan[4][sp2d]" value="680000">
then
jQuery(function($){
$(".sp2d").change(function(){
alert(this.id)
})
})
If I understand correctly, each row of your table includes :
an anggaran (budget) field [fixed value]
a sp2d (spend to date) field [user entered].
And you want to perform a check, on change of every sp2d (spend to date) value against its corresponding anggaran (budget) value.
For this, you do not need to know either of the the fields' IDs. Simply find the anggaran field relative to whichever sp2d field triggers the change event.
First, delete onchange="tesbos()" from the HTML.
Then paste this code between <script></script> tags in your document's HEAD (or in a .js file if your code is organised that way).
jQuery(function($) {
$("#containerID").on('change', ".sp2d", tesbos); // where containerID is the ID of eg. a DIV in which the YII table sits
function tesbos() {
var sp2d_value = $(this).val();
var anggaran_value = $(this).closest("tr").find(".anggaran").val();//find the anggaran field in the same row, and grab its value.
console.log(anggaran_value, sp2d_value);
if(sp2d_value > anggaran_value) {
//anggaran is exceeded
...
} else {
//anggaran is not exceeded
...
}
}
});

Categories