Javascript / Angular - Function runs too fast - javascript

This is my simple filter table.
<tr class="text-center" ng-repeat="ticket in filteredTickets = (vm.tickets | orderBy : vm.propertyName : vm.reverse | filter : vm.search | limitTo:vm.itemsPerPage:vm.itemsPerPage*(vm.currentPage-1))">
And a search input
<input class="form-control w25 pull-right" ng-change="vm.searchChanged()" type="text" ng-model="vm.search" placeholder="Search..." />
And I created a fake td to get the value of filteredTickets.length (because I cannot get the value of this in the scope, if you know a way tell me)
<td class="hidden" id="filteredTicketLength">{{filteredTickets.length}}</td>
basically the innerText of this will have the length of the tickets after the filtering.
Now here comes the problem. When I type something on the input search the totalItems does not update until I write/delete another character. Basically, the correct message is displayed after I write/delete another letter
<span class="pull-left">Showing {{filteredTickets.length}} tickets of {{vm.totalItems}} found.</span>
vm.searchChanged = function () {
var filteredTickets = document.getElementById('filteredTicketLength');
console.log(filteredTickets);
if(filteredTickets !== null)
vm.filteredTicketLength = filteredTickets.innerText;
vm.totalItems = vm.filteredTicketLength;
};
How can I write that message showing x items of x found after the filtering? It's like the searchChanged function is being run before the filteredTicketLength is updated.

Related

filter by field in array - angularJS [duplicate]

This question already has answers here:
ng-repeat :filter by single field
(12 answers)
Closed 2 years ago.
im trying to display some rows in array, and filter them by some field.
for example:
i have the array "fieldindex",
the fields in the array are:
fieldname
pageindex
and the array content is:
[{fieldname:'firstname',pageindex:'1'},{fieldname:'lastname',pageindex:'2'}]
and i have this code:
<input type="text" id="pageindex" />
<span class="fieldindex" ng-repeat="x in fieldsonpdf">
{{x.fieldname}}</span>
and i want the span to display only the fields that the 'pageindex' of them is equel to the input value
for example:
if the value of the input is 1, the span display "firstname",
and if the value of the input is 2, the span display "lastname".
thanks for the helpers.
You could add ng-model to the input like,
<input type="text" id="pageindex" ng-model="pageindex"/>
Then you can use the pageindex as filter to ng-repeat like,
<span class="fieldindex" ng-repeat="x in fieldsonpdf | filter:pageindex">
Working Snippet:
angular.module('test', [])
.controller('test', ['$scope', function ($scope) {
$scope.fieldsonpdf =
[
{fieldname:'firstname',pageindex:'1'},
{fieldname:'lastname',pageindex:'2'}
]
$scope.pageindex = '1';
}]);
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
<div ng-app="test" ng-controller="test">
<input type="text" id="pageindex" ng-model="pageindex"/>
<span class="fieldindex" ng-repeat="x in fieldsonpdf | filter:pageindex">
{{x.fieldname}}</span>
</div>
Let's consider that you have already the value from your input. You can use the function filter to bring all objects that match with your criteria or just find to get the first match, the best way is to add this code into your controller and the access from the template, using your example:
const list = [{fieldname:'firstname',pageindex:'1'},{fieldname:'lastname',pageindex:'2'}];
const getField = (value) => { return list.filter(item => +item.pageindex === value)}
then you just call from your template:
getField(2)
Be aware that I force the property item.pageindex to be a number using +.

How to programmatically add ng-models for later use

I'm listing out several inputs based on another input like this like this:
<span ng-repeat="_ in ((_ = []) && (_.length=assistant.bends || 0) && _) track by $index" class="bendsInput">
#{{$index+1}} <br>
<input type="text" placeholder="ft" ng-change="calculateLength()"> ft
<input type="text" placeholder="in" ng-change="calculateLength()"> in
</span>
NOTE: the ng-repeat section might be really confusing, basically it's an ng-repeat between 0 and whatever the value of assistant.bends is the $index variable is the current index of the loop.
I need to add an ng-model to both the ft and in textboxes so that I can access them (the value of assistant.bends is dynamic and not fixed.
I'm thinking something like this: ng-model="assistant.bend{{$index}}.ft"
So that the final result will be ng-model="assistant.bend1.ft"
Then in my javascript I can loop through it and add all the feet and inches together.
var totalFeet = 0;
for(i=0; i<assistant.bends; i++) {
totalFeet += assistant.bend+i+.ft;
}
I'm not sure on the correct syntax for something like this.
Some advice on dynamic models: If you need a complex structure, use one, rather than repeating for a number of times based on a number
Ex:
// your JS needs a more complex structure
$scope.assistant = {
// bends: 5 // not great, you can use this value to generate objects such as below
bends: [ {ft: '', in: ''}, {ft: '', in: ''}, {ft: '', in: ''} ]
}
// if bends value changes, update the array
HTML
<span ng-repeat="bend in assistant.bends track by $index" class="bendsInput">
#{{$index+1}} <br>
<input type="text" placeholder="ft" ng-model="bend.ft" ng-change="calculateLength()"> ft
<input type="text" placeholder="in" ng-model="bend.in" ng-change="calculateLength()"> in
</span>
<div class='sum' ng-bind="totalFeet"></div> <!-- this will update each time your function for summation runs -->
This way, your ng-model gets assigned to whatever attribute is on the structure. You can even create new keys dynamically, though I don't recommend it for the sake of consistency.
Then your loop can be about the same:
$scope.totalFeet = 0, totalInches = 0;
for(i=0; i<$scope.assistant.bends.length; i++) {
$scope.totalFeet += assistant.bends[i].ft;
totalInches += assistant.bends[i].in;
}
$scope.totalFeet += (totalInches / 12);

How to make some fields hidden depending on value of other field AngularJS, Razor, C#

I'm new in angularjs and razor. so please help me. I have such code
<div ng-app="">
<p>Input page number to filter: <input type="text" ng-model="pageNumber"></p>
<div class="table-bordered">
#{
string pageNo = "0";
}
#foreach (var item in Model.sol)
{
if (pageNo != item.TaskPageNo.ToString())
{
pageNo = item.TaskPageNo.ToString();
<div id="PAGENUMBER" class="text-success" ng-show="**CONDITION**"><abbr title="select something">Page - #pageNo</abbr></div>
}
var pt = pat + item.Task_ID;
#item.TaskNo
}
</div>
</div>
I don't know how to set the CONDITION value using AngularJS...
I want to type into 'PageNumber' input box some value and filter pages, so the condition must be something like this
if (PAGENUMBER.value.indexOf(pageNumber.value)>-1) { show this page
number } else { hide it }
The ID PAGENUMBER is only used here in question not in real code
How can I do this ? pleease help :)
You need to get your data using angular and then use ng-repeat over that data. Then you can add a filter on the ng-repeat based of your input ng-repeat="item in items | filter: {pageNumber: pageNumber}":
if you set PAGENUMBER like #pageNo
for your checking you can use simple condition like
<div id="#pageNo" class="text-success" ng-show="'#pageNo'.indexOf(pageNumber) > -1"><abbr title="select something">Page - #pageNo</abbr></div>

Dynamically add filter options in angularjs

Hello I have a small project in which I want to have perform search from multiple dynamically added text fields.
This is how I add the search fields:
<div class="form-group" ng-repeat="choice in choices">
<button ng-show="showAddChoice(choice)" ng-click="addNewChoice()">Add another choice</button>
<input type="text" ng-model="choice.name" name="" placeholder="Search criteria">
</div>
And later I have a table with ng-repeat and here is that part:
<tr ng-repeat="todo in todos | filter: {filter from all fields}">
.......
</tr>
What I want to do is to have the contents filtered with all dynamically added search fields.
You'll have to create your own filter to handle that. I've gone ahead and gotten you started.
$scope.myFilter = function(input){
for(var key in input){
for(var x = 0; x < $scope.choices.length; x++){
if(input[key] == $scope.choices[x].name){
return true;
}
}
}
return false;
}
Here is the jsFiddle of the output: http://jsfiddle.net/wsPrv/
Rather than using the filter, do the filtering in the controller yourself. Here is the updated fiddle with the solution. In the first textbox, replace choice1 with "some" and you will see the todo with text "Some stuff" being displayed.
See the relevant part below. For details, see the fiddle.
$scope.$watch('choices', function(newValue) {
$scope.DisplayedTodos = [];
// Filter items here and push to DisplayedTodos. Use DisplayedTodos to display todos
}, true);

Filtering the Data in AngularJs

I am creating a project in AngularJs. I have problem while filtering data. Data is coming from API in the form of 0 and 1. I am showing the data in conditional form like:
ng-if = 0 ; Internal
ng-if = 1; External
My problem is that the data is filtered when I type 0 and 1 in search box, but I want data should be filtered when I type internal and external in search box.
Here is my code:
<input type="search" ng-model="customersFlowsList.linkStatus" class="flow_filter_searchbox">
<li ng-repeat="customersFlowsList in customersFlows | filter:{linkStatus:customersFlowsList.linkStatus} | unique:'linkStatus'">
<div class="check_box">
<input type="checkbox" id="checkbox1" name="checkbox2" ng-model="filterLink[customersFlowsList.linkStatus]">
<label for="checkbox1"><span for="checkbox1">{{customersFlowsList.linkStatus | contractStatusName}}</span></label>
</div>
</li>
You can write a simple custom filter function to do this. Some sample code might look like this:
$scope.filterFn = function(item){
if($scope.search.Mode == "external"){
return item.Mode == 1
}
else if ($scope.search.Mode == "internal"){
return item.Mode == 0;
}
else return false;
};
Then replace your filter in your ng-repeat with the new filter function
ng-repeat="item in items | filter: filterFn"
Also, another option could be to replace the property on the data when you receive it from 0 and 1 to internal or external, then your original search would work.

Categories