I have a list page (List.Html) where n number of rows can be selected, in order to visually display the row data in a chart (using C3).
This is done by clicking on a button (compareList()) that navigates to a new page (Chart.Html). The problem is that the chart is not displaying on the new page, possibly because the chart data is being loaded before the page is loading meaning the HTML where the chart needs to be inserted is not found.
If the Chart Page is loaded before the list page, the chart is generated but
only once upon click but then is lost.
Controller.js
$scope.compareList = function(){
var total = $scope.array.length;
var tempArray= [];
for(var i=0; i<total; i++){
if($scope.array[i].selected){
tempArray[i] = $scope.array[i];
}
}
if(comparr.length>0){
$scope.compGraph(tempArray);
}
}
$scope.compGraph = function(array){
var tempData = [];
for(var i=0; i<array.length;i++){
tempData.push([array[i].name,array[i].evi]);
}
var chart = c3.generate({
bindto: '#chart',
data: {
columns: tempData,
type:'bar'
}
});
$state.go('eventmenu.compare');
}
List.Html
<ion-view view-title="List">
<ion-nav-buttons side="right">
<button class="button button-icon icon ion-stats-bars" ng-click="compareList()"></button>
</ion-nav-buttons>
<ion-content>
<ion-item ng-repeat="item in items" class="item-remove-animate">
<div class="row" >
<div class="col col-40"{{ item.name }}</div>
<div class="col col-30" style=";">{{ item.area}}m<sup>2</sup></div>
<div class="col col-20" style=";">{{ item.value}}</div>
<div class="col col-10 col-top" ><ion-checkbox style="border:none;margin-top: -20px;" ng-model="item.selected"></ion-checkbox></div>
</div>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
Chart.HTML
<ion-view view-title="Land Comparison">
<ion-content ng-controller="Controller">
<div class="padding">
<div id="chart" ></div>
</div>
</ion-content>
</ion-view>
I am using ng-if for charts. Set a value for listen to loading situation and use it.
In HTML:
<div class="padding">
<div ng-if="isDataLoaded" id="chart"></div>
</div>
In controller:
$scope.isDataLoaded = false;
function loadData(){
$scope.myData = [1,2,3];
$scope.isDataLoaded = true;
}
Related
I am trying to make a UI using list of product in a json(products.json) file on local and their availability in number from wp rest api call back in html(ionic) I have this:
Controller:
.controller('ShopCtrl', function($scope, $ionicActionSheet, BackendService, CartService, $http, $sce ) {
$scope.siteCategories = [];
$scope.cart = CartService.loadCart();
$scope.doRefresh = function(){
BackendService.getProducts()
.success(function(newItems) {
$scope.products = newItems;
console.log($scope.products);
})
.finally(function() {
// Stop the ion-refresher from spinning (not needed in this view)
$scope.$broadcast('scroll.refreshComplete');
});
};
$http.get("http://example.com/wp-json/wp/v2/categories/").then(
function(returnedData){
$scope.siteCategories = returnedData.data;
console.log($scope.siteCategories);
}, function(err){
console.log(err);
});
Template view:
<div ng-repeat = "product in products">
<div class="item item-image" style="position:relative;">
<img ng-src="{{product.image}}">
<div ng-repeat = "siteCategory in siteCategories">-->
<button class="button button-positive product-price" ng-click="addProduct(product)">
<p class="white-color product-price-price">post <b>{{siteCategory[$index].count}}</b></p>
</button>
</div>
</div>
<div class="item ui-gradient-deepblue">
<h2 class="title white-color sans-pro-light">{{product.title}} </h2>
</div>
<div class="item item-body">
{{product.description}}
</div>
</div>
so how can I achieve that? I tried to use nested ng-repeat but it didn't work out.
I am not able to get the ng-click event to trigger when inside an item in a ionic modal that pops up. When I click on an item I see it turn gray so it seems like it is registering the click but I have a console.log statement as the first line in my joinGroup function and nothing is output to the console.
I also tried using the ion-list and ion-item elements but those didn't work either.
<ion-modal-view>
<ion-header-bar class="bar bar-header bar-balanced">
<h1 class="title">Join Court</h1>
<button class="button button-clear button-primary" ng-click="modal.hide()">Done</button>
</ion-header-bar>
<ion-content class="padding">
<div class="list">
<div class="item item-icon-right" ng-repeat="group in groups" ng-click="joinGroup(group)">
<h2>{{group.name}}</h2>
<p>{{group.address}}</p>
</div>
</div>
</ion-content>
</ion-modal-view>
var joinGroup = function (group) {
console.log("Call joinGroup");
try this
<ion-modal-view>
<ion-header-bar class="bar bar-header bar-balanced">
<h1 class="title">Join Court</h1>
<button class="button button-clear button-primary" ng-click="modal.hide()">Done</button>
</ion-header-bar>
<ion-content class="padding">
<ion-list ng-repeat="group in groups" >
<ion-item ng-click="joinGroup(group)">
<h2>{{group.name}}</h2>
<p>{{group.address}}</p>
</ion-item>
</ion-list>
</ion-content>
</ion-modal-view>
In your controller try to do with $scope when writing function like this.
$scope.groups = [];
$scope.joinGroup = function(){
//do your stuff here
}
I assume you did not connect your view with your controller correctly
either you have
.controller('myCtl', myCtl);
function myCtl($scope) {
$scope.groups = [];
$scope.joinGroup = function(args) {};
}
and your view
<div ng-controller="myCtl">
<ion-content class="padding">
<ion-list ng-repeat="group in groups" >
<ion-item ng-click="joinGroup(group)">
<h2>{{group.name}}</h2>
<p>{{group.address}}</p>
</ion-item>
</ion-list>
</ion-content>
</div>
or you can use this approach, which I prefer
.controller('myCtl', myCtl);
function myCtl() {
var vm = this;
vm.groups = [];
vm.joinGroup = function(args) {};
}
view
<div ng-controller="myCtl as vm">
<ion-content class="padding">
<ion-list ng-repeat="group in vm.groups" >
<ion-item ng-click="vm.joinGroup(group)">
<h2>{{group.name}}</h2>
<p>{{group.address}}</p>
</ion-item>
</ion-list>
</ion-content>
</div>
you need to define angular module and angular controller
and put the
app.controller('name',function($scope){
$scope.joinGroup = function(group){
console.log("Call joinGroup");
}
})
sorry for newbie question. I want to add filtering and sorting by name to my page. When i try using this code it is still work when i am using list of items from variable in controller scope but after i am using factory in services.js, there is two problem:
When i am typing the search word in search box, filter is work and only show the filtered item but i can't clear the filter again (when i am deleting the search word with backspace the item is still filtered)
The order by doesn't work anymore for sorting the items
Here is the code :
(HTML)
<ion-view view-title="Foods">
<ion-content class="padding">
<div class="bar bar-header item-input-inset">
<label class="item-input-wrapper">
<i class="icon ion-ios-search placeholder-icon"></i>
<input type="search" placeholder="Search" ng-model="foodSearch.search">
</label>
</div>
<button class="button button-block button-energized" ng-click="showOrderOptions()">
Order by
</button>
<div class="list ">
<a class="item" href="#" ng-hide="isOrderOptionsHide" ng-click="reverse=!reverse;order('name',reverse)">
Name
</a>
<a class="item" href="#" ng-hide="isOrderOptionsHide" ng-click="reverse=!reverse;order('rating',reverse)">
Rating
</a>
</div>
<ion-list>
<ion-item class="list card" ng-repeat="food in foods = (foods | filter: filterFood)"
href="#/tab/foods/{{food.id}}">
<div class="item item-head">
<h2 style="text-align:center;"><b>{{food.name}}</b></h2>
<div class="row">
<div class="col item item-image" style="width:100px;height:100px;">
<img class="" src="{{food.imageSrc}}" >
</div>
<div class="col item item-image">
<h2>{{food.title}}</h2>
<div class="row">
<img src="img/smile.jpg" style="width:100%; height:100%; margin-top: -10px;"class="col col-40">
<h3 class="col col-60" >{{food.rating}}</h3>
</div>
</div>
</div>
</div>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
(Controller.js):
.controller('FoodsCtrl', function($scope,Foods,$filter) {
$scope.foods = Foods.all();
$scope.remove = function(food) {
Foods.remove(food);
};
$scope.foodSearch = {search: ''};
$scope.filterFood = function (item){
return item.title.toLowerCase().indexOf($scope.foodSearch.search.toLowerCase()) >= 0
|| item.name.toLowerCase().indexOf($scope.foodSearch.search.toLowerCase()) >= 0;
}
$scope.isOrderOptionsHide = true;
$scope.reverse=true;
$scope.showOrderOptions = function (){
$scope.isOrderOptionsHide = !$scope.isOrderOptionsHide;
}
var orderBy = $filter('orderBy');
$scope.order = function(predicate, reverse) {
$scope.foods = orderBy($scope.foods, predicate, reverse);
$scope.isOrderOptionsHide = true;
};
})
Just do this way ng-repeat="food in foods | filter: foodSearch.search | orderBy: 'name'" You do not have to do this :
$scope.filterFood = function (item){
return item.title.toLowerCase().indexOf($scope.foodSearch.search.toLowerCase())..
angular filter automaticaly does that.
In my ionic app from the controller I received a json string of comma separated values. I want to display the json string in a html in tabular format. The html is placed inside template directory.
I am calling a java script function from the div of html to achieve this but the js function is not getting hit. The js is included in index.html. What I am doing wrong?
Here is the sample:
the template/shop.html file:
<ion-tabs class="tabs-icon-top tabs-color-active-positive">
<!-- Dashboard Tab -->
<ion-tab title="Status" icon-off="ion-ios-pulse" icon-on="ion-ios-pulse-strong">
<ion-view view-title="Shop">
<ion-content>
<ion-list>
<ion-item ng-repeat="shop in shopList">
<!--
<div class="row">
<div class="col col-50 text-center">
<script type="text/javascript">
**createTable({{shop.Method}})**
</script>
</div>
</div>
-->
<div id="Method"></div>
<script>
console.log("Inside div"); **HERE IS THE CALL TO JS FUNCTION**
**createTable({{shop.Method}});**
</script>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
</ion-tab>
<!-- Chats Tab -->
<ion-tab title="Chats" icon-off="ion-ios-chatboxes-outline" icon-on="ion-ios-chatboxes">
<ion-view view-title="Shop">
<ion-content>
<ion-list>
<ion-item ng-repeat="shop in shopList">
<div class="row">
<div class="col col-50 text-center">
{{shop.Offers}}
</div>
</div>
</ion-item>
</ion-list>
</ion-content>
</ion-view>
</ion-tab>
And here is my smaple JS function placed in utility.js
//function createTable($scope, method){
function createTable(Method){
// var tar=document.getElementById(Method);
// $scope.shopMethod = [];
var table=document.createElement('TABLE');
table.border='1';
var tbdy=document.createElement('TBODY');
table.appendChild(tbdy);
for (var j=0;j<4;j++){
var tr=document.createElement('TR');
tbdy.appendChild(tr);
for (var k=0;k<2;k++){
var td=document.createElement('TD');
td.width='100';
if(k==0) td.innerHTML="School" +(j+1);
else td.innerHTML="Percent" +(j+1);
tr.appendChild(td);
}
}
//tar.appendChild(table);
// <div class="row">
// <div class="col col-50 text-center">
// {{shop.Method}}
// </div>
// </div>
// </div>
// $scope.shopMethod.push(table);
console.log(table);
//document.getElementById(Method).innerHTML="Hello"
}
I am having an issue with AngularJS filtering my products list. I have done a few console.log queries on my variables and all seem fine. The problem is that the view does not update to show the filtered products.
Filtering works perfectly fine when you enter the search text in the input box but it does not work when clicking on the Category menu items.
I would like to filter the product list by category when the user clicks on the menu item.
Please see my code below and any help or advice is greatly appreciated.
My app.js
myApp.controller('StoreController', function($scope, $filter, storeFactory, cartFactory) {
$scope.cartTotal = 0;
$scope.cartItems = [];
$scope.categories = [];
$scope.counted = 0;
$scope.filteredProducts = {};
//get the products
storeFactory.getProducts(function(results) {
$scope.products = results.products;
$scope.counted = $scope.products.length;
$scope.filteredProducts = results.products;
});
$scope.$watch("search", function(query){
if($scope.filteredProducts.length) {
$scope.filteredProducts = $filter("filter")($scope.products, query);
$scope.counted = $scope.filteredProducts.length;
}
});
$scope.filterProductsByCategory = function(categoryName){
console.log('category filter');
/*$scope.products.forEach(function(o,i){
console.log('filter');
if( o.category_id !== categoryId ){
$scope.filteredProducts.splice(i,1);
console.log('removing');
console.log(o);
}
});*/
$scope.filteredProducts = $filter("filter")($scope.filteredProducts, categoryName);
console.info('the filtered items');
console.log($scope.filteredProducts);
$scope.counted = $scope.filteredProducts.length;
}
$scope.getCategories = function(){
storeFactory.getCategories(function(results){
$scope.categories = results.rows;
});
}
$scope.getCategories();
});
My store.htm
UPDATE :
I removed the extra controller reference and wrapped everything in one div.
<div ng-controller="StoreController">
<!-- the sidebar product menu -->
<div class="block-content collapse in">
<div class="daily" ng-repeat="category in categories | orderBy:'name'">
<div class="accordion-group">
<div ng-click="filterProductsByCategory(category.category_name)" class="accordion-toggle collapsed">{{category.category_name}}</div>
</div>
</div>
</div>
</div>
<!-- Load store items start -->
<div class="label">Showing {{counted}} Product(s)</div>
<div class="row" ng-repeat="product in filteredProducts | orderBy:'product_name'" style="margin-left: 0px; width: 550px;">
<hr></hr>
<div class="span1" style="width: 120px;">
<!-- <a data-toggle="lightbox" href="#carouselLightBox"> -->
<a data-toggle="lightbox" href="#carouselLightBox{{product.product_id}}">
<!--img alt={{ product.product_name }} ng-src="{{product.image}}" src="{{product.image}}" /-->
<img id="tmp" class="" src="images/products/{{product.product_image_filename}}" alt=""></img>
</a>
<div class="lightbox hide fade" id="carouselLightBox{{product.product_id}}" style="display: none;">
<div class='lightbox-content'>
<img src="images/products/{{product.product_image_filename}}" alt="" />
<!--img alt={{ product.product_name }} ng-src="{{product.image}}" src="{{product.image}}" /-->
<button class="btn btn-primary" id="close_lightbox" ng-click="closeBox(product.product_id, $event)">Close</button>
</div>
<style>
#close_lightbox
{
position: absolute;
top: 5px;
right: 5px;
}
</style>
</div>
</div>
<div class="span6" style="width: 330px; margin-bottom: 15px;">
<h5 style="font-size: 14px; font-weight: bold;">{{product.product_name}}</h5>
<p>{{product.product_description }}</p>
<p>Category : {{product.category_name}}</p>
</div>
<div class="span3">
<p class="price">Price : <strong>R{{ product.product_price }}</strong></p>
</div>
</div>
<!-- end of controller -->
</div>
$scope.filteredProducts = {};
//get the products
storeFactory.getProducts(function (results) {
$scope.products = results.products;
$scope.counted = $scope.products.length;
$scope.filteredProducts = results.products;
});
Is results.products an array of objects or an object of objects? Because $filter('filter')($scope.products,query); expects $scope.products to be an array.
$scope.$watch("search", function (query) {
if($scope.filteredProducts.length) {
$scope.filteredProducts = $filter("filter")($scope.products, query);
$scope.counted = $scope.filteredProducts.length;
}
});
Here's what I'm thinking this should look like and you won't need the $watch statement or the filteredProducts array/object, In controller:
$scope.search = '';
$scope.products = [];
$scope.categories = ['category1','category2','category3'];
// assuming that your store function getProducts returns a promise here
storeFactory.getProducts().then(function(results){
$scope.products = results.products; // needs to be an array of product objects
});
$scope.filterProductsByCategory = function(category){
$scope.search = category;
};
Then in your HTML Partial, this is not exactly how your's is, I'm just showing you here in shorter form what is possible:
<button ng-repeat="cat in categories" ng-click="filterProductsByCategory(cat)">{{cat}}</button>
<div class="row" ng-repeat="product in products | filter:search | orderBy:'product_name'">
<!-- Product Information Here -->
</div>
I created a JSFiddle to demonstrate: http://jsfiddle.net/mikeeconroy/QL28C/1/
You can free form search with any term or click a button for a category.
The side bar is using one instance of StoreController, and the main div is using another instance of StoreController. Each instance having its own scope. The should both use the same controller instance: wrap everything inside a div, and use a unique StoreController for this wrapping div.