I want to create a filter in angular JS . My list comes from database as CouponsOperationResult objResult = ViewBag.StoreList;
and there are 74 store names in this list. i want a filter where there is an input textbox.first thing is the list shows up down filter accordingly. second thing is it should only show up when there is a key up event. third thing it should filter accordingly with the value in the textbox and fourth is that on click on list it should populate value in textbox.
Layout = "~/Views/Shared/_LayoutCoupons.cshtml";
CouponsOperationResult objResult = ViewBag.StoreList;
//List <Store> objStoreList = objResult.Storelist;
int ListCount = objResult.Storelist.Count();
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<link rel="stylesheet" href="~/content/css/coupons.css">
</head>
<body>
<section class="section panel">
<h2 class="no-margin-top">Submit your Coupon:</h2>
<div class="panel-body">
<form class="form" id="SubmitCoupon" name="SubmitCoupon" method="post">
<div ng-app="StoreApp" ng-controller="Store">
<div class="col-md-11">
<div class="form-row">
<h4>STORENAME: </h4> <input type="text" ng-keyup="getkeys($event)" class="myInput form-control" name="txtStorename" id="txtStorename" ng-model="test" placeholder="Search for Store.." title="Type in a Store" data-error-message="Please enter StoreName">
</div>
<ul id="myUL">
<li ng-repeat="x in StoreName | filter:test">
{{ x }}
</li>
</ul>
</div>
</div>
</div>
</section>
<script>
angular.module('StoreApp', []).controller('Store', function ($scope) {
$scope.StoreName = [
'Flipkart',
'Amazon',
'Snapdeal',
'Jabong',
'Trendin',
'Lenskart',
'Zovi',
'BabyOye',
'ShopMore24',
'BasicsLife',
'PrettySecrets',
'American Swan',
'ShopClues',
'FernsNPetals',
'Pepperfry',
'Koovs',
'FoodPanda',
'BookmyFlower',
'Printvenue',
'Amar Chitra Katha',
'Booking',
'TicketGoose',
'Myntra',
'FirstCry',
'Archies Online',
'Dominos',
'Bewakoof',
'Healthkart',
'Zivame',
'eBay',
'Paytm',
'Surat Diamond',
'Groupon',
'indiatimes',
'Yatra Hotels',
'Thomas Cook Hotels',
'FabFurnish',
'VistaPrint',
'KFC',
'Mobikwik',
'JustEat',
'Candere',
'Eureka Forbes',
'Simplilearn',
'Thomas Cook Flights',
'Nord51',
'ClickSense',
'The Mobile Store',
'MakeMyTripHotels',
'Expedia',
'HomeShop18',
'StarCJ',
'Fashionara',
'BigFlix',
'IndiaCircus',
'Yepme',
'Infibeam',
'Purplle',
'AliExpress',
'HappilyUnmarried',
'BagItToday',
'Croma',
'Naaptol',
'ManiacStore',
'D2HShop',
'AskMeBazaar',
'Rediff',
'Xiaomi',
'Syberplace',
'makemytrip',
'nearbuy',
'GreenDust',
'Tatacliq',
'LeMall'];
});
</script>
</body>
In this the list names are hard coded .and i want it from object but i dont know how to use scope as object
Here's an example that will do a quick search of the list on the value in the text box, and has two radio buttons that will sort the list in ascending or descending order. Almost everything is handled by AngularJS.
I also updated it to fill in a textbox when you click on any store.
(function() {
var app = angular.module('StoreApp', []);
var StoreController = function() {
var vm = this;
vm.sortType = "+";
vm.storeSearch = "";
vm.setSort = function(value) {
vm.sortType = value;
};
vm.fillBox = function(store) {
vm.selectedStore = store;
}
vm.StoreName = [
'Flipkart',
'Amazon',
'Snapdeal',
'Jabong',
'Trendin',
'Lenskart',
'Zovi',
'BabyOye',
'ShopMore24',
'BasicsLife',
'PrettySecrets',
'American Swan',
'ShopClues',
'FernsNPetals',
'Pepperfry',
'Koovs',
'FoodPanda',
'BookmyFlower',
'Printvenue',
'Amar Chitra Katha',
'Booking',
'TicketGoose',
'Myntra',
'FirstCry',
'Archies Online',
'Dominos',
'Bewakoof',
'Healthkart',
'Zivame',
'eBay',
'Paytm',
'Surat Diamond',
'Groupon',
'indiatimes',
'Yatra Hotels',
'Thomas Cook Hotels',
'FabFurnish',
'VistaPrint',
'KFC',
'Mobikwik',
'JustEat',
'Candere',
'Eureka Forbes',
'Simplilearn',
'Thomas Cook Flights',
'Nord51',
'ClickSense',
'The Mobile Store',
'MakeMyTripHotels',
'Expedia',
'HomeShop18',
'StarCJ',
'Fashionara',
'BigFlix',
'IndiaCircus',
'Yepme',
'Infibeam',
'Purplle',
'AliExpress',
'HappilyUnmarried',
'BagItToday',
'Croma',
'Naaptol',
'ManiacStore',
'D2HShop',
'AskMeBazaar',
'Rediff',
'Xiaomi',
'Syberplace',
'makemytrip',
'nearbuy',
'GreenDust',
'Tatacliq',
'LeMall'
];
};
app.controller("StoreController", [StoreController]);
})();
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<link rel="stylesheet" href="~/content/css/coupons.css"> </head>
<body>
<section class="section panel">
<h2 class="no-margin-top">Submit your Coupon:</h2>
<div class="panel-body" ng-app="StoreApp">
<form>
<div ng-controller="StoreController as vm">
<div>
<div>
<h4>STORENAME: </h4>
<input type="text" placeholder="Search for Store.." ng-model="vm.storeSearch"/>
<input type="text" placeholder="Selected Store" ng-model="vm.selectedStore" disabled />
<fieldset>
<label for="ascending">Ascending</label>
<input id="ascending" type="radio" ng-model="vm.sortType" name="group" ng-change="vm.setSort('+')">
<label for="descending">Descending</label>
<input id="descending" type="radio" ng-model="vm.sortType" name="group" ng-change="vm.setSort('-')">
</fieldset>
</div>
<ul id="myUL" ng-repeat="store in vm.StoreName | orderBy: vm.sortType | filter: vm.storeSearch">
<li ng-click="vm.fillBox(store)"> {{ store }} </li>
</ul>
</div>
</div>
This looks like you're recreating Angular-UI's UI-Select. Would that fill your needs? Don't recreate the wheel if you don't have to.
Related
I've built a basic Angular app that successfully displays the results of an HTTP GET request.
I'd like to include fallback code that displays two static HTML elements in place of the remote content if the GET request fails.
I can just call a vanilla JS function to do DOM manipulation, but I'd like to do this the Angular way. I've read a lot of documentation and articles, but I'm not seeing a straightforward way to do this. Code below.
I'd like to replace the call to updateUIError() with Angular code that performs the same task.
Here's a Plunk: https://plnkr.co/edit/PDwSUCXGNW2cwAIwl9Z9?p=streamer
HTML:
<div class="scene fullheight" id="attractions" ng-app="listApp">
<article class="content">
<h1>Upcoming Events</h1>
<div class="main" ng-controller="ListController as eventsList">
<div class="search">
<label>search: </label>
<input ng-model="query" placeholder="Search for events" autofocus>
<label class="formgroup">by:
<select ng-model="eventOrder" ng-init="eventOrder='start.local'">
<option value="start.local">Date</option>
<option value="name.text">Name</option>
</select>
</label>
<label class="formgroup">
<input type="radio" ng-model="direction" name="direction" checked>
ascending
</label>
<label class="formgroup">
<input type="radio" ng-model="direction" name="direction" value="reverse">
descending
</label>
</div>
<ul class="eventlist">
<li class="event cf" ng-repeat="item in eventsList.events | filter: query | orderBy: eventOrder:direction">
<div class="info">
<h2>{{item.name.text}}</h2>
<p>{{item.start.local | date:"dd MMMM ', ' h:mma"}}</p>
</div>
</li>
</ul>
</div>
</article>
</div>
Angular:
angular.module('listApp', [])
.controller('ListController', ['$scope', '$http', function($scope,$http) {
var eventsList = $scope.eventsList;
$http.get(URI)
.success(function(data) {
console.log(data);
eventsList.events = data.events;
}).error(function() {
updateUIError();
});
}]);
function updateUIError() {
var events = document.querySelector('#attractions article');
events.innerHTML = '<h1>Local Attractions</h1><p>There's lots to do nearby.</p>';
}
You need to create a static error and show it when the error occurs using ngIf
<div class="scene fullheight" id="attractions" ng-app="listApp">
<div ng-controller="ListController">
<article class="content" ng-if="hasUIError">
<h1>Local Attractions</h1>
<p>There's lots to do nearby.</p>
</article>
<article class="content" ng-if="!hasUIError">
<h1>Upcoming Events</h1>
<!-- REST OF THE HTML -->
</article>
</div>
</div>
Then, in your controller, you need to set the flag to false by default:
$scope.hasUIError = false;
And when there's an error in the ajax, set it to true
$http.get(URI).then(
function(response) {
console.log(response);
$scope.events = response.data.events;
},
function() {
$scope.hasUIError = true;
}
);
Before solving your issue, there is another issue to address. Specifically, since you are using the ControllerAs approach, you'll want to attach your variables to 'this' rather than $scope.
Then you create a variable called showError that will get evaluated in showing the message. Then you can use the ng-show directive to hide/show the message.
angular.module('listApp', [])
.controller('ListController', ['$http',
function($http) {
var vm = this;
vm.events = [];
vm.showError = false;
$http.get(URI)
.success(function(data) {
vm.events = data.events;
}).error(function() {
vm.showError = true;
});
}
]);
<!DOCTYPE html>
<html ng-app="listApp">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.10/angular.min.js" data-semver="1.5.10"></script>
<script src="app.js"></script>
</head>
<body ng-controller="ListController as eventsList">
<div class="scene fullheight" id="attractions">
<div ng-show="eventsList.showError">
<h1>Local Attractions</h1>
<p>There's lots to do nearby.</p>
</div>
<article class="content">
<h1>Upcoming Events</h1>
<div class="main">
<div class="search">
<label>search:</label>
<input ng-model="query" placeholder="Search for events" autofocus>
<label class="formgroup">by:
<select ng-model="eventOrder" ng-init="eventOrder='start.local'">
<option value="start.local">Date</option>
<option value="name.text">Name</option>
</select>
</label>
<label class="formgroup">
<input type="radio" ng-model="direction" name="direction" checked>ascending
</label>
<label class="formgroup">
<input type="radio" ng-model="direction" name="direction" value="reverse">descending
</label>
</div>
<ul class="eventlist">
<li class="event cf" ng-repeat="item in eventsList.events | filter: query | orderBy: eventOrder:direction">
<div class="info">
<h2>{{item.name.text}}</h2>
<p>{{item.start.local | date:"dd MMMM ', ' h:mma"}}</p>
</div>
</li>
</ul>
</div>
</article>
</div>
</body>
</html>
Do something like this:
angular.module('listApp', [])
.controller('ListController', ['$scope', '$http', function($scope,$http) {
var eventsList = $scope.eventsList;
$http.get(URI)
.success(function(data) {
console.log(data);
eventsList.events = data.events;
}).error(function() {
eventsList.errorMessage = '<h1>Local Attractions</h1><p>There's lots to do nearby.</p>';
});
}]);
In the HTML, add a span inside the scope of ListController that will have ngModel="errorMessage". You can add additional property to show / hide the error span and main content div.
I want to create dynamic lists in my page. Where user can add item to list from form. Something like this:
w3school example
but I want add more inputs and send one object to angular function. Something like this:
<!DOCTYPE html>
<html>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<link rel="stylesheet" href="http://www.w3schools.com/lib/w3.css">
<body>
<script>
var app = angular.module("myShoppingList", []);
app.controller("myCtrl", function($scope) {
$scope.products = [{food: "Milk", price: "1$"}, {food : "Bread", price: "1$"}, {food : "Cheese", price: "1$"}];
$scope.addItem = function () {
$scope.errortext = "";
if (!$scope.addMe) {return;}
if ($scope.products.indexOf($scope.addMe) == -1) {
$scope.products.push($scope.addMe);
} else {
$scope.errortext = "The item is already in your shopping list.";
}
}
$scope.removeItem = function (x) {
$scope.errortext = "";
$scope.products.splice(x, 1);
}
});
</script>
<div ng-app="myShoppingList" ng-cloak ng-controller="myCtrl" class="w3-card-2 w3-margin" style="max-width:400px;">
<header class="w3-container w3-light-grey w3-padding-16">
<h3>My Shopping List</h3>
</header>
<ul class="w3-ul">
<li ng-repeat="x in products" class="w3-padding-16">{{x.food}} : {{x.price}}<span ng-click="removeItem($index)" style="cursor:pointer;" class="w3-right w3-margin-right">×</span></li>
</ul>
<div class="w3-container w3-light-grey w3-padding-16">
<div class="w3-row w3-margin-top">
<div class="w3-col s10">
<input placeholder="Add shopping items here" ng-model="addMe.food" class="w3-input w3-border w3-padding">
<input placeholder="Add shopping items here" ng-model="addMe.price" class="w3-input w3-border w3-padding">
</div>
<div class="w3-col s2">
<button ng-click="addItem()" class="w3-btn w3-padding w3-green">Add</button>
</div>
</div>
<p class="w3-padding-left w3-text-red">{{errortext}}</p>
</div>
</div>
</body>
</html>
but if I added new item to my list and then I start change value in textbox so too change value in my list. There is something like pointer. If I send array of string then dont do it but I dont want connected to one string. Now I have connected to one string but I dont want it.
Thanks for all answers.
Create a copy using angular.copy() and then push that copied object to array.
Have a look at ngModelOptions to control how the model is updated:
https://docs.angularjs.org/api/ng/directive/ngModelOptions
try this:
<input placeholder="Add shopping items here"
ng-model="addMe.price"
ng-model-options="{ updateOn: 'blur' }"
class="w3-input w3-border w3-padding">
Just mess around with what JavaScript event will trigger the update.
So, I have this form, made using AngularJS here, which basically lets me create a purchase object to send to a server, i.e, it lets me select a store where I bought some items, set a "date of purchase" (just a text field for now), and add those items to the object I'm gonna send.
After the submit button it is shown how the model I'm going to send will look like, showing the id of the store, the "datetime", and an array of items.
My question is: Is there a way of doing this form using angular-formly only?
The question arises because I've been reading formly's docs and I haven't figured out how to make it create such a dynamic model as this form does, i.e., with a variable-length array of items of the purchase, or if it is at all possible.
Thanks in advance for any clue you can give me to answer this question :)
The code for the form is as follows:
(function(){
var app = angular.module('test', []);
})();
The html page:
<!DOCTYPE html>
<html>
<head>
<link type="text/css" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.5/angular.js"></script>
<script src="inab.js"></script>
<script src="PurchaseCtrl.js"></script>
</head>
<body ng-app="test">
<div ng-controller="PurchaseCtrl" class="col-md-4">
<h2>Purchase</h2>
<div class="panel panel-default">
<div class="panel-heading">Title</div>
<div class="panel-body">
<div class="form-group">
<label>Store</label>
<select class="form-control" ng-model="model.store">
<option ng-repeat="store in stores" value="{{store.id}}">{{store.name}}</option>
</select>
</div>
<div class="form-group">
<label>date-time</label>
<input class="form-control" type="text" ng-model="model.datetime"/>
</div>
<div ng-repeat="item in items">
<div class="form-group">
<div class="col-sm-2">
<label>{{item.label}}</label>
</div>
<div class="col-sm-8">
<input class="form-control" type="text" ng-model="item.nome" />
</div>
<div class="col-sm-2">
<button type="submit" class="btn btn-alert submit-button col-md-2" ng-click="removeItem()">remove item</button>
</div>
</div>
</div>
<button ng-click="addItem()">Add item</button>
</div>
</div>
<button type="submit" class="btn btn-primary submit-button" ng-click="onSubmit()">Submit</button>
<pre>{{model | json}}</pre>
</div>
</body>
</html>
The controller:
(function(){
angular.module('test').controller('PurchaseCtrl', ['$scope', function(scope){
scope.stores = [{id: 1, name:'Store 1'}, {id: 2, name: 'Store 2'}];
scope.items = [];
scope.datetime = '';
scope.store = '';
var i = 0;
scope.model = {
store: scope.store,
datetime: scope.datetime,
items: scope.items
};
scope.addItem = function(){
scope.items.push({label: 'algo' + (i++), nome:''});
}
scope.removeItem = function(){
scope.items.splice(scope.items.length - 1);
}
scope.onSubmit = function(){
console.log(scope.model);
}
}]);
})();
As #Satej commented, it was with repeated sections. Thanks :)
I have a loop ng-repeat
<div ng-repeat="data in datas">
Name: {{data.name}} <input type="text" ng-model="age">
</div>
I want $scope.age become to $scope.age_data.name. Eg: $scope.age_Tan, $scope.age_Jim...
So i have tried ng-model="age_{{data.name}}" but it make error.
How to solve this?
The "right" way to do this is to, in the controller, do this:
$scope.ages = {};
Then in the template:
Name: {{data.name}} <input type="text" ng-model="ages[data.name]">
Should work...
What you show here won't work exactly here's a couple of options
angular.module('myApp', [])
.controller('MyCtrl', function() {
var vm = this;
vm.datas = [{
name: 'thing1'
}, {
name: 'thing2'
}, {
name: 'thing3'
}];
})
<html ng-app="myApp">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
</head>
<body ng-controller="MyCtrl as myCtrl">
Option 1
<div ng-repeat="data in myCtrl.datas">
<input type="text" ng-model="data.age" />
</div>
<br/>
<br/>Option 2
<div ng-repeat="data in myCtrl.datas">
<input type="text" ng-model="myCtrl.age[data.name]" />
</div>
<pre>{{myCtrl|json}}</pre>
</body>
</html>
I am not sure why you want to keep age of a person in another object/container. Here is the solution which may help you rethink you design.
$scope.people= [
{name: 'Tan', age: 20},
{name: 'Jim', age: 21}
];
<div ng-repeat="person in people">
Name: {{person.name}} <input type="text" ng-model="person.age">
</div>
I am using Ionic/Angular.
I have a search bar which I need to have it working in 2 different scenarios BUT at the same time. Look:
<label class="item item-input">
<i class="icon ion-search placeholder-icon"></i>
<!--here is the ng-model query-->
<input type="search" placeholder="Search" ng-model="query">
</label>
<!--here is the 1st filter:query-->
<div ng-repeat="sport in sports | filter:query" ng-show="sport.leagues.length">
<div>
<strong>{{sport.name}}</strong>
</div>
<!--here is the 2nd filter:query-->
<div class="item item-button-right"
ng-repeat="league in sport.leagues | filter:query"
on-tap="goToLines(league)">
{{league.name}}
</div>
so, all I need is that when the user is searching for something, the search bar returns sport.name and league.name, is it clear for you guys?
UPDATE*
this is the service where I am calling sports:
getSports: function(agent) {
var defer = $q.defer();
LocalForageFactory.retrieve(CONSTANT_VARS.LOCALFORAGE_SPORTS)
.then(function(sports) {
if (!_.isNull(sports)) {
defer.resolve(_.values(sports));
}else {
$http.get(CONSTANT_VARS.BACKEND_URL + '/lines/sports/' + agent)
.success(function(sports) {
//forcing array instead of object
sports = _.values(sports);
sports = _.sortBy(sports, function(sport) {
return sport.priority;
});
LocalForageFactory.set(CONSTANT_VARS.LOCALFORAGE_SPORTS, sports);
defer.resolve(sports);
})
.error(function(err) {
defer.reject(err);
});
}
});
return defer.promise;
},
If you wanted to search either field, drop the second filter and use the special $ to traverse the object hierarchy. See the documentation for more info.
var myApp = angular.module('myApp',[]);
myApp.controller('TestController', ['$scope', function($scope) {
$scope.sports = [
{name: 'Basketball', leagues: [{name: 'Mens'}, {name: 'Womens'}]},
{name: 'Volleyball', leagues: [{name: 'Mens'}, {name: 'Womens'}]},
{name: 'test', leagues: [{name: 'test'}]}
];
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="TestController">
<input type="search" placeholder="Search" ng-model="query">
<div ng-repeat="sport in sports | filter:{$: query}" ng-show="sport.leagues.length">
<div>
<strong>{{sport.name}}</strong>
</div>
<div class="item item-button-right"
ng-repeat="league in sport.leagues"
on-tap="goToLines(league)">
{{league.name}}
</div>
</div>
</div>