I´m stuck in something that seems to be quite easy, but I can´t find the way to go.
I´m developing an hybrid mobile app in AngularJS with Intel XDK, and I have to show a array of results from JSON, and allow users to click on one of them to get further info. I need to show the list on page A, and the complete info on page B.
By now I´ve done all but showing the full info on page B, even if I managed to get the ID of the item clicked. What I have is
Controller.js
.controller('myController', function($scope,$http) {
//This to get de JSON
$http({ method: 'GET',
url: '/lib/myData.json'
}).then(function successCallback(response) {
$scope.misDatos = response.data;
}, function errorCallback(response) {
console.error ("no json data");
});
//This to get the item clicked
$scope.setMaster = function(section) {
$scope.selected = section;
console.log("Item Clicked: " + $scope.selected.id);
};
})
PageA.html
<div class="card" ng-repeat="dato in misDatos" ng-click="setMaster(dato)" >
<div class="item item-divider">
{{dato.objetivo}}
</div>
<div class="item item-text-wrap">
<p>{{dato.descripcion}}...</p>
</div>
<div class="item item-divider">
</i> Más información
</div>
</div>
PageB.html
<div class="list card" ng-repeat="dato in misDatos | filter: {id:selected}">
<div class="item item-avatar">
<h4>{{dato.objetivo}}</h4>
</div>
<div class="item">
<p>{{dato.descripcion}}</p>
</div>
</div>
In my console I can see the correct ID clicked on page A
Item Clicked:3
But i can´t make my "B" page to show the data from the result selected...
Do you know what am I doing wrong? Is there a nice tutorial to do so?
Thanks everyone in advance!
In page B, you should be binding to the value of the selected item as below
<div class="list card">
<div class="item item-avatar">
<h4>{{selected.objetivo}}</h4>
</div>
<div class="item">
<p>{{selected.descripcion}}</p>
</div>
</div>
This is because the value of the selected item is now bound to the scope through $scope.selected
Finally I did it. This is how it works for me; wish it could help someone, bcos I spent the whole with this issue.
The problem, as Evans said, was that there was no data available on "page B", so the solution is to send the info to that page. I´ve used the reference of http://excellencenodejsblog.com/angularjs-sharing-data-between-controller/, placing the factory on the "app.js" file, and the controllers on the "controllers.js" file.
Cheers!
Related
I used angular js and ejs.
Repeat is good but, Database data does not come in.
How should I fix my code?
In this angularjs code
var app = angular.module('myApp', []);
app.controller('BasicCtrl20', function($scope, $http) {
$http.get("/concept_db")
.then(function(response) {
$scope.gridOptions4 = response.data;
});
});
In this my code
<div class="container">
<div ng-app="myApp" ng-controller="BasicCtrl20">
<div class="row">
<span style="line-height:30px"><br></span>
<div class="toggles">
<button id="showall">전체 제품 보기</button>
<button id="furniture">가구/인테리어</button>
<button id="homeappliances">디지털 가전</button>
<button id="life">생활/건강</button>
<button id="sport">스포츠/레저</button>
<button id="delivery">출산/육아</button>
<button id="fashion">패션잡화</button>
</div>
<div class="posts">
<div class="gallery">
<div ng-repeat="gridoptions in gridOptions4">
<div class="{{gridOptions.class}}">
<div class="gallery-item">
<a href="{{gridOptions.main_href}}">
<div class="gallery-item-image">
<img ng-src="{{gridOptions.imgsrc}}">
</div>
</a>
<div class="gallery-item-description">
<p align="center">{{gridOptions.name}}</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
and reuslt
I want to import data from the database.
console log result
You have a bunch of elements, so there is clearly something there. ng-repeat does not create 20 elements from an error or thin air.
But the field name is probably wrong. It is not name (or name is actually empty on every item in the database!). Check that you got the field name right. Maybe its upper case Name or NAME or mispellt naem. Or something completely different like label or title.
the easy thing to do is to log the data when you get it, and see for yourself.
.then(function(response) {
console.log( response.data ); <-- look in the console!
scope.gridOptions4 = response.data;
Or since it's a GET-request. Right-click that link in your console XHR finished loading: GET "https://localhost:3000/concept_db". <-- Right-click, open in a new tab. It might not be the most easy thing to read, but it's a such a quick thing to just take a peek at data so you know what you are working with.
I am a beginner at angular. I am pretty certain I am doing this the completely incorrect way but because I finally have it "somewhat working" as it works on the second click I am stuck going in this direction and can't seem to figure out another way to do it.
The filter sorts on the second click because it is initialing as "undefined" before the first click and sets it based on that I believe.
In my html:
<div class="col-xs-12 col-sm-4 location-list" ng-repeat="key in careerlist.location">
<div class="locations" ng-click="careerlist.criteriaMatch()">{{key}}
</div>
</div>
<div class="col-xs-12">
<div class="row">
<div class="col-xs-12 col-sm-6 col-md-4 job-container" ng-repeat="job in careerlist.career | filter : searchText | filter: selectExperience | filter: careerlist.criteria.name">
<h2>
{{job.title}}
</h2>
<h3>
{{job.location}}
</h3>
<div class="job-description" ng-bind-html="job.description | limitHtml : 200">
</div>
<br><br>
<button>Read More</button>
</div>
<br><br>
</div>
</div>
In my controller:
cl.criteriaMatch = function( criteria ) {
jQuery(document).on('click', '.locations', function(){
cl.criteria = {};
console.log("just the element text " + jQuery(this).text());
cl.criteria.name = jQuery(this).text();
return function( criteria ) {
return criteria.name === criteria.name;
};
});
};
Use ng-click instead of jQuery#on('click'). Angular does not know that the filter should be updated.
Update
#Makoto points out that the click is bound twice. It very much looks like you should just remove the jQuery binding altogether. I would even go so far as suggesting removing jQuery from you project.
I'm trying to create a system in which I can display, edit and delete information on players and teams using angular along with a RESTful API. I have the parts working in which I show all the data and post data to the database.
The part I am having trouble with is updating data as I can't manage to get the http put working with the correct data being sent.
HTML
<script type="text/ng-template" id="team-single.html">
<div class="team-box">
<div class="badge">
<img ng-src="images/{{x.club_name}}.png" width="100" height="100"></div>
<div ng-hide="editorEnabled">
<div class="team-name">{{x.club_name}}</div>
<p><b>Manager:</b> {{x.club_manager}}</p>
<p><b>Ground:</b> {{x.club_ground}}</p>
<p><b>Nickname:</b> {{x.club_nickname}}</p>
<div class="team-p">{{x.club_info}}</div>
Edit Team
</div>
<div ng-show="editorEnabled">
<p><input ng-model="x.club_name"></p>
<p><input ng-model="x.club_manager"></p>
<p><input ng-model="x.club_ground"></p>
<p> <input ng-model="x.club_nickname"></p>
<p><input ng-model="x.club_info"></p>
<input type="hidden" name="id" ng-value="" />
Save
</div>
</script>
<div class="row teams">
<div class="container">
<div class="col-md-4" ng-repeat="x in teams" ng-include="'team-single.html'"></div>
</div>
JS
var app = angular.module('footballApp', []);
app.controller("TeamCtrl", function ($scope, $http) {
$scope.updateTeam = function () {
$http({
method: 'PUT',
url: 'clubs.php/teams/' + id,
data: ??,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
};
});
I have enabled an editor on the front end to edit the fields. I don't know how to pass the one object being edited back into the updateTeam function while not passing the entire team array.
Also in the HTTP PUT, I have to use the id field of the relevant club in the URL but I'm not sure how to send this back.
Any help would be greatly appreciated.
To solve your problem you might need to rethink your UI. Why do you want to show edit option for all teams at once in the UI. Ideally you should show the team details along with an option to edit them.
When user click on edit call a function with team data and then show a form where those details can be edited and later can be send for submission.
Refer to this plnkr example https://plnkr.co/edit/muqnmIhO77atLyEHS9y7?p=preview
<div class="row">
<div class="col-xs-6 col-lg-4" ng-repeat="team in teams">
<h2>{{ team.club_name }}</h2>
<p>{{ team.club_info }}</p>
<p><a class="btn btn-default" ng-click="onEditDetails(team)" href="javascript:void(0);" role="button">Edit details »</a></p>
</div>
</div>
and then in controller
$scope.onEditDetails = function(team) {
$scope.team = team;
};
This will give you the reference of current selected team. You can use $scope.team then to show a form in UI which can be submitted along with its new edited data.
Note: In your example you are using a template to show HTML in UI but since they are in a ng-repeat each of your template will be using the last variable of loop. A template included using ng-include doesn't create a different scope for each of your team in teams.
If you want to create reusable HTML (though un-necessary as per your requirement) you can create a directive and include it in your ng-repeat as <my-team-directive data="x"></my-team-directive>
I'm trying to get the list of stacks from my server and populate view with ng-repeat but for some reason the view doesn't update even though the scope is updated. Here's my code
$scope.my = {stacks : []};
$http.post('https://myurl',{"action":"login"}).success(function (data, status, headers, config) {
$scope.my.stacks = data.stacks;
console.log($scope.my.stacks); //logs the correct value
//$scope.$apply() // don't need to do it, tried but it raised the already running digest cycle error
}).error(function (data, status){
alert(data)
});
And here's my HTML
//{{stacks}} if I do this, the view updates OK, strange
<ion-slide-box on-slide-changed="slideHasChanged($index)">
<ion-slide ng-repeat="stack in my.stacks">
<div class="list card">
<div class="item item-avatar">
<img src="./img/ionic.png">
<h2>{{stack.stack_name}}</h2>
<p>{{stack.stack_description}}</p>
</div>
<div class="item item-image">
<img style="max-width:100%;height:auto" src="./img/Test_Icon.png">
</div>
<a class="item item-icon-left assertive" ng-click="chooseStack(stack)">
<i class="icon ion-social-buffer-outline"></i>
Go to Stack
</a>
</div>
</ion-slide>
</ion-slide-box>
Also, the view updates as soon as I change the orientation. What am I doing wrong?
The problem is the Ionic slidebox. You need to let it know that the scope variable has been updated as described here.
I want a live search: the results are queried from web api and updated as the user types.
The problem is that the list flickers and the "No results" text appears for a fraction of second, even if the list of results stays the same. I guess I need to remove and add items with special code to avoid this, calculating differences between arrays, etc.
Is there a simpler way to avoid this flicker at least, and probably to have possibility to animate the changes?
It looks like this now:
The html part is:
<div class="list-group">
<a ng-repeat="test in tests track by test.id | orderBy: '-id'" ng-href="#/test/{{test.id}}" class="list-group-item">
<h4 class="list-group-item-heading">{{test.name}}</h4>
{{test.description}}
</a>
</div>
<div ng-show="!tests.length" class="panel panel-danger">
<div class="panel-body">
No tests found.
</div>
<div class="panel-footer">Try a different search or clear the text to view new tests.</div>
</div>
And the controller:
testerControllers.controller('TestSearchListCtrl', ['$scope', 'TestSearch',
function($scope, TestSearch) {
$scope.tests = TestSearch.query();
$scope.$watch('search', function() {
$scope.tests = TestSearch.query({'q':$scope.search});
});
}]);
You should use ng-animate module to get the classes you need for smooth animation. For each ng-repeat item that's moved, added, or removed - angular will add specific classes. Then you can style those classes via CSS or JS so they don’t flicker.
An alternative way of doing what you require is to use the angular-ui bootstrap Typeahead component (check at the bottom of the post). It has a type-ahead-wait property in milliseconds and also a template url for customising it.
<div ng-app>
<div ng-controller="MyController">
<input type="search" ng-model="search" placeholder="Search...">
<button ng-click="fun()">search</button>
<ul>
<li ng-repeat="name in names">{{ name }}</li>
</ul>
<p>Tips: Try searching for <code>ann</code> or <code>lol</code>
</p>
</div>
</div>
function MyController($scope, $filter) {
$scope.names = [
'Lolita Dipietro',
'Annice Guernsey',
'Gerri Rall',
'Ginette Pinales',
'Lon Rondon',
'Jennine Marcos',
'Roxann Hooser',
'Brendon Loth',
'Ilda Bogdan',
'Jani Fan',
'Grace Soller',
'Everette Costantino',
'Andy Hume',
'Omar Davie',
'Jerrica Hillery',
'Charline Cogar',
'Melda Diorio',
'Rita Abbott',
'Setsuko Minger',
'Aretha Paige'];
$scope.fun = function () {
console.log($scope.search);
$scope.names = $filter('filter')($scope.names, $scope.search);
};
}