Ionic angular js - angularjs

Hello guys im struggeling with ionic and angular i build an news site view with menu points like this
ionic menu points
i wrote my news in an array
for example
http://plnkr.co/edit/ZWOHlCmZDxUkd4laWN4t?p=catalogue
.controller('NewsCtrl', function($scope) {
var items = [
{id: 1, news_item: 'NEWS EXAMPLE'}
];
});
how can i route the right path to the news_item.html site which i klicked on. so if i click on first one i get the tempalte with 'NEWS EXAMPLE'

I couldn't test my answer because your plunker is not working. I think you forgot the index.html file.
But I believe you should add to your items list the url to redirect your page :
.controller('NewsCtrl', function($scope) {
var items = [
{id: 1, news_item: 'NEWS EXAMPLE', template_url : '/path/to/template'}
];
});
Then you can add the path to a href in your <a></a> block.
Hope it will help

Change your variable to be $scope.links this will make it available in the view for repeating using ng-repeat. You can then access values in the JSON Object as setting your href value to the template_url.
.controller('NewsCtrl',function($scope)({
$scope.links = [{
id:1,
news_item: 'NEWS EXAMPLE',
template_url: '/path/to/template'
},
{
id:2,
news_item: 'NEWS EXAMPLE',
template_url: 'path/to/tempalte'
}];
})
<div class='rows' ng-repeat="link in links">
<a href='{{link.template_url}}' class='col' value='{{link.news_item}}' />
</div>
Hope this helps

Related

Using a variable in ng-repeat and passing it to a controller

I have created an AngularJS app that contains two columns: one for a menu and a second for content (each link in the menu links to). The content and menu is in a table in DynamoDB that I am scanning with a Lambda function. The output of this function is being consumed as a JSON response with the following structure:
{
"body": [{
"course-content": "RL front matter",
"course-video": "https://123-course-videos.s3.amazonaws.com/vid_1.mp4",
"course-id": "rcl",
"course-title": "sml",
"course-lesson": "Lesson One"
}, {
"course-content": "RL2 front matter",
"course-video": "https://123-course-videos.s3.amazonaws.com/vid_2.mp4",
"course-id": "rcl2",
"course-title": "sml",
"course-lesson": "Lesson Two"
}, {
"course-content": "RL3 front matter",
"course-video": "https://123-course-videos.s3.amazonaws.com/vid_3.mp4",
"course-id": "rcl3",
"course-title": "sml",
"course-lesson": "Lesson Three"
}]
}
I (with the help of the great folks here) built the following controller that loops through the response and builds the menu:
controller
app.controller('menu', function($scope, $http) {
$http.get('api address').
then(function(response) {
$scope.navi = response.data.body;
$scope.selectCourse = function(course, index, path) {
console.log(path)
$scope.content = response.data.body[index]
console.log($scope.content)
};
});
});
menu built using ng-repeat
<div ng-repeat="nav in navi">
<ul><li>{{ nav['course-lesson'] }}
<button ng-click="selectCourse(nav, $index, '/content/' +
$index)">Select</button>
</li></ul>
</div>
This build the following menu:
Lesson One <button>
Lesson Three <button>
Lesson Two <button>
And I am using a second controller that consumes the content from the same api call:
app.controller('content', function($scope, $http) {
$http.get('api address').
then(function(response) {
$scope.content = response.data.body;
});
});
content is displayed in a route with a simple content.html template as follows:
app.config(function($routeProvider) {
$routeProvider
.when("/", {
templateUrl : "templates/main.html"
})
.when("/content/:id", {
templateUrl : "templates/content.html",
controller : "content"
});
Updated: Here is where I still need help:
How do I pass/use the $index variable in the menu controller to the content controller so the content updates as needed in the right template when I click on each button?
To help better understand the functionality:
Lesson One links to content for lesson one - lesson one content is
displayed in the content template.
List item Lesson Two links to content for lesson two - lesson two content is
displayed in the content template.
List item Lesson Three links to content for lesson three - lesson three content
is displayed in the content template.
Sorry for the long post, but I wanted to provide enough detail to help clarify any confusion.
To pass data to a controller from an ng-repeat element, use the ng-click directive:
<div class="col-4" ng-controller="menu">
<div ng-repeat="nav in navi">
<ul>
<li>
{{ nav['course-lesson'] }}
<button ng-click="selectCourse(nav, $index)">Select</button>
</li>
</ul>
</div>
Assign the function to scope:
$scope.selectCourse = function(course, index) {
console.log(course, index);
};
For more information, see
AngularJS ng-click Directive API Reference

How to Redraw Tables using Angular UI Tabs and UI Grid?

I'm trying to migrate from jQuery Data Tables to Angular UI. My app uses the MySQL World schema and displays the data in 3 different tables. In jQuery, I'd 3 different pages, each launched from a home page. Here's a live example.
In Angular, I created 3 tabs, clicking on each of which is supposed to reload the page with a new grid and populate it with data. Problem is, the grid gets displayed alright on page load with the content on the first tab. On clicking the other tabs, page goes empty and nothing is rendered. Now the data returned is not insignificant, sometimes around 4k rows. However, the problem isn't a latency issue as I've confirmed by waiting several minutes.
I'm not a JS/CSS/HTML guy so most likely I'm missing something. That's why this question.
Edit:
Plnkr
Following is the code:
HTML:
<body>
<div id="selection-panel" class="selection-panel" ng-controller="HelloWorldCtrl">
<div>
<uib-tabset type="pills" justified="true">
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="update(tab.title)">
<div id="data-panel" class="data-panel" ui-grid="gridOptions"></div>
</uib-tab>
</uib-tabset>
</div>
</div>
<script src="js/app.js"></script>
</body>
JS:
(function() {
var app = angular.module('helloWorld', ['ui.bootstrap', 'ui.grid']);
app.controller('HelloWorldCtrl', ['$http', '$scope', function ($http, $scope) {
$scope.tabs = [
{ title: 'Countries' },
{ title: 'Cities' },
{ title: 'Languages' }
];
$scope.gridOptions = {};
$scope.gridOptions.data = [];
$scope.gridOptionsCountries = {
columnDefs: [
{ name: 'code'},
{ name: 'name'},
{ name: 'continent'},
{ name: 'region'},
{ name: 'population'}
]
};
$scope.gridOptionsCities = {
columnDefs: [
{ name: 'id'},
{ name: 'name'},
{ name: 'country'},
{ name: 'population'}
]
};
$scope.gridOptionsLanguages = {
columnDefs: [
{ name: 'country'},
{ name: 'language'}
]
};
$scope.update = function(title) {
if (title === "Countries") {
$scope.gridOptions = angular.copy($scope.gridOptionsCountries);
} else if (title === "Cities") {
$scope.gridOptions = angular.copy($scope.gridOptionsCities);
} else if (title === "Languages") {
$scope.gridOptions = angular.copy($scope.gridOptionsLanguages);
}
$http.get(title.toLowerCase()).success(function(data) {
$scope.gridOptions.data = data;
});
};
}]);
})();
I see 2 problems here:
You are creating/changing gridOptions dinamically. This is not the usual way of doing things and can bring many problems.
You are using grids inside of uib-tabs and this, like uib-modals, can have some annoying side effects.
I'd suggest you to address the first issue using different gridOptions (as you do when you create them) and then putting them inside your tabs array children, this way you can refer them from the html this whay:
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="update(tab.title)">
<div id="data-panel" class="data-panel" ui-grid="tab.gridOptions"></div>
</uib-tab>
The second problem is quite known and inside this tutorial they explain how to address it: you should add a $interval instruction to refresh the grid for some time after it's updated in order to let the tab take its time to load and render.
The code should be as follows:
$scope.tabs[0].gridOptions.data = data;
$interval( function() {
$scope.gridCountriesApi.core.handleWindowResize();
}, 10, 500);
Where gridCountriesApi are created inside of a regular onRegisterApi method.
I edited your plunkr, so you can see the whole code.
I can not get this to work in tabs, my guess is because you first use ng-repeat which creates a scope for each iteration, and then maybe the tabs itself creates a new scope and this causes a lot of headache with updates.
The quickest solution is just to move the grid outside of the tabs.
Here is the updated html.
HTML
<body>
<div id="selection-panel" class="selection-panel" ng-controller="HelloWorldCtrl">
<div>
<uib-tabset type="pills" justified="true">
<uib-tab ng-repeat="tab in tabs" heading="{{tab.title}}" select="update(tab.title)"></div>
</uib-tab>
</uib-tabset>
<!-- This is moved outside -->
<div id="data-panel" class="data-panel" ui-grid="gridOptions">
</div>
</div>
<script src="js/app.js"></script>
</body>
In my situation tab contents consume important time to be loaded. So if your case is that you don't want to update tab content everytime the tab is clicked, you can use this workaround:
In the HTML part I use select property to indicate which tab is pressed:
<tabset justified="true">
<tab heading="Tab 1" select="setFlag('showTab1')">
<div ng-if="showTab1">
...
</div>
</tab>
</tabset>
In the tab (*) container I used a switch to recognize which tab is pressed and broadcast the press action:
case 'showTab1':
$scope.$broadcast('tab1Selected');
break;
And in the controller part I listen the event and handle resizing:
// The timeout 0 function ensures that the code is run zero milliseconds after angular has finished processing the document.
$scope.$on('tab1Selected', function () {
$timeout(function() {
$scope.gridApi1.core.handleWindowResize();
}, 0);
});
Here is my Plunkr. Hope it helps.
(*) For current bootstrap version you should use and

angular js ng-class shows expression as class instead of processing it

I'm trying to make highlighted menu items by using angular js. I've read this question and tried implementing the anwser, but instead of angular evaluating the expression, it just shows it as the class name. I don't know what's going on.
I have the menu items listed as JSON, and the iterate trough it with ng-repeat. Once the list items are created, I want the angular to add a class of 'active', if the location url is the same as the link.href attribute of a menu item (it's a json attribute, not the html one).
Here's the relevant html:
<div class="header" ng-controller="NavbarController">
<ul>
<li ng-repeat="link in menu" ng-class="{ active: isActive({{ link.href }}) }"><a ng-href="{{ link.href }}">{{ link.item }}</a>
</li>
</ul>
</div>
and my controller:
.controller('NavbarController', function ($scope, $location) {
// navbar links
$scope.menu = [
{
item: 'PTC-Testers',
href: '#/PTC-Testers'
},
{
item: 'articles',
href: '#/articles'
},
{
item: 'PTC sites',
href: '#/sites'
},
{
item: 'account reviews',
href: '#/account_reviews'
},
{
item: 'forum',
href: '#/forum'
},
{
item: 'contact us',
href: '#/contact'
},
{
item: 'login',
href: '#/login'
}
]; // end $scope.menu
$scope.isActive = function (viewLocation) {
return viewLocation === $location.path();
};
});
This is the navbar part of a bigger project, and I tried only inserting the relevant code. If you need further info to understand the question properly, please let me know.
It should be ng-class="{'active' : isActive(link.href)}"
You didn't end the curly brace in ng-class and its better to put class name inside quotes

Using Template with Typeahead in UI Bootstrap

I am working on an AngularJS app. My app has a plunker that can be seen here. This app has a service that I made for another project. That service looks like this:
myApp.service('myService', ['$http', '$timeout', '$q', function($http, $timeout, $q) {
this.getResults = function() {
var deferred = $q.defer();
var results = [];
results.push({ name: 'Alpha', id:1, description:'The first' });
results.push({ name: 'Bravo', id:2, description:'The second' });
results.push({ name: 'Charlie', id:3, description:'The third' });
deferred.resolve(results);
return deferred.promise;
};
I'm trying to use the Typeahead control in UI Bootstrap framework. I successfully have the basics wired up. However, I cannot figure out how to get the custom result templates to work. I do not understand where they are pulling the property values from. I'm just trying to create a template that shows the name and description field. When the item is selected, I want to show the name in the text box. My plunker is here.
Please see here http://plnkr.co/edit/VJFx436Tsew9unXWNQsJ?p=preview
1.Here you setting up template name typeahead-template-url="result.html"
so id of your template script has to be "result.html"
To access data from your match model in template you need to use match.model prefix.
<script type="text/ng-template" id="result.html">
<a>
<div><h6>{{match.model.name}}<h6>< /div>
<div><p>{{match.model.description}}</p></div>
</a>
</script>

AngularJS - FAQ inside a modal (bug?)

Currently i'm developing a webapp with AngularJS for a giant company, and i'm trying to have a simple FAQ inside a modal.
In my localhost the FAQ it's working just fine (very similar to the original FAQ in angular documentation), but when i write exactly the same code inside a modal i'm getting a console error:
TypeError: Object [object Object] has no method 'addGroup'
Important to state that inside the modal my $scope.oneAtATime = true; it's being ignored, so basically even if i force it to be true
<accordion close-others="true">
It's always false.
This addGroup method is on the AngularJS library code.
Any ideas?
The HTML:
<div class="modal__container__body">
<div id="faq_accordion" ng-controller="AccordionController">
<accordion close-others="true">
<accordion-group heading="{{faq.title}}" ng-repeat="faq in faqs">
{{faq.content}}
</accordion-group>
</accordion>
</div>
</div>
The controller
lobby.controller("AccordionController", ["$scope", function ($scope) {
$scope.oneAtATime = true;
$scope.faqs = [
{
title: "Q1?",
content: "A1"
},
{
title: "Q2?",
content: "A2"
},
{
title: "Q3?",
content: "A3"
},
{
title: "Q4?",
content: "A4"
}
];
}]);
Please notice that in the above code i'm forcing close-others to be true, directly in the html tab.
Help?
We had the same problem recently, change
<div id="faq_accordion" ng-controller="AccordionController">
to
<div id="faq_accordion" ng-controller="MyAccordionController">
That should fix it. You basically overwrote the plugin controller with your own. Don't forget to change the controller definition also, it's the part that's breaking it.

Resources