Why ng-if is not working inside ng-repeat - javascript

I cannot properly use my ng-if inside an ng-repeat. I've updated my AngularJS to the newest version (09/27/2014) and I still can not get it to work right. I have code that works fine outside of the ng-repeat and I also have code that works inside ng-repeat fine when I ng-if="vm.detail == false". However ng-if="vm.detail == true" does NOT work. I even have printed the value of vm.detail to the console and it's correct, as it should be. But, the block of code that evaluates ng-if="vm.detail == true" as "true" does NOT execute. It's nuts. Here is my code:
<th>Division</th>
<th>Pool</th>
<th>Subpool</th>
<th ng-click="sort.predicate = 'ExperienceGroup.RenewalGroup.Name'; sort.reverse = !sort.reverse">
RenewalGroup
</th>
<th>MCH</th>
<th ng-click="sort.predicate = 'ContractNumber'; sort.reverse = !sort.reverse">
Contract
</th>
<th ng-click="sort.predicate = 'PlanCode'; sort.reverse = !sort.reverse">
PlanCode
</th>
</tr>
<!--Search By: Mch, Contract Number, Mcp, PlanCode-->
<tr ng-if="vm.detail == true">
<th>Trust</th>
<th>MCH</th>
<th>Contract</th>
<th>Plan Code</th>
<th>Status Date</th>
<th>Status</th>
<th>Effective Date</th>
<th >MCP</th>
<th >Rates</th>
<th>State Availability</th>
</tr>
</thead>
<tbody>
<!--Data for MchNumber, ContractNumber, PlanCode Searches-->
<tr ng-repeat="vm in vm.Mch2Information" ng-if="vm.detail == 'true'">
<!--<th>{{vm.CustomerNumber}}</th>-->
<td> {{vm.TrusteeCustNum}}</td>
<td>{{vm.CustomerNumber}}</td>
<td>{{vm.ContractNumber}}</td>
<td>{{vm.PlanCode}}</td>
<td>{{vm.PlanStatusDate}}</td>
<td>{{vm.PlanStatus}}</td>
<td> {{vm.PlanEffectiveDate}}</td>
<td>{{vm.Mcp}}</td> <!--Not yet implemented-->
<td>Rates</td>
<td>State Availability</td>
</tr>
<!--Data for Division, Pool, Subpool, and RenewalGroup Searches-->
<tr ng-repeat="plan in vm.plans
| filter: {MchNumber : planFilter.Mch}
| limitTo: vm.pageSize" ng-if="vm.detail == false">
<td>{{plan.ExperienceGroup.RenewalGroup.Subpool.Pool.Division.DivisionName}}</td>
<td>{{plan.ExperienceGroup.RenewalGroup.Subpool.Pool.PoolName}}</td>
<td>{{plan.ExperienceGroup.RenewalGroup.Subpool.SubpoolName}}</td>
<td>{{plan.ExperienceGroup.RenewalGroup.RenewalGroupName}}</td>
<td>{{plan.MchNumber}}</td>
<td>{{plan.PlanDesign.ContractNumber}}</td>
<td>{{plan.PlanDesign.PlanCode}}</td>
<td>{{plan.Mcp}}</td>
</tr>
And the controller:
function getPlans(searchParameters)
{
vm.loadingPlans = true; vm.search = searchParameters;
mchService.searchParameters = searchParameters.MchNumber;
datacontext.getAssignedPlans(searchParameters, vm.pageSize).then(function (plans)
{
vm.plans = plans;
//Compares which columns are being populated for choosing which headings to show
if (vm.search.MchNumber != null
||vm.search.ContractNumber != null
|| vm.search.PlanCode != null)
{
vm.detail = true;
vm.test = !vm.test;
alert("vm.detail is: " + vm.detail)
//vm.detail = !vm.detail;
//If users enter JUST a MCH number then display those results
if (vm.search.ContractNumber == null & vm.search.PlanCode == null)
{
vm.getEntityInformation();
}
}
if (vm.search.DivisionName != null
|| vm.search.PoolName != null
|| vm.search.SubpoolName != null
|| vm.search.RenewalGroupName != null)
{
vm.detail = false;
alert("vm.detail is: " + vm.detail);
// vm.detail = !vm.detail;
}
//Sets values to NULL after every search is performed
vm.search.MchNumber =
vm.search.ContractNumber =
vm.search.PlanCode =
vm.search.DivisionName =
vm.search.PoolName =
vm.search.SubpoolName =
vm.search.RenewalGroupName = null;
}).finally(function () { vm.loadingPlans = false; });
}

Please update that bit.
<tr ng-repeat="vm in vm.Mch2Information" ng-if="vm.detail == 'true'">
<!--<th>{{vm.CustomerNumber}}</th>-->
<td>{{vm.TrusteeCustNum}}</td>
<td>{{vm.CustomerNumber}}</td>
<td>{{vm.ContractNumber}}</td>
<td>{{vm.PlanCode}}</td>
<td>{{vm.PlanStatusDate}}</td>
<td>{{vm.PlanStatus}}</td>
<td>{{vm.PlanEffectiveDate}}</td>
<td>{{vm.Mcp}}</td>
<!--Not yet implemented-->
<td>Rates
</td>
<td>State Availability
</td>
</tr>
to :
<tr ng-repeat="info in vm.Mch2Information" ng-if="vm.detail == 'true'">
<!--<th>{{vm.CustomerNumber}}</th>-->
<td>{{info.TrusteeCustNum}}</td>
<td>{{info.CustomerNumber}}</td>
<td>{{info.ContractNumber}}</td>
<td>{{info.PlanCode}}</td>
<td>{{info.PlanStatusDate}}</td>
<td>{{info.PlanStatus}}</td>
<td>{{info.PlanEffectiveDate}}</td>
<td>{{info.Mcp}}</td>
<!--Not yet implemented-->
<td>Rates
</td>
<td>State Availability
</td>
</tr>

Related

Sorting the table data using angular js

I am trying to sort the table data based on the column "Submitted Date" . I have written some code but it doesn't seem to be working. As I am new to Angular JS I need some guidance here. Please help.
code:
Angular js:
vm.sotData = function (column) {
vm.reverseSort = (vm.sortColumn == column) ? !vm.reverseSort : false;
vm.sortColumn = column;
}
Html Code:
<th style="width:13%" ng-click="">Total Amt<span ng-class=""></span></th>
<th style="width:7%" ng-click="">Status<span ng-class=""></span></th>
<th style="width:7%" ng-click="vm.sotData('SubmittedDate')">Submitted Date
<span ng-class="vm.getSortClass('SubmittedDate')"></span>
</th>
The main key of writing sorting functionality is to use
{{ orderBy_expression | orderBy : expression : reverse }}
This returns a sorted Array based on the item. You can change the sorting order by specifying the reverse parameter.
Let's take the example of below array
$scope.friends = [
{sno:1,name:'Yogesh Singh',age:23,gender:'Male'},
{sno:2,name:'Sonarika Bhadoria',age:23,gender:'Female'},
{sno:3,name:'Vishal Sahu',age:24,gender:'Male'},
{sno:4,name:'Sanjay Singh',age:22,gender:'Male'}
];
// column to sort
$scope.column = 'sno';
// sort ordering (Ascending or Descending). Set true for descending
$scope.reverse = false;
// called on header click
$scope.sortColumn = function(col){
$scope.column = col;
if($scope.reverse){
$scope.reverse = false;
$scope.reverseclass = 'arrow-up';
}else{
$scope.reverse = true;
$scope.reverseclass = 'arrow-down';
}
};
// remove and change class
$scope.sortClass = function(col){
if($scope.column == col ){
if($scope.reverse){
return 'arrow-down';
}else{
return 'arrow-up';
}
}else{
return '';
}
};
In html reverse is used for detecting ascending or descending ordering. The default value set to false for ascending.
<table border='1'>
<tr >
<th ng-click='sortColumn("sno")' ng-class='sortClass("sno")'>S.no</th>
<th ng-click='sortColumn("name")' ng-class='sortClass("name")'>Name</th>
<th ng-click='sortColumn("age")' ng-class='sortClass("age")'>Age</th>
<th ng-click='sortColumn("gender")' ng-class='sortClass("gender")'>Gender</th>
</tr>
<tr ng-repeat='friend in friends|orderBy:column:reverse'>
<td width='20%' align='center'>{{friend.sno}}</td>
<td width='35%' align='center'>{{friend.name}}</td>
<td width='20%' align='center'>{{friend.age}}</td>
<td width='25%' align='center'>{{friend.gender}}</td>
</tr>
</table>
<th style="width:13%" ng-click="">Total Amt<span ng-class=""></span></th>
<th style="width:7%" ng-click="">Status<span ng-class=""></span></th>
<th style="width:7%" ng-click="vm.sotData('SubmittedDate')">Submitted Date
<span class="fa" ng-class="{'fa-caret-down':sortType.type=='SubmittedDate' && sortType.order==-1 ,
'fa-caret-up':sortType.type=='SubmittedDate' && sortType.order==1}"> </span></th>
/*for sorting Column*/
$scope.vm.sotData= function (type) {
$scope.sortType.order = $scope.sortType.order === 1 ? -1 : 1;
if ($scope.sortType.order == '1') {
$scope.sortBy = type;
}
else {
$scope.sortBy = '-' + type;
}
};
Try this quick fix.
Code for sorting with Name in Friends
In your HTML,
1st change in table header for which sorting is to be done:-
<th style="width:7%" ng-click="orderByField='name'; reverseSort = !reverseSort"">Friend Name<span ng-class=""></span></th>
2nd change in table row
<tr ng-repeat="friend in Friends | orderBy:orderByField:reverseSort">....</tr>

Build an array of objects with two key/value pairs

I have to build an array like this :
[{'test1': 't1', 'test2' :'t2'},
{'test3' :'t3', 'test4': 't4' },
{'test5': 't5', 'test6' :'t6'},
{'test7' :'t7' , 'test8': 't7' }]
It will be an array of objects.
The object will have always have two key/value pairs.
Key and values will be dynamic.
I have to loop through the object below to build the array:
In the end, I have got to build a table out of the array, which will look like this:
It has to be a 2-columns table, with the key and value.
HTML:
<table class="detailList" >
<tbody>
<tr></tr>
<tr>
<th class="labelCol" scope="row"> <label>test1</label> </th>
<td class="dataCol"> t1</td>
<th class="labelCol" scope="row"> <label>test2</label> </th>
<td class="dataCol"> t2</td>
</tr>
<tr>
<th class="labelCol" scope="row"> <label>test3</label> </th>
<td class="dataCol"> t3</td>
<th class="labelCol" scope="row"> <label>test4</label> </th>
<td class="dataCol"> t4</td>
</tr>
<tr>
<th class="labelCol" scope="row"> <label>test5</label> </th>
<td class="dataCol"> t5</td>
<th class="labelCol" scope="row"> <label>test6</label> </th>
<td class="dataCol"> t6</td>
</tr>
<tr>
<th class="labelCol" scope="row"> <label>test7</label> </th>
<td class="dataCol"> t7</td>
<th class="labelCol" scope="row"> <label>test8</label> </th>
<td class="dataCol"> t7</td>
</tr>
</tbody>
</table>
Any idea how to do this?
Here is how I would create that table:
Working jsFiddle
var testObject = {
some_key: {
key1: '1',
key2: '2',
key3: '3',
}
};
var elements = [];
var last = null;
// loop over the keys in the object in question
$.each(testObject.some_key, function(key, value) {
var item = '<th class="labelCol" scope="row"><label>' + key + '</label></th><td class="dataCol">' + value + '</td>';
if (!last) { // if no last item, set this row to last dont add to the array of elements just yet, we need the other two columns first
last = item;
} else {
// if we already have a last, add these two columns to it, then add it to our array of elements
elements.push(last + item);
last = null;
}
});
if (last) {
// at the end, if we still have a "last" hanging around, add two empty columns
var item = '<th class="labelCol" scope="row"><label></label></th><td class="dataCol"></td>';
elements.push(last + item);
}
// join the array wrapping each set of 4 columns with a tr
var rows = '<tr>' + elements.join('<tr></tr>') + '</tr>';
$('.detailList tbody').html(rows);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table class="detailList">
<tbody>
</tbody>
</table>
What a crazy requirement. I like it. Here's my take on it. (Didn't test it)
var twoPairArray = []; //array to be returned
var twoPairObj = {}; //temp obj for manipulation
for(var key in targetObj) //target obj has the keys to be processed
{
if(Object.keys(twoPairObj).length == 2) //does temp obj have enough keys?
{
twoPairArray.push(JSON.parse(JSON.stringify(twoPairObj))); //sloppy clone of temp obj
twoPairObj = {}; //reset the temp obj.
}
twoPairObj[key] = targetObj[key]; //temp obj being manipulated into this craziness
}

How do I get this loop to work? It's returning undefined angualrjs

I am trying to extract the ID from an object which is at 0 in the index in the object. I need to then convert this key to a string to be able to pass it into an api endpoint.
My Controller event:
$scope.attach = function () {
var rules_id = $scope.rules.selected;
if (rules_id) {
var l = rules_id.length;
for (var i = 0, j = l; i < j;)
{
var key_value = rules_id[i];
}
}
console.log($scope.rules);
console.log(key_value);
console.log($scope.rules.selected);
console.log($scope.asset.id);
};
At present, I am just trying to define each variable in the console, the only thing returning undefined is the loop variable "key_value".
I have checked this against a number of examples and standard setups for a loop and this isn't working.
$scope.rules.selected is a checkbox result which key is represented by a rule ID. See below:
<form name="rules" method="post">
<table class="table table-striped table-hover" ng-model="associated_rules">
<thead>
<th>Rule ID:</th>
<th>Rule Types:</th>
<th>Description:</th>
<th>Start Time:</th>
<th>End Time:</th>
<th>Apply Rule to Vehicle:</th>
</thead>
<tr ng-repeat="associated_rule in associated_rules">
<td>#{{ associated_rule.id }}</td>
<td>#{{ associated_rule.resource_ids.accounts }}</td>
<td>#{{ associated_rule.description }}</td>
<td>#{{ associated_rule.start_time }}</td>
<td>#{{ associated_rule.end_time }}</td>
<td><input type="checkbox" ng-model="rules.selected[associated_rule.id]"aria-label="associated_rule.id" ng-true-value="true"ng-false-value="false" value="rules.selected"></td></tr>
</table>
<button class="btn btn-primary" ng-click="attach()"><i class="fa fa-paperclip"></i> Attach</button>
</form>
Your for loop is wrong, also you are trying to console log a variable that is declared inside the for loop, it will always be undefined!
This is the correct for loop example:
for (i = 0; i < rules_id.length; i++) {
console.log(rules_id[i]);
}
Please have a read on how for loop works
But the real problem here is with your Angular Code
What you want maybe can archived if you rethink in a more declarative way:
// creates the module
angular.module("samplemodule",[])
// apppend the controller to the module
angular.module("samplemodule").controller("SampleCtl",function(){
this.values = [// sample data
{a:"XXX",b:0,c:new Date(),d:true },
{a:"XXY",b:1,c:new Date(),d:false},
{a:"XYX",b:2,c:new Date(),d:false},
{a:"XYY",b:3,c:new Date(),d:true },
{a:"YXX",b:4,c:new Date(),d:false},
{a:"YXY",b:5,c:new Date(),d:false}
]
this.attach = function attach(){
var selectedones = this.values.filter(function(e){
return e.d // just the selected ones
}).map(function(e){
return e.b // just the ids or anything you want
}).join(",")
alert(selectedones)
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="samplemodule" ng-controller="SampleCtl as ctl">
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat="vl in ctl.values">
<td>{{vl.a}}</td>
<td>{{vl.b}}</td>
<td>{{vl.c}}</td>
<td><input type="checkbox" ng-model="vl.d"/></td>
</tr>
</tbody>
</table>
<button ng-click="ctl.attach()">The selected ones</button>
</div>
On this approach we take some well-formed input and do some transformations so we can do a better use of it
// creates the module
angular.module("samplemodule",[])
// apppend the controller to the module
angular.module("samplemodule").controller("SampleCtl",function(){
// log data from somewhere
this.originalData = [
"{db77370c-fbfe-11e5-8468-ed8c21fd14a1: true, c9f2c76c-fbfe-11e5-8fe5-70c120bc96b5: true}",
"{db77370c-fbfe-11e5-8468-ed8c21fd14a2: false, c9f2c76c-fbfe-11e5-8fe5-70c120bc96b6: true}",
"{db77370c-fbfe-11e5-8468-ed8c21fd14a3: true, c9f2c76c-fbfe-11e5-8fe5-70c120bc96b7: true}",
"{db77370c-fbfe-11e5-8468-ed8c21fd14a4: true, c9f2c76c-fbfe-11e5-8fe5-70c120bc96b8: false}",
]
this.values = this.originalData.map(function(e){
e = e.replace(/{/g,"{\"").replace(/:/g,"\":").replace(/, /g,", \"")
e = JSON.parse(e)
var kv = []
for(var attr in e)
kv.push({key:attr,value:e[attr]})
return kv
})
this.attach = function attach(){
var selectedones = [].concat.apply([],this.values).filter(function(e){
return e.value
})
alert(selectedones)
}
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="samplemodule" ng-controller="SampleCtl as ctl">
<table>
<tbody>
<tr ng-repeat="vl in ctl.values">
<td ng-repeat="kv in vl">
{{kv.key}}
<input type="checkbox" ng-model="kv.value"/>
</td>
</tr>
</tbody>
</table>
<button ng-click="ctl.attach()">The selected ones</button>
</div>

How to change the element at a row and column of a table in JavaScript

I re-read earlier posts on the subject and I thought that I implemented it correctly until it did not work. Is there a better way to change the element at a row and column of a table in JavaScript?
From HTML:
<table class="center" border="3" id="checkersBoard">...
<tr>
<td class="block"><img class="BlankSpace" src="Directory/BlankSpace.png"></td> <td class="block"><img class="RedPiece" src="Directory/RedPiece.png"></td> <td class="block"><img class="BlankSpace" src="Directory/BlankSpace.png"></td> <td class="block"><img class="RedPiece" src="Directory/RedPiece.png"></td> <td class="block"><img class="BlankSpace" src="Directory/BlankSpace.png"></td> <td class="block"><img class="RedPiece" src="Directory/RedPiece.png"></td> <td class="block"><img class="BlankSpace" src="Directory/BlankSpace.png"></td> <td class="block"><img class="RedPiece" src="Directory/RedPiece.png"></td>
</tr> // I know terrible but I was just copying and pasting from someone... will change later
From JavaScript:
var board = document.getElementById("checkersBoard");
var isRedHighlighted = false;
var isBlackHighlighted = false;
var lastClick;
board.addEventListener("click", function(e)
{
if(isBlackHighlighted || isRedHighlighted)
{
if(isBlackHighlighted)
{
if(e.target.getAttribute('src') == "Directory/BlankSpace.png")
{
var targetLoc = {row :(e.target.parentNode.parentNode.rowIndex+1), col :(e.target.parentNode.cellIndex+1) };
var lastClickLoc = {row :(lastClick.parentNode.parentNode.rowIndex +1), col :(lastClick.parentNode.cellIndex +1) };
lastClick.src = "Directory/BlankSpace.png";
e.target.src= "Directory/BlackPiece.png";
if(lastClickLoc.row - 2 == targetLoc.row && lastClickLoc.col -2 == targetLoc.col)
{
alert('something should have happened');
board.rows[(lastClickLoc.row)].cells[(lastClickLoc.col)].setAttribute('src',"Directory/BlankSpace.png" ); // why does this not work
board.parentNode.rows[5].cells[5].src = "Directory/BlackPiece.png" // why does this not work
}
isBlackHighlighted = false;
}
To access an element at a given row and col you can use:
board.getElementsByTagName('tr')[row].getElementsByTagName('td')[col]
So you should change
board.rows[(lastClickLoc.row)].cells[(lastClickLoc.col)].setAttribute('src',"Directory/BlankSpace.png" );
board.parentNode.rows[5].cells[5].src = "Directory/BlackPiece.png"
to
board.getElementsByTagName('tr')[(lastClickLoc.row)].getElementsByTagName('td')[(lastClickLoc.col)].getElementsByTagName('img')[0].setAttribute('src',"Directory/BlankSpace.png" );
board.parentNode.getElementsByTagName('tr')[5].getElementsByTagName('td')[5].getElementsByTagName('img')[0].src = "Directory/BlackPiece.png"

How do i get to the table header = "1"

In this example:
function onRowClickHandler(evt){
var clickedTaxLotId = grid.getItem(evt.rowIndex).PARCELID;
var selectedTaxLot;
dojo.forEach(map.graphics.graphics,function(graphic){
if((graphic.attributes) && graphic.attributes.PARCELID === clickedTaxLotId){
selectedTaxLot = graphic;
return;
}
});
var taxLotExtent = selectedTaxLot.geometry.getExtent();
map.setExtent(taxLotExtent);
}
And they select the PARCELID from here:
<th field="PARCELID">Parcel ID</th>
<th field="OWNERNME1" >Owner 1</th>
<th field="OWNERNME2">Owner 2</th>
<th field="RESYRBLT ">Year Built</th>
<th field="SITEADDRESS" width="100%">Address</th>
But now my problem is that i have a <th field="1"> that isnt changeable. But i need to get that value like this var clickedTaxLotId = grid.getItem(evt.rowIndex).2; but in javascript that isnt possible.
table header looks like this:
<div data-dojo-type="dijit.layout.ContentPane" data-dojo-props="region:'bottom'" style="height:350px;" >
<table data-dojo-type="dojox.grid.DataGrid" jsid="grid" id="grid" data-dojo-props="rowsPerPage:'5', rowSelector:'20px'">
<thead>
<tr>
<th field="0" width="auto" >
Gezocht op
</th>
<th field="1" width="auto" >
Gevonden
</th>
</tr>
</thead>
</table>
EDIT
Here i set the value of the th field. This gets done by dataForGrid. the first field is "0" and gets filled with result.foundFieldName, "1" with result.value
map.graphics.clear();
var dataForGrid = [];
//Build an array of attribute information and add each found graphic to the map
dojo.forEach(results, function(result) {
var graphic = result.feature;
dataForGrid.push([result.foundFieldName, result.value]);
var userlabel = result.value;
switch (graphic.geometry.type) {
case "point":
graphic.setSymbol(markerSymbol);
break;
case "polyline":
graphic.setSymbol(lineSymbol);
break;
case "polygon":
graphic.setSymbol(polygonSymbol);
break;
}
map.graphics.add(graphic);
});
var data = {
items: dataForGrid
};
var store = new dojo.data.ItemFileReadStore({
data: data
});
grid.setStore(store);
}

Categories

Resources