Show/hide template URL's in angularjs - javascript

I have a dynamic Array in Controller which has templates(html files) similar to below
$scope.templates =
[ { name: 'template1.html', url: 'template1.html'},
{ name: 'template2.html', url: 'template2.html'} ];
I have a dropdown to choose the template.
I am using ng-include in html to get these files.
The issue is:
When I have loaded template1.html and then switching to template2.html, I want to hide template1.html data and show template2.html.
The next time, when I select template1.html, I want to hide template2.html data and show template1.html data instead of loading template1.html again.
I have tried below:
html:
<div ng-controller="ExampleController">
<select ng-model="template" ng-options="t.name for t in templates">
<option value="">(blank)</option>
</select>
url of the template: <code>{{template.url}}</code>
<hr/>
<div class="slide-animate-container" ng-show="template.isHidden">
<div class="slide-animate" ng-include="template.url"></div>
</div>
<div class="slide-animate-container" ng-hide="template.isHidden">
<div class="slide-animate"></div>
</div>
</div>
app.controller('ExampleController', ['$scope', function($scope) {
$scope.templates =
[ { name: 'template1.html', url: 'template1.html'},
{ name: 'template2.html', url: 'template2.html'} ];
$scope.template = $scope.templates[0];
$scope.$watch('template',function(newValue, oldValue) {
$scope.templates[0].isHidden = true;//will do _.each to update
$scope.templates[1].isHidden = true;
var xyz = $scope.template;
xyz.isHidden = false;
});
}]);
template1.html, template2.html can be normal html files.
Please suggest.
https://plnkr.co/edit/TJKYbDrp1C1g4fQNHCi2?p=preview

This line:
<div class="slide-animate-container" ng-show="template.isHidden">
prob. meant to be:
<div class="slide-animate-container" ng-include="template.url" ng-show="!template.isHidden">
You want to show the div if the value of isHidden is false.

Related

AngularJS data model architecture

I have the following thing on my Angular app:
$scope.things = [{
title: 'Simple',
type: 1,
form: {
input: [1, 2, 3],
clone: true
}
}];
$scope.clone = function(item) {
item.form.input.push(Math.floor(Math.random() * 999));
};
And on the HTML part:
<div ng-repeat="item in things" class="item">
<h2>{{item.title}}</h2>
<div ng-repeat="input in item.form.input">
<input type="text" />
</div>
<button ng-click="cloneInput(item)">Clone</button>
</div>
When press the Clone button I'm pushing a new element to form.input array and add a new input to the DOM.
I want to $http.post all the values for the inputs.
I know to push something I need to use
$http.post('/path/to/my/api', {my object}).callback()
But I dont know how to make an object from all the .item inputs.
Can someone explain me how or suggest a better solution?
If you use a ng-model for your inputs and set it to an object you can then inject that object to the post, here is a really basic example:
JSFiddle
HTML:
<div ng-app="myApp" ng-controller="dummy">
<div ng-repeat="input in items">
<input type="text" name="{{input.name}}" ng-model="data[input.name]" />
</div>
<button ng-click="submit()">Submit</button>
<p ng-show="displayIt">{{data}}</p>
</div>
JS:
angular.module('myApp', [])
.controller('dummy', ['$scope', function ($scope) {
$scope.items = [{
name: 'test'
}, {
name: 'test2'
}];
$scope.data = {};
$scope.displayIt = false;
$scope.submit = function () {
// This is only to check it
$scope.displayIt = true;
// Do your post here
};
}]);

Selecting a single object from an array to display in a view [Angular]

I've similarly asked this before, but neither solution proved useful.
I currently have a store app built with AngularJS, my problem is, I need to be able to click on one item and open into the "item" view and display only the information with a matching ID from the items array stored in a services.
For example. Item one displayed on store view has an id of 1, and on the store displays the product name etc. When clicked, the item is opened with the item view to display just that product and it's information.
Here's my store Controller:
'use strict';
angular.module('angularStoreApp')
.controller('storeCtrl', function($scope, StoreService){
$scope.items = StoreService.items();
});
Services (Shortened to save spare, there's 12 other items).
'use strict';
angular.module('angularStoreApp')
.service("StoreService", function() {
var items = [ {
itemId: 1,
qty: 0,
stock: 5,
price: 99.00,
name: 'Almond Toe Court Shoes, Patent Black',
category: 'Womens Footerwear'
},
{
qty: 0,
stock: 4,
price: 42.00,
name: 'Suede Shoes, Blue',
category: 'Womens Footerwear'
}];
this.items = function() {
return items;
};
});
Store View
<!-- Start of item iteration -->
<div ng-repeat="item in items">
<!-- Start of item -->
<div class="item">
<div class="item_info">
<img src="http://i.imgur.com/Bn1iB6X.jpg"/>
<div class="item_footer">
<div class="info_text">
<h2>{{item.name| limitTo: 8}}...</h2>
<span>{{item.price | currency}}</span>
</div>
<div class="icon">
<a ng-href="#"><button role="button">More</button></a>
</div>
</div>
</div>
</div>
<!-- End of item -->
</div>
<!-- End of item iteration-->
Item Ctrl
'use strict';
angular.module('angularStoreApp')
.controller('itemCtrl', function ($scope, StoreService) {
$scope.items = StoreService.items();
});
Item View
<div ng-include="'components/navbar/navbar.html'"></div>
<div ng-repreat="item in items">
<div class="item-page-container">
<div class="item-p-img">
{{item.name}}
</div>
<div class="item-p-tab-Container">
<ul>
<li>{{item.name}}</li>
<li></li>
<li></li>
</ul>
</div>
</div>
</div>
Please ask for any more code or for easier view, see my Github Repo
Please be clear on the function, feel free to put into a plunker, my Javascript skills come from Angular, but searching an array like this I haven't done before. I'd need a good solution where I can transfer/learn the logic.
Store View
(not sure about your routing) but would try smt like this:
<a ng-href="/items/{{item.itemID}}"><button role="button">More</button></a>
this should send you to your item view.
In your Item ctrl, if you inject $routeParams you could fetch the id like so:
item_id = $routeParams.id
and then search for your item like so:
items = StoreService.items();
$scope.item = items.indexOf(item_id)
so in your item view remove the ng-repeat and work with the item object.
As I said before, not enterily sure of your project's structures,. but this should get you on your way.
Make your routes like this :
$routeProvider
.when('/items', {
templateUrl: 'yourtemplate-path/items.html',
controller: 'yourItemController'
})
.when('/items/:itemId', {
templateUrl: 'yourtemplate-path/items-detail.html',
controller: 'yourItemDetailsController'
})
Your controller:
For items,
'use strict';
angular.module('angularStoreApp')
.controller('storeCtrl', function($scope, StoreService){
StoreService.items(function(){
$scope.items = data;
});
});
For item detail page,
'use strict';
angular.module('angularStoreApp')
.controller('storeDetailsCtrl', function($scope, $routeParams, StoreService){
StoreService.items({itemId: $routeParams.itemId}, function(){
$scope.item = data;
});
});
and create your new service, which fetches the data based on this id(itemId)
NOTE: I didn't tested the code.

Angularjs bind dynamic form bulit in js

I have a form that I want to build at run time via js and use it in a form controller in angularjs.
As you can see in the following example, it is not being thrown as html, and i want it to be binded to the model variable. http://jsfiddle.net/g6m09eb7/
<div>
<form ng-controller="TodoCtrl" ng-submit="blabla()">
<div ng-repeat="field in fields">{{field.input}}</div>
</form>
</div>
function TodoCtrl($scope) {
$scope.model = {
'FirstName': 'Test',
'LastName': 'Test Last'
}
$scope.fields = [{
input: '<input type="text" ng-model="model.FirstName">'
}, {
input: '<input type="text" ng-model="model.LastName">'
}, ];
}
First, I'm going to show you how to make this work as you're trying to accomplish it, for the sake of being informative. This is not the approach you should use to solve your overall problem. This example will get the html in the document, but it won't be compiled with Angular. To do that, you would have to have a different directive, like this (click). This is all kinds of a bad approach.
angular.module('myApp', [])
.controller('TodoCtrl', function($scope) {
$scope.fields = [{
input: '<input type="text" ng-model="model.FirstName">'
}, {
input: '<input type="text" ng-model="model.LastName">'
}, ];
})
// filter to make Angular trust the html
.filter('safeHtml', ['$sce', function ($sce) {
return function (text) {
return $sce.trustAsHtml(text);
};
}])
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="myApp" ng-controller="TodoCtrl">
<!-- use ng-bind-html on trusted html to bind it (see the js) -->
<div ng-repeat="field in fields" ng-bind-html="field.input | safeHtml"></div>
</form>
Instead, you can do this naturally. Just use the properties of your object as the criteria for ng-repeat. Simple and clean!
angular.module('myApp', [])
.controller('TodoCtrl', function($scope) {
$scope.model = {
'FirstName': 'Test',
'LastName': 'Test Last'
};
})
;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<form ng-app="myApp" ng-controller="TodoCtrl">
<div ng-repeat="(key,value) in model">
<input type="text" ng-model="model[key]"/>
</div>
</form>
Be sure to avoid concerning your controller with DOM manipulation. If you have html snippets in a controller, your approach is probably off track. DOM manipulation should be done entirely with directives.

AngularJS dynamically populate details from json based on item selected

I am trying to create a page where you have few items in a list group which when selected should show more details.
Please view the example here http://plnkr.co/edit/Oava3pA9OTsm80K58GdT?p=preview
How can I populate the details from the json file based on the item that is selected in the list group?
This is what I have so far.
html:
<div ng-controller=ItemsController>
<h3>Test</h3>
<div class="row">
<div class="col-md-4">
<div class="panel panel-default">
<ul class="list-group">
<a class="list-group-item" ng-repeat="item in itemDetails">{{item.name}}</a>
</ul>
</div>
</div>
<div class="col-md-8">
<div class="panel panel-default">
<h2>Name: </h2>
<br />Address Line 1:
<br />Address Line 2:
<br />Suburb:
<br />Phone:
<br />Email:
</div>
</div>
</div>
</div>
script:
var myItemsApp = angular.module('myItemsApp', []);
myItemsApp.factory('itemsFactory', ['$http', function($http){
var itemsFactory ={
itemDetails: function() {
return $http(
{
url: "mockItems.json",
method: "GET",
})
.then(function (response) {
return response.data;
});
}
};
return itemsFactory;
}]);
myItemsApp.controller('ItemsController', ['$scope', 'itemsFactory', function($scope, itemsFactory){
var promise = itemsFactory.itemDetails();
promise.then(function (data) {
$scope.itemDetails = data;
console.log(data);
});
}]);
json:
[
{
"$id":"1",
"name":"Test itemName 1",
"themeName":"ASD",
"addressLine1":"18 Banksia Street",
"addressLine2":null,
"suburb":"Heidelberg",
"state":"VIC",
"postalCode":"3084",
"contactPhone":"+61 3 123456",
"emailAddress":"qwerty.it#xyz.com"
},
{
"$id":"2",
"name":"Test itemName 2",
"themeName":"WER",
"addressLine1":"11 Riverview Place",
"addressLine2":"Metroplex on Gateway",
"suburb":"Murarrie",
"state":"QLD",
"postalCode":"4172",
"contactPhone":"1300 73123456",
"emailAddress":"asdfg.it#xyz.com"
},
{
"$id":"3",
"name":"Test itemName 3",
"themeName":"ERT",
"addressLine1":"60 Waterloo Road",
"addressLine2":null,
"suburb":"North Ryde",
"state":"NSW",
"postalCode":"2113",
"contactPhone":"123456",
"emailAddress":"zxcvb.it#xyz.com"
}
]
Any help would be greatly appreciated.
I am very new to programming. Please also feel free to alternative ways of achieving this if I have done it wrong.
You can use the ng-click directive to specify what happens when you click something.
So I made it assign the clicked item to the $scope.selected object using a function ($scope.select(item)) and then I bound the properties of that object to your little details section. That's probably the simplest way to do it.
Ctrl
$scope.select = function(item) {
$scope.selected = item;
}
$scope.selected = {};
HTML
<a class="list-group-item" ng-click="select(item)" ng-repeat="item in itemDetails">
{{item.name}}
</a>
And the selected object is then available like this:
<h2>Name: {{selected.name}}</h2>
etc...
See my example here: http://plnkr.co/edit/mUMZ0VGO8l1ufV1JJNQE?p=preview

Dynamically insert directives using meta data in AngularJS?

I'd like to define meta data which will dynamically use the correct directive based on a "type" value:
$scope.items = [
{
type: 'directive-one',
value: 'One'
},{
type: 'directive-two',
value: 'Two'
},{
type: 'directive-three',
value: 'Three'
}
];
and then
<li ng-repeat="item in items" {{type}}>
{{value}}
</li>
I've created a jsfiddle here. So far I've had no success
Is this possible? How would I accomplish this?
Here is an alternative way of solving the problem:
Use ngSwitch to map between type and directive.
<li ng-repeat="item in items">
<div ng-switch on="item.type">
<div ng-switch-when="type-one" directive-one>
</div>
<div ng-switch-when="type-two" directive-two>
</div>
<div ng-switch-when="type-three" directive-three>
</div>
</div>
</li>
See jsfiddle
But if you really need to define the directive in the metadata, you can add a directive that will generate the div element with the appropriate directive
angular.module('myApp').directive('dynamicDirective', function($compile) {
return {
restrict: 'A',
link: function (scope, ele) {
//add a child div element that contains the directive specified in the type property
var itemEl = angular.element('<div>').attr(scope.item.type,'');
$compile(itemEl)(scope);
ele.append(itemEl);
}
};
});
See jsfiddle

Categories

Resources