add click function to retrieve related data from object in web api - arrays

this is my starter work
I just call the web API and retrieved the hotel names
(function() {
var myAPI = "https://gmgapi.azurewebsites.net/SystemParameters/Hotels/GetAll?langId=en";
$.getJSON(myAPI, {
format: "json"
})
.done(function(data) {
doSomething(data);
console.log("Load was performed.");
});
})();
function doSomething(data) {
for (var i = 0; i < data.length; i++) {
var div = $("<div>");
var label = $("<label>").text(data[i].DisplayValue);
$(div).append(label);
$('#result').append(div);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="result"> </div>
now i want to click on hotel name to get other data related to hotel like deescription and other data
the proplem faced me that i couldn't get the value correctely when i clicked on html to retrive the data
i tried to declare var and use it but not worked for me like showed here
(function () {
var myAPI = "http://gmgapi.azurewebsites.net/SystemParameters/Hotels/GetAll?langId=en";
$.getJSON(myAPI, {
format: "json"
})
.done(function (data) {
doSomething(data);
doSomethinginClick(data);
});
})();
function doSomething(data) {
for (var i = 0; i < data.length; i++) {
var div = $("<div>");
var h1 = $("<h1>").text(" Hotel name : " + data[i].DisplayValue);
$(div).append(h1);
$('#result').append(div);
}
}
function doSomethinginClick(data) {
// var clicked = data[this].Id;
var clicked = data[0];
$('h1').click(function () {
var divx = $("<div>");
var h1 = $("<h1>").text(" Hotel name : " + clicked.DisplayValue);
var p = $("<p>").text(" Hotel Description : " + clicked.DisplayValueDesc);
var p2 = $("<p>").text(" CurrencyTitle : " + clicked.CurrencyTitle);
var price = $("<p>").text(" PriceStart : " + clicked.PriceStart);
var rate = $("<p>").text(" Rate : " + clicked.Rate);
$(divx).append(h1, p, p2, price, rate);
$('#resultsec').append(div);
});
}
<div id="result">
</div>
<div id="resultsec">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

First of, In the method doSomethinginClick(), where you define the h1 click function, you have missed to define the div element which you are appending to.
Add the following
var div = $("<div>");
To make the solution more dynamic, you can store a identifier on the h1 tag thats connect the tag to an hotel.
I added a custom field called hotelId on the html tag for this
function doSomething(data) {
for (var i = 0; i < data.length; i++) {
var h1 = $("<h1></h1>").text(" Hotel name : " + data[i].DisplayValue);
h1.data('hotelId', i);
$("#result").append(h1);
}
}
function doSomethinginClick(data) {
$('h1').click(function () {
var id = $(this).data('hotelId');
var clicked = data[id];
var h1 = $("<p>").text(" Hotel name : " + clicked.DisplayValue);
var p = $("<p>").text(" Hotel Description : " + clicked.DisplayValueDesc);
var p2 = $("<p>").text(" CurrencyTitle : " + clicked.CurrencyTitle);
var price = $("<p>").text(" PriceStart : " + clicked.PriceStart);
var rate = $("<p>").text(" Rate : " + clicked.Rate);
var div = $("<div>");
$(div).append(h1, p, p2, price, rate);
$('#resultsec').append(div);
});
}
Here's a plunker with mocked data

Related

Trying to get array to log if its empty to the console

I am working with a map and data. When you click on a state, it pulls the appropriate data from the JSON and displays the stores in an unordered list. If a state does not have data (Wyoming is one for example), it should be logging to the console that it is empty. So when you click on Wyoming, it should realize the array is empty and log that its empty to the console.
$("#paginateView").hide();
$("#stateButton").hide();
$("#mapWhereToBuy").usmap({
click: function(event, data) {
$.ajax({
url: 'https://165.227.69.79:8443/alanric/armaster/state/' + data.name + '?callback=functionCall',
dataType: "jsonp",
cache: true,
jsonpCallback: "functionCall",
success: function(json){
console.log(json);
var storeNames = '<ul class="list-group">';
$.each(json, function (i, item) {
var stores = item.cname;
if (stores && stores.length) {
storeNames += '<li class="content list-group-item">' + stores + '</li>';
} else {
console.log("Sorry, we do not carry products in your state.");
}
});
storeNames +='</ul>';
$('#clicked-state').html(storeNames);
$("#paginateView").show();
$("#stateButton").show();
$("#stateButton").html('You Selected:' + ' ' + data.name);
pageSize = 15;
showPage = function(page) {
$(".content").hide();
$(".content").each(function(n) {
if (n >= pageSize * (page - 1) && n < pageSize * page)
$(this).show();
});
}
showPage(1);
$("#paginateView li a").click(function() {
$("#paginateView li a").removeClass("current");
$(this).addClass("current");
showPage(parseInt($(this).text()))
});
}
});
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://www.cento.com/js/raphael.js"></script>
<script src="https://www.cento.com/js/jquery.usmap.js"></script>
<div id="mapWhereToBuy"></div>
<h1>Search By State</h1>
<h4>Click on a state to see store locations</h4>
<hr>
<div id="clicked-state"></div>
Some Array methods do not recognize empty arrays, like map(). But map() will always return something even an empty array. First example is .map() with an array of numbers the second example is with an empty array.
Demo
var array1 = [];
var result1 = array1.map(function(obj, idx) {
var ID = idx;
return idx;
});
console.log(result1);
var array2 = [0, 0, 1];
var result2 = array2.map(function(obj, idx) {
var ID = idx;
return idx;
});
console.log(result2);
I was able to get it to work by using this "json.length === 0". If there is a better alternative please let me know thanks!

passing variable value from controller to view in AngularJS

I am developing an application where i popup a window and when it gets popup the next time i will try to open it should not be opened. Next time it should open When i will close the popup then it should open.
Now for that i am using count variable and whenever it will be 1 the popup opens and whenever it is greater than or equal to 2 it shows alert. But now when i close the popup it is not resetting the value of count to 0 in view.
In JSfiddle i tried using var self = this; it works fine but when i tried it on my code it says Uncaught Exception Typeerror cannot find property 'count' defined at line self.count = 0;
How to achieve this? or any alternate solution for this?
<a ui-sref-active="active" ng-click="count=count+1; connectMachine(machine, count)" ng-init="count=0" ><span><i class="fa fa-desktop fa-5x"></i></span></a>
$scope.connectMachine = function(machine, count) {
var promise = restAPIService.connectMachineService(
$scope.thisStudentThisBatch.guacProfileId,
machine.connectionId, $stateParams.batchID).get();
promise.$promise.then(function(response) {
var json = JSON.parse(response.data);
console.log(json.id);
var dnsUrl = $location.absUrl().split('/');
dnsUrl = dnsUrl[0] + '//' + dnsUrl[2];
var apiUrl = dnsUrl + $rootScope.apiUrl + "guacamole/disconnect/"
+ json.id;
var conn_params = $http.defaults.headers.common.Authorization
+ "++" + apiUrl;
$scope.machineURL = response.headers.url + "&conn_params="
+ conn_params;
var params = "height=" + screen.availHeight + ",width="
+ screen.availWidth;
var NewWin;
var self = this;
if ($scope.count == 1) {
NewWin = window.open($scope.machineURL);
} else if ($scope.count >= 2) {
alert("Back Off Back Off");
}
function checkWindow() {
if (NewWin && NewWin.closed) {
window.clearInterval(intervalID);
self.count = 0;
}
}
var intervalID = window.setInterval(checkWindow, 500);
}, function(error) {
dialogs.error("Error", error.data.error, {
'size' : 'sm'
});
});
}
You can use a variable defined on $scope to trigger the value of button instead of using ng-init
HTML:
<div ng-app="myApp">
<ul ng-controller="TodoCtrl">
<li class="list-group-item" ng-repeat="todo in todos">{{todo.text}}
<button class="btn btn-default" ng-click="addLike($index)">value- {{count[$index]}}</button>
</li>
</ul>
</div>
JS:
var myApp = angular.module('myApp', []);
function TodoCtrl($scope) {
$scope.todos = [{
text: 'todo one'
}, {
text: 'todo two',
done: false
}];
$scope.count = [0, 0];
$scope.addLike = function(index) {
var NewWin;
$scope.count[index] ++;
if ($scope.count[index] == 1) {
NewWin = window.open('https://www.google.com');
} else if ($scope.count >= 2) {
alert("Back Off Back Off");
}
function checkWindow() {
if (NewWin && NewWin.closed) {
window.clearInterval(intervalID);
$scope.count[index] = 0;
$scope.$apply();
}
}
var intervalID = window.setInterval(checkWindow, 500);
};
};
JS Fiddle :https://jsfiddle.net/p41dLjmn/

Is this a correct way of pagination in angularjs?

On clicking "more" i call loadNextPage method that call loadComments method which load data based next id nextCommentId and push the data to allComments array and this array is rendered in html
$scope.loadNextPage = function()
{
loadComments($scope.nextCommentId);
}
function loadComments(page){
$scope.allComments.push(d.data);
..
..
$scope.nextCommentId = nextId;
}
Here is my html
<div ng-repeat="comment in allComments">
...
</div>
My question is, is this the correct way of doing pagination in angularjs as i am keeping all data in array so if data will grow it will consume memory.
<div data-pagination="" data-num-pages="numPages()"
data-current-page="currentPage" data-max-size="maxSize"
data-boundary-links="true"></div>
todos.controller("TodoController", function($scope) {
$scope.filteredTodos = []
,$scope.currentPage = 1
,$scope.numPerPage = 10
,$scope.maxSize = 5;
$scope.makeTodos = function() {
$scope.todos = [];
for (i=1;i<=1000;i++) {
$scope.todos.push({ text:"todo "+i, done:false});
}
};
$scope.makeTodos();
$scope.numPages = function () {
return Math.ceil($scope.todos.length / $scope.numPerPage);
};
$scope.$watch("currentPage + numPerPage", function() {
var begin = (($scope.currentPage - 1) * $scope.numPerPage)
, end = begin + $scope.numPerPage;
$scope.filteredTodos = $scope.todos.slice(begin, end);
});
});

Not able to set column width in angular datatables

var app = angular.module('tableTest', ['datatables']);
app.controller('TableCtrl',function ($scope,$compile,DTOptionsBuilder, DTColumnBuilder) {
$scope.showUpdateForm = function(code,reason,startTime,endTime,transactionGroup,geoGroup,transactionGroup) {
$scope.$parent.code = code;
$scope.$parent.reason = reason;
$scope.$parent.startTime = startTime.split(' ')[1].substring(0,startTime.split(' ')[1].lastIndexOf(':'));
$scope.$parent.endTime = endTime.split(' ')[1].substring(0,endTime.split(' ')[1].lastIndexOf(':'));
$scope.$parent.startDate = startTime.split(' ')[0];
$scope.$parent.endDate = endTime.split(' ')[0];
$scope.$parent.transactionGroup = transactionGroup;
$scope.$parent.geoGroup = geoGroup;
$scope.$parent.group = transactionGroup;
$scope.$parent.getGeographyList();
$scope.$parent.getTransactionsList();
}
var vm = this;
vm.dtOptions = DTOptionsBuilder.newOptions()
.withOption('ajax', {
url: '<some url>',
type: 'GET'
})
.withDataProp('data')
.withOption('serverSide', true)
.withOption('createdRow', function(row, data, dataIndex) {
$compile(angular.element(row).contents())($scope);
})
.withOption('responsive', true).withOption('bAutoWidth', false)
.withPaginationType('full_numbers');
vm.dtColumns = [
DTColumnBuilder.newColumn('group').withTitle('Group').withOption('bSortable',true),
DTColumnBuilder.newColumn('startTime').withTitle('Start').withOption('bSortable',true),
DTColumnBuilder.newColumn('endTime').withTitle('End').withOption('bSortable',true),
DTColumnBuilder.newColumn('status').withTitle('Status').withOption('bSortable',true),
DTColumnBuilder.newColumn('reason').withTitle('Reason').withOption('bSortable',true).withOption('sWidth', '20%'),
DTColumnBuilder.newColumn('transactionGroup').withTitle('Transaction Group').withOption('bSortable',true),
DTColumnBuilder.newColumn('geoGroup').withTitle('Geo Group').withOption('bSortable',true),
DTColumnBuilder.newColumn('group').withTitle('Current Status').renderWith(function(data, type, full, meta) {
var arr = full.endTime.split(/-|\s|:/);
var endTime = new Date(arr[0], parseInt(arr[1])-1, arr[2], arr[3], arr[4], arr[5]);
arr = full.startTime.split(/-|\s|:/);
var startTime = new Date(arr[0], parseInt(arr[1])-1, arr[2], arr[3], arr[4], arr[5]);
var currentTime = new Date();
var color = ['#2196F3','#009688'];
var currentStatus = ['INACTIVE','ACTIVE']
var index;
if(startTime.getTime() <= currentTime.getTime() && currentTime.getTime() <= endTime.getTime()) {
index = 1;
} else {
index = 0;
}
return '<span style="background : '+color[index]+';color: #FFF;font-weight: 500;" class="currentStatus"> '+currentStatus[index]+' </span>';
}).notSortable(),
DTColumnBuilder.newColumn('code').withTitle('').notSortable().renderWith(function(data, type, full, meta) {
return '<div class="btn-group" > <label class="btn btn-primary"><input type="radio" name="blockedTransaction" ng-click="showUpdateForm(\''+full.code+'\',\''+full.reason+'\',\''+full.startTime+'\',\''+full.endTime+'\',\''+full.transactionGroup+'\',\''+full.geoGroup+'\',\''+full.transactionGroup+'\')" ng-model="blockedTransaction" data-toggle="modal" data-target="#updateForm" data-whatever="#getbootstrap" >EDIT</label></div>';
})
];});
The above code is my table controller. The problem is that I am not able to set the column width. When there is a lot of data for a column, the table resizes and it goes out of its page. What is wrong in the code. What is right key value pair to be put in "withOption" so that it sets the width of the column properly.
Link to Datatables plugin and
Link to Datatables + Angular plugin
Since your test is using a long word without any space, you will need to use the word-break.
See this pen for example:
.dataTable td {
word-break: break-all;
}

How can I load youtube videos with angularjs?

I am trying to delay loading of youtube videos via javascript code as explained here.
and here is the code for that:
function optimizeYouTubeEmbeds() {
// Get all iframes
var frames = document.getElementsByTagName('iframe');
// Loop through each iframe in the page.
for (var i = 0; i < frames.length; i++) {
// Find out youtube embed iframes.
if (frames[i].src && frames[i].src.length > 0 && frames[i].src.match(/http(s)?:\/\/www\.youtube\.com/)) {
// For Youtube iframe, extract src and id.
var src = frames[i].src;
var p = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/;
var id = (src.match(p) ? RegExp.$1 : false);
if (id == false) { continue; }
// Get width and height.
var w = frames[i].width;
var h = frames[i].height;
if (src == '' || w == '' || h == '') { continue; }
// Thease are to position the play button centrally.
var pw = Math.ceil(w / 2 - 38.5);
var ph = Math.ceil(h / 2 + 38.5);
// The image+button overlay code.
var code = '<img src="http://i.ytimg.com/vi/' + id + '/hqdefault.jpg" style="" />';
// Replace the iframe with a the image+button code.
var div = document.createElement('div');
div.innerHTML = code;
div = div.firstChild;
frames[i].parentNode.replaceChild(div, frames[i]);
i--;
}
}
}
// Replace preview image of a video with it's iframe.
function LoadYoutubeVidOnPreviewClick(id, w, h) {
var code = '<iframe src="https://www.youtube.com/embed/' + id + '/? autoplay=1&autohide=1&border=0&wmode=opaque&enablejsapi=1" width="' + w + '" height="' + h + '" frameborder=0 allowfullscreen style="border:1px solid #ccc;" ></iframe>';
var iframe = document.createElement('div');
iframe.innerHTML = code;
iframe = iframe.firstChild;
var div = document.getElementById("skipser-youtubevid-" + id);
div.parentNode.replaceChild(iframe, div);
}
This code worked before switching my project to the angular way of doing things.
I initially thought I could just wrap that code in a $scope and call it, but that did not work. Here is my code that retrieves the videos:
$scope.renderHtml = function (html) {
return $sce.trustAsHtml(html);
};
$scope.Videos = [];
$scope.getVideos = function() {
// api call
$http.get('/api/Videos/AllVideos')
.success(function(data) {
$scope.Videos = data;
});
};
$scope.getVideos();
and here is the html tag where it is rendered:
<div ng-repeat="vid in Videos">
<div ng-bind-html="renderHtml(vid.url)"></div>
</div>
The vid.url includes all the iframe tag information etc. What do I need to do to make this work?

Resources