Angular.js string to html - html

Hello I want to bind html to div . Code below I wrote like that
.controller('HomeCtrl',['$http','$scope','$state',function($http,$scope,$state){
$scope.data = {};
$scope.userInfo = function() {
$state.go('user');
}
var user=JSON.parse(sessionStorage.user);
$scope.user=user.name+ ' ' + user.surname;
$http.get('http://example:3000/projects').success(function(response){ //make a get request to mock json file.
var data=response;
var text='';
for (var i=0;i<data.length;i++) {
text+='<a id="task_'+data[i]._id+'" class="item item-icon-left task_'+data[i]._id+'" ng-click="getProject('+data[i]._id+')">';
text+='<i class="icon ion-android-folder-open"></i> '+data[i].name;
text+='</a>';
}
console.log(text);
$scope.tasks=text;
})
.error(function(err){
alert("hata");
})
}])
in console.writeline string seems correctly but in html ngclick and id attributes aren't shown .
<div ng-bind-html="tasks">
</div>
in html i wrote above . Where do I make mistake ?
Thanks in advance ...

You will use ng-repeat ;
in html
<a class="item item-icon-left" ng-repeat="item in projects" ng-click="getProject({{item.id}},'{{item.name}}')">
<i class="icon ion-android-folder-open"></i> {{item.name}}
</a>
put this and in controller.js put the data in array below
$http.get('http://example:3000/projects').success(function(response){ //make a get request to mock json file.
var data=response;
var text='';
var projects=[];
for (var i=0;i<data.length;i++) {
var item={
id:data[i]._id,
name:data[i].name
}
projects.push(item);
}
console.log(projects);
$scope.projects=projects;
})
.error(function(err){
alert("hata");
})

Related

How Can I change jQuery data handling to Knockout bindings for openWeather API

I'd like to use Knockout data binding to update weather API data in my html div element. Currently, I am using jQuery to update the DOM but I prefer to use Knockout. I also want to dynamically change the location zip so weather is specific to that one location in my div. I have an array for locations.
Here's my code:
html:
var zip = locations[0].zipcode;
var myOpenWeatherAPIKey = 'xxxxxxxxxxxxxxxxxxxx';
var openWeatherMapUrl = "http://api.openweathermap.org/data/2.5/weather?zip=" + zip + ",us&APPID=" + myOpenWeatherAPIKey + "&units=imperial";
console.log(zip);
//using JSON method for retrieving API data
$.getJSON(openWeatherMapUrl, function(data) {
var parameters = $(".weather-data ul");
var iconCode = data.weather[0].icon;
var iconDescription = data.weather[0].main;
var iconUrl = "http://openweathermap.org/img/w/" + iconCode + ".png";
detail = data.main;
windspd = data.wind;
parameters.append('<li>Temp: ' + Math.round(detail.temp) + '° F <br></li>');
parameters.append('<li><img style="width: 25px" src="' + iconUrl + '"> ' + iconDescription + '</li>');
}).fail(weatherError = function(e) {
$(".weather-data").append("OpenWeatherAPI is unable to load!");
});
<div id="open-weather" class="open-weather">
<div id="weather-data" class="weather-data">
<p> <br> Current Weather</p>
<ul id="weather-items" class="weather-items">
</ul>
</div>
</div>
Thanks,
You can write a custom KO binding or a custom KO component to encapsulate your markup, API keys, jQuery, and XHR calls.
With your code and use case, a component sounds like a good fit. Then your consuming markup could look like
<weather params="zip: myZipCode"></weather>
where myZipCode is a ko.observable in your consuming page's view model.
Update 1
Added roughed in code for encapsulating inside a KO component.
Update 2
Moved jquery DOM references out of KO component code so component template uses KO bindings. Added consuming page view model to show full example.
function openWeatherComponentViewModel(params) {
var self = this;
self.zip = ko.observable(ko.unwrap(params.zip));
self.temperature = ko.observable();
self.iconCode = ko.observable();
self.iconUrl = ko.pureComputed(function() {
return "http://openweathermap.org/img/w/" + self.iconCode() + ".png";
});
self.iconDescription = ko.observable();
self.hasWeather = ko.observable(false);
self.errorMessage = ko.observable();
var apiKey = 'xxxxxxxxxxxxxxxxxxxx';
var url = "https://api.openweathermap.org/data/2.5/weather?zip=" + self.zip() + ",us&APPID=" + apiKey + "&units=imperial";
$.getJSON(url, function(data) {
self.temperature(Math.round(data.main.temp));
self.iconCode(data.weather[0].icon);
self.iconDescription(data.weather[0].main);
self.hasWeather(true);
}).fail(function(error) {
self.hasWeather(false);
self.errorMessage("OpenWeatherAPI is unable to load! " + error.responseJSON.message);
});
}
ko.components.register('weather-component', {
viewModel: openWeatherComponentViewModel,
template: `<div id="open-weather" class="open-weather">
<div id="weather-data" class="weather-data" data-bind="if: hasWeather()">
<p>Current Weather for Zip Code <span data-bind="text: zip"></span></p>
<ul id="weather-items" class="weather-items">
<li>Temp: <span data-bind="text: temperature"></span>° F</li>
<li><img style="width: 25px" data-bind="attr: { src: iconUrl }"><span data-bind="text: iconDescription"></span></img></li>
</ul>
</div>
<div id="weather-data" class="weather-data" data-bind="if: !hasWeather()">
<span data-bind="text: errorMessage"></span>
<div>
</div>`
});
function myConsumingPageViewModel() {
var self = this;
self.myZipCode = ko.observable("80130");
}
var vm = new myConsumingPageViewModel();
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<weather-component params="zip: myZipCode"></weather-component>

What does this tag do?

I have been learning how to read other people's code and when ever I see something like this <meganav-item item="item" ng-repeat="item in website.nav.primary"></meganav-item> I get stuck.
I have a basic understand of angular, but the problem is the <meganav> tag. I do not know what this is..I have done a Google search, but nothing useful is showing.
Update
I have managed to locate the file of the <meganav> element. After following the instructions from the links that you guys have provided, it led me to a file named "MegaNavItem.js". Here is the code:
window.tcoStore.directive('meganavItem', ['$timeout','transport', function($timeout,transport) {
var lockTimeout = false;
var meganavLocks = transport.getModel('meganavLocks', {lock : false});
var clear = function (){
if(meganavLocks.timeout){
$timeout.cancel(meganavLocks.timeout);
}
}
var action = function(callback, time) {
if(meganavLocks.lock){
return;
}
clear();
meganavLocks.timeout = $timeout(callback, time);
}
var dropLock = function(callback, time) {
meganavLocks.lock = false;
}
return {
restrict : 'E',
replace: true,
templateUrl : '/page/header/meganav/item.html',
scope : {
item : '=',
clickOnly : '#',
delayIn : '#',
delayOut : '#'
},
link : function($scope, elem, attrs){
if(!$scope.clickOnly){
$scope.delayInValue = parseInt($scope.delayIn || 300,10);
$scope.delayOutValue = parseInt($scope.delayOut || 500,10);
elem.on('mouseenter', $scope.showDelayed);
if($scope.delayOutValue > 0){
elem.on('mouseleave', $scope.hideDelayed);
}
}
},
controller: ['$scope', '$timeout', 'transport', '$location' ,
function($scope, $timeout, transport,$location) {
// When $location changes ...
$scope.$on('$locationChangeSuccess', function() {
$scope.hide(true);
$scope.isActive = !_.isUndefined($scope.item.link) && ($scope.item.link.replace(/\/+$/,'') == $location.path().replace(/\/+$/,''));
});
$scope.loadSubmenu =0;
// tranposrt model accessable by other items
var meganavVisibleModel = transport.getModel('meganavActive');
var meganavVisibleModelId = $scope.item.$$hashKey;
meganavVisibleModel[meganavVisibleModelId] = false;
// hide and show funs
$scope.hide = function(forceFullClose){
clear();
meganavVisibleModel[meganavVisibleModelId] = false;
if(forceFullClose) {
meganavLocks.lock = true;
$timeout.cancel(lockTimeout);
lockTimeout = $timeout(dropLock, 1000);
}
};
$scope.hideDelayed = function (delay) {
action($scope.hide, _.isNumber(delay) ? delay : $scope.delayOutValue);
};
$scope.show = function(){
if(meganavLocks.lock){
return;
}
clear();
$scope.loadSubmenu = 1;
for(var i in meganavVisibleModel){
meganavVisibleModel[i] = (meganavVisibleModelId == i);
}
};
$scope.showDelayed = function (delay) {
action($scope.show, _.isNumber(delay) ? delay : $scope.delayInValue);
};
$scope.$watch(function(){
$scope.visible = meganavVisibleModel[meganavVisibleModelId];
});
// first touch click, second touch go to link
$scope.touch = function($event, path){
if(!$scope.visible) {
//$event.preventDefault();
$scope.show();
}else if(tco.empty(path)) {
$scope.hide();
} else {
if(path.match(/^https?:/)){
window.location.href = path;
}else{
$location.path(path);
}
}
}
}]
}
}]);
And this file led me to another file named item.html. The code :
<li class="header--menu__item my-repeat-animation" ng-class="{ 'is-active': isActive, open : visible && item.groups.length}" off-click="hide()" >
<a ng-if=":: item.groups.length"
ng-class="{active: item.active}"
class="header--menu__item--link has-children"
ng-click="show()"
title="{{::item.name}}">
{{::item.name}}
</a>
<a ng-if=":: !item.groups.length"
class="header--menu__item--link"
href="{{::item.link}}"
title="{{::item.name}}">
{{::item.name}}
</a>
<div class="header-menu-dropdown ng-hide" ng-show="visible" ng-if=":: item.groups.length">
<ul class="header-menu-dropdown__meganavGroup">
<li ng-repeat="meganavGroup in item.groups" class="header--menu-group">
<span class="meganav--group--name">{{::meganavGroup.name}}</span>
<ul class="meganav--group--items">
<li ng-repeat="groupItem in meganavGroup.items">
{{::groupItem.name}}
<span class="icon"></span>
</li>
</ul>
</li>
<li class="header-menu-offers" ng-repeat="offer in item.offers">
<a href="{{::offer.offer_link}}" class="placeholder">
<img tco-image="offer.offer_image" crop="3" alt="{{::offer.offer_name}}" />
</a>
<span class="offer-name">{{::offer.offer_name}}</span>
</li>
</ul>
<div class="header-menu-message" ng-bind-html="item.message"></div>
</div>
</li>
My issue is now that I cannot make out what where to find {{::item.name}}, which is the thing that I want to change. What technique can I use to find {{::item.name}}?
Sorry for all the noob questions! Your help is much appreciated!
In Angular it is possible to build your own HTML element. You won't find any information about this element because it doesn't exist. The developer has created that on its own and handles the content inside a module. Have a look at http://www.aleaiactaest.ch/2012/07/29/build-your-own-html-element-with-angular/ for more information.
Hope this helps, Cheers.
As i've noticed it's Angular App, so probably there are defined an directive which is called meganavItem. See Angular Directive for more information, you have to find definition of that directive and discover what is html layout and logic lives under <meganav-item>. However if there are no directive with defined name.
Also it may be separate registered element, see "Custom Elements
"article of how it's done and it would be more easy for you to find out how it works ( if it registered in that way...)

clone object with unique name in Angular

I'm new to Angular and looking for a way to make a clone button inside a list.
When I click this button, it will clone the object and add a number to the object name:
"new test" - will be changed to "new test (2)" and so on...
It requires to check the last 3 letters every time and check all the objects every time.
Is there any library doing this?
I think you don't need any lib for this. Basically, it you need one loop that looks for duplicates. See an example:
angular.module('myApp', [])
.controller('MyCtrl', function($scope){
$scope.items = ['Sample item'];
$scope.suggestedNewName = 'Sample item';
var isNameOccupied = function(name) {
return $scope.items.indexOf(name) >= 0;
};
$scope.addNewItem = function(){
var suggestedName = $scope.suggestedNewName;
var newName = suggestedName;
for (var i = 2; isNameOccupied(newName); i++) {
newName = suggestedName + " (" + i + ")";
}
$scope.items.push(newName);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<form ng-controller="MyCtrl" ng-submit="addNewItem()">
<ul>
<li ng-repeat="item in items">{{ item }}</li>
</ul>
<label>Suggested name for new item:</label>
<input type="text" ng-model="suggestedNewName">
<button type="submit">Add new item!</button>
</form>
</div>

JSON Media Type for for request with AngularJS

This is the backend Java Side with Jersey in an embedded Jetty.
#GET
#Path("/jason")
#Produces({MediaType.APPLICATION_JSON})
public MyJaxBean getMyBean() {
MyJaxBean myJB = new MyJaxBean();
myJB.add("Hello", 1);
myJB.add("World", 2);
return myJB;
}
checking that with curl brings back this text
{"person":[{"name":"Hello","age":1},{"name":"World","age":2}]}
Using that in an HTML Page
<p id="demo"></p>
<button onclick="doRequest()">REQUEST !</button>
<script>
"use strict";
function doRequest(){
var xmlhttp = new XMLHttpRequest();
var url = "http://localhost:8080/api/entry-point/jason";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
var myHTML = iterateObject(myArr);
document.getElementById("demo").innerHTML = myHTML
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
function iterateObject(myArr) {
var out = '';
myArr.person.forEach(function(p) {
out+= p.name + ',' + p.age + '<br>';
});
return out;
}
</script>
brings back
Hello,1
World,2
However this try with AngularJS does not show anthing from the Jason Call
<!DOCTYPE html>
<html>
<script src= "http://localhost:8080/ressources/angular.js"></script>
<body>
<h2>AngularJS doing a JSON HTTP Request</h2>
<div ng-app="myApp" ng-controller="customersCtrl">
<ul>
<li ng-repeat="p in persons">
{{ p.name + ', ' + p.age }}
</li>
</ul>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('customersCtrl', function($scope, $http) {
$http.get("http://localhost:8080/api/entry-point/jason")
.success(function (response) {$scope.persons = response.records;});
});
</script>
</body>
</html>
Replacing the http.get with
$scope.persons = [{name:"Hello", age:1},{name:"World",age:2}]
does work.
Any Idea what is wrong with the Media Type or the AngularJS Example ?
Thanks for any help here
Change <li ng-repeat="p in names"> to <li ng-repeat="p in persons">. You are setting the value in persons object but using names in the view.
DEMO http://plnkr.co/edit/0aNUfTwyBJYjQjCsP1UU?p=preview

How can i make pagination through AngularJS?

Recently I create a AngularJs App . Thats code are below
HTML :
<div ng-app="" ng-controller="Hello">
<ul>
<li ng-repeat="x in greeting">
{{ x.user_name }}
</li>
</ul>
</div>
And my JS code is:
function Hello($scope, $http) {
$http.get('http://localhost/google/cibl/dashboard/get_all_user').
success(function(data) {
$scope.greeting = data;
});
}
Its working fine. This http service give me 2000 row now i want to paginate this by AngularJs. How can I do that ?
In your controller
app.controller('Hello', function($scope){
$scope.pageSize = 10;
$scope.currentPage = 0;
$scope.changePage = function(page){
$scope.currentPage = page;
}
})
In your mark up, you should have
<div ng-app="" ng-controller="Hello">
<ul>
<li ng-repeat="x in greeting | startFrom: currentPage * pageSize | limitTo: pageSize">
{{ x.user_name }}
</li>
</ul>
</div>
We're missing the startFrom filter so lets create that
app.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
Now all thats left is the paginating panel, I'll leave it up to you to pretty it with css
<ul class="pagination" >
<li ng-repeat="page in pagination" ng-class="{'active':currentPage == page}"><a ng-click="changePage(page)">{{page + 1}}</a></li>
</ul>
Notes:
The reason why we use changePage() instead of currentPage = page is due to ng-repeat which could break some of the variables
In your anchor () tag, instead of ng-click, you can use a href to mark the page and in your controller, watch the page ref and change based on the queries. The benefits to this is that when you decide to do SEO for your website, it will be ready for that!
href="#!/partialname?page={{page}}"
You can do this way:
Pagination Example: http://jsfiddle.net/2ZzZB/56/
Found it in this question:
Pagination on a list using ng-repeat
At least I got a solution and its work properly :
HTML :
<div ng-controller="userController" class="jumbotron">
<h2>User List</h2>
<table class="table table-striped">
<thead>
<tr>
<th>User </th>
<th>Group</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr dir-paginate="u in users | itemsPerPage : 5">
<td>{{u.user_name}}</td>
<td>{{u.user_type}}</td>
</tr>
</tbody>
</table>
<dir-pagination-controls on-page-change="pageChanged(current)" template-url="<?php echo base_url(); ?>js/dirPagination.tpl.html"></dir-pagination-controls>
</div>
and JS :
Here i use AngularJs pagination directive
function userController($scope, $http) {
$scope.users = [];
$scope.total = 0;
$scope.perPage = 25; // this should match however many results your API puts on one page
getUsers(1);
$scope.pagination = {
current: 1
};
$scope.pageChanged = function (newPage) {
getUsers(newPage);
};
function getUsers(pageNumber) {
// this is just an example, in reality this stuff should be in a service
$http.get(app.baseUrl + 'dashboard/get_all_user/' + pageNumber)
.success(function (data) {
console.log(data);
$scope.users = data.users;
$scope.total = data.total;
})
.error(function (data) {
console.log(data);
alert("There was a problem. Please try again later.");
});
}
};
var myApp = angular.module('myApp', ['angularUtils.directives.dirPagination']);
var app = app || {};
app.baseUrl = '<?= base_url() ?>';
myApp.controller('userController', userController);