Need to make deviceorientation recognized on iphone safari through localhost - ios

I'm building a mobile web that needs to read device orientation value from iphone, and the other webpage that gets the value.
This project is going to be displayed in the exhibition, so I'm planning to use USB to connect mobile and the macbook through localhost for realtime response.
But when I see it on iphone by connecting it to my localhost, device orientation value cannot be read.
https://medium.com/#wiekatz/testing-web-applications-running-on-localhost-with-an-iphone-7db6258b8f2
I followed this instruction to connect the device to localhost, and the connection works fine so that I can see it on my phone. I checked that other features like recognizing which button has been clicked are working fine in realtime.
I could see device orientation working when I deploy this to other domain and check on the phone, but I need to make this working through localhost.
Let me know if there's any clue what is causing this!
//mobile.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<title>Mobile PtoR</title>
<link rel="stylesheet" href="mobile_style.css" />
<script src="https://www.gstatic.com/firebasejs/6.3.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/6.3.1/firebase-firestore.js"></script>
<style></style>
</head>
<body>
<div id="closewrapper"><button id="closebutton">x</button></div>
<div class="iconwrapper">
<div class="icons" id="AppBank"><p>Bank</p></div>
<div class="icons" id="AppWeather"><p>Weather</p></div>
<div class="icons" id="AppDict"><p>Dictionary</p></div>
<div class="icons" id="AppFb"><p>Facebook</p></div>
<div class="icons" id="AppCal"><p>Calendar</p></div>
</div>
<div class="sensorcheck">
<h1>Device Orientation API</h1>
<span id="do-unsupported" class="hidden"
>deviceorientation event not supported</span
>
<span id="dm-unsupported" class="hidden"
>devicemotion event not supported</span
>
<span id="cnc-unsupported" class="hidden"
>compassneedscalibration event not supported</span
>
<div id="do-results">
<div id="cube" class="cube">
<div class="face one">1</div>
<div class="face two">2</div>
<div class="face three">3</div>
<div class="face four">4</div>
<div class="face five">5</div>
<div class="face six">6</div>
</div>
<div id="do-info" class="hidden">
<p>
Coordinates: (<span id="beta" class="value">null</span>,
<span id="gamma" class="value">null</span>,
<span id="alpha" class="value">null</span>)
<br />
Position absolute?
<span id="is-absolute" class="value">unavailable</span>
</p>
</div>
<div id="dm-info" class="hidden">
<p>
Acceleration: (<span id="acceleration-x" class="value">null</span>,
<span id="acceleration-y" class="value">null</span>,
<span id="acceleration-z" class="value">null</span>) m/s<sup>2</sup>
</p>
<p>
Acceleration including gravity: (<span
id="acceleration-including-gravity-x"
class="value"
>null</span
>,
<span id="acceleration-including-gravity-y" class="value">null</span>,
<span id="acceleration-including-gravity-z" class="value">null</span>)
m/s<sup>2</sup>
</p>
<p>
Rotation rate: (<span id="rotation-rate-beta" class="value">null</span
>, <span id="rotation-rate-gamma" class="value">null</span>,
<span id="rotation-rate-alpha" class="value">null</span>)
</p>
<p>Interval: <span id="interval" class="value">0</span> milliseconds</p>
</div>
</div>
</div>
<script>
if (!window.DeviceOrientationEvent) {
document.getElementById("do-unsupported").classList.remove("hidden")
} else {
document.getElementById("do-info").classList.remove("hidden")
window.addEventListener("deviceorientation", function(event) {
document.getElementById(
"cube"
).style.webkitTransform = document.getElementById(
"cube"
).style.transform =
"rotateX(" +
event.beta +
"deg) " +
"rotateY(" +
event.gamma +
"deg) " +
"rotateZ(" +
event.alpha +
"deg)"
document.getElementById("beta").innerHTML = Math.round(event.beta)
document.getElementById("gamma").innerHTML = Math.round(event.gamma)
document.getElementById("alpha").innerHTML = Math.round(event.alpha)
document.getElementById("is-absolute").innerHTML = event.absolute
? "true"
: "false"
})
}
</script>
<!-- Custom fuctions of firebase-->
<script src="mobileFirebase.js"></script>
</body>
</html>
//mobileFirebase.js
//the value is passed to firebase
var firebaseConfig = {
--------
}
firebase.initializeApp(firebaseConfig)
var firestore = firebase.firestore()
/* define things to be used*/
const AppBank = document.querySelector("#AppBank")
const AppWeather = document.querySelector("#AppWeather")
const AppDict = document.querySelector("#AppDict")
const AppFb = document.querySelector("#AppFb")
const AppCal = document.querySelector("#AppCal")
const closewrapper = document.querySelector("#closewrapper")
const closebutton = document.querySelector("#closebutton")
//const CurrentStatus = "landing"
const DOsensorRef = firestore.doc("status/DOsensor")
const docRef = firestore.doc("status/ClickStatus")
/* device orientation */
if (!window.DeviceOrientationEvent) {
document.getElementById("do-unsupported").classList.remove("hidden")
} else {
document.getElementById("do-info").classList.remove("hidden")
window.addEventListener("deviceorientation", function(event) {
const val_beta = Math.round(event.beta)
const val_gamma = Math.round(event.gamma)
const val_alpha = Math.round(event.alpha)
console.log(
"beta : ",
val_beta,
"gamma : ",
val_gamma,
"alpha : ",
val_alpha
)
DOsensorRef.set({
fire_beta: val_beta,
fire_alpha: val_alpha,
fire_gamma: val_gamma
})
.then(function() {
console.log("in sync")
})
.catch(function(error) {
console.log(error)
})
})
}
/* status recognize */
closebutton.addEventListener("click", function(){
closewrapper.style.display="none"
const CurrentStatus = "Landing"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
})
AppBank.addEventListener("click", function() {
const CurrentStatus = "Bank"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
AppWeather.addEventListener("click", function() {
const CurrentStatus = "Weather"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
AppDict.addEventListener("click", function() {
const CurrentStatus = "Dictionary"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
AppFb.addEventListener("click", function() {
const CurrentStatus = "Facebook"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})
AppCal.addEventListener("click", function() {
const CurrentStatus = "Calendar"
docRef.set({
AppStatus: CurrentStatus
})
.then(function() {
console.log("Status changed!")
})
.catch(function(error) {
console.log("got an error: ", error)
})
closewrapper.style.display="block"
})

I had the same Problem yesterday. Your localhost probably does not run on https but on http. So certain features as device orientation gets blocked. You are only able to use them in a secure context.
Easy solution is to tunnel your local server to the outside e.g. with https://localtunnel.github.io/www/
or make your own secure certificate for your local webserver. Maybe you can find some infos here.

Related

Excel js, unable to make rest call

We are developing a excel plugin using Excel JS. The server code written in java and deployed in wildfy server.
Through excel plugin I'm unable to make the rest call to retrieve the user data. The aim is to perform login operation and retrieve the excel byte format stored at server and display in excel.
Any suggestions? Following is sample code which we tried so-far.
index.html
<body class="ms-font-m ms-welcome">
<div id="content-header">
<div class="padding">
<h1>Welcome</h1>
</div>
</div>
<div id="content-main">
<button id="ping-server3" onclick="pingServer2()">Ping server2</button>
<p id="demo"></p>
<p id="demo1"></p>
<button id="ping-server">Ping server</button>
<p></p>
<div class="padding">
<form>
<div class="container">
<label for="uname"><b>Username</b></label>
<input id="uname" type="text" placeholder="Enter Username"
name="uname" required>
<label for="psw"><b>Password</b></label>
<input type="password" placeholder="Enter Password" name="psw"
required>
<button id="login-button" onclick="pingServer2()">Login</button>
</div>
<div class="container" style="background-color:#f1f1f1">
<span class="psw">Need password help?</span>
</div>
</form>
</div>
</div>
<script type="text/javascript" src="node_modules/core-js/client/core.js">
</script>
<script type="text/javascript" src="node_modules/jquery/dist/jquery.js">
</script>
<script type="text/javascript" src="node_modules/office-ui-fabric-
js/dist/js/fabric.js"></script>
<script type="text/javascript" src="app.js" ></script>
<script type="text/javascript" src="utility.js" ></script>
</body>
app.js
(function () {
Office.initialize = function (reason) {
$(document).ready(function () {
if (!Office.context.requirements.isSetSupported('ExcelApi', 1.7)) {
alert("ERROR");
console.log('Sorry. The tutorial add-in uses Excel.js APIs that are
not available in your version of Office.');
}
$('#login-button').click(createTable);
});
};
function createTable() {
axios({
method: 'post',
url: 'http://localhost:8183/x/operation.do?&operationId=LOGIN_USER',
data: {emailAddress : 'x#xyz.com,password : '123#asdA'}
})
.then(response => {
$('#demo').innerHTML = response.data;
content=response.data.uiUser.createdBy;
$('#demo1').innerHTML = content;
})
.catch(error => {
$('#demo').innerHTML = response.status;
});
Excel.run(function (context) {
const currentWorksheet =
context.workbook.worksheets.getActiveWorksheet();
const expensesTable = currentWorksheet.tables.add("A1:D1", true
/*hasHeaders*/);
expensesTable.name = "ExpensesTable";
expensesTable.getHeaderRowRange().values = [["Date", "Merchant",
"Category", "Amount"]];
expensesTable.rows.add(null /*add at the end*/, [["1/1/2017", "The
Phone Company", "Communications", "120"], ["1/2/2017", "Northwind
Electric Cars", "Transportation", "142.33"], ["1/5/2017", "Best For You
Organics Company", "Groceries", "27.9"], ["1/10/2017", "Coho Vineyard",
"Restaurant", "33"], ["1/11/2017", "Bellows College", "Education",
"350.1"], ["1/15/2017", "Trey Research", "Other", "135"], ["1/15/2017",
"Best For You Organics Company", "Groceries", "97.88"]]);
expensesTable.columns.getItemAt(3).getRange().numberFormat =
[['€#,##0.00']];
expensesTable.getRange().format.autofitColumns();
expensesTable.getRange().format.autofitRows();
return context.sync();
}).catch(function (error) {
console.log("Error: " + error);
if (error instanceof OfficeExtension.Error) {
console.log("Debug info: " + JSON.stringify(error.debugInfo));
}
});
}
})
the URL you're trying to POST is in http format:
http://localhost:8183/x/operation.do?&operationId=LOGIN_USER
The Excel AddIn is deployed using https.
If you inspect the AddIn, using the F12 Debugger Tools, you will see a Mixed Content error.
Mixed Content: The page at
'https://Your_AddIn_Url' was loaded over HTTPS, but requested an insecure resource
'http://localhost:8183/x/operation.do?&operationId=LOGIN_USER'. This request has
been blocked; the content must be served over HTTPS.
Using an https endpoint should solve your issue.

Gap between header and rest of calendar

I am having problem with rendering fullcalendar in my asp.net mvc application. Library I am using is Fullcalendar jquery.
As shown by the lower arrow in picture,blue event date range between times is actually between 12 am and 1 am, but in calendar event marked in blue exceeds 1 am. Why? It also seems that there is some kind of a gap as shown by the above arrow between header and the rest of calendar. See the picture_1.See the picture_2
Here is cshtml code:
model OrdinacijaS.Termin
#{
ViewBag.Title = "Create";
}
<h2>Create</h2>
#using (Html.BeginForm()) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Termin</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Pocetak)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Pocetak, new { id = "textBoxPocetak" })
#Html.ValidationMessageFor(model => model.Pocetak)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Kraj)
</div>
<div class="editor-field">
#Html.TextBoxFor(model => model.Kraj, new { id = "textBoxKraj" })
#Html.ValidationMessageFor(model => model.Kraj)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Pacijent_PacijentId, "Pacijent")
</div>
<div class="editor-field">
#Html.DropDownList("Pacijent_PacijentId", String.Empty)
#Html.ValidationMessageFor(model => model.Pacijent_PacijentId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.Zahvat_ZahvatId, "Zahvat")
</div>
<div class="editor-field">
#Html.DropDownList("Zahvat_ZahvatId", String.Empty)
#Html.ValidationMessageFor(model => model.Zahvat_ZahvatId)
</div>
<p>
<input type="submit" value="Create" id="submitButton" />
</p>
</fieldset>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
<div id="calendar"></div>
#*<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.css" rel="stylesheet" />#
<link href="https://cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.print.css" rel="stylesheet" media="print" />*#
<link href='/Content/fullcalendar.css' rel='stylesheet' />
<link href='/Content/fullcalendar.print.css' rel='stylesheet' media='print' />
Here is javascript code:
#section Scripts {
#*#Scripts.Render("~/bundles/jqueryval")*#
#*<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js" rel="stylesheet"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/fullcalendar.min.js" rel="stylesheet"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/3.4.0/locale/hr.js" rel="stylesheet"></script>*#
<script src='Scripts/jquery.min.js' rel="stylesheet"></script>
<script src='Scripts/moment.min.js' rel="stylesheet"></script>
<script src='Scripts/fullcalendar/fullcalendar.js' rel="stylesheet"></script>
<script>
$(document).ready(function(myevents){
var myevents = [];
$.ajax({
cache: false,
type: "GET",
asyc:false,
url: "/Termin/getTermin",
success: function (data) {
$.each(data, function (i, v) {
myevents.push({
title: v.Ime,
description: "some description",
start: moment(v.Pocetak),
end: v.Kraj != null ? moment(v.Kraj) : null,
color: "#378006",
allDay: false
});
})
alert(myevents.length);
GenerateCalendar(myevents);
},
error: function (error) {
alert(error);
}
})
})
GenerateCalendar();
function GenerateCalendar(myevents) {
$('#calendar').fullCalendar('destroy');
$('#calendar').fullCalendar({
defaultDate: new Date(),
defaultView: 'agendaWeek',
timeFormat: 'h(:mm)a',
header: {
left: 'prev, next, today',
center: 'title',
right: 'month, basicWeek, basicDay, agenda'
},
eventLimit: true,
eventColor: "#378006",
events: myevents,
selectable: true,
allDaySlot: false,
select: function(start, end, allDay) {
endtime = moment(end).format('YYYY/MM/DD hh:mm');
starttime = moment(start).format('YYYY/MM/DD hh:mm');
var mywhen = starttime + ' - ' + endtime;
$("#textBoxPocetak").val(starttime);
$("#textBoxKraj").val(endtime);
},
businessHours: {
dow: [1, 2, 3, 4],
start: '8:00am',
end: '4:00pm',
}
})
}
$("#submitButton").on('click', function () {
//var myEvent = [];
//myEvent.push({
// title: 'Long Event',
// start: '2017-08-08T08:30:00',
// end: '2017-08-08T09:30:00'
//});
//myEvent = {
// title: 'Long Event',
// start: '2017/08/08 08:30',
// end: '2017/08/08 09:30'
//};
//$('#calendar').fullCalendar('renderEvent', myEvent, 'stick');
//myEvent = {
// title: 'Long Event',
// start: $('#textBoxPocetak').val(),
// end: $('#textBoxKraj').val()
//};
//$('#calendar').fullCalendar('renderEvent',myEvent,true);
//$('#calendar').fullCalendar('renderEvent', {
// title: 'Long Event',
// start: '2017-08-08T08:30:00',
// end: '2017-08-08T09:30:00'
//}, true);
//$("#calendar").fullCalendar('addEventSource', myEvent);
//$('#calendar').fullCalendar('updateEvent', myEvent);
});
</script>
}
Here is css code:
<style>
.fc-sun{
color:#FFF;
background: red;
}
.fc-clear {
clear: none !important;
}
</style>
Sorry for delayed answer, but (I think) I found a solution. I implemented FullCalendar jquery using MVC 4 application in Visual Studio 2013. MVC4 doesn't come with included bootstrap.js dependency,like later versions of MVC (MVC5 for example). It seems that Full Calendar jquery is somehow connected or depended on bootstrap.js becasue the moment after I installed booststrap.js (via Nugget)and included it in my MVC4 procjet the problem solved.

Angularjs ReferenceError: post is not defined

I'm working on a simple app that create posts and comments to learn how to create ROR apps implemented with Angularjs.
I'm finding a problem as I'm trying to make my addComment function work. Seems like the variable that holds the expected object is not defined. At least this is the message I got from network inspection
ReferenceError: post is not defined
at k.$scope.addComment (http://localhost:3000/javascripts/app.js:99:34)
at bb.functionCall (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:176:141)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:193:165
at k.$get.k.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:112:319)
at k.$get.k.$apply (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:113:48)
at HTMLFormElement.<anonymous> (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:193:147)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:31:225
at Array.forEach (native)
at q (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:7:280)
at HTMLFormElement.c (http://ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js:31:207)angular.js:9959 (anonymous function)angular.js:7298 $getangular.js:12695 $get.k.$applyangular.js:18941 (anonymous function)angular.js:2822 (anonymous function)angular.js:325 qangular.js:2821
If someone can se a problem in my code that points to this error please let me know.
follows my code
angular.module('flapperNews', ['ui.router'])
//Provider
.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'MainCtrl',
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
})
.state('posts', {
url: '/posts/{id}',
templateUrl: '/posts.html',
controller: 'PostsCtrl',
resolve: {
postPromise: ['posts', function(posts){
return posts.getAll();
}]
}
})
$urlRouterProvider.otherwise('home');
}])
//Posts service
.factory('posts', ['$http', function($http){
var o = {
posts: []
};
o.getAll = function() {
return $http.get('/posts.json').success(function(data){
angular.copy(data, o.posts);
});
};
o.create = function(post) {
return $http.post('/posts.json', post).success(function(data){
o.posts.push(data);
});
};
o.addComment = function(id, comment) {
return $http.post('/posts/' + id + '/comments.json', comment);
};
return o;
}])
//Main Controller
.controller('MainCtrl', [
'$scope',
'posts',
function($scope, posts){
$scope.posts = posts.posts;
$scope.addPost = function(){
if(!$scope.title || $scope.title == '') { return; }
posts.create({
title: $scope.title,
link: $scope.link
});
$scope.title = '';
$scope.link = '';
};
$scope.incrementUpvotes = function(post) {
post.upvotes += 1;
};
}])
//Posts Controller
.controller('PostsCtrl', [
//the $scope declares that it will have elements visible in the view
'$scope',
'$stateParams',
//the posts under is the service
'posts',
function($scope, $stateParams, posts){
$scope.post = posts.posts[$stateParams.id];
$scope.addComment = function(){
if($scope.body === '') { return; }
posts.addComment( post.id, {
body: $scope.body,
author: 'user'
}).success(function(comment){
$scope.post.comments.push(comment);
});
$scope.body = '';
};}]);
and the html
<!DOCTYPE html>
<html>
<head>
<title>FlapperNews</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.js"></script>
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css" rel="stylesheet">
<script src="javascripts/app.js"></script>
<script src="javascripts/application.js"></script>
<%= csrf_meta_tags %>
</head>
<body ng-app="flapperNews">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<ui-view></ui-view>
</div>
</div>
<script type="text/ng-template" id="/home.html">
<div class="page-header">
<h1>Flapper News</h1>
</div>
<div ng-repeat="post in posts | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(post)"></span>
{{post.upvotes}}
<span style="font-size:20px; margin-left:10px;">
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</span>
<span>
Comments
</span>
</div>
<form ng-submit="addPost()"
style="margin-top:30px;">
<h3>Add a new post</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Title"
ng-model="title">
</div>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Link"
ng-model="link">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
<script type="text/ng-template" id="/posts.html">
<div class="page-header">
<h3>
<a ng-show="post.link" href="{{post.link}}">
{{post.title}}
</a>
<span ng-hide="post.link">
{{post.title}}
</span>
</h3>
</div>
<div ng-repeat="comment in post.comments | orderBy:'-upvotes'">
<span class="glyphicon glyphicon-thumbs-up"
ng-click="incrementUpvotes(comment)"></span>
{{comment.upvotes}} - by {{comment.author}}
<span style="font-size:20px; margin-left:10px;">
{{comment.body}}
</span>
</div>
<form ng-submit="addComment()"
style="margin-top:30px;">
<h3>Add a new comment</h3>
<div class="form-group">
<input type="text"
class="form-control"
placeholder="Comment"
ng-model="body">
</div>
<button type="submit" class="btn btn-primary">Post</button>
</form>
</script>
</body>
</html>
I think the problem is here Comments. You missed {. Because of which it is unable to find the stateparam id, which you are using to create post object on controller's scope.

AngularJS doesn't work in MVC Partial Views

I'm currently working on a ASP.NET MVC project. The sites of the web application are created with Bootstrap. Later I added some AngularJS script to be able to translate the page into different languages. This works fine for all the pages, but not so if a partial view is loaded from a page.
So, for example I have a page to search for rollout objects by name or host name. On the page all the angular expressions in curly braces are evaluated properly and are replaced with strings in several languages by using a translate script. Now if I filter the objects by one of the three attributes the partial view for that page is loaded showing the results of the search, but here are the angular expressions not evaluated and it just shows the expressions themselves.
Here is the page where it works properly:
#{
ViewBag.Title = "{{ 'ROLLOUT-OBJECT_MANAGEMENT.TITLE' | translate }}";
}
<!-- html -->
<div style="font-size: 20px; margin-top: 20px; margin-bottom: 20px;">
<div class="gray-background list-group-item" translate="{{'ROLLOUT-OBJECT_MANAGEMENT.TITLE'}}"></div>
</div>
<div class="list-group">
<div class="gray-background list-group-item">
<div class="row margin-bottom">
<div class="col-md-3">
<h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.FIRST_NAME'}}"></h6>
</div>
<div class="col-md-3">
<h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.SURNAME'}}"></h6>
</div>
<div class="col-md-3">
<h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.HOST_NAME'}}"></h6>
</div>
</div>
<div class="row margin-bottom">
<div class="col-md-3">
<!-- referenced in getPartial() -->
<input type="text" class="form-control" id="iFirstName" name="iFirstName" placeholder="">
</div>
<div class="col-md-3">
<!-- referenced in getPartial() -->
<input type="text" class="form-control" id="iSurName" name="iSurName" placeholder="">
</div>
<div class="col-md-3">
<!-- referenced in getPartial() -->
<input type="text" class="form-control" id="iHostName" name="iHostName" placeholder="">
</div>
<div class="col-md-3">
<!-- getPartial() added to click through javascript-->
<button type="submit" class="btn btn-primary btn-block" id="iButton"><span translate="{{'ROLLOUT-OBJECT_MANAGEMENT.BUTTON_SEARCH'}}"></span><span class="white-color glyphicon glyphicon-search"></span></button>
</div>
</div>
</div>
</div>
<div class="list-group">
<div class="gray-background list-group-item">
<h5><span translate="{{'ROLLOUT-OBJECT_MANAGEMENT.RESULTS'}}"></span><span class="purple-color glyphicon glyphicon-globe"></span></h5>
</div>
<!-- referenced in getPartial() -->
<div class="gray-background list-group-item">
<div class="row">
<div class="col-md-12" id="partialViewContainer">
#{Html.RenderPartial("_RolloutObjectManagementResultsPartial");}
</div>
</div>
</div>
</div>
<!-- layout -->
#Styles.Render(
"~/content/chosen/chosen.css",
"~/content/chosen/prism.css",
"~/content/chosen/style.css",
"~/content/bootstrap.css",
"~/content/Site.css")
<!-- javascript -->
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/chosen/chosen.jquery.js"></script>
<script src="~/Scripts/chosen/prism.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script>
var config = {
'.chosen-select': {},
'.chosen-select-deselect': { allow_single_deselect: true },
'.chosen-select-no-single': { disable_search_threshold: 10 },
'.chosen-select-no-results': { no_results_text: 'Oops, nothing found!' },
'.chosen-select-width': { width: "95%" }
}
for (var selector in config) {
$(selector).chosen(config[selector]);
}
</script>
<script>
//add functionality to button
$('#iButton').click(function () {
getPartial('0');
});
</script>
<script>
function previous() {
var temp = document.getElementById("hPage").value;
//alert(temp);//debug
if (temp > 0) {
temp = --temp;
}
getPartial(temp);
}
function next() {
var temp = document.getElementById("hPage").value;
//alert(temp);//debug
temp = ++temp;
getPartial(temp);
}
</script>
<script>
function getPartial(newPage) {
//get search values
var tempFirst = document.getElementById("iFirstName");
var tempSur = document.getElementById("iSurName");
var tempHost = document.getElementById("iHostName");
var firstResult = tempFirst.value;
var surResult = tempSur.value;
var hostResult = tempHost.value;
//ajax call
$.ajax({
url: "_RolloutObjectManagementResultsPartial",
type: "POST",
data: { firstName: firstResult, surName: surResult, hostName: hostResult, page: newPage, count: 10 },
dataType: "html",
error: function (xhr) {
//alert(xhr.responseText);//debug
},
success: function (result) {
$("#partialViewContainer").html(result).find("select").each(function () {
$(this).chosen({});
})
},
complete: function () {
//alert("everything worked");//debug
}
});
}
</script>
And here is the partial view where it doesn't work (important are the expressions in {{...}}:
<!-- Import needed namespaces -->
#using RolloutTool.BusinessLayer.Foundation
#using RolloutTool.Utility
<!-- Initializing needed variables -->
#{
List<RolloutObject> RolloutObjects = ViewContext.Controller.ViewBag.RolloutObjects;
List<Cluster> Clusters = ViewContext.Controller.ViewBag.Clusters;
string name = "";
int count = 0;
string rowID = "";
int page = 0;
if (ViewContext.Controller.ViewBag.Page != null)
{
page = ViewContext.Controller.ViewBag.Page;
}
}
<!-- html elements -->
<div class="row">
<div class="col-md-12">
<table class="table">
<thead>
<tr>
<th style="width:25%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.EMPLOYEE'}}"></h6></th>
<th style="width:20%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.WORK_STATION'}}"></h6></th>
<th class="text-center" style="width:15%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.EDIT'}}"></h6></th>
<th class="text-center" style="width:25%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.CLUSTER'}}"></h6></th>
<th class="text-center" style="width:15%"><h6 translate="{{'ROLLOUT-OBJECT_MANAGEMENT.ASSIGN'}}"></h6></th>
</tr>
</thead>
<tbody>
<!-- creating all RolloutObject Table rows -->
#foreach (RolloutObject ro in RolloutObjects)
{
<!-- generating rowID -->
rowID = "row" + Convert.ToString(count);
count++;
<!-- generating the full employee name -->
name = Functions.TryGetValue(ro.Employee.FirstName) + " " + Functions.TryGetValue(ro.Employee.SecondName) + " " + Functions.TryGetValue(ro.Employee.Name);
<tr id="#rowID">
<td>#name</td>
<td id="#Convert.ToString(rowID + "_hn")">#Convert.ToString(Functions.TryGetValue(ro.Hostname))</td>
<!-- generate link to right rolloutobjectedit -->
<td class="text-center"><span class="btn-pencil glyphicon glyphicon-pencil blue-color glyph-hov" onclick="location.href='#Url.Action("RolloutObjectEdit", "RolloutObject", new {hostName = ro.Hostname })'"></span></td>
<!-- generating the link for cluster addition and populating cluster dropdown -->
<td class="text-center">
<div class="row">
<div class="col-sm-12">
<select class="chosen-select no-margin" style="width:100%" id="#Convert.ToString(rowID + "_cl")" name="iCluster" data-placeholder="Cluster">
#if (ro.Cluster != null)
{
<option selected>#Convert.ToString(Functions.TryGetValue(ro.Cluster.Name))</option>
}
else
{
<option></option>
}
#foreach (Cluster cluster in Clusters)
{
<option>#Convert.ToString(Functions.TryGetValue(cluster.Name))</option>
}
</select>
</div>
</div>
</td>
<td class="text-center"><span class="btn-ok glyphicon glyphicon-ok green-color glyph-hov" onclick="callAjax('#rowID')" /></td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-md-12">
<input class="hidden" id="hPage" value="#Convert.ToString(page)" />
<nav>
<ul class="pager">
<li class="pull-left"><a class="btn-paging glyphicon glyphicon-arrow-left" onclick="previous()"></a></li>
<li class="pull-right"><a class="btn-paging glyphicon glyphicon-arrow-right" onclick="next()"></a></li>
</ul>
</nav>
</div>
</div>
<!-- javascript -->
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/chosen/chosen.jquery.js"></script>
<script src="~/Scripts/chosen/prism.js"></script>
<script>
function callAjax(idRow) {
//get row values
var tempTD = document.getElementById(idRow + "_hn");
var tempSelect = document.getElementById(idRow + "_cl");
var tempHostName = tempTD.textContent;
var tempCluster = tempSelect.options[tempSelect.selectedIndex].text;
//ajax call
$.ajax({
url: "AddToCluster",
type: "POST",
data: { clusterName: tempCluster, hostName: tempHostName },
dataType: "html",
error: function (xhr) {
alert(xhr.responseText);
},
success: function (result) {
},
complete: function () {
//alert("everything worked");//debug
}
});
}
</script>
<script>
function previous() {
var temp = document.getElementById("hPage").value;
//alert(temp);//debug
if (temp > 0) {
temp = --temp;
}
getPartial(temp);
}
function next() {
var temp = document.getElementById("hPage").value;
//alert(temp);//debug
temp = ++temp;
getPartial(temp);
}
</script>
<script>
function getPartial(newPage) {
//get search values
var tempFirst = document.getElementById("iFirstName");
var tempSur = document.getElementById("iSurName");
var tempHost = document.getElementById("iHostName");
var firstResult = tempFirst.value;
var surResult = tempSur.value;
var hostResult = tempHost.value;
//ajax call
$.ajax({
url: "_RolloutObjectManagementResultsPartial",
type: "POST",
data: { firstName: firstResult, surName: surResult, hostName: hostResult, page: newPage, count: 10 },
dataType: "html",
error: function (xhr) {
alert(xhr.responseText);
},
success: function (result) {
$("#partialViewContainer").html(result).find("select").each(function () {
$(this).chosen({});
})
},
complete: function () {
//alert("everything worked");//debug
}
});
}
</script>
This is the _Layout.cshtml where the scripts are contained and loaded:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - {{ 'TITLE.PROGRAM' | translate }}</title>
#Styles.Render(
"~/Content/css",
"~/Content/flag-icon-css-master/assets/docs.css",
"~/Content/flag-icon-css-master/css/flag-icon.min.css",
"~/Content/Site.css")
<script src="~/Scripts/angular/angular.js"></script>
<script src="~/Scripts/angular/angular-translate.js"></script>
<script src="~/Scripts/angular/angular-cookies.min.js"></script>
<script src="~/Scripts/angular/translate.js"></script>
<script src="~/Scripts/angular/angular-route.min.js"></script>
<script src="~/Scripts/angular/angular-translate-storage-cookie.min.js"></script>
<script src="~/Scripts/angular/angular-translate-storage-local.min.js"></script>
</head>
<body ng-controller="Ctrl">
<!-- Here is the html for the navigation bar etc. -->
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</body>
</html>
I am really not an expert on AngularJS as I only wanted to provide some cool translation feature, but I hope you guys have an idea why it doesn't work in the partial views.
Its just that you need to call the partial view using ng-include("'controller/action'"). Apostrophe(') is important while writing url.
Example
<div id="TestDiv" ng-include="templateUrl"></div>
and inside the angular controller
var app = angular.module("Layout", []);
app.controller("LoadPage", function ($scope, $http, $sce) {
//Initially
$scope.templateUrl = '/Home/DefaultPage';
// To dynamically change the URL.
$scope.NewProjFn = function () {
$scope.templateUrl = '/Home/ProjectPage';
};
});
It might well not at all be difficult for you to re-implement it but by using ng-include you also need not to make an ajax call. It do it all by itself which includes ajax call, compilation and display. But the functions like ng-click and other events will not work as its a one time compilation process.

jQuery-ui autocomplete text box closes on mouse over

I've got a fairly simple jquery-ui autocomplete box on my page. The HTML is simple and looks like this:
<div class="control-group">
<label for="addCampaignUser"></label>
<div class="controls">
<input id="addCampaignUser" />
<button id="addCampaignUserButton">Add User</button>
</div>
</div>
The JavaScript is a bit more complex, but still not too bad:
$('#addCampaignUser').autocomplete({
minLength: 2,
source: function (request, response) {
var term = request.term;
if (term in cache) {
response(cache[term]);
return;
}
$.post("#Url.Action("ForCampaignAutoComplete", "CustomerUser")", { "searchTerm": request.term })
.done(function (data) {
console.log('{request: ' + JSON.stringify(request) + "}");
console.log('{data: ' + JSON.stringify(data) + "}");
cache[request.term] = data;
response(data);
})
.fail(function (err) {
console.error(err);
});
},
select: function (event, ui) {
console.log(ui.item ? "Selected: " + ui.item.Name : "Nothing selected, input was " + this.value);
},
close: function(event, ui) {
console.log("closed: " + event);
}
})
.data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li>").append("<a>" + item.Name + " (" + item.CustomerName + ")</a>").appendTo(ul);
};
Everything seems to work as expected:
The problem is that as soon as I mouse over any of the items in the list, or if I try to select one of the items via up/down arrow, the list closes, without anything being selected (or the select or focus events firing).
I've tried removing the <a> tags around the item.Name in the .data("ui-autocomplete") handler, like so:
.data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li>").append(item.Name + " (" + item.CustomerName + ")").appendTo(ul);
};
That fixes the auto-close problem, but then nothing ever gets selected.
I've tried disabling all the various add-ons and libraries that might be interfering, but nothing so far. I'm using jquery-2.0.3.js and jquery-ui-1.10.3.js.
Am I doing something obviously wrong?
[Edit: Including code for entire page, as requested]
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="/Content/bootstrap?v=j_-_1Zyowtnxf-sjdU3kRasY7Qp7ZP_jWGqEkV333nA1" rel="stylesheet"/>
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="/scripts/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="navbar navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="/">Payboard</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li>Customers</li><li>Campaigns</li><li>Integrations</li><li>Account</li><li>Logout</li><li>Test</li>
</ul>
</div>
</div>
</div>
</div>
<div class="container">
<h2>AutoComplete</h2>
<h4>End users assigned to the campaign</h4>
<div class="control-group">
<label for="addCampaignUser"></label>
<div class="controls">
<input id="addCampaignUser" />
<button id="addCampaignUserButton">Add User</button>
</div>
</div>
<hr>
<footer>
<p>© Payboard 2013</p>
</footer>
</div>
<script src="/Scripts/jquery-2.0.3.js"></script>
<script src="/Scripts/jquery-ui-1.10.3.js"></script>
<script src="/Scripts/jquery.unobtrusive-ajax.js"></script>
<script src="/Scripts/jquery.validate.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive-custom-for-bootstrap.js"></script>
<script src="/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="/Scripts/flot/jquery.flot.js"></script>
<script src="/Scripts/flot/jquery.flot.time.js"></script>
<script src="/Scripts/flot/jquery.flot.stack.js"></script>
<script src="/Scripts/flot/jquery.flot.categories.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<!-- Payboard JS bundle -->
<script src="/Scripts/knockout-2.3.0.debug.js"></script>
<script src="/Scripts/jquery.event.drag.js"></script>
<script src="/Scripts/SlickGrid/slick.core.js"></script>
<script src="/Scripts/SlickGrid/slick.formatters.js"></script>
<script src="/Scripts/SlickGrid/slick.grid.js"></script>
<script src="/Scripts/require.js"></script>
<script src="/Scripts/jquery.signalR-1.1.3.js"></script>
<script src="/Scripts/linq.js"></script>
<script src="/Scripts/Payboard/Main.js"></script>
<script src="/Scripts/dateformat.js"></script>
<script type="text/javascript">
// Payboard.ready(function () {
$(function () {
var cache = {};
$('#addCampaignUser').autocomplete({
minLength: 2,
source: function (request, response) {
var term = request.term;
if (term in cache) {
response(cache[term]);
return;
}
$.post("/CustomerUser/ForCampaignAutoComplete", { "searchTerm": request.term })
.done(function (data) {
console.log('request: ' + JSON.stringify(request));
console.log('data: ' + JSON.stringify(data));
cache[request.term] = data;
response(data);
})
.fail(function (err) {
console.error(err);
});
},
select: function (event, ui) {
console.log(ui.item ? "Selected: " + ui.item.Name : "Nothing selected, input was " + this.value);
},
focus: function (event, ui) {
console.log(ui.item ? "Focused: " + ui.item.Name : "Nothing focused, input was " + this.value);
}
})
.data("ui-autocomplete")._renderItem = function (ul, item) {
return $("<li>").append("<a>" + item.Name + " (" + item.CustomerName + ")</a>").appendTo(ul);
// return $("<li>").append(item.Name + " (" + item.CustomerName + ")").appendTo(ul);
};
});
</script>
</body>
</html>
Looks like you're including jQueryUI twice. Once here:
<script src="/Scripts/jquery-ui-1.10.3.js"></script>
and again here:
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
This could be causing your problem--remove one of the references.

Resources