Loop thru 100 background-images onClick - loops

a) I have 100 body-background images
b) and a single link
The background image should change to the next one in the lot every time the link is clicked, going thru the lot one by one (would be nice if the name/number of current image also is displayed).
The images are all in a dedicated directory. jQuery is already loaded.
Anyone know where I can find the code to do this simply?
All the best...

var allImages = ["path/to/image2", "path/to/image1"];
$(document).ready(function() {
$("#theLink").click(function() {
var newImageLink = allImages.pop();
$("body").css("background-image", "url(" + newImageLink + ")");
});
});

You don't necessarily need to hard code the path to your images that way. You can name your images something like image_xxx.png, 1 - 100 and refer to that name in one place. That way if you ever need to change the name, you can easily do it in one place. Furthermore, make sure that the href attribute of the anchor tag is set to # to prevent page reloads on each click.
Here's a more complete solution that also does range checking and it wraps around when we reach our limit:
<script language="javascript" type="text/javascript">
<!--
var ctr = 0;
$(document).ready( function () {
nextBg();
});
function nextBg()
{
++ctr;
if( ctr <= 100 )
{
$("body").css( "background-image", "url(images/image_" + ctr + ".png)" );
$("#message").text("Current image: " + "image_" + ctr + ".png");
if( ctr == 100 )
ctr = 0;
}
}
//-->
</script>
</head>
<body>
<div>
<span id="message"></span><br />
<a href="#" onclick="nextBg();" />Next</a>
</div>
</body>

(added counter to gs' answer)
var allImages = ["path/to/image2", "path/to/image1"];
var counter = 0;
$(document).ready(function() {
$("#theLink").click(function() {
var newImageLink = allImages.pop();
$("body").css("background-image", "url(" + newImageLink + ")");
$("#displayhere").html("<b>"+ counter +"</b>");
counter = counter + 1;
});
});

Related

rendering html from a controller in angular

Hopefully someone can point my in the right direction.
I am building a web app and part of it requires a user to click a button as fast as they can to obtain a score. The design dictates that I will need to show this score in double digits i.e 9 would be 09 so for styling I need to wrap span tags around each digit.
I have got everything working as required, I'm just having an issue with outputting the score that is wrapped in span tags as rendered html in my view.
I've put together a fiddle for the section that is causing me problems. Any advice, help, best practices etc is much appreciated.
What I've tried:
I've included a few of the things I've tried. Basically they involve using $sce and trying to ng-bind-html in the view. Attempt 3 seems the most logical to me but the $scope.count isn't being updated. I'm guessing I need to add a $watch or $apply function to keep it binded? but I'm not too sure how to implement it or even if this is good practice. Also, because I'm outputting html is it better practice to do this in a directive?
Fiddle http://jsfiddle.net/funkycamel/gvxpnvqp/4/
HTML
<section ng-app="myApp">
<div ng-controller="MyController">
<button ng-click="add(1)">add</button>
<!-- First attempt -->
<p class="first-attempt">{{ pad(count) }}</p>
<!-- Second attempt -->
<!-- in order for this attempt to work I have to call the pad2 function which
returns trustedHtml -->
{{ pad2(count) }}
<p class="second-attempt" ng-bind-html="trustedHtml"></p>
<!-- Third attempt -->
<p class="third-attempt" ng-bind-html="moreTrustedHtml"></p>
</div>
Javascript
var app = angular.module('myApp', []);
app.controller('MyController', ['$scope', '$sce', function ($scope, $sce) {
// Set initial count to 0
$scope.count = 0;
// function to add to $scope.count
$scope.add = function (amount) {
$scope.count += amount;
};
// Attempt 1
// make sure number displays as a double digit if
// under 10. convert to string to add span tags
$scope.pad = function (number) {
var input = (number < 10 ? '0' : '') + number;
var n = input.toString();
var j = n.split('');
var newText = '';
var trustedHtml = '';
for (var i = 0; i < n.length; i++) {
newText += '<span>' + n[i] + '</span>';
}
return newText;
};
// Attempt 2 - trying to sanitise output
// same as above just returning trusted html
$scope.pad2 = function (number) {
var input = (number < 10 ? '0' : '') + number;
var n = input.toString();
var j = n.split('');
var newText = '';
var trustedHtml = '';
for (var i = 0; i < n.length; i++) {
newText += '<span>' + n[i] + '</span>';
}
// return sanitised text, hopefully
$scope.trustedHtml = $sce.trustAsHtml(newText);
return $scope.trustedHtml;
};
// Attempt 3
// Trying to sanitise the count variable
$scope.moreTrustedHtml = $sce.trustAsHtml($scope.pad($scope.count));
}]);
These currently output
<span>0</span><span>0</span>
<span>0</span><span>0</span>
00
00
Again any advice/help is greatly appreciated.
Far simpler solution:
HTML
<p>{{ count < 10 ? '0' + count : count}}</p>
Controller:
app.controller('MyController', ['$scope', function ($scope) {
$scope.count = 0;
$scope.add = function (amount) {
$scope.count += amount;
};
}]);
DEMO
If you prefer you can do the padding in the controller instead, just use another variable
app.controller('MyController', ['$scope', function ($scope) {
var count = 0;
$scope.countText = '0';
$scope.add = function (amount) {
count += amount;
$scope.countText = count < 10 ? '0' + count : count;
};
}]);

angularJS $scope not being applied

Im pretty new to angularJS so please forgive me if I say anything completely wrong. I making some sort of a chat. I have a problem with the scope/view not beign updated after getting the data. I have a variable $scope.users which is an array containing infos about users and the view does an ng-repeat on the users to display their infos.
The data is stored from a previous page and loaded through session storage.
The controller looks like:
app.controller('table-controller',['$scope','$interval','HttpService','TableModel',
function($scope,$interval,HttpService,TableModel){
var _this = this;
console.log('loading table controller ...');
$scope.users = [];
var sessionData = JSON.parse(sessionStorage.getItem('sessionData'));
var activeUsers = sessionData.activeUsers;
//$scope.users = TableModel.initUsers();
$scope.$watch('users',function(){
for(var i = 0; i < 10; i++){
$scope.users.push({
user : ' ',
name : 'Vacant',
picture : '../img/sit_default.png',
speak_turn : ' ',
sit : i,
last_request : 0
});
}
for(var i = 0; i < activeUsers.length; i++){
var sit = activeUsers[i].sit;
$scope.users[sit] = activeUsers[i];
}
});
$scope.className = function(index){
return "sit" + (index + 1);
}
And the html is :
<ul class="first-place">
<li ng-repeat="user in users track by $index" ng-class="className($index)">
<div class="pro_pic_wrap">
<img ng-src="{{user.picture}}" alt="">
<span>{{$index + 1}}</span>
</div>
{{user.name}}
</li>
</ul>
Everything works fine if I use $watch to create $scope.users. Otherwise when the page loads the view sees an empty $scope.users so ng-repeat does nothing. If i reload the page everything works fine. I tried $scope.$apply() but gives me an error saying digest is already being called. I dont understand why I need to use $watch here.
Thanks in advance for your help!
you can create a method and call it instead of using $watch
$scope.getUsers= function(){
for(var i = 0; i < 10; i++){
$scope.users.push({
user : ' ',
name : 'Vacant',
picture : '../img/sit_default.png',
speak_turn : ' ',
sit : i,
last_request : 0
});
}
for(var x = 0; x < users.length; x++){
var sit = activeUsers[x].sit;
$scope.users[sit] = activeUsers[x];
}
}
$scope.getUsers();

d3 change text bound to data

Conncerning the code below I have three questions,
which seem to be related to each other:
(1) I try to change the text of a single div, which was previously
bound as part of an array
-> if the way I do it below (changing textContent directly),
how can I get access to the data-array instead (is there an index available
to adress the correct element of the data-array directly)?
(2) what happens if I bind an array of divs and then unbind single divs?
will all divs be unbound afterwards ? or does it result in a mix
of bound or unbound elements: is data[1] still bound, bout data[3]
not?
(3) why do the data not update if I change them (they do not update at all,
neither if I assign something to textContent, nor if I do not:
you can check this, if you click on another number but the 8: also in that case
the array does not update)!
If the questions sound somehow unconnected please
try the code first (click the numbers with the mouse, especially the "-8-"),
this should clarify what I mean a bit!
<!DOCTYPE html>
<html>
<head>
<script src="d3.js"></script>
<style>
div.bar:hover {
border: 1px solid yellow;
}
div.bar {
width: 50px;
}
</style>
</head>
<body>
<div class="labeledDiv">
</div>
<script>
var data = [4,8,16,23,9];
function mousedown() {
var txt = d3.select(this).node().textContent;
alert("text of this node is: " + txt);
if (txt == "-8-") {
d3.select(this).node().textContent = "hit!!!";
}
var id = d3.select(this).node().id;
alert("id IS NOT:" + id);
var x = "";
for (i = 0;i<5;i++) {
data[i] = data[i]+1;
x = x + i + ": " + data[i] + " " ;
}
alert("x: " + x);
}
d3.select(".labeledDiv")
.selectAll("div")
.data(data)
.enter().append("div")
.attr("class","bar")
.text(function(d) { return "-" + d + "-";});
d3.select(".labeledDiv")
.selectAll("div")
.on("mousedown",mousedown);
</script>
</html>
(1) node has no property id (unless I set it manually)
(2) changing data-array needs an update function to be called:
function update() {
d3.select(".labeledDiv")
.selectAll("div")
.text(function(d,i) { return "text: " + d + " " + data[i]; });
};
function mousedown() {
//... same as above
// and then after changing data:
update();
}

AngularJS NG-CSV files not downloading

I am fairly new to AngularJS, i am trying to generate .csv files from an Array using ng-csv.
Now i have tried everything but the files are not generated, i even tried the most simple example i could see on the internet.
I do not see any errors in the error console but still no files are generated.
I am working under windows with XAMPP.
<!DOCTYPE html>
<html ng-app="APP">
<head>
<meta charset="UTF-8">
<title>angular-count-to example</title>
<style type="text/css">
.element{cursor:pointer;float:left;background-color:#ccc;padding:4px;}
</style>
</head>
<body ng-controller="ExampleController">
<p>{{data}}</p>
<button type="button" ng-csv="data" filename="test.csv">Export</button>
<script type="text/javascript" src="bower_components/angular/angular.min.js"></script>
<script type="text/javascript" src="bower_components/angular-sanitize/angular-sanitize.min.js"></script>
<script type="text/javascript" src="bower_components/ng-csv/src/ng-csv/ng-csv.js"></script>
<script>
angular.module('APP',["ngSanitize","ngCsv"]).
controller('ExampleController', function ($scope) {
$scope.filename = "test";
$scope.data = [{a: 1, b:2}, {a:3, b:4}];
});
</script>
</body>
</html>
Above is the simplest example i tried, however even this is not working.
Try out a pure HTML5 Solution. This was a code block i did a while ago. Try customizing for yourself by excluding useless paramaters
function (JSONData, ReportTitle, ShowLabel, reportType, reportName) {
//If JSONData is not an object then JSON.parse will parse the JSON string in an Object
var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
angular.forEach(arrData, function (data, index) {
if (data.date != undefined)
data.date = dateFormat(data.date)
});
var CSV = '';
//Set Report title in first row or line
CSV += ReportTitle + '\r\n\n';
//This condition will generate the Label/Header
if (ShowLabel) {
var row = "";
//This loop will extract the label from 1st index of on array
for (var index in arrData[0]) {
row += index + ';';
}
row = row.slice(0, -1);
//append Label row with line break
CSV += row + '\r\n';
}
//1st loop is to extract each row
for (var i = 0; i < arrData.length; i++) {
var row = "";
//2nd loop will extract each column and convert it in string comma-seprated
for (var index in arrData[i]) {
//var temp = arrData[i][index].toString().replace('.', ',');
//arrData[i][index] = temp;
row += '"' + arrData[i][index] + '";';
}
row = row.split('.').join(",");
row.slice(0, row.length - 1);
//add a line break after each row
CSV += row + '\r\n';
}
if (CSV == '') {
alert("Invalid data");
return;
}
//Generate a file name
var fileName = "MyReport_";
//this will remove the blank-spaces from the title and replace it with an underscore
fileName += ReportTitle.replace(/ /g, "_");
//Initialize file format you want csv or xls
var uri = 'data:text/csv;charset=utf-8,' + escape(CSV);
// Now the little tricky part.
// you can use either>> window.open(uri);
// but this will not work in some browsers
// or you will not get the correct file extension
//this trick will generate a temp <a /> tag
var link = document.createElement("a");
link.href = uri;
//set the visibility hidden so it will not effect on your web-layout
link.style = "visibility:hidden";
link.download = fileName + ".csv";
//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
It looks like you are linking to the wrong ng-csv.js. The ng-csv.js file in the bower_components/ng-csv/src/ng-csv/ folder doesn't contain all of the code, you need to use the build version. Try this:
<script type="text/javascript" src="bower_components/ng-csv/build/ng-csv.js"></script>

ngRepeat dont refresh when I change the values - AngularJS

I'm doing a application to a calendar and I create a function that everytime change the values of my variable called "$scope.days", when I was using the version 1.0 didnt give error, but now the ngRepeat doesnt refresh, the new values go to the variable, but the ngRepeat dont show the new result...
$scope.loadMonth = function()
{
$scope.titleCalendar = $scope.months[$scope.month-1].name + ' ' + $scope.year;
getTotalFebruary($scope.year);
var dtString = $scope.year + '/' + $scope.month + '/' + 1,
date = new Date(dtString),
day = 1,
weekday = date.getDay(),
totalDays = $scope.months[date.getMonth()].qty + date.getDay();
$scope.days = [];
for(var i = 0; i < totalDays; i++)
{
if(i < weekday)
$scope.days.push('');
else
$scope.days.push(day++);
}
};
my html:
<div class="day" ng-repeat="day in days"><p>{{ day }}</p></div>
If I put an alert after push new values, I can see the new values, but my ngRepeat doesnt refresh the results, I already try many things but didnt work. Somebody know the solution?
Not sure I understand what you are trying to achieve given the small sample of code you provided but if you look at this sample you'll see that it should update the display every time you click the click me text, just enter either 1,2, or 3 in the input area. you might want to check that looping logic of yours.
<html lang="en-US" ng-app="mainModule">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
</head>
<body>
<div ng-controller="mainController">
<input type="text" ng-model="monthModel" placeholder="enter 1 2 or 3"/>
<h1 ng-click="loadMonth(monthModel)">Click Me to Repeat</h1>
<span class="day" ng-repeat="day in days">{{ day }} , </span>
</div>
<script type="text/javascript">
var app = angular.module("mainModule", []);
app.controller("mainController", function ($scope) {
//$scope.monthModel = 1; // default some date
$scope.year = "2014";
$scope.months = [
{"name":"January", "qty":10},
{"name":"February", "qty":5},
{"name":"March", "qty":10},
];
$scope.loadMonth = function(monthModel)
{
$scope.month = monthModel;
$scope.titleCalendar = $scope.months[$scope.month-1].name + ' ' + $scope.year;
//getTotalFebruary($scope.year);
var dtString = $scope.year + '/' + $scope.month + '/' + 1,
date = new Date(dtString),
day = 1,
weekday = date.getDay(),
totalDays = $scope.months[date.getMonth()].qty + date.getDay();
$scope.days = [];
for(var i = 0; i < totalDays; i++)
{
//if(i < weekday)
// $scope.days.push('');
//else
$scope.days.push(day++);
console.log($scope.days) ;
}
};
});
</script>
</body>
</html>

Resources