Add in Hash and update DOM element dynamically using ng-repeat - angularjs

I have hash of users as the following:
{"A1": {name: "Demo-1", status: "active"}, "A2": {name: "Demo-2", status: "deactive"}};
And I have two hashes of active/deactive users, and I make the table of each of them as the following:
<tr ng-repeat="(id, user) in deactiveUsers">
<td>
{{ user.name }}
</td>
<td>
<button type="button" ng-click="change(id)">Active</button>
</td>
</tr>
And If I click on Active button, I remove the object from deactiveUsers, and add it in activeUsers, the change function as the following:
$scope.change = function(id){
if($scope.users[id].status == "active"){
delete $scope.activeUsers[id];
$scope.users[id].status = "deactive";
$scope.deactiveUsers[id] = $scope.users[id];
}else{
delete $scope.deactiveUsers[id];
$scope.users[id].status = "active";
$scope.activeUsers[id] = $scope.users[id];
}
}
This my demo, it's working well if I tried it on plnkr. But on my localhost the deleting only is working, when I add on activeUsers the DOM element doesn't update with the new record.
I can't find out the issue.
How can I add in Hash to update the DOM element dynamically ?
why it's working on plnkr, but the same code doesn't work on localhost ?

You have multiple body tags in your DOM. I think the first (after the first table element) cause the others angular directives are outside the app.
Replace the body in your table elements by tbody elements.
Edit By the question's owner
My Error was I developed the tables as the following:
<div class="panel panel-primary" ng-controller="ExampleCtrl">
<table></table>
</div>
<div class="panel panel-primary" ng-controller="ExampleCtrl">
<table></table>
</div>
So, I called ng-controller twice, I fixed it by develop one div for the both as the following:
<div ng-controller="ExampleCtrl">
<div class="panel panel-primary">
<table></table>
</div>
<div class="panel panel-primary">
<table></table>
</div>
</div>

Related

AngularJS filter is requiring two clicks before it filters results

I am a beginner at angular. I am pretty certain I am doing this the completely incorrect way but because I finally have it "somewhat working" as it works on the second click I am stuck going in this direction and can't seem to figure out another way to do it.
The filter sorts on the second click because it is initialing as "undefined" before the first click and sets it based on that I believe.
In my html:
<div class="col-xs-12 col-sm-4 location-list" ng-repeat="key in careerlist.location">
<div class="locations" ng-click="careerlist.criteriaMatch()">{{key}}
</div>
</div>
<div class="col-xs-12">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 job-container" ng-repeat="job in careerlist.career | filter : searchText | filter: selectExperience | filter: careerlist.criteria.name">
<h2>
{{job.title}}
</h2>
<h3>
{{job.location}}
</h3>
<div class="job-description" ng-bind-html="job.description | limitHtml : 200">
</div>
<br><br>
<button>Read More</button>
</div>
<br><br>
</div>
</div>
In my controller:
cl.criteriaMatch = function( criteria ) {
jQuery(document).on('click', '.locations', function(){
cl.criteria = {};
console.log("just the element text " + jQuery(this).text());
cl.criteria.name = jQuery(this).text();
return function( criteria ) {
return criteria.name === criteria.name;
};
});
};
Use ng-click instead of jQuery#on('click'). Angular does not know that the filter should be updated.
Update
#Makoto points out that the click is bound twice. It very much looks like you should just remove the jQuery binding altogether. I would even go so far as suggesting removing jQuery from you project.

How to create div and assign object to dataset dynamically using Angularjs

I have below div (class name 'sp') which I would like to dynamically create based on the sk from a dataset object.
div code
<div style="" class="swindow">
<div class="sp" style="">
<div class="svis" style="">
<div style="height:95%;width:95%;margin-top:0px;margin-left:5px;">
<chart dsn="dyndata" editable="false" labelled="true"></chart>
</div>
</div>
<div class="sdata" style="">
<div class="stext" style="">Average:78% </div>
</div>
</div>
While searching for similar examples, I came across ng-repeat in Angular js and I thought it might suit for this kind of objective.
But am very new to Angular js and not sure how to assign the data to my dyndata variable dynamically and create new div (class=sp) for each of the given id.
Here is the lookup object
[
{"id":20,"st":[{"label":"Audi","value":10},{"label":"BMW","value":70}]},
{"id":26,"st":[{"label":"Benz","value":40},{"label":"BMW","value":20}]},
{"id":12,"st":[{"label":"AUDI","value":60},{"label":"Tesla","value":70}]},
{"id":57,"st":[{"label":"MZ","value":30},{"label":"Honda","value":40}]}
]
When I input the id's as a set [12,26,57] - Three divs (each for #sp) should get created one for each of ids. In those, each div should have the dyndata assigned with the respective 'st' from above javascript object.
I could create div's in jquery using .append function to the container (#swindow) each time when I need. But am not sure how to assign sk as input to dyndata dataset for each div that gets created.
Could you please share how this can be achieved using Angular js ?
Here is the angular js code I used -
<script>
var app = angular.module('ExampleApp', ['ui.plot']);
app.controller('PlotCtrl', function ($scope) {
$scope.dyndata={};
});
</script>
I'm not exactly sure what you're trying to do but I think it should look something like this. Here is a plnkr..
Controller:
app.controller('PlotCtrl', function($scope) {
$scope.items = [
{"id":20,"st":[{"label":"Audi","value":10},{"label":"BMW","value":70}]},
{"id":26,"st":[{"label":"Benz","value":40},{"label":"BMW","value":20}]},
{"id":12,"st":[{"label":"AUDI","value":60},{"label":"Tesla","value":70}]},
{"id":57,"st":[{"label":"MZ","value":30},{"label":"Honda","value":40}]}
]
});
HTML:
<body ng-controller="PlotCtrl">
<div style="" class="swindow">
<div class="sp" style="" ng-repeat="item in items">
<div class="svis" style="">
<strong>{{item.id}}:</strong>
<div>-{{item.st[0].label}}</div>
<div>-{{item.st[1].label}}</div>
<div style="height:95%;width:95%;margin-top:0px;margin-left:5px;">
<chart dsn="dyndata" editable="false" labelled="true"></chart>
</div>
</div>
<div class="sdata" style="">
<div class="stext" style="">Average:78% </div>
<br>
</div>
</div>
</div>
</body>

How to perform double click on a repeater row?

I have the following html code:
<div class="table">
<div class="header">
<div class="w10r">Id</div>
<div class="w20r">Title</div>
</div>
<div ng-repeat="row in home.grid.view">
<div>{{ row.id }}</div>
<div>{{ row.title }}</div>
</div>
</div>
I want to double click on the first row in the repeater and below is my test code.
element.all(by.repeater('row in home.grid.view')).first()
.then(function (element) {
browser.actions().doubleClick(element).perform();
});
When I execute the test code, the cursor would click on the table header instead of on the first row of the repeater. Does anyone have any idea what I'm doing wrong here?
Well, It seems you haven't mentioned anywhere to click first row of repeater. You might have to use some extra ID for particular div you want to click and pass it on to function.
<div ng-repeat="row in home.grid.view">
<div ng-repeat="Some Id">{{ row.id }}</div>
<div>{{ row.title }}</div>
</div>
And modify your code to click that particular row with div ID:
element.all(by.repeater('Some ID')).first()
.then(function (element) {
browser.actions().doubleClick(element).perform();
});
Hope this helps!

AngularJS - Show and Hide multiple content

In AngularJS, to simply show a field through an a tag, I would do in this way:
<div ng-show="aField">Content of aField</div>
<a ng-click="aField=true">Show aField</a>
until here, no problem.
I would like now to put more buttons and fields so that, when I click on A it shows the content of A, then when I click on button B, content of A disappears and content of B appears.
How can I do this? Thank you.
UPDATE
Thank you everyone for your solutions, they works! Now, I am doing a template for every content of and because I have much data to show but all in the same structure.
Here the index.html
<div ng-model="methods"
ng-include="'templateMethod.html'"
ng-repeat = "method in methods">
here the script.js:
function Ctrl($scope) {
$scope.methods =
[ { name: 'method1',
description: 'bla bla bla',
benefits: 'benefits of method1',
bestPractices : 'bestPractices',
example: 'example'},
{ name: 'method2',
description: 'bla bla bla',
benefits: 'benefits of method2',
bestPractices : 'bestPractices',
example: 'example'} ];
}
and here the templateMethod.html:
<table>
<tr>
<td>
<div ng-show="toShow=='{{method.name}}Field'">
<h3>{{mmethodethod.name}}</h3>
<p>
<strong>Description</strong>
{{method.description}}
</p>
<p>
<strong>Benefits</strong>
{{method.benefits}}
</p>
<p>
<strong>Best practices</strong>
{{method.bestPractices}}
</p>
<p>
<strong>Examples</strong>
{{method.example}}
</p>
</div>
</td>
<td class = "sidebar">
<ul>
<li><a ng-click="toShow='{{method.name}}Field'" class="{{method.name}} buttons">{{method.name}}</a></li>
</ul>
</td>
</tr>
</table>
It works!
But: if I click the first button and then the second one, the content of the first button do not disappear, it appears under the content of the first button...
Problem with the repetition?
Thanks
It might be better to handle more complex logic in the controller, but in general think about the content of the directive strings as normal js:
<div ng-show="aField">Content of aField</div>
<div ng-show="bField">Content of bField</div>
<a ng-click="aField=true; bField=false">Show aField</a>
<a ng-click="aField=false; bField=true">Show bField</a>
Or use ng-show in concert with ng-hide:
<div ng-show="aField">Content of aField</div>
<div ng-hide="aField">Content of bField</div>
<a ng-click="aField=true">Show aField</a>
<a ng-click="aField=false">Show bField</a>
In the former strategy, nothing shows upon page load. In the latter, the bField content shows by default. If you have more than two items, you might do something like:
<div ng-show="toShow=='aField'">Content of aField</div>
<div ng-show="toShow=='bField'">Content of bField</div>
<div ng-show="toShow=='cField'">Content of cField</div>
<a ng-click="toShow='aField'">Show aField</a>
<a ng-click="toShow='bField'">Show bField</a>
<a ng-click="toShow='cField'">Show cField</a>
I'm guessing that you have a list of items and want to show each item content. Something an accordion component does.
Here is a plunker that shows how you could do it: http://plnkr.co/edit/UTf3dEImiDReC89vULpX?p=preview
Or if you want to display the content on the same place (something like a master detail view) you can do it like this: http://plnkr.co/edit/68DJHL582oY4ecSiiUdE?p=preview
simply use one variable which content is visible. http://jsfiddle.net/gjbw7/
<a ng-click="show='a'">Show aField</a>
.
<div ng-show="show=='a'">Content of aField</div>
I would recommend to create a service in case your fields belong to different controllers.
Service:
App.factory('StateService', function() {
return {
openPanel: ''
};
});
Injecting the service in a Controller:
App.controller('OneCtrl', function($scope, StateService) {
$scope.stateService = StateService;
});
Finally using it a view:
<a ng-click="stateService.openPanel='home'">Home</a>
<div ng-show="stateService.openPanel == 'home'">Content of Home</div>
Demo: http://jsfiddle.net/codef0rmer/BZcdu/
Try this way.
<div>{{content}}</div>
<a ng-click="content='a'">Show aField</a>
<br>
<a ng-click="content='b'">Show bField</a>
<br>
<a ng-click="content='c'">Show cField</a>
<br>
<a ng-click="content='d'">Show dField</a>
<br>
<a ng-click="content='e'">Show eField</a>
<br>
<a ng-click="content='f'">Show fField</a>
Take a look at the ng-switch directive.
<div ng-switch="aField">
<div ng-switch-when="someValue1">
HTML content that will be shown when the aField variable value is equal to someValue1
</div>
<div ng-switch-when="someValue2">
HTML content that will be shown when the aField variable value is equal to someValue2
</div>
<div ng-switch-default>
This is where the default HTML content will go (if aField value is not equal to any of the ng-switch-when values)
</div>
</div>

Angular -- accessing variables defined inside ngRepeat from outside

I am implementing in-place element editing in my Angular app and based my code on this answer https://stackoverflow.com/a/15453512/2026098, using an editing variable for each entry inside ng-repeat.
See http://jsfiddle.net/LYtQU/2/.
I would now like to access this variable from outside the scope of ng-repeat in order to conditionally show/hide an element. Basically, I would like to do something like ng-hide="if any entry has editing==true":
<div class="note" ng-hide="if any entry has editing==true">This should disappear when any entry is being edited</div>
<div class="entry"
ng-repeat="entry in entries"
ng-class="{'editing': editing}">
<span ng-hide="editing" ng-click="editing=true">{{ entry.name }}</span>
<span ng-show="editing" ng-click="editing=false">Editing entry...</span>
</div>
I am trying to avoid using jQuery as the editing variable seems perfect for the job, but just out of reach from my comprehension...
Set up a count in the controller and increment/decrement everytime editing is toggled. Then show the message if the count is 0.
function MainCtrl($scope) {
$scope.state = {editing: 0};
$scope.entries = [{name: 'Entry 1'}, {name: 'Entry 2'}];
};
<body ng-app>
<div ng-controller="MainCtrl">
<div class="note" ng-show="state.editing == 0">This should disappear when any entry is being edited</div>
<div class="entry"
ng-repeat="entry in entries"
ng-class="{'editing': editing}">
<span ng-hide="editing" ng-click="editing=true; state.editing = state.editing + 1">{{ entry.name }}</span>
<span ng-show="editing" ng-click="editing=false; state.editing = state.editing - 1">Editing entry...</span>
</div>
</div>
</body>
http://jsfiddle.net/LYtQU/5/

Resources