Multiple selection from grid in ionic framework - html

I want to make a grid of categories images, select multiple categories from them and send their values to controller. I don't know how to achieve this with ionic framework.
Here is my view:
<ion-view cache-view="false">
<div class="bar login-bar bar-header bar-stable">
<h1 class="title ttl-log-bar">Welcome</h1>
</div>
<div class="bar bar-subheader welcome-subhead">
<h2 class="title welc-sub-h2">What do you like to shop for?</h2>
<h5 class="title welc-sub-h5">Pick at least one category</h5>
</div>
<ion-content scroll="true" class="has-header has-subheader">
<div class="row row-cat" style="flex-wrap: wrap;">
<div class="col col-cat col-50" ng-repeat="items in categoryList">
<img ng-src="{{items.image}}" width="100%" />
</div>
</div>
</ion-content>
</ion-view>

Add on img tag ng-click with function passing e.g. ID like this:
<img ng-src="{{items.image}}" ng-click="selectCategory(items.id)" />
Then in controller define this function
$scope.selectedCategory = [];
$scope.selectCategory = function(id){
var index = $scope.selectedCategory.indexOf(id);
if(index === -1){
$scope.selectedCategory.push(id);
}else{
$scope.selectedCategory.splice(index, 1);
}
}
Then you can us selectedCategory array as a collection of selected item's IDs

Related

Delete an item(Object) from an array using ng-if

I am trying to remove item using ng-if and ng-else-if.
"ng-if="navItem.gbn.indexOf('12345') !== -1" is true then array item only show contains('12345') items.
but the item still remain in array so I think ng-else-if is not working.
I don't know how to delete it.
I have the following Angular code:
<div ng-controller="PIDAEController">
<div class="container-fluid" style="padding-top:30px;">
<div class="row">
<div class="col-lg-2 col-md-3 col-xs-6 tubmbimg" ng-repeat="navItem in navItems | Fpage: curPage * pageSize | limitTo:pageSize" ng-if="navItem.gbn.indexOf('12345') !== -1">
<a class="thumbnail border" href="#/item/{{navItem.site}}">
<div class="b-marjin">
<span align="center" class="label label-primary full-width" >{{ navItem.gbn }}</span>
</div>
<div>
<img style="border: 1px solid black;" class="img-responsive full-width" src="{{navItem.pimg}}" alt="">
</div>
<div align="center" class="under-block">
<span title="{{ navItem.pname }}" align="center">{{ navItem.pname2}}</span>
</div>
</a>
</div>
<div ng-else-if="navItems.splice(navItem, 1)"></div>
</div>
</div>
</div>
angular.forEach(item, function (value, key) {
var keepGoing = true;
if(keepGoing) {
if(value.gbn.indexOf("11600") != -1) {
$scope.initialized = true;
$scope.navItems = item;
$scope.curPage=0;
$scope.pageSize=20;
$scope.numberOfPage = Math.ceil(item.length / $scope.pageSize);
keepGoing = false;
}
else {
$scope.navItems.splice(key, 1);
}
}
});
ng-else-if does NOT EXIST. its neither angular or angularJS.
In the line
<div ng-else-if="navItems.splice(navItem, 1)"></div>
splice requires navItem to be an index/int, not an object.
As an alternative to ng-else-if you can simply do:
ng-if="navItem.gbn.indexOf('12345') == -1
Also, splice would return the removed array item when found, not sure if "ng-if" handles that as being TRUE.

Unable to List the materialize css cards in the same row

I am making a webpage where i fetch movies using an api and i am trying to list the movie posters using the materilize css card in the same row, but it only gets listed on top of each other as a column.
app.js
class App extends React.Component {
constructor(props) {
super(props);
this.state={};
this.performSearch()
}
performSearch(){
$.ajax({
url:urlString,
success:(searchResults) =>{
console.log("Feteched succesfully");
//console.log(searchResults);
const results = searchResults.results
//console.log(results[0])
const movieRows = [];
results.forEach((movie) =>{
// console.log(movie.title);
console.log(movie.poster_path)
const movieRow = <MovieLists movie={movie}/>
movieRows.push(movieRow);
})
this.setState({rows:movieRows})
},
error:(xhr,status,err) =>{
console.error("Failed to fetch");
}
})
}
render() {
return (
<div className="App">
{this.state.rows}
</div>
);
}
}
export default App;
MovieLists.js
<div className="container">
<div className="row">
<div className="col s12">
<Movie key ={props.movie.id} image={props.movie.poster_path}
title={props.movie.title}/>
</div>
</div>
</div>
Movie.js
<div className="col s12 m6 l3">
<div className="card" >
<div className="card-image waves-effect waves-block waves-dark">
{
props.image == null ?
<img src ={'https://www.google.com/url?sa=i&url=https%3A%2F%2Fmarket.ionicframework.com%2Fstarters%2Fomdb-search&psig=AOvVaw3Beb0rUUVxt3OsEfwzu07Q&ust=1585542435018000&source=images&cd=vfe&ved=0CAIQjRxqFwoTCJj8kIPsvugCFQAAAAAdAAAAABAD'}
alt="card image"
style={{width:"100%",height:360}}/>
:
<img src ={`http://image.tmdb.org/t/p/w185${props.image}`}
alt="card image"
style={{width:"100%",height:360}}/>
}
<div className="card-content">
<p>
</p>
</div>
</div>
</div>
</div>
The movieLists component lists the movie component on top of each other, i am trying to find the way to list them horizontally responsively.
Remember to always use the correct grid structure, which is:
.container > .row > .col
All cols MUST sit in rows to behave responsively. Adding a .row div around the movie.js output will fix your problem.
<div class="container">
<div class="row">
<div class="col">
[content goes here]
</div>
<div class="col">
[content goes here]
</div>
</div>
</div>
See this answer from yesterday:
Materialize grid s12 not working in mobile view or on Chrome's developer tools
Codepen with a single .row div to fix your problem (note I've had to chnage className to class):
https://codepen.io/doughballs/pen/eYNbwOQ
https://materializecss.com/grid.html

Highlighting a field in angularJS if different value is present after comparison

I have rows of data and each row has 2 columns.
<div class="row">
<div class="col-md-2"><strong>Natural ID:</strong></div>
<div class="col-md-4">{{ctrl.firstobject.naturalId}}</div>
<div class="col-md-2"><strong>ManulaID:</strong></div>
<div class="col-md-4">{{ctrl.firstobject.manualID}}</div>
</div>
Now, I would like to compare the value of the field called "NaturalID" with another Natural ID (accessed by ctrl.CustomObject.naturalid) and if these two values are different, I would like to highlight in red the field corresponding to Natural ID in the above HTML. How can I do this?
You can use ng-class something like
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl',function($scope, $timeout) {
$scope.firstobject={
naturalId:1,
manualID:2
}
$scope.customObj={
naturalId:2
}
});
.red{
color:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl" >
<div class="row">
<div class="col-md-2"><strong>Natural ID:</strong>
</div>
<div class="col-md-4" ng-class="{'red':firstobject.naturalId !=customObj.naturalId}">{{firstobject.naturalId}}<span ng-if="firstobject.naturalId !=customObj.naturalId" class="glyphicon glyphicon-alert"></span>
</div>
<div class="col-md-2"><strong>ManulaID:</strong>
</div>
<div class="col-md-4">{{firstobject.manualID}}</div>
</div>
</div>

AngularJS Filter is not working as expected

Right side Bajra atta, Besan, Corn Flour .. are subcategories.
Index.html
<body>
<div class='container'>
<div class='row'>
<div class='col-md-4'></div>
<!-- Serach Area -->
<div class='col-md-5'>
<input style="margin-top:5px;" type="text" ng-model="SearchText" placeholder="Search for more than 10,000 products..." class='form-control' size="50">
</div>
<div class='col-md-1'></div>
<div class='col-md-2'>
<a id="top_login" href="#Login" style="position:absolute; margin-top:15px; color:#FFFCBA">
<strong>LOGIN </strong>
</a>
</div>
</div>
</div>
<div ng-controller="MainCtrl">
<div class='container'>
<div class='row'>
<div class='col-md-2 Name'>
<!-- Super Categories-->
</div>
<div class='col-md-7'> </div>
<div class='col-md-2'>
<!--SC Cart-->
</div>
<div class='col-md-1'></div>
</div>
</div>
<div id="middle" class='container'>
<div class='row'>
<div id="left" class="col-md-2">
<!-- categoris and sub categories -->
</div>
<div id="right" class="col-md-6">
<div ng-view></div>
</div>
</div>
</div>
</div>
<div id="footer">
<!-- Footer -->
</div>
</body>
products.html
<div class='box' ng-repeat="product in ProductService.Products | filter:SearchText | filter:FilterExpr:true| orderBy:'ProductName'">
<!-- Display filtered Products -->
</div>
ProductsController
sampleApp.controller('ProductsController', function ($scope, $routeParams, $log, $rootScope, ProductService) {
$scope.SCId = $routeParams.SCId;
$scope.ChangeFilter = function() {
if ($routeParams.SCId) {
$scope.FilterExpr = {'SubCategoryID': $routeParams.SCId.toString()};
}
};
$scope.ChangeFilter();
});
config Code
sampleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/Login', {
templateUrl: 'templates/ShowLogin.html',
controller: 'LoginController'
}).
when('/ShoppingCart', {
templateUrl: 'templates/ShoppingCart.html',
controller: 'ShoppingCartController'
}).
when('/Products/:SCId', {
templateUrl: 'templates/Products.html',
controller: 'ProductsController'
}).
otherwise({
redirectTo: '/Products/38'
});
}]);
When user clicks on subcategory, products of that subcategory is listed.
As otherwise is redirectTo: '/Products/38' products of subcategory 38 is listing initially.
I'm facing the following problems:
when user start typing in search box, filter:SerachText is applied on displayed subcategory products. But at this moment i want filter:SerachText to be apply on all the products (Not only on selected subcategory products)
Filter is not applying, if we are in some other routed page say login page. I want as soon as user start typing in search Box products.html and productsController to be activate.
When user has inputted something in search Box, and clicks on sub category, not all the products of that subcategory is listing because filter:SerachText is applied here. In this case i dont want to apply filter:SerachText filter
Can please some one help me to fix all these issues. I've tried all the combinations and permutations, but no luck. I'm also Ok if any architecture change is required that can make the things better.
Have you ever tried to hoist the SearchText filter scope to $parent.SearchText??
I guess, a superior scope ($parent or $rootScope) in your filter could work.
BTW: It works for me, 'cause it seems that ng-include does a local scope for each HTML to render, even in the same page.
P.D: Sorry for my English, greetings from Venezuela :D

Bootstrap Responsive Product Grid

I am building a product grid built upon AngularJS data - where there will be images and product details (text)
The text sometimes extends to the 2nd line, causing havoc.
Here is my code:
<div class="row">
<div data-ng-repeat="s in Results">
<div class="col-xs-4">
<a href="#" class="thumbnail">
<div>
<img ng-src="{{s.ProductImage}}" class="img-responsive">
</div>
<div>
{{s.Store}} {{s.Category}} {{s.ProductName}}
</div>
</a>
</div>
<div class="clearfix visible-xs-block"></div>
</div>
</div>
This is what it looks like:
How do I fix it so that <div>s all have the same height?
I tried to look online for solutions, but I think I am 50% there. Please help.
Note: I Don't want to hide content.
This is what I ended up doing for anyone who stumbles on this again in the future.
Javascript
function ResizeToLargestElement(element) {
var maxHeight = -1;
if ($(element).length > 0) {
$(element).each(function () {
maxHeight = maxHeight > $(this).height() ? maxHeight : $(this).height();
});
$(element).each(function () {
$(this).height(maxHeight);
});
}
}
Without AngularJS
For those who aren't using AngularJS, just call ResizeToLargestElement() when data changes or the window is resized using
$(window).resize(function() {
ResizeToLargestElement('.AutoResizeToLargestElement');
});`
With AngularJS
The idea is to call the ResizeToLargestElement() function whenever $scope.Results changes or when the window resizes.
To know when $scope.Results changed is easy, but to know when elements (that are bound to it) finished rendering is not easy. To do that, you need a AngularJS directive.
To know when the window re-sizes, use angular.element($window).on('resize', function () {...});
HTML
<div class="row">
<div data-ng-repeat="s in Results" data-ng-repeat-finished> <!--ADDED Directive-->
<div class="col-xs-4">
<a href="#" class="thumbnail AutoResizeToLargestElement"> <!--ADDED Class-->
<div>
<img ng-src="{{s.ProductImage}}" class="img-responsive">
</div>
<div>
{{s.Store}} {{s.Category}} {{s.ProductName}}
</div>
</a>
</div>
<!--REMOVED clearfix-->
</div>
</div>
MyDirectives.js
angular.module('myApp').directive('ngRepeatFinished', function ($timeout) {
return {
restrict: 'A',
link: function (scope, element, attr) {
if (scope.$last === true) {
$timeout(function () {
scope.$emit('ngRepeatFinished');
});
}
}
}
});
mycontroller.js
$scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) {
ResizeToLargestElement(".AutoResizeToLargestElement");
});
angular.element($window).on('resize', function () {
ResizeToLargestElement(".AutoResizeToLargestElement");
});
Note: this requires you to include $window in the AngularJS dependency list.
I.E. angular.module('myApp').controller('....', ['...., '$window', ....]);
If you want to keep the height of each product dynamic, you will need to split the results into columns. And then use ng-if to put the right items in the right column. Every 3rd item will go into the same column. To set them to different columns, just reduce the $index by 1 for each extra column.
<div class="row">
<div class="col-xs-4">
<div ng-repeat="s in Results"> <a href="#" class="thumbnail" ng-if="$index%3==0">
<div>
<img ng-src="{{s.ProductImage}}" class="img-responsive" />
</div>
<div>{{s.Store}} {{s.Category}} {{s.ProductName}}</div>
</a>
<div class="clearfix visible-xs-block"></div>
</div>
</div>
<div class="col-xs-4">
<div ng-repeat="s in Results"> <a href="#" class="thumbnail" ng-if="($index-1)%3==0">
<div>
<img ng-src="{{s.ProductImage}}" class="img-responsive" />
</div>
<div>{{s.Store}} {{s.Category}} {{s.ProductName}}</div>
</a>
<div class="clearfix visible-xs-block"></div>
</div>
</div>
<div class="col-xs-4">
<div ng-repeat="s in Results"> <a href="#" class="thumbnail" ng-if="($index-2)%3==0">
<div>
<img ng-src="{{s.ProductImage}}" class="img-responsive" />
</div>
<div>{{s.Store}} {{s.Category}} {{s.ProductName}}</div>
</a>
<div class="clearfix visible-xs-block"></div>
</div>
</div>
</div>
You can manually restrict the height of the div and use an overflow. Use something like
<div class="col-xs-4" style="height:200px; overflow: auto;">Content</div>
Or, you could always use a responsive table (<table class="table table-responsive">) for your layout.
The best solution for this problem is to add clearfix class to hidden divs for earch size of viewport. for example:
Large size: i want 6 columns (large desktops)
Medium size: i want 4 columns (Desktops)
Tablets: i want 3 coumns
phones: i want 2 columns
so i have the products list:
<?php $count=1; foreach($productList as $product) : ?>
<div class="item col-xs-6 col-sm-4 col-md-3 col-lg-2">
Picture and description
</div><!-- /item -->
<?php if( ($count%2)==0) {?><div class="clearfix visible-xs-block"></div><?php }?>
<?php if( ($count%3)==0) {?><div class="clearfix visible-sm-block"></div><?php }?>
<?php if( ($count%4)==0) {?><div class="clearfix visible-md-block"></div><?php }?>
<?php if( ($count%6)==0) {?><div class="clearfix visible-lg-block"></div><?php }?>
<?php $count++; endforeach?>