I need to do app,which doing something like that:
One web page separated on 2 tabs.
In first tab we have list of items. If you click on item it should be transferred to another tab and should be hidden on first tab.
Tools to do this thing is AngularJS.
Any ideas about that? Sorry for this question. I'm noobie in AngularJS.
Here's a really basic example of how you could implement your idea with AngularJS:
Tabs
one easy way to create tabs is to create the markup and use your controller to hold a reference to which tab to show:
// in the controller
$scope.currentTab = 1;
// in the markup
<li class="tab" ng-show="currentTab === 1">
... tab contents
</li>
... repeat for as many tabs as you want
you could then change the tab inside an ng-click directive in your page markup:
// in the markup
<a ng-click="currentTab = 1">change to tab 1</a>
Items
to show items in your tab first create the items in your controller:
// in the controller
$scope.tab1Items = [1, 2, 3, 4, 5];
then display in your tab:
// in the markup
<li class="tab">
<div ng-repeat="item in tab1Items">{{ item }}</div>
...
</li>
Moving the items
This can be done with a function in ng-click that passes the item from one array of items to another:
// in the controller
$scope.moveItem = function(item) {
if ($scope.tab1Items.indexOf(item) > -1) {
$scope.tab1Items.splice($scope.tab1Items.indexOf(item), 1);
$scope.tab2Items.push(item);
}
else {
$scope.tab2Items.splice($scope.tab2Items.indexOf(item), 1);
$scope.tab1Items.push(item);
}
}
// in the markup
<div ng-repeat="item in tab1items" ng-click="moveItem(item)">
...
The concept here is to create a page with one controller that maintains current tab state, as well as the items to display in those tabs. Since you have access to all the items in the same scope it's easy to manipulate and pass those items from one tab to another.
Here's a link to a basic working example in plnkr: http://plnkr.co/edit/PjSXI0JH4uQ1OW8u3f2z?p=preview
Related
I am trying to pull all items from my array called 'collections'. When I input the call in my html I see only the complete code for the first item in the array on my page. I am trying to only pull in the 'edm.preview' which is the image of the item. I am using Angular Firebase and an api called Europeana. My app allows the user to search and pick which images they like and save them to that specific user.
here is the js:
$scope.users = fbutil.syncArray('users');
$scope.users.currentUser.collections = fbutil.syncArray('collections');
$scope.addSomething = function (something) {
var ref = fbutil.ref('users');
ref.child($rootScope.currentUser.uid).child('collections').push(something);
}
$scope.addSomething = function(item) {
if( newColItem ) {
// push a message to the end of the array
$scope.collections.$add(newColItem)
// display any errors
.catch(alert);
}
};
and the html:
<ul id="collections" ng-repeat="item in collections">
<li ng-repeat="item in collections">{{item.edmPreview}}</li>
</ul>
First, remove the outer ng-repeat. You want to only add the ng-repeat directive to the element which is being repeated, in this case <li>.
Second, from your AngularJS code, it looks like you want to loop over users.currentUser.collections and not just collections:
<ul id="collections">
<li ng-repeat="item in users.currentUser.collections">{{item.edmPreview}}</li>
</ul>
And third, you're defining the function $scope.addSomething twice in your JavaScript code. Right now, the second function definition (which, incidentally, should be changed to update $scope.users.currentUser.collections as well) will completely replace the first.
I have successfully created a function to toggle the individual rows of my ng-table to open and close using:
TestCase.prototype.toggle = function() {
this.showMe = !this.showMe;
}
and
<tr ng-repeat="row in $data">
<td align="left">
<p ng-click="row.toggle();">{{row.description}}</p>
<div ng-show="row.showMe">
See the plunkr for more code, note the expand/collapse buttons are in the "menu".
However, I can't figure out a way to now toggle ALL of the rows on and off. I want to be able to somehow run a for loop over the rows and then call toggle if needed, however my attempts at doing so have failed. See them below:
TestCase.prototype.expandAllAttemptOne = function() {
for (var row in this) {
if (!row.showMe)
row.showMe = !row.showMe;
}
}
function expandAllAttemptOneTwo(data) {
for (var i in data) {
if (!data[i].showMe)
data[i].showMe = !data[i].showMe;
}
}
Any ideas on how to properly toggle all rows on/off?
Using the ng-show directive in combination with the ng-click and ng-init directives, we can do something like this:
<div ng-controller="TableController">
<button ng-click="setVisible(true)">Show All</button>
<button ng-click="setVisible(false)">Hide All</button>
<ul>
<li ng-repeat="person in persons"
ng-click="person.visible = !person.visible"
ng-show="person.visible">
{{person.name}}
</li>
</ul>
</div>
Our controller might then look like this:
myApp.controller('TableController', function ($scope) {
$scope.persons = [
{ name: "John", visible : true},
{ name: "Jill", visible : true},
{ name: "Sue", visible : true},
{ name: "Jackson", visible : true}
];
$scope.setVisible = function (visible) {
angular.forEach($scope.persons, function (person) {
person.visible = visible;
});
}
});
We are doing a couple things here. First, our controller contains an array of person objects. Each one of these objects has a property named visible. We'll use this to toggle items on and off. Second, we define a function in our controller named setVisible. This takes a boolean value as an argument, and will iterate over the entire persons array and set each person object's visible property to that value.
Now, in our html, we are using three angular directives; ng-click, ng-repeat, and ng-show. It seems like you already kinda know how these work, so I'll just explain what I'm doing with them instead. In our html we use ng-click to set up our click event handler for our "Show All" and "Hide All" buttons. Clicking either of these will cause setVisible to be called with a value of either true or false. This will take care of toggling all of our list items either all on, or all off.
Next, in our ng-repeat directive, we provide an expression for angular to evaluate when a list item is clicked. In this case, we tell angular to toggle person.visible to the opposite value that it is currently. This effectively will hide a list item. And finally, we have our ng-show directive, which is simply used in conjunction with our visible property to determine whether or not to render a particular list item.
Here is a plnkr with a working example: http://plnkr.co/edit/MlxyvfDo0jZVTkK0gman?p=preview
This code is a general example of something you might do, you should be able to expand upon it to fit your particular need. Hope this help!
My question in short
how do i manipulate the isolated scope created by ng-repeat inside of my controller?
To read the full problem i am having continue reading below:
I have a collection on timelines and each of them further has a collection of captures (essentially images).
HTML
<ul>
<li ng-repeat="timeline in timelines | filter:search | orderBy:'event_date':sort">
<ul ng-if="timeline.captures">
<li ng-repeat="captures in timeline.captures | limitTo:imageLimit">
<img ng-src="<% captures.capture_location %>">
</li>
</ul>
<a ng-click="(imageLimit = imageLimit + 1)">Load more</a>
</li>
</ul>
I want to limit the number of images being loaded on page load.. which i am able to do using limitTo
I want to load more images when the user clicks on 'Load more'. I am also able to do this by ng-click="(imageLimit = imageLimit + 1)
What i want to do:
I want to extract this out as a function
so that the following
Load more
becomes
Load more
To achieve this, i tried the following:
inside my controller
$scope.imageLimit = 1; // number of images to show initially on page load
$scope.loadMore = function() {
$scope.imageLimit += 1;
};
Now what is happening is that this this not create the imageLimit model inside the repeated scope (if you understand what i mean) but instead creates the imageLimit model at the controller scope. This is also the expected behaviour but i want to know how do i manipulate the scope within the repeated timeline (isolated scope for that timeline) inside my controller?
If I understand correctly, you want to be able to loadMore() for each timeline, independantly of the other ones. The loadMore() function should thus take the timeline as argument, and the limit should be a property of the timeline:
angular.forEach($scope.timelines, function(timeline) {
timeline.imageLimit = 10; // default value
});
$scope.loadMore(timeline) {
timeline.imageLimit++;
}
And in your template:
<li ng-repeat="captures in timeline.captures | limitTo:timeline.imageLimit">
...
<a ng-click="loadMore(timeline)">Load more</a>
i have list of items and i want to create filter from button that shows\hides the element, instead of add\remove it from the DOM.
<li ng-repeat="li in list" ng-show="">
<a ng-click="">category</a>
</li>
i mean that instead of filtering list i want to hide\show list items by this filter.
i found this fiddle http://jsfiddle.net/cKa6K/
but i want to do the same only with hide\show.
Without more information on your code, I'd do something like that : http://jsfiddle.net/DotDotDot/tpmxN/1/
I used an item list with 2 properties, the name and a category
I defined a function for the ng-show, which will compare the item category to the filter
<li ng-repeat="li in list" ng-show="isDisplayed(li, filter)">
Then in the controller the function is defined by :
$scope.isDisplayed=function(item, filter){
if(filter!="")
{
if(item.category==filter)
return true;
return false;
}
return true;
}
Nothing really hard in this, then you just have to set the filter property, I used buttons with ng-click and the category in the ng-repeat, you can click on them, it will hide/show the proper items
I hope this helps
Have fun
I'm trying to update a $scope object's array that is displayed in a ng-repeat on the page using input elements containing the array's contents. The plunker example can be found here: Plunker demo (Basic, stripped down example of my problem)
I have the following settings object defined:
$scope.settings = {
list: ['list item one', 'list item two', 'list item three']
};
and I am representing the data on the page like so:
<ul>
<li ng-repeat="item in settings.list">
<input type="text"
value="{{item}}"
ng-model="singleItem"
ng-change="settings.list[$index] = singleItem" />
delete
</li>
</ul>
My goal is to initially populate the <input> fields with the contents of $scope.settings.list and whenever an item is changed update the array, but I haven't figured out how to in the view. Omitting the ng-model and ng-change on the input properly renders the input vale in the text boxes, but then the array isn't modified when changes are made.
Side Note:
In the Plunker example I have $watch on the settings object. In my actual code, this is used to update a "settings cookie" using the $cookies module. Cookies have been omitted in the example, but for debugging purposes I have left the watch in.
There are two primary problems with your approach. The first is that ngRepeat uses an inherited scope, so primitive values (like strings and numbers) don't play nicely. You should pass arrays of objects to ngRepeat rather than arrays of primitives. Your second problem is the over-complicated way of of binding to an input. All you need is to this:
$scope.settings = {
list: [
{ val: 'list item one'},
{ val: 'list item two'},
{ val: 'list item three'}
]
};
And then in your view:
<ul>
<li ng-repeat="item in settings.list">
<input type="text" ng-model="item.val"></input>
<a ng-click="remove($index)">delete</a>
</li>
</ul>
Here's a revised plunker: http://plnkr.co/edit/ZGFjBnVSwM4hNSgVSOCW?p=preview .