I have some issues with select on angular Js, I searched a lot and found some solutions but not working.
I have a Json Structured like that generated from my service.php
[
{
"Name": "Name1",
"Variante": [
{
"Prix": "79.00",
"Name": "20 Piéces"
}
],
"Description": "",
"main_image": "images/products/DSC_0192.jpg"
},
{
"Name": "NAME2",
"Variante": [
{
"Prix": "39.00",
"Name": "250g"
},
{
"Prix": "60.00",
"Name": "500g"
}
],
"Description": "",
"main_image": "images/products/DSC_0125.jpg"
}
]
Here is my controller.js
.controller('productsCtrl', function($scope, $http, $stateParams) {
$http.get('service.php')
.success(function (response) {
$scope.products = response;
});
});
Here is my products.html
<ion-view view-title="Products">
<ion-content>
<ion-list>
<ion-item style="background-image: url({{product.main_image}})"
ng-repeat="product in products" class="productListItem">
<h2 class="h2Name">{{product.Name}}</h2>
<button class="button button-balanced button-right">
<i class="icon ion-ios-cart"></i>
</button>
<select class="Variantes"
ng-if="product.Variante.length > 1"
ng-model="selectedItem"
ng-options="variant.Name for variant in product.Variante">
</select>
<h2 class="Variantes" ng-if="product.Variante.length == 1">
{{product.Variante[0].Name}}
</h2>
<h2 class="h2Price" ng-if="product.Variante.length > 1">
{{selectedItem.Prix}}
</h2>
<h2 class="h2Price" ng-if="product.Variante.length == 1">
{{product.Variante[0].Prix}}
</h2>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
If I have more than one VarianteI want to be able to change the price (Prix) value when I change the select box. But it doesn't work.
Any help needed !!
Thanks
The issue you have is due to the ng-if. It creates a separate scope, use ng-show instead cause it uses the same scope and your code should work perfectly.
Using ng-show would work but you could also use ng-if if you're taking care of the dot rule for ng-model.
If you would add your selectedItem to the product object your markup with ng-if will work as expected. Your ng-model for the select would be like ng-model="product.selectedItem".
Please have a look at the demo below or in this jsfiddle.
var jsonData = [
{
"Name": "Name1",
"Variante": [
{
"Prix": "79.00",
"Name": "20 Piéces"
}
],
"Description": "",
"main_image": "images/products/DSC_0192.jpg"
},
{
"Name": "NAME2",
"Variante": [
{
"Prix": "39.00",
"Name": "250g"
},
{
"Prix": "60.00",
"Name": "500g"
}
],
"Description": "",
"main_image": "images/products/DSC_0125.jpg"
}
];
angular.module('demoApp', ['ionic'])
.controller('productsCtrl', function($scope, $http, $stateParams) {
$scope.product = {
selectedItem: {}
};
//$http.get('service.php')
//.success(function (response) {
//http just removed for the demo
$scope.products = jsonData;//response;
//});
});
<script src="http://code.ionicframework.com/1.1.0/js/ionic.bundle.js"></script>
<link href="http://code.ionicframework.com/1.1.0/css/ionic.css" rel="stylesheet"/>
<ion-view ng-app="demoApp" ng-controller="productsCtrl" view-title="Products">
<ion-content>
<ion-list>
<ion-item style="background-image: url({{product.main_image}})"
ng-repeat="product in products" class="productListItem" ng-init="product.selectedItem = product.Variante[0]">
<h2 class="h2Name">{{product.Name}}</h2>
<button class="button button-balanced button-right">
<i class="icon ion-ios-cart"></i>
</button>
<select class="Variantes"
ng-if="product.Variante.length > 1"
ng-model="product.selectedItem"
ng-options="variant.Name for variant in product.Variante">
</select>
<h2 class="Variantes" ng-if="product.Variante.length == 1">
{{product.Variante[0].Name}}
</h2>
<h2 class="h2Price" ng-if="product.Variante.length > 1">
{{product.selectedItem.Prix | currency}}
</h2>
<h2 class="h2Price" ng-if="product.Variante.length == 1">
{{product.Variante[0].Prix | currency}}
</h2>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
Related
I'm a complete angular noob so please forgive the rudimentary question.
I have a post/comment structure for my model that looks like this:
[
{
"title": "awesome post",
"desc": "asdf",
"comment_set": [
{
"id": 2,
"desc": "another awesome comment",
}
]
}
]
My angular template looks like the following:
<li ng-repeat="post in $ctrl.phones | filter:$ctrl.query | orderBy:$ctrl.created_at" class="media media-clearfix-xs">
<div>{{post.title}}</div>
<ul class="comments">
<li ng-repeat="comment in post.comment_set | orderBy:created_at" clas="media">
<div>{{comment.desc}}
</li>
<li class="comment-form">
<div class="input-group">
<form ng-submit="$ctrl.addComment()">
<input ng-model="post.comment_set.desc" type="text" class="form-control" />
</form>
<span class="input-group-btn">
<input type="submit" class="btn btn-default"><i class="fa fa-photo"></i></input>
</span>
</div>
</li>
</ul>
</li>
My angular component looks like this:
angular.
module('phoneList').
component('phoneList', {
templateUrl: '/static/common/angular/phone-list/phone-list.template.html',
controller: ['$http',
function PhoneListController($http) {
var self = this;
self.addComment = function() {
self.push({desc:post.comment_set.desc});
};
$http.get('api/posts/').then(function(response) {
self.phones = response.data;
});
}
]
});
What am I missing that will add comments to the comments ng-repeat?
Your addComment function is incorrect.
You should have:
ng-submit="addComment(post.comment_set)"
and:
ng-model="$ctrl.desc"
Then, addComment() should be:
self.addComment(comment_set){
comment_set.push({desc: self.desc, id: <ID_HERE>});
self.desc = null;
}
This way, you reset the desc variable so you can add a new comment
i have
in html its looks like:
<ul class="filter-ul">
<li class="filter-li">
<span class="filter-title">Все бренды</span>
<ul class="filter-ul" ng-repeat="brand in vendors |filter:query_brand">
<li class="filter-li">{{ brand.name }}</li>
</ul>
</li>
</ul>
One item in my Json looks like this:
{
"name": "Bra by Joseline",
"category": null,
"price": 8370.0,
"old_price": 8370.0,
"vendor": {
"id": 1,
"name": "Agent Provocateur",
"seo_name": ""
},
"recommended": [],
"id": 750
}
i want filtering my items by "vendor.name" field and i have no idea how make it reality, its my first expirience in angularJS, sorry for noob question :)
My controller look like this:
(function () {
'use strict';
angular
.module('beo.products.controllers')
.controller('ProductsListController', ProductsListController);
ProductsListController.$inject = ['$scope', '$http'];
function ProductsListController($scope, $http) {
$scope.setMainClasses('catalog-page');
activate();
function activate() {
$http.get('api/v1/products/').success(function(data) {
$scope.products = data;
$scope.ProductSortLeft = '-id'; //по умолчанию фильтроваться будут по обновлению
});
$http.get('api/v1/categories/').success(function(data) {
$scope.categories = data;
});
$http.get('api/v1/shops/').success(function(data) {
$scope.shops = data;
});
$http.get('api/v1/vendors/').success(function(data) {
$scope.vendors = data;
});
}
}
})();
I use filter columns like these:
<filter></filter>
<!-- CATALOG -->
<div class="catalog-main" id="catalog">
<div class="catalog-result-options hidden-xs">
<div class="result-alert" id="result-show-modal">Уведомление о рапродаже</div>
<select class="selectpicker" ng-model="ProductSortLeft">
<option value="-price">Самые дорогие</option>
<option value="price">Самые дешевые</option>
<option value="click_count">Популярные</option>
<option value="-id">Новые</option>
</select>
</div>
<div class="catalog-item" ng-repeat="product in products | orderBy:ProductSortLeft">
<div class="item-pre-title">
Бесплатная доставка $150+
</div>
<div class="item-img">
<a href="/products/{{ product.id }}/"><img ng-src="{{ product.picture[0].external_img_url }}" width="150px"
height="150px" alt=""></a>
</div>
{{ product.name }}
<div class="item-price">
<div class="price-old">{{ product.old_price }}</div>
<b>{{ product.price }}</b>
</div>
<div class="item-footer">
<div class="item-sales-alert">
Получить скиду
</div>
</div>
</div >
You can filter on vendor.name like this:
var app = angular.module('myapp', []);
app.controller('myctrl', function($scope) {
$scope.filter = "";
$scope.brands = [{
"name": "Bra by Joseline",
"category": null,
"price": 8370.0,
"old_price": 8370.0,
"vendor": {
"id": 1,
"name": "Agent Provocateur",
"seo_name": ""
},
"recommended": [],
"id": 750
}, {
"name": "Another brand",
"category": null,
"price": 8370.0,
"old_price": 8370.0,
"vendor": {
"id": 1,
"name": "Agent Bond",
"seo_name": ""
},
"recommended": [],
"id": 750
}]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myapp" ng-controller="myctrl">
<input ng-model="filter" placeholder="filter" />
<ul class="filter-ul" ng-repeat="brand in brands | filter: {vendor: {name: filter}}">
<li class="filter-li">{{ brand.name }}</li>
</ul>
</div>
I am new to angularjs. I am trying to add check boxes into a particular scope.group
Below is the mock-up of what i want to achieve and code.
<accordion close-others="false">
<accordion-group ng-repeat="group in groups" is-open="group.open">
<accordion-heading>
<i ng-class="{'icon-minus-sign':groups[$index].open,'icon-plus-sign':!groups[$index].open }"></i>
<span class="title-pos" >{{group.title}}</span>
</accordion-heading>
{{group.content}}
</accordion-group>
</accordion>
<script>
angular.module('main',['ui.bootstrap'])
.controller('AppCtrl', function($scope){
$scope.groups = [
{
"title":"Series",
"open":true
},
{
"title":"Price Range",
"content":"Content B",
"open":true
},
{
"title":"Engine Type",
"content":"Content C",
"open":false
},
{
"title":"Engine Type",
"content":"Content C",
"open":false
},
{
"title":"Life Style",
"content":"Content C",
"open":false
},
{
"title":"Seats",
"content":"Content C",
"open":false
},
];
})
</script>
I would like to add the check box to Engine type group.
Look forward for any help
Thanks in advance
Replace {{group.content}} with <div ng-bind-html="group.content"></div>
You should then add your checkboxes HTML code inside "content" part of "Engine Type" group, similar to this :
...
{
"title":"Engine Type",
"content":'<input type="checkbox" name="checkbox1" value="Petrol">Petrol',
"open":false
},
...
For each one of the enteries in $scope.groups whatever comes in "content" will appear inside <div ng-bind-html="group.content"></div> block.
Finally, Be sure to add ngSanitize to your module dependencies as in this plunkr
You can add the checkboxes in the content area
<accordion-group ng-repeat="group in groups" is-open="group.open">
<accordion-heading>
<i ng-class="{'icon-minus-sign':groups[$index].open,'icon-plus-sign':!groups[$index].open }"></i>
<span class="title-pos" >{{group.title}}</span>
</accordion-heading>
<div ng-repeat="option in group.options">
<!-- checkbox and text here -->
</div>
</accordion-group>
And reorganize your data to include the checkboxes model
$scope.groups = [
{
"title":"Engine Type",
"content":"Content C",
"open":false,
"options": [
"Petrol", // or if you have id for them: {id:engine_petrol, name:"Petrol"}
"Diesel",
"Hybrid"
]
}
];
Background:
I have created an AngularJS test app which, obtains data from a JSON file, which is separated into categories and within each category is an employee card which is displayed through ng-repeat. These categories can then be viewed utilising a slider (using bxSlider).
Aim:
With bxSlider you can use custom Next/Previous buttons, what I wanted to achieve was to dynamically display the relevant category names in the Next/Previous buttons (please see annotation link below - my level does not allow me to post images).
Website Category Slider Wireframe
For example: the current category on view is the 'Technology' department, the previous button may then show 'Motors' department and the next button may show 'Law' department.
I understand that the code below would allow me to access the Category name 'Technology'. However this needs to be done in a dynamic nature.
{{employees[0].category}}
Below this I will include all what I believe to be relevant code.
JSON file:
[
{
"category": "Technology",
"shortname": "tech",
"icon": "fa-desktop",
"cards": [
{
"id": "card-1",
"name": "George Sofroniou",
"shortname": "G_Sof",
"age": "23",
"company": "Pirean Ltd.",
"role": "Graduate UI Developer"
},
{
"id": "card-2",
"name": "Steve Jobs",
"shortname": "S_Jobs",
"age": "56 (Died)",
"company": "Apple Inc.",
"role": "Former CEO"
},
{
"id": "card-3",
"name": "Mark Zuckerberg",
"shortname": "M_Zuck",
"age": "30",
"company": "Facebook",
"role": "CEO"
},
{
"id": "card-4",
"name": "Tim Cook",
"shortname": "T_Cook",
"age": "54",
"company": "Apple Inc.",
"role": "CEO"
},
{
"id": "card-5",
"name": "Jony Ive",
"shortname": "J_Ive",
"age": "48",
"company": "Apple Inc.",
"role": "Senior Vice President of Design"
},
{
"id": "card-6",
"name": "Marissa Mayer",
"shortname": "M_May",
"age": "39",
"company": "Yahoo!",
"role": "CEO"
},
{
"id": "card-7",
"name": "Yves Behar",
"shortname": "Y_Beh",
"age": "47",
"company": "Fuseproject",
"role": "Founder"
}
]
},
{
"category": "Motors",
"shortname": "mot",
"icon": "fa-car",
"cards": [
{
"name": "Elon Musk",
"shortname": "E_Musk",
"age": "43",
"company": "Tesla Motors",
"role": "CEO"
}
]
},
{
"category": "Football",
"shortname": "foot",
"icon": "fa-futbol-o",
"cards": [
{
"id": "card-1",
"name": "Sir Alex Ferguson",
"shortname": "A_Fer",
"age": "73",
"company": "N/A",
"role": "Retired"
}
]
},
{
"category": "Law",
"shortname": "law",
"icon": "fa-gavel",
"cards": [
{
"id": "card-1",
"name": "Harvey Specter",
"shortname": "H_Spec",
"age": "43",
"company": "Pearson Specter Litt",
"role": "Name Partner"
}
]
}
]
HTML Code:
<!-- Slider Container -->
<div class="slider-container">
<!-- Search Content -->
<!-- controls: true -->
<div class="content-results bxslider"
bx-slider="mode: 'horizontal', pager: true, nextSelector: '#next', prevSelector: '#prev', nextText: '<i class=\'fa fa-chevron-right\'></i>', prevText: '<i class=\'fa fa-chevron-left\'></i>', minSlides: 1, maxSlides:1, infiniteLoop: true, adaptiveHeight: true, hideControlOnEnd: false">
<!-- Employee -->
<div class="cards-container"
ng-repeat="item in filtered = ( employees | filter: query | orderBy:empOrder:direction )"
notify-repeat-finished>
<div class="category" ng-animate="'animate'" >
<div class="category-title">
<h1 class="title-cat"><i class="fa {{item.icon}}"></i> {{ item.category }}</h1>
</div>
<div class="category-cards-container">
<div class="employee-card card" ng-repeat="employee in filtered = (item.cards | filter: query | orderBy:empOrder:direction )" dom-manipulation>
<!-- Front Card -->
<div class="front">
<div class="pic-container">
<img ng-src="../static/images/placeholders/{{ employee.shortname }}.jpg" class="emp-pic" alt="Photo of {{ employee.name }}">
<h3 class="emp-name">{{ employee.name }}</h3>
<div class="darken"></div>
</div>
<ul class="emp-details">
<li class="detail emp-age">
<h5>Age: <small>{{ employee.age }}</small></h5>
</li>
<li class="detail emp-role">
<h5>Role: <br><small>{{ employee.role }}</small></h5>
</li>
<li class="detail emp-company">
<h5>Company: <br><small>{{ employee.company }}</small></h5>
</li>
</ul>
</div>
<!-- END Front Card -->
<!-- Back Card -->
<div class="back">
<div id="map-load">
<i class="fa fa-map-marker"></i>
</div>
<div id="maps-container">
<div id="googleMap"></div>
</div>
<i class="fa fa-times"></i>
</div>
<!-- END Back Card -->
</div>
</div>
</div>
<!-- No Matches -->
<div class="no-match" ng-show="filtered.length == 0">
<h3 class="no-matchText">Your search provides no matches!</h3>
</div>
<!-- END No Matches -->
</div>
<!-- END Employee -->
</div>
<!-- END Search Content -->
<!-- Next & Previous Buttons -->
<div class="btn-nextprev">
<div class="next-container">
<a href="" class="btn btn-next" id="next">
</a>
</div>
<div class="prev-container">
<a href="" class="btn btn-prev" id="prev">
</a>
</div>
</div>
<!-- END Next & Previous Buttons -->
</div>
<!-- END Slider Container -->
AngularJS:
Controller
var personControllers = angular.module('personControllers', ['ngAnimate']);
//PersonSearch Controller
personControllers.controller('PersonList', ['$scope', '$http',
function($scope, $http) {
$http.get('../static/scripts/data2.json').
success(function(data) {
console.log("JSON file loaded");
console.log(data);
$scope.employees = data;
//$scope.empOrder = 'name';
}).
error(function(){
console.log("JSON file NOT loaded");
});
}]);
EDIT
Updated Controller
var personControllers = angular.module('personControllers', ['ngAnimate']);
//PersonSearch Controller
personControllers.controller('PersonList', ['$scope', '$http',
function($scope, $http) {
$http.get('../static/scripts/data2.json').
success(function(data) {
console.log("JSON file loaded");
console.log(data);
$scope.employees = data;
//$scope.empOrder = 'name';
//Next & Previous Button Category Label
$scope.getNextCategoryIndex = function(currentIndex){
var nextIndex = currentIndex+1;
if( nextIndex >= $scope.employees.length ){
//move to start if at list end
nextIndex = 0;
}
return nextIndex;
}
$scope.getPrevCategoryIndex = function(currentIndex){
var prevIndex = currentIndex+1;
if( prevIndex < 0 ){
//move to the last index, if already at the start
prevIndex = $scope.employees.length - 1;
}
return prevIndex;
}
}).
error(function(){
console.log("JSON file NOT loaded");
});
}]);
Updated Next/Previous Buttons
<!-- Next & Previous Buttons -->
<div class="btn-nextprev">
<div class="next-container">
<a href="" class="btn btn-next" id="next">
{{ employees[getNextCategoryIndex($index)].category }}
</a>
</div>
<div class="prev-container">
<a href="" class="btn btn-prev" id="prev">
{{ employees[getPrevCategoryIndex($index)].category }}
</a>
</div>
</div>
<!-- END Next & Previous Buttons -->
I would probably do something like this: create functions to your controller to get the previous and next indexes (to handle the index overflows):
$scope.getNextCategoryIndex = function(currentIndex) {
var nextIndex = currentIndex+1;
if (nextIndex >= $scope.employees.length) {
// move over to start if we already were at the end of the list
nextIndex = 0;
}
return nextIndex;
}
$scope.getPrevCategoryIndex = function(currentIndex) {
var prevIndex = currentIndex+1;
if (prevIndex < 0) {
// move over to the last index, if we already are at the start
prevIndex = $scope.employees.length - 1;
}
return prevIndex;
}
And then in the HTML call those functions using $index (the current index of ng-repeat, see AngularJS documentation for ngRepeat for more details) as parameter:
<!-- Next & Previous Buttons -->
<div class="btn-nextprev">
<div class="next-container">
<a href="" class="btn btn-next" id="next">
{{employees[getNextCategoryIndex($index)].category}}
</a>
</div>
<div class="prev-container">
<a href="" class="btn btn-prev" id="prev">
{{employees[getPrevCategoryIndex($index)].category}}
</a>
</div>
</div>
<!-- END Next & Previous Buttons -->
The code you need should be:
{{employees[$index - 1].category}} //For the prev
{{employees[$index + 1].category}} //For the next
Recent Update (09-Apr-2015):
I have now been able to achieve what I wanted, on click of the button the relevant function runs and loops through the category names. One more thing to add now is that the buttons run in sync.
Controller
//Next & Previous Button Category Label
$scope.i = 0;
$scope.j = $scope.employees.length;
$scope.nextCat = $scope.i + 1;
$scope.prevCat = $scope.j - 1;
$scope.getNext = function(){
//console.log($scope.nextCat);
$scope.nextCat++;
if( $scope.nextCat >= $scope.employees.length ){
$scope.nextCat = 0;
}
$scope.prevCat++;
if( $scope.prevCat >= $scope.employees.length ){
$scope.prevCat = 0;
}
};
$scope.getPrev = function(){
//console.log($scope.nextCat);
$scope.prevCat--;
if( $scope.prevCat < 0 ){
$scope.prevCat = $scope.employees.length - 1;
}
$scope.nextCat--;
if( $scope.nextCat < 0 ){
$scope.nextCat = $scope.employees.length - 1;
}
};
HTML
<!-- Next & Previous Buttons -->
<div class="btn-nextprev">
<div class="next-container">
<a href="" class="btn btn-next" id="next"
ng-click="getNext()">
</a>
{{ employees[nextCat].category }}
</div>
<div class="prev-container">
<a href="" class="btn btn-prev" id="prev"
ng-click="getPrev()">
</a>
{{ employees[prevCat].category }}
<!-- {{ employees[prevCat].category }} -->
</div>
</div>
<!-- END Next & Previous Buttons -->
Update:
This is still not going to be a viable solution. I am technically able to achieve what is required however I am still required to use position: fixed. This means that the Category label then disappears.
I am now going to try and achieve this without it being within the ng-repeat and using ng-click it will iterate to the next Category name. Hopefully this will be the solution, and I will update upon any success/failure.
Update:
I am yet to find my optimal solution however, my current workaround for this utilises #jmustonen's solution.
Outside of the bxSlider I have the custom arrow's (if I placed these inside there were issues with the arrows not duplicating across pages - I believe there's an issue with it when it has position:fixed).
Then within my ng-repeat I include...
{{ employees[getNextCategoryIndex($index)].category }}
I will then be required to do some CSS in order for this to appear as if it is displayed as part of the Next/Previous buttons. Again these become invisible if position: fixed is used.
I for my stage have to modifie a web site for that i need angularjs i wanted to use the command ng-repeat to display some documentation but when i add ng-repeat in the div it "destroy" it and i cant figure out why...
So there is the code hope u can help me.
There is my js
App.controller('doccontroller', [ function(){
return {
scope: {},
restrict: 'A',
link: function ($scope){
$scope.docs = [
{
"id_section" : 0,
"description": "RANDOM STUFF",
"source": [
{
"python": "TEXTE",
"ruby": "TEXTE",
"javascript": "TEXTE"
}
]
},
{
"id_section" : 1,
"description": "RANDOM STUFF",
"source": [
{
"python": "TEXTE",
"ruby": "TEXTE",
"javascript": "TEXTE"
}
]
},
{
"id_section" : 2,
"description": "RANDOM STUFF",
"source": [
{
"python": "TEXTE",
"ruby": "TEXTE",
"javascript": "TEXTE"
}
]
}
]
}
}
}
])
`There is my route to "include" the controller
$routeProvider.when '/docs',
templateUrl : config.BaseHtml+'/Page/docs.html'
controller : 'doccontroller'
`
and to finish the html :)
<div id="api-docs">
<div id="methods">
<div class="languages">
<a class="language selected" data-lang="ruby" href="#">Ruby</a>
<a class="language" data-lang="python" href="#">Python</a>
<a class="language" data-lang="php" href="#">PHP</a>
</div>
<div>
<div class="method" id="intro">
<div class="method-section clearfix">
<div class="method-description" ng-repeat="doc in docs">
<h3>Introduction</h3>
<p>
{{doc.description}}
</p>
</div>
<div class="method-example">
<pre>
<code class="ruby"># All this code is just folololol
React.api_key = "In here goes your api key!"</code><code class="python"># All this code is just for demonstration purposes
react.api_key = "In here goes your api key!"</code><code class="php"># All this code is just for demonstration purposes
React::setApiKey("In here goes your api key!");</code>
</pre>
</div>
</div>
</div>
</div>
</div>
</div>
So to say it again, what i need to do is to fill create 1 div / id_section and to fill it with the
descrition for now.
Change:
ng-repeat="docs in docs"
to:
ng-repeat="doc in docs"
Also, in your code you have a call to {{ doc.des }}, which probably should be {{ doc.description }}