document.write a json vector to a table - html

Firstly I get orders:
app.controller('customersController', ['$scope', '$http', function($scope,$http) {
$http.get("http://18ff2f50.tunnel.mobi/yii2-basic/tests/Customers_JSON.json")
.success(function (response)
{
console.log("debug",response);
$scope.orders = response;
});
In an order I have a detail:
<div class="row" ng-repeat="x in orders|orderBy:'order_id'">
....
<div class="col right">
<button ng-click="viewOrderDetails(x.detail)">订单详情</button>
</div>
I have a json vector (which is returned from the server) stored in "detail" like this:
"detail":
"{\"4\":
{\"num\":2,
\"id\":\"4\",
\"name\":\"\\u86cb\\u7092\\u996d\",
\"price\":\"10.00\",\"total\":20},
\"6\":
{\"num\":1,
\"id\":\"6\",
\"name\":\"\\u626c\\u5dde\\u7092\\u996d\",
\"price\":\"10.00\",\"total\":\"10.00\"},
\"5\":
{\"num\":1,
\"id\":\"5\",
\"name\":\"\\u51b0\\u6dc7\\u51cc\",
\"price\":\"8.00\",\"total\":\"8.00\"
}}"
$scope.viewOrderDetails = function viewOrderDetails(detail) {
var newWin = open('orderdetails.html','windowName','height=300,width=300');
newWin.document.write('html to write...\n');
newWin.document.write(detail);
newWin.document.write('<input type="button" value="Close this window" onclick="window.close()">');
}
I want it displayed in a new window like this:
how should I do the document.write? Thanks.

You can use $compile service to compile template to write into new window:
app.controller('customersController', function($scope, $http, $compile) {
$http.get("order.json").success(function(response) {
$scope.x = response;
});
$scope.viewOrderDetails = function viewOrderDetails(order) {
var newWin = open('', 'windowName', 'height=300,width=300');
var template =
'<div>' +
'<table>' +
'<tr ng-repeat="(key, value) in order">' +
'<td>{{value.name}}</td>' +
'<td>{{value.id}}</td>' +
'<td>{{value.price}}</td>' +
'<td>{{value.total}}</td>' +
'</tr>' +
'</table>' +
'<input type="button" value="Close this window" onclick="window.close()">' +
'</div>';
$scope.order = order;
var table = $compile(template)($scope);
newWin.document.body.appendChild(table[0]);
}
});
Demo: http://plnkr.co/edit/pMCClUYMkpeyMiFwphrj?p=preview

Please take a look the code below, If you don't want to use jQuery, and want to use document.write() way. Use this code in your orderdetails.html file
<table>
<thead>
<tr>
<th>ID</th><th>Name</th><th>Price</th><th>Total</th>
</tr>
</thead>
<tbody>
<script>
var detail = window.opener.detail;
for(key in detail) {
document.write("<tr><td>"+ detail[key]["num"] +"</td><td>"+ detail[key]["name"] +"</td><td>"+ detail[key]["price"] +"</td><td>"+ detail[key]["total"] +"</td></tr>");
}
</script>
</tbody>
</table>
Please let me know if it is not working.

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>

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

Insert an HTML table into sharepoint 2013 webpart script

I have a problem, I've created a simple webpart that perfoms basics CRUD OPERATIONS, I wanted to add an HTML table to format and display the results retrieved from the READ operation, here is the code for a better understanding:
function retriveListItem() {
execute(
"items?$orderby=Nom&$select=Nom,Cognom,Indirizz",
"GET",
"GET",
null,
function (data, status, xhr) {
$("#result").empty();
var string = "<table><tr><th>Nome</th><th>Cognome</th><th>Indirizzo</th></tr>";
$("#result").append(string);
string = string = "";
for (var i = 0; i < data.d.results.length; i++) {
var item = data.d.results[i];
string = "<tr><td>" + item.Nom + "</td><td>" + item.Cognom + "</td><td>" + item.Indirizz + "</td></tr>";
$("#result").append(string);
}
string = "</table>";
$("#result").append(string);
},
function (xhr, status, error) {
$("#result").empty().text(error);
});
}
But when the page is rendered in the browser if I hit the F12 key I discover that sharepoint automatically adds the tbody tag (which I haven't wrote) and it close the tag /table automatically in the wrong position here is the code rendered in the browser:
<div id="result">
<table>
<tbody>
<tr>
<th>Nome</th>
<th>Cognome</th>
<th>Indirizzo</th>
</tr>
</tbody>
</table>
<tr>
<td>Giova</td>
<td>Nardi</td>
<td>Viale della Cagna, Verona</td>
</tr>
<tr>
<td>Antonio</td>
<td>Petrarca</td>
<td>Via Camello 31, Rovegna</td>
</tr>
<tr>
<td>Luca</td>
<td>Mandelli</td>
<td>Via Rossini, 32 Cesano Maderno</td>
</tr>
</div>
Does anybody knows why that? Any idea on how to workaround that issue? Thanks a lot
It looks like in your code, your string variable is just overwriting itself, and you are posting the results to the browser each time. Rather than using .append() each time you update the string, just use a string += .... and then append after the loops have run and the string is populated with the full table.
Here is a JSFiddle as an example using your code (for the most part).
So your code would look like:
function retriveListItem() {
execute(
"items?$orderby=Nom&$select=Nom,Cognom,Indirizz",
"GET",
"GET",
null,
function (data, status, xhr) {
$("#result").empty();
var string = "<table><tr><th>Nome</th><th>Cognome</th><th>Indirizzo</th></tr>";
//$("#result").append(string);
//string = string = "";
for (var i = 0; i < data.d.results.length; i++) {
var item = data.d.results[i];
string += "<tr><td>" + item.Nom + "</td><td>" + item.Cognom + "</td><td>" + item.Indirizz + "</td></tr>";
//$("#result").append(string);
}
string += "</table>";
$("#result").append(string);
},
function (xhr, status, error) {
$("#result").empty().text(error);
});
}
Hope this helps!
You can always insert HTML into an existing table using JQuery's after() method. Since you have a first <tr> already, you can poke in your built up HTML after that first row:
// First, put your basic table into #result
$("#result").html('<table id="resulttable"><tr><td>...</td></tr></table>');
// Next build up the necessary rows and columns
for (var i = 0; i < data.d.results.length; i++) {
// Build up your string as above
}
// Next, poke it into the DOM after the first <tr>
$("#resulttable tr").first().after(string);
You will find a full mockup below. The results data and the code to populate rows is shown in the page's <head> section. Below that, in the <body> a table is defined with ID mytab. That ID is picked up in the code that populates the rows.
<html>
<head>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
data = { d : {
results: [
{ Nom: 'nom1', Cognom: 'Cognom1', Indirizz: 'Indirrizz1' },
{ Nom: 'nom2', Cognom: 'Cognom2', Indirizz: 'Indirrizz2' },
{ Nom: 'nom3', Cognom: 'Cognom3', Indirizz: 'Indirrizz3' } ] } };
$(document).ready(function() {
for (var i = 0; i < data.d.results.length; i++) {
item = data.d.results[i]
str = '<tr><td>' + item.Nom + '</td><td> ' + item.Cognom +
'</td><td>' + item.Indirizz + '</td></tr>';
$('#mytab tr').first().after(str);
}
});
</script>
</head>
<body>
<table id="mytab">
<tr>
<td>First column</td> <td>Second column</td> <td>Third column</td>
</tr>
</table>
</body>
</html>

unable to call click event in template in angularjs directive

In have one common directive which will display in each and every page. Already visited page displaying as a done, So i want click event on already visited page. I added ng-click and wrote function in controller. Can anybody help why it's not working.
html
<div class="row">
<div class="col-sm-12">
<wizard-menu currentPage="searchOffering"></wizard-menu>
</div>
</div>
js
function generateMenuHtml(displayMenuItems, currentPage, businessType) {
var htmlOutput = '';
var indexOfCurrentPage = getIndexOf(displayMenuItems, currentPage, 'pageName');
if (businessType) {
htmlOutput += '<ol class="wizard wizard-5-steps">';
} else {
htmlOutput += '<ol class="wizard wizard-6-steps">';
}
angular.forEach(displayMenuItems, function (value, key) {
var htmlClass = '';
if (indexOfCurrentPage > key) {
htmlClass = 'class="done" ng-click="goToFirstPage()"';
} else if (key === indexOfCurrentPage) {
htmlClass = 'class="current"';
} else {
htmlClass = '';
}
if (key!==1){
htmlOutput += '<li ' + htmlClass + '><span translate="' + value.title + '">' + value.title + '</span></li>';
}
});
htmlOutput += '</ol>';
return htmlOutput;
}
.directive('wizardMenu',['store','WIZARD_MENU', 'sfSelect', function(store, WIZARD_MENU, Select) {
function assignPageTemplate(currentPageValue){
var storage = store.getNamespacedStore(WIZARD_MENU.LOCAL_STORAGE_NS);
var data=storage.get(WIZARD_MENU.LOCAL_STORAGE_MODEL);
var businessTypePath='offeringFilter.businessType.masterCode';
var businessTypeValue = Select(businessTypePath, data);
if(businessTypeValue!=='' && businessTypeValue==='Prepaid'){
template = generateMenuHtml(businessTypePrepaid, currentPageValue, true);
}
else{
template = generateMenuHtml(commonMenu, currentPageValue, true);
}
return template;
}
return {
require: '?ngModel',
restrict: 'E',
replace: true,
transclude: false,
scope: {
currentPage: '='
},
controller: ['$scope', '$state', '$stateParams', function($scope, $state, $stateParams) {
$scope.goToFirstPage = function() {
console.log('inside First Page');
};
}],
link: function(scope,element,attrs){
element.html(assignPageTemplate(attrs.currentpage));
},
template: template
};
}])
I'm unable to call goToFirstPage(). Can anybody tell what is wrong here.
Thanks in advance....
You need to compile the template. If you use Angular directive such as ng-click and you simply append them to the DOM, they won't work out of the box.
You need to do something like this in your link function:
link: function(scope,element,attrs){
element.append($compile(assignPageTemplate(attrs.currentpage))(scope));
},
And don't forget to include the $compile service in your directive.
Hope this helps, let me know!
Documentation on $compile: https://docs.angularjs.org/api/ng/service/$compile

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);