How to use Routeprovider to toggle sections? - javascript

I have what I'm hoping is a simple problem.
Let's say I have a JSON object which is the data for the url /page-b
{
"name": "Page B",
"url": "page-b",
"sections": [{
"name": "A",
"description": "Foo",
}, {
"name": "B",
"description": "Bar",
}, {
"name": "C",
"description": "Dog"
}, {
"name": "D",
"description": "Cat",
}]
}
Each page has a different JSON file it goe's and grabs, but for this example, I'll run it on B.
dashboard.controller('siteCtrl', ['$scope', '$http', '$rootScope', '$location', function($scope, $http, $rootScope, $location) {
$rootScope.location = $location.path();
var url = '';
switch($rootScope.location) {
case '/':
case '/page-a':
url = '/data/page-a.json';
break;
case '/page-b':
url = '/data/page-b.json';
break;
case '/page-c':
url = '/data/page-c.json';
break;
}
$http.get(url).success(function(data){
$scope.brandData = data;
});
}]);
Simple route provider, that get's the pages from the hash key. I have this simple menu, which I do not have control over the html at all, but I want to toggle the SECTIONS in the json object, instead of displaying them all, there's a click event on the page-b root page, but I'm not sure how I can find out which child link was clicked.
<ul>
<li>Page B
<ul>
<li>A</li>
<li>B</li>
<li>C</li>
<li>D</li>
</ul>
</li>
</ul>
I just want to be able to toggle the section that was clicked on the child menu elements. Is this possible with this code provided?
I notice that Angular pushes a $$hashkey into the array of objects, is this usable?

If you have a scope variable like :
$scope.activeSection ='A';
You can use this value as a filter for ng-repeat and use ng-click to make the changes within your menu. Also use it in ng-class to set an active class in menu
<a ng-click="activeSection='A'" ng-class="{active: activeSection=='A'}">A</a>
<div ng-repeat="section in data.sections |filter: {'name': activeSection}">
Name:{{section.name}}<br>
Description: {{section.description}}
</div>
As far as the angular hashkeys go you are best off to just ignore them. Use the documented api instead

Related

filtering $http json data with angular

I have read through numerous questions here already, but something just isnt clicking with me and understanding this issue i have.
the js code:
app.controller('example_ctrl',['$scope','$http', function($scope,
$http){
$http.get('api_call_here').then(function successCallBack(response){
$scope.response = response;
});
Json format of api:
{
"categoryOne": {
"1": {
"title": "someData1",
"description": "This is number One"
},
"2": {
"title": "moreData1",
"description": "I am not a number, I'm a free man!"
}
}
}
Now because this hasnt been returned in an array, I get an error whenever I try to filter it. As an example:
<div ng-repeat="(category, object) in response.data">
<div ng-repeat="item in object">
<p>{{item.title}}</p>
</div>
</div>
Now if i try to put an ng-model on a search input, and tie that to the ng-repeat with a |filter:ng-model name, I get an error.
What I basically WANT to do, is when you type text into the search field, have it return only the title/descriptions that contain that text.
You can transform the list of object in each category to array:
app.controller('example_ctrl',['$scope','$http', function($scope, $http){
$http.get('api_call_here').then(function(response) {
Object.keys(response.data).forEach(function(category) {
response.data[category] = Object.values(response.data[category]); // Transfom list of objects in each category to array
});
console.log("transformed: ", response);
$scope.response = response;
});

Accessing array of objects in an object using Angular

I am trying to have an array of 30 recipes shown on my view with data from an API call.
// app.js
angular.module('recipeApp', [])
.controller('RecipesCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.mainview = [];
$http.get('/API')
.then(function(response) {
$scope.mainview = response.data;
});
// index.html
<html lang="en" ng-app="recipeApp">
<body ng-controller="RecipesCtrl">
{{mainview}} //this outputs the same data shown on the API call.
// when I try 'ng-repeat' nothing shows up at all
// data from API call (this is just a sample of the data. there is really an array of 30 objects in "recipes")
{
"count": 30,
"recipes": [
{
"publisher": "Closet Cooking",
"f2f_url": "http://food2fork.com/view/35382",
"title": "Jalapeno Popper Grilled Cheese Sandwich",
"source_url": "http://www.closetcooking.com/2011/04/jalapeno-popper-grilled-cheese-sandwich.html",
"recipe_id": "35382",
"image_url": "http://static.food2fork.com/Jalapeno2BPopper2BGrilled2BCheese2BSandwich2B12B500fd186186.jpg",
"social_rank": 100,
"publisher_url": "http://closetcooking.com"
},
{
"publisher": "The Pioneer Woman",
"f2f_url": "http://food2fork.com/view/47024",
"title": "Perfect Iced Coffee",
"source_url": "http://thepioneerwoman.com/cooking/2011/06/perfect-iced-coffee/",
"recipe_id": "47024",
"image_url": "http://static.food2fork.com/icedcoffee5766.jpg",
"social_rank": 100,
"publisher_url": "http://thepioneerwoman.com"
},
When I have {{mainview}} in the html, it shows the same as above, but how can I have it so all 30 recipes are looped in the view? I looked into ng-repeat, but I am very new to Angular and couldn't figure it out. Any information on this would be appreciated.
you can use ng-repeat like this:
<body ng-controller="RecipesCtrl">
<ul>
<li ng-repeat="recipe in mainview.recipes">{{recipe}}</li>
</ul>
</body>
It will generate a li element for every recipe in your array. You can access the properties of a recipe using . as you would in javascript.
{{recipe.publisher}}
Note: ng-repeat works with any elements, I used ul and li for show purposes only.
Something like this may help you:
<ul>
<li ng-repeat="recipe in mainview.recipes">
{{recipe.title}}
<br />
- {{recipe.publisher}}
</li>
</ul>
I think you're looking for a view fragment like:
<div data-ng-repeat="item in mainview.recipes">
<div>
<label>Publisher</label><span>{{item.publisher}}</span>
<div>
<div>
<label>Title</label><span>{{item.title}}</span>
<div>
...
</div>
where ... is whatever else you want to display in the view. Documentation at: https://docs.angularjs.org/api/ng/directive/ngRepeat (though I know you've read it (: )

angularjs routeprovider variation

I am quite new with angular, so I am not sure if what I want to do is actually achievable with angular or if it is better to use some other framework.
This is my situation, we have a website made in wordpress, that contains a bit more than 500 pages, all of the pages are the same (exact same content). The main reason they builded this way is:
availability to have custom "domain names", IE:
www.page.com/mypage1
www.page.com/mypage2
www.page.com/mypage...
there is one section on the page that contains an iframe, the iframe is the same on all pages except for a parameter so for instance the iframe of mypage1 has as an url: www.otherpage.com?client=client1Id
So I have use angular before to do a very simple $routeProvider, so I am wondering if I can use the same concept but with some changes
var sampleLandingPage = angular.module('sampleLandingPage', []);
sampleLandingPage.controller('landingPage',['$scope', function ($scope){
$scope.pages = [
{
"FullName": "Client No 1",
"Name": "mypage1",
"CM": null,
"AF": "CLID001",
"OtherURL": null
},
{
"FullName": "Client No 2",
"Name": "mypage2",
"CM": "CLID002",
"AF": "CLID002",
"OtherURL": null
},
{
"FullName": "Client Special",
"Name": "mypage3",
"CM": "CLID002",
"AF": "CLID003",
"OtherURL": "/somethingelse"
}
];
}]);
sampleLandingPage.config(['$routeProvider',
function($routeProvider) {
//$routeProvider.
}]);
so what I want to achieve is if the URL is requesting mypage2; to be able to display CM and AF in my page like {{ CM }} this way I can have only one page but on my iframe have the url like
www.otherpage.com?client={{ CM }}&otherparam={{ AF }}
and have a unique page that looks like
<body ng-app="sampleLandingPage">
<div class="container">
<div ng-controller="landingPage">
page text...
.........
iframe ... url=www.otherpage.com?client={{ CM }}&otherparam={{ AF }}
</div>
</div>
</body>
and finally if the OtherURL param is different to null, then display the actual URL define in this param

Dynamically Load ng-options from API with Angular

I would like to dynamically load select elements from an API request.
Here is my controller:
var myApp = angular.module('myApp',[]).controller('tripCtrl', function($scope){
//Call to API to get people
$scope.people = [
{
"id": 1,
"name": "Joe Hamlet"
},
{
"id": 2,
"name": "Mary Jane"
},
{
"id": 3,
"name": "Tom Lee"
}
];
//Call to API to get the element to load
$scope.selectElement =
{
"Options": "person[dynamicValue] as person[dynamicDisplayName] for person in people",
"DisplayName": "name",
"Value": "id"
};
//Dynamicly load properties
$scope.dynamicValue = $scope.selectElement.DisplayName;
$scope.dynamicDisplayName = $scope.selectElement.Value;
});
HTML:
<select ng-model="selectedPerson" ng-options="{{selectElement.Options}}">
<option value="">Select</option>
</select>
{{selectedPerson}}
I created a JSFiddle trying to accomplish this. http://jsfiddle.net/HB7LU/9493/
I found this question which I was able to implement, but when I tried to set the ng-options from the Element's Options property, it failed to load. When inspected the HTML the code looks to be set properly, but the model binding isn't working.
Edit 12/28/2014:
After updating the Angular version in the original JS Fiddle, it worked properly, however when I expanded to use an actually API, I found another issue with loading ng-options dynamically. Here is the more in depth JS Fiddle: http://jsfiddle.net/zjFp4/330/
Also here is my updated controller. The dataService.getElement() calls a hard coded string, where as the dataService.getElementFromApi() calls the same exact string, just from json-generator (which is the mock API). When inspected the objects set from the API, everything is there, so it must be an issue with the binding in Angular. Any ideas on how to fix this?
function tripCtrl($scope, dataService) {
//Call to API to get people
dataService.getPeople().then(
function (event) {
$scope.people = event;
},
function (s) {
console.log(s); }
);
//Call to API to get the element to load
$scope.selectElement = dataService.getElement();
dataService.getElementFromApi().then(
function (event) {
$scope.apiElement = event;
$scope.dynamicValue = $scope.apiElement.Value;
$scope.dynamicDisplayName = $scope.apiElement.DisplayName;
},
function (s) {
console.log(s); }
);
}

AngularJS: How to create a model which holds an array for a dynamic list of input fields?

I have quite an interesting question (I hope) for all you AngularJS gurus out there. I am looking to create a dynamic list of form input fields based on a SELECT dropdown. As an example, we have a number of categories with each category having a set of specifications which are unique to that category. To help with the explanation we have the following:
Firstly, in the controller we start by initializing the models.
$scope.category = {};
$scope.category.specs = [];
Next we ready the data to be used in the form (actually retrieved from the server via $http). We also initialize a variable to the first element in the categories array.
$scope.categories = [
{ "id": "1", "name": "mobile", specs: [
{ "id": "1", "label": "Operating System" },
{ "id": "2", "label": "Camera type" } ] },
{ "id": "2", "name": "laptop", specs: [
{ "id": "1", "label": "Operating System" },
{ "id": "2", "label": "Graphics Card" } ] }
};
$scope.selectedCategory = $scope.categories[0];
In the form, we have a dropdown which when selected loads the appropriate input fields specific to that category. We use the ngRepeat directive to accomplish this. This is a dynamic list of fields based on $scope.categories.specs. (please note the ???)
<select ng-model="selectedCategory" ng-options="category.name for category in categories"></select>
<div ng-repeat="spec in selectedCategory.specs">
<label>{{spec.label}}</label>
<input type="text" ng-model="???">
</div>
Ultimately, when the user clicks the submit button, we would like to extract the category he/she has selected and then package it together with the specifications they have filled in. The post request should contain something like the following for instance (of course, I only included one spec item, but in reality there would be many):
{ "id": "1", specs [ { "id": "2", "details": "RADEON HD 8970M" } ] }
Unfortunately I am not really sure how to accomplish this. I need to somehow create an array for the spec model, and then ensure that both the ID and user entered data are appropriately extracted... what goes in the ??? and what do we do after? Any help would be much appreciated.
this is how I do it. I make a form, validate it with angular, and then when its valid I submit it with a function.
<form name="signup_form" novalidate ng-submit="signupForm()"></form>
$scope.signupForm = function() {
var data = $scope.signup;
$http({
method : 'POST',
url : 'http://yoursite.com/mail.php',
data : $.param(data), // pass in data as strings
headers : { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers so angular passing info as form data (not request payload)
})
.success(function(data) {
});
}
also if you want to look at another form validation system for angular check out http://nimbly.github.io/angular-formly/#!/ It may help you solve your current form system.
In the controller, initialize $scope.specDetails as follows:
$scope.specDetails = {};
angular.forEach($scope.categories, function (category, index1) {
$scope.specDetails[category.id] = {};
angular.forEach(category.specs, function (spec, index2) {
$scope.specDetails[category.id][spec.id] = '';
});
});
In the html, replace "???" with specDetails[selectedCategory.id][spec.id]

Categories