AngularJS - Change view based on user preferences - javascript

I am building an email app. It consists of an option to change the default settings. When it is clicked, the following partial view is loaded.
In this view, when the Save changes button is clicked, the values chosen by the user are saved in $localStorage using ngStorage like so:
savePreferenceService.js
(function() {
'use strict';
var savePreferenceService = function ($localStorage) {
this.setPreferences = function (selectedLang, converse, selectedNumber, selectedNumberContact, reply, signature) {
$localStorage.selectedLang = selectedLang;
$localStorage.converse = converse;
$localStorage.selectedNumber = selectedNumber;
$localStorage.selectedNumberContact = selectedNumberContact;
$localStorage.reply = reply;
$localStorage.signature = signature;
console.log($localStorage.selectedLang);
console.log($localStorage.converse);
console.log($localStorage.selectedNumber);
console.log($localStorage.selectedNumberContact);
console.log($localStorage.reply);
console.log($localStorage.signature);
}
};
angular.module('iisEmail')
.service ('savePreferenceService', ['$localStorage', savePreferenceService]);
}());
I have the following questions:
1) Is there a way to store values entered by the user (e.g. selectedLang, converse, selectedNumber) in a JSON file. I have no database.
2) If the user only changes a few preferences (e.g. language preference and number of conversations per page preference), all other preferences (e.g. number of contacts per page and reply) return a value of undefined. Is there a way to return the default values for the preferences that were not changed by the user?. Here is the JSON file that contains the dropdown menu options (e.g. data.languages contains all the languages the user can choose from) and default preferences, data.userPreferences.
settings.json
{
"data": {
"languages": [
"Afrikaans",
"Albanian",
"Arabic",
"Armenian",
"Basque",
"Bengali",
"Catalan",
"Cambodian",
"Chinese (Mandarin)",
"German",
"Greek",
"Gujarati",
"Hebrew",
"Icelandic",
"Maori",
"Marathi",
"Mongolian",
"Serbian",
"Slovak",
"Slovenian",
"Spanish",
"Swahili",
"Swedish",
"Tamil",
"Tatar",
"Telugu"
],
"undoSend": [
5,
10,
20,
30
],
"conversations": [
10,
20,
30,
40,
50,
60,
70,
80,
90,
100
],
"contacts": [
20,
40,
60,
80,
100,
120,
130,
140,
180,
200
],
"userPreferences": {
"selectedLang": "Telugu",
"converse": false,
"selectedNumber": 10,
"selectedNumberContact": 20,
"reply": false,
"signature": "--"
}
}
}
3) My final goal - In the settings page, if the user selects 20 conversations per page, then the next time Inbox is clicked I want to show only 20 emails. Right now, 50 emails are being displayed like so (top-right - It says 1-50 of 277):
Does anyone have ideas regarding these questions?
UPDATE - Question 1
Looks like there is no way to store user entered data in a JSON file, so I am using localStorage to save it on the client-side.
UPDATE - Question 3
Here is a solution for question 3. I bound $scope.conversation property to conversation in the view. The value of $scope.conversation is set to the number selected by the user. This number is saved in localStorage.
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Gmail App</title>
<style>
body {
margin: 10px;
padding: 50px;
}
</style>
<link rel="stylesheet" href="Content/css/bootstrap.min.css">
<link rel="stylesheet" href="Content/css/bootstrap-theme.min.css">
<script src="Vendor/jquery-1.11.3.min.js"></script>
<script src="Vendor/bootstrap.min.js"></script>
<script src="Vendor/angular.min.js"></script>
<script src="Vendor/angular-ui-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.4/angular-route.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ngStorage/0.3.6/ngStorage.min.js"></script>
</head>
<body data-ng-app="iisEmail">
<div class="container" data-ng-controller="mainController">
<div class="row">
<div class="col-sm-3 col-md-2">
<div class="btn-group">
<button type="button" class="btn dropdown-toggle" data-toggle="dropdown">
Email <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Mail</li>
<li>Contacts</li>
<li data-ng-click="loadView('settings')">Settings</li>
</ul>
</div>
</div>
<div class="col-sm-9 col-md-10">
<!-- split button -->
<div class="btn-group">
<button type="button" class="btn btn-default">
<div class="checkbox" style="margin: 0;">
<label>
<input type="checkbox"
data-ng-click="selectAllEmail()"
data-ng-model="checkAllEmail">
</label>
</div>
</button>
</div>
<button type="button" class="btn btn-default" data-toggle="tooltip" title="Refresh">
   <span class="glyphicon glyphicon-refresh"></span>   
</button>
<!-- Single button -->
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
More <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Mark all as read</li>
<li class="divider"></li>
<li class="text-center"><small class="text-muted">Select messages to see more actions</small></li>
</ul>
</div>
<div class="pull-right" data-ng-controller = "settingsController">
<span class="text-muted"><b>1</b>–<b data-ng-bind = "conversation" data-ng-cloak>{{conversation}}</b> of <b>277</b></span>
<div class="btn-group btn-group-sm">
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon-chevron-left"></span>
</button>
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon-chevron-right"></span>
</button>
</div>
</div>
</div>
</div>
<hr/>
<div class="row">
<div class="col-sm-3 col-md-2">
COMPOSE
<hr/>
<ul class="nav nav-pills nav-stacked">
<li class="" data-ng-repeat="item in leftMenu">
<span class="badge pull-right"> {{item.emailCount}}</span> {{item.name}}
</li>
<!--<li>Starred</li>
<li>Important</li>
<li>Sent Mail</li>
<li>-->
</ul>
</div>
<div class="col-sm-9 col-md-10">
<!-- Nav tabs -->
<ul class="nav nav-tabs">
<li class="active"><a href="#home" data-toggle="tab"><span class="glyphicon glyphicon-inbox">
</span>Primary</a></li>
<li><a href="#profile" data-toggle="tab"><span class="glyphicon glyphicon-user"></span>
Social</a></li>
<li><a href="#messages" data-toggle="tab"><span class="glyphicon glyphicon-tags"></span>
Promotions</a></li>
<li><a href="#settings" data-toggle="tab"><span class="glyphicon glyphicon-plus no-margin">
</span></a></li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div ui-view></div>
</div>
</div>
</div>
</div>
<script src="app/main.js"></script>
<!--Services-->
<script src="app/services/commonApiService.js"></script>
<script src="app/services/savePreferenceService.js"></script>
<script src="app/services/fetchDataService.js"></script>
<script src="app/controllers/mainController.js"></script>
<script src="app/controllers/settingsController.js"></script>
<script src="app/controllers/emailViewController.js"></script>
</body>
</html>
savePreferenceService.js
(function() {
'use strict';
var savePreferenceService = function ($localStorage) {
this.setPreferences = function (selectedLang, converse, selectedNumber, selectedNumberContact, reply, signature) {
$localStorage.selectedLang = selectedLang;
$localStorage.converse = converse;
$localStorage.selectedNumber = selectedNumber;
$localStorage.selectedNumberContact = selectedNumberContact;
$localStorage.reply = reply;
$localStorage.signature = signature;
};
};
angular.module('iisEmail')
.service ('savePreferenceService', ['$localStorage', savePreferenceService]);
}());
settingsController.js
(function() {
'use strict';
var settingController = function (fetchDataService, $scope, savePreferenceService, $localStorage) {
$scope.url = 'app/mock/settings.json';
$scope.save = {};
fetchDataService.getContent($scope.url)
.then(function(response){
$scope.contacts = response.data.contacts;
$scope.languages = response.data.languages;
$scope.conversations = response.data.conversations;
$scope.undoSend = response.data.undoSend;
$scope.save = response.data.userPreferences;
});
$scope.setPreference = function () {
savePreferenceService.setPreferences($scope.save.selectedLang, $scope.save.converse, $scope.save.selectedNumber, $scope.save.selectedNumberContact, $scope.save.reply, $scope.save.signature);
};
$scope.conversation = $localStorage.selectedNumber;
};
angular.module('iisEmail')
.controller ('settingsController',
['fetchDataService', '$scope', 'savePreferenceService', '$localStorage', settingController]);
}());

Related

open bootstrap modal when condition is true

User needs to input Bitcoin address
after bitcoin address is valid modal should open
if bitcoin adress is invalid modal should stay closed
enter image description here
enter image description here
enter image description here
And here is the code
(Bicoin validation works, i only need help with the modal)
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>BItmixxer</title>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<style media="screen">
hr.style1{
border-top: 1px solid #8c8b8b;
}
</style>
</head>
<body>
<nav class="navbar navbar-expand-md bg-dark navbar-dark">
<!-- Brand -->
<a class="navbar-brand" href="#">Navbar</a>
<!-- Toggler/collapsibe Button -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
<span class="navbar-toggler-icon"></span>
</button>
<!-- Navbar links -->
<div class="collapse navbar-collapse" id="collapsibleNavbar">
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
</ul>
</div>
</nav>
<div class="jumbotron jumbotron-fluid" style="text-align:center" >
<div class="container">
<h1>Crypto Mixxer</h1>
<p>some more Text about crypto mixxer</p>
</div>
</div>
<div class="container" style="text-align:center" >
<h1>BTC Mixxer</h1>
<p>Choose COins to mix:</p> <button type="button" class="btn btn-outline-primary">Bitcoin</button>
<button type="button" class="btn btn-outline-success">Ethereum</button>
<br>
<br>
<br>
<div class="form-group" id="elMessage" class="msg">
<input type="text" class="form-control" id="inpAddress" value="">
</div>
<button type="button" class="btn btn-primary" id="btnValidate" data-toggle="modal" data-target="#myModal">Next</button>
<script>
var normalize = (s) => {
let x = String(s) || '';
return x.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
};
var check = (s) => {
if (s.length < 26 || s.length > 35) {
return false;
}
let re = /^[A-Z0-9]+$/i;
if (!re.test(s)) {
return false;
}
return true;
};
var getEl = (id) => {
return document.getElementById(id) || null;
};
var elMessage = getEl('elMessage');
var inpAddress = getEl('inpAddress');
var btnValidate = getEl('btnValidate');
var lnkClear = getEl('lnkClear');
var setMessage = (txt = '', clss = 'msg') => {
elMessage.className = clss;
elMessage.innerHTML = txt;
};
var validate = (s) => {
let className = 'msg fail';
let textMessage = 'Invalid bitcoin address';
if (!s) {
textMessage = 'Please enter a valid address';
}
let re = check(s);
if (re) {
className = 'msg pass';
textMessage = 'Bitcoin address is valid';
}
setMessage(textMessage, className);
return re;
};
btnValidate.onclick = () => {
let v = normalize(inpAddress.value);
let result = validate(v);
if (result) {
inpAddress.value = v;
}
};
lnkClear.onclick = () => {
inpAddress.value = '';
inpAddress.focus();
setMessage('Enter any text and press "Validate"');
};
</script>
</div>
<!-- The Modal -->
<div class="modal" id="myModal">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Modal Heading</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<h3>Please send your BTC(min0.5) to</h3>
<p id ="btc-house" style="color:blue;"></p>
<script>
var myArray = ['1QFsuDg4HyCJZFBfC2ivxHCK2CX2i9YvWN', ' 1EhfSjMuyAyrpRRGf5sSCU3YDbVAqjJNxH', '1N2e39vyTrk6HtvZPqWPrHfHKBzsnQNN4V','1GVSGZxwU69fN5oPprSxXRnjsZPvo8bGw3'];
var rand = myArray[Math.floor(Math.random() * myArray.length)];
document.getElementById("btc-house").innerHTML = rand;
</script>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</body>
</html>
I know i need to use
$('#myModal').modal('show');
$('#myModal').modal('hide');
i just dont know where to put it
First remove the data-toggle="modal" target="#myModal" from #btnValidate
<button type="button" class="btn btn-primary" id="btnValidate">Next</button>
Then change your if statment inside your validate function to:
if (re) {
className = 'msg pass';
textMessage = 'Bitcoin address is valid';
$('#myModal').modal('show')
}
Note that you import jquery twice, which can lead to bugs. Remove one import and make sure jquery is imported before bootsrap.js

No Console Log Output When Clicking Plus Icon in Unordered List

I have an ul (unordered list) which contains several li (list items) when I click on the + sign left to li, console log should output "description expanded" For the two first li, it works just fine, but not for any other li's. The html code by default includes only 2 li's. any li after that is added through the form. However, any new li does not produce the console log output. Which means they're not responding to clicks. I'm using jQuery to listen for click events. When clicking on the icon.
project link http://pctechtips.org/apps/todo/
//variables
//todoList array to hold (title, description) for every todo tiem
var todoList = []; //{title: "value", desc: "value"},
var numId = 2; //num is for desc paragraph id eg <p id="plus-3">
/*
* Script main body
*/
$(document).ready(function() {
//hide form when doc loads first time
$("#submit-form").hide();
//hide list item description <p>
$(".item-desc").hide();
//listener for show hide form functionality
$("#add-todo").click(function() {
toggleForm();
return false; //return false to prevent page reload
});
//listener for add new item form (submit button)
$(".btn").click(function() {
console.log("submit item");
addToList();
});
//listener for expanding li description
$(".plus").click(function() {
console.log("description expanded")
var plusId = $(this).attr("id"); //grabbing id of plus sign
showDescription(plusId);
return false;
});
});
//functionality for show / hide form
function toggleForm() {
if($("#submit-form").is(":hidden")) {
console.log("form exapnded");
$("#submit-form").show("slow");
$("#form-icon").removeClass("fa-plus-square-o");
$("#form-icon").addClass("fa-minus-square-o");
}
else {
console.log("form hidden");
$("#submit-form").hide("slow");
$("#form-icon").removeClass("fa-minus-square-o");
$("#form-icon").addClass("fa-plus-square-o");
}
}
//add new item to todo list items
function addToList() {
numId++;
//getting data from input fields
var todoTitle = $("#todo-title").val();
var todoDesc = $("#todo-desc").val();
//checking user input
if(todoTitle == "" || todoDesc == "") {
alert("fill in all fields!");
}
else {
console.log(todoTitle + "\n" + todoDesc);
//adding values to array
todoList.push({title: todoTitle, desc: todoDesc},);
//adding new li to ul
var ul = document.getElementById("list");
var li = document.createElement("li");
$(li).addClass("list-group-item justify-content-between align-items-center");
$(li).append(($('<i id="plus-'+numId+'" class="plus fa fa-plus-square-o left" aria-hidden="true"></i>')));
$(li).append(($('<span class="left marg-left">'+todoTitle+'</span>')));
$(li).append(($('<i class="fa fa-trash-o right" aria-hidden="true"></i>')));
$(li).append(($('<i class="fa fa-pencil right marg-right pr-2" aria-hidden="true"></i>')));
ul.appendChild(li);
}
}
//expanding description under for each todo
function showDescription(plusId) {
//getting the number from id
var num = plusId.substring(plusId.indexOf("-")+1);
//checking for hide / show description paragraph
if($("#desc-"+num).is(":hidden")) {
$("#desc-"+num).show("slow");
$("#desc-"+num).removeClass("fa-plus-square-o");
$("#desc-"+num).addClass("fa-minus-square-o");
}
else {
$("#desc-"+num).hide("slow");
$("#desc-"+num).removeClass("fa-minus-square-o");
$("#desc-"+num).addClass("fa-plus-square-o");
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<title>TodoList App</title>
<!-- bootstrap, fontawsome cdn -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- local stylesheet -->
<link rel="stylesheet" type="text/css" href="css/style.css">
<!-- jquery cdn -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<!-- local javascript -->
<script type="text/javascript" src="js/todo.js"></script>
</head>
<body>
<!-- navbar -->
<nav class="navbar navbar-expand-lg navbar-drak bg-dark mb-4">
<a class="navbar-brand" href="#"><i class="fa fa-thumb-tack" aria-hidden="true"></i> Todo<strong>List</strong></a>
</nav>
<!-- /navbar -->
<!-- todoList -->
<div class="container">
<div class="add-item text-white text-center col-sm-12 col-md-10 col-lg-8 mb-4">
<a id="add-todo" class="new-todo text-white text-center" href=""><i id="form-icon" class="fa fa-plus-square-o" aria-hidden="true"></i> Enter new todo item</a>
<div id="submit-form" class="form-hide text-center col-sm-12 col-md-12 col-lg-8">
<form class="">
<div class="form-group">
<input type="text" class="form-control" id="todo-title" placeholder="Todo Title" value="Pay Car Insurance">
</div>
<div class="form-group">
<input type="text" class="form-control" id="todo-desc" placeholder="Todo Description" value="This is to pay car insurance">
</div>
<button type="button" class="btn btn-primary btn-lg col-12">Submit Todo</button>
</form>
</div>
<!-- horizontal line -->
<hr>
<!-- list items -->
<h1 class="heading-4">Todo List Items</h1>
<ul id="list" class="list-group mt-4 pb-4">
<li class="list-group-item justify-content-between align-items-center">
<i id="plus-1" class="plus fa fa-plus-square-o left" aria-hidden="true"></i>
<span class="left marg-left">Pay Car Insurance </span>
<i class="fa fa-trash-o right" aria-hidden="true"></i>
<i class="fa fa-pencil right marg-right pr-2" aria-hidden="true"></i>
</li>
<p id="desc-1" class="item-desc bg-white">Helloooooooooo this is description</p>
<li class="list-group-item justify-content-between align-items-center">
<i id="plus-2" class="plus fa fa-plus-square-o left" aria-hidden="true"></i>
<span class="left marg-left">Pay Car Insurance </span><i class="fa fa-trash-o right" aria-hidden="true"></i>
<i class="fa fa-pencil right marg-right pr-2" aria-hidden="true"></i>
</li>
<p id="desc-2" class="item-desc bg-white">Helloooooooooo this is description</p>
</ul>
</div>
</div>
</body>
</html>
ok for dynamically added elements the even listener needs to be defined at the root / document level. so
$("class").on("click", function() { });
will not work. It needs to be
$(document).on("click", ".class", function() { });
Thanks to "MADDY BLACKLISTED" above pointed me in right directions
Use
$(document).on("click", ".plus", function() {
console.log("description expanded")
var plusId = $(this).attr("id"); //grabbing id of plus sign
showDescription(plusId);
return false;
});
Instead of having a static click listener defined at document load.

Pass a value to another controller which executes first

I have two controllers headerController, aboutController.
headerController -> To maintain the navigation and redirection
aboutController -> works when about-us page loads.
My issue is I have to update the headerController variable value when aboutController loads. i.e When about us page loads, the navigation about-us should active, similar to all the pages.
This is my code:
app.service('shareService', function () {
var data;
return {
getProperty: function () {
return data;
},
setProperty: function (value) {
data = value;
}
};
});
app.controller('headerController', function ($scope, shareService) {
$scope.navigation = [
{url: '#!/home', name: 'Home'},
{url: '#!/about-us', name: 'About Us'},
{url: '#!/services', name: 'Services'}
];
var data = shareService.getProperty();
console.log(data);
$scope.selectedIndex = 0;
$scope.itemClicked = function ($index) {
console.log($index);
$scope.selectedIndex = $index;
};
});
app.controller('aboutController', function ($scope, shareService) {
console.log('test');
$scope.selectedIndex = 1;
shareService.setProperty({navigation: $scope.selectedIndex});
});
header.html:
<header ng-controller="headerController">
<div class="header">
<div class="first-half col-md-6">
<div class="row">
<div class="logo">
<img src="assets/img/logo.png" alt=""/>
</div>
</div>
</div>
<div class="second-half col-md-6">
<div class="row">
<div class="social-share">
<ul id="social-share-header">
<li><i class="fa fa-facebook" aria-hidden="true"></i></li>
<li><i class="fa fa-twitter" aria-hidden="true"></i></li>
<li><i class="fa fa-google-plus" aria-hidden="true"></i></li>
</ul>
</div>
</div>
</div>
<nav>
<ul ng-repeat="nav in navigation">
<li class="main-nav" ng-class="{ 'active': $index == selectedIndex }"
ng-click="itemClicked($index)">
{{nav.name}}
</li>
</ul>
</nav>
</div>
</header>
index.html
This is how my template works.
<body ng-app="myApp">
<section class="first-section">
<div ng-include="'views/header.html'"></div>
</section>
<section class="second-section">
<div ng-view></div>
</section>
<section class="last-section">
<div ng-include="'views/footer.html'"></div>
</section>
</body>
Update 1: Added index.html file.
Update 2: Issue explanation: If I run directly to the about us page, then still the home navigation is on active. But it should be About us
What is you are looking for is event based communication between your controllers. This can be easily done using. $rootScope.$on, $rootScope.$emit and $rootScope.$broadcast. Since explaining all three of them in this answer will be overkill. Kindly go through this article

Angular: ngView and functions not working right away?

On my website, if you scroll down to the third section that says "Victorious Gaming" and hover over the arrows on the left and right, no text shows up. However, the second time and thereafter you hover over the arrows, the text correctly shows up. Why do they not work the very first time? The same applies to when you hover over the text "Victorious Gaming"
In my Controller, I have:
projectApp.controller("featuredController", ["$rootScope", "$scope", function ($rootScope, $scope) {
$scope.leftArrow = function(){
$(function(){
$(".left-arrow a").hover(function(){
$('.left-info').css('opacity','1');
}, function(){
$('.left-info').css('opacity','0');
});
});
};
$scope.rightArrow = function(){
$(function(){
$(".right-arrow a").hover(function(){
$('.right-info').css('opacity','1');
}, function(){
$('.right-info').css('opacity','0');
});
});
};
$scope.bigWords = function(){
$(function(){
$(".big-word-padding").hover(
function() {
$('.blur-background').fadeOut(700);
$('.big-word-padding').find('h2').css('color','blue');
$('.color-blue').css('color','white');
}, function() {
$('.blur-background').fadeIn(300);
$('.big-word-padding').find('h2').css('color','white');
$('.color-blue').css('color','blue');
});
$(".big-word-padding").hover(
function() {
$('.blur-background').fadeOut(700);
$('.big-word-padding').find('.m-title').css('color','white');
$('.big-word-padding').find('#manga-title').addClass('textShadowM');
$('.big-word-padding').find('.m-title').addClass('textShadowManga');
$('.color-blue').css('color','white');
}, function() {
$('.blur-background').fadeIn(300);
$('.big-word-padding').find('.m-title').css('color','rgb(26, 107, 156)');
$('.big-word-padding').find('#manga-title').removeClass('textShadowM');
$('.big-word-padding').find('.m-title').removeClass('textShadowManga');
$('.color-blue').css('color','blue');
});
});
};
}]);
My HTML:
<div class="ng-container" ng-controller="featuredController">
<div ng-view class="view-animate">
</div>
</div>
External HTML file(templates/featured-proj.html):
<div class="big-feature">
<div class="big-background second-background"></div>
<div class="blur-background second-background"></div>
<div class="big-word">
<div class="big-word-padding" ng-mouseover="bigWords()">
<h2> Victorious <span class="color-blue">Gaming</span></h2>
<h3>UI Developer. Design.</h3>
<hr>
<i class="fa fa-caret-right fa-3x" aria-hidden="true" id="arrow-project"></i>
</div>
</div>
<div class="left-arrow">
<i class="fa fa-angle-left" aria-hidden="true"></i>
</div>
<div class="left-info">
My Art
</div>
<div class="right-arrow">
<i class="fa fa-angle-right" aria-hidden="true"></i>
</div>
<div class="right-info">
Mangahere
</div>
<!-- <ul class="nav navbar-nav navbar-right">
<li><i class="fa fa-shield"></i> Home</li>
<li><i class="fa fa-shield"></i> About</li>
<li><i class="fa fa-comment"></i> Contact</li>
</ul> -->
<div class="info-vic">
<div class="row-vic">
<div class="left-vic"></div>
<div class="right-vic"></div>
</div>
<div class="row-vic">
<div class="left-vic"></div>
<div class="right-vic"></div>
</div>
<div class="row-vic">
<div class="left-vic"></div>
<div class="right-vic"></div>
</div>
</div>
</div>
And my config for routing:
projectApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/feature', {
templateUrl : 'templates/featured-proj.html'
})
// route for the about page
.when('/feature2', {
templateUrl : 'templates/featured-proj-2.html'
})
// route for the contact page
.when('/feature3', {
templateUrl : 'templates/featured-proj-3.html'
})
.otherwise( { redirectTo: '/feature' } );
}]);
First, you have an extra $(function(){ ... }) wrapper both in leftArrow() and rightArrow().
In addition, the hover effect gets set only when when those functions are called for the first time. During that call, the opacity will not be modified.
I would replace ng-mouseover="leftArrow()" with ng-mouseenter="leftArrowShow()" ng-mouseleave="leftArrowHide()" and then define these functions like:
$scope.leftArrowShow = function() {
$('.left-info').addClass('show');
};
$scope.leftArrowHide = function() {
$('.left-info').removeClass('show');
};
And then, in CSS, have:
.left-info.show {
opacity: 1;
}
rightArrow() would be handled in a similar manner.

Why is this template now showing up?

I have a problem with showing a template on my Meteor.js app. It's website_list. For some reason it doesn't show, maybe you can help me out?
I'm trying to show the website list from the websites MongoDB collection.
HTML Code:
<!-- master layout template -->
<template name="ApplicationLayout">
{{> yield "navbar"}}
{{> yield "main"}}
</template>
<!-- / master layout template -->
<!-- WELCOME -->
<template name="welcome">
<div class="container">
<div class="jumbotron">
<h1>Welcome to Site Ace, {{username}}!</h1>
Enter
</div>
</div>
</template>
<!-- / WELCOME-->
<!-- NAVBAR - you will be putting the login functions here -->
<template name="navbar">
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand" href="/">
Site Ace
</a>
</div>
<ul class="nav navbar-nav login">
<li>
{{> loginButtons}}
</li>
</ul>
</div>
</nav>
</template>
<template name="websites">
<div class="container">
{{> website_form}}
{{> website_list}}
</div>
</template>
<!-- / NAVBAR -->
<!-- WEBSITE FORM -->
<template name="website_form">
{{#if currentUser}}
<a class="btn btn-default js-toggle-website-form" href="#">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> Add a Website
</a>
{{/if}}
<div id="website_form" class="hidden_div">
<form class="js-save-website-form">
<div class="form-group">
<label for="url">Site address</label>
<input type="text" class="form-control" id="url" placeholder="http://blablabla.org">
</div>
<div class="form-group">
<label for="title">Title</label>
<input type="text" class="form-control" id="title" placeholder="Mysite">
</div>
<div class="form-group">
<label for="description">Description</label>
<input type="text" class="form-control" id="description" placeholder="I found this site really useful for ...">
</div>
<button type="submit" class="btn btn-default js-">Submit</button>
</form>
</div>
</template>
<!-- / WEBSITE FORM -->
<!-- WEBSITE LIST -->
<template name="website_list">
<ol>
{{#each websites}}
{{>website_item}}
{{/each}}
</ol>
</template>
<!-- / WEBSITE LIST -->
<!-- WEBSITE ITEM -->
<template name="website_item">
<li>
{{title}}
<p>
{{description}}
</p>
<p>
<a href="/details/{{_id}}" class="btn btn-info">
Details
</a>
<a href="#" class="btn btn-success js-upvote">
<span class="glyphicon glyphicon-arrow-up" aria-hidden="true"></span>
</a>
<a href="#" class="btn btn-danger js-downvote">
<span class="glyphicon glyphicon-arrow-down" aria-hidden="true"></span>
</a>
</p>
<!-- you will be putting your up and down vote buttons in here! -->
</li>
</template>
<!-- / WEBSITE ITEM -->
JS Code:
// SECURITY
Websites = new Mongo.Collection("websites");
// set up security on Websites collection
Websites.allow({
// we need to be able to update websites for ratings.
update:function(userId, doc){
console.log("Testing security on website update");
if (Meteor.user()){// they are logged in
return true;
} else {// user not logged in - do not let them update (rate) the website
return false;
}
},
insert:function(userId, doc){
console.log("Testing security on website insert");
if (Meteor.user()){ // they are logged in
if (userId != doc.createdBy){ // the user is messing around
return false;
}
else{ // the user is logged in, the website has the correct user id
return true;
}
}
else{ // user not logged in
return false;
}
},
remove:function(userId, doc){
return true;
}
})
// / SECURITY
if (Meteor.isClient) {
/////
// ROUTERS
/////
// GLOBAL LAYOUT
Router.configure({
layoutTemplate: 'ApplicationLayout'
});
// ROUTES
Router.route('/', function() {
this.render('welcome', { // welcome is the template to render
to:"main" // main is the template to render welcome INTO
});
});
Router.route('/websites', function() {
this.render('navbar', {
to:"navbar"
});
this.render('websites', {
to:"main"
});
});
Router.route('/websites/:_id', function () {
this.render('navbar', {
to:"navbar"
});
this.render('image', {
to:"main",
data:function(){
return Websites.findOne({_id:this.params._id});
}
});
});
/////
// STARTUP (Creating Websites)
/////
if (Meteor.isServer) {
// start up function that creates entries in the Websites databases.
Meteor.startup(function () {
// code to run on server at startup
if (!Websites.findOne()){
console.log("No websites yet. Creating starter data.");
Websites.insert({
title:"Goldsmiths Computing Department",
url:"http://www.gold.ac.uk/computing/",
description:"This is where this course was developed.",
createdOn:new Date()
});
Websites.insert({
title:"University of London",
url:"http://www.londoninternational.ac.uk/courses/undergraduate/goldsmiths/bsc-creative-computing-bsc-diploma-work-entry-route",
description:"University of London International Programme.",
createdOn:new Date()
});
Websites.insert({
title:"Coursera",
url:"http://www.coursera.org",
description:"Universal access to the world’s best education.",
createdOn:new Date()
});
Websites.insert({
title:"Google",
url:"http://www.google.com",
description:"Popular search engine.",
createdOn:new Date()
});
}
});
}
You forgot to implement a helper function for your website_list template, which returns documents of your Websites collection.
For example:
Template.website_list.helpers({
websites: function() {
return Websites.find();
}
});
Here's a MeteorPad.

Categories