I wrote post several hours ago, where I have several interesting answers, but I don't uderstand everything and now I can't use that post. So I create one new.
I sill have problem with callback in this code:
<div id='temp'></div>
<div id='points'></div>
<div onClick ="play(1, 1)" id='click'>clickclickclick</div>
<script>
play(function (addpoints) {
document.getElementById('temp').innerHTML = addpoints;
}());
function play (choosecolor, randescolor) {
if (choosecolor == randescolor) {
if (document.getElementById('points').innerHTML === '') {
document.getElementById('points').innerHTML=100;
}
else {
var points = function (allpoints) {
var addpoints = parseInt(allpoints) + 100;
callback(addpoints);
document.getElementById('points').innerHTML=addpoints;
}
}
points(document.getElementById('points').innerHTML);
}
}
I uderstand that function callback doesn't send var addpoint with its value to second function, so in second function addpoints is undefined. But I don't understand why addpoints lose its value (but I can show it in div), what callback do and how correct it. Some user gave me advise that I should to choosecolor(addpoints); instead of callback(addpoints); but it still not work.
After some thoughts and research. i came accross that i was wrong somewhere. Here is the solution , pass the last parameter - which is the name of the function you want to call back. Now this will work as you want it to work.
Now here i mentioned the third parameter as name of the function i want to call after this function.
<div id='temp'></div>
<div id='points'></div>
<div onClick ="play(1, 1, newcallback)" id='click'>clickclickclick</div>
Here i declared a newcallback function which i will call after this method:
function newcallback(addpoints) {
document.getElementById('temp').innerHTML = addpoints; //undefined
});
function play (choosecolor, randescolor,callback) {
if (choosecolor == randescolor) {
if (document.getElementById('points').innerHTML === '') {
document.getElementById('points').innerHTML=100;
}
else {
var points = function (allpoints) {
var addpoints = parseInt(allpoints) + 100;
callback(addpoints);
document.getElementById('points').innerHTML=addpoints;
}
}
points(document.getElementById('points').innerHTML);
}
}
Here is the fiddle : JsFiddle
Related
I have this function that alerts the user when their amount of "moonstone" is 10. However, for various reasons, I would like the if statement to be outside the function. When I do this though, the alert doesn't work. Could someone please explain and post a fix for it?
<!DOCTYPE html>
<html>
<img id="game-board" onclick="totalCount()" class="game-board" src="https://pics.clipartpng.com/thumbs/Mars_PNG_Clip_Art-3002.png"></img>
<h2 id="counts">Moonstone:</h2>
<script>
let stone = 0;
function totalCount() {
let newCounts = stone++;
document.getElementById('counts').innerHTML= "Moonstone:"+ newCounts;
}
if (newCounts == 10){
alert('10');
}
</script>
</html>
What does work, but that I don't want to use, is
<DOCTYPE html>
<html>
<img id="game-board" onclick="totalCount()" class="game-board" src="https://pics.clipartpng.com/thumbs/Mars_PNG_Clip_Art-3002.png"></img>
<h2 id="counts">Moonstone:</h2>
<script>
let stone = 0;
function totalCount() {
let newCounts = stone++;
document.getElementById('counts').innerHTML= "Moonstone:"+ newCounts;
if (newCounts == 10){
alert('10');
}
}
</script>
In your code you calling the totalcount() function on onclick event so whatever inside the totalcount() function will executed and code outside the totalcount() function will not execute
I'm not entirely clear why you wouldn't want the if test within the function. But, there is something that you could do:
const counter = {
value: 0,
addOne: function() {
this.value++;
if (this.value > 10) {
alert("Too many");
this.value--;
} else {
document.getElementById("counts").innerHTML = "Moonstones: " + this.value;
}
}
}
function updateCounter() {
counter.addOne();
}
<button onclick="updateCounter();">Add</button>
<div id="counts"></div>
This creates the counter as an object and includes an if test on a addOne function directly attached to that object. Whenever the updateCounter() function is called, the addOne function updates the counter value and checks to see if it has passed 10. If it has, the user gets and alert, otherwise the "counts" element gets updated.
But, as others have said, there is no real reason why an if test shouldn't be part of a function - perhaps you could explain your reasons for that requirement?
I am trying to get the file input preview working.
I have a jquery script which works fine when I call the function normally.
$('#images').on("change", previewImages);
This works.
But when I put the call to the same function differently like following
$('#images').on("change", function(){
previewImages();
});
This doesn't work.
I need to write an if else statement to call a different function on else.
Valid question
Reason: this happens because of this which refers to file element when you are using first approach but in case of second approach this is referring to window element in which it is called. So pass this to function and your question is solved.
$('#images').on("change", function(e) {
/* issue is with this */
previewImages(e, this);
});
var count = 0;
function previewImages(evt, cur) {
var $fileUpload = $("input#images[type='file']");
count = count + parseInt($fileUpload.get(0).files.length);
if (parseInt($fileUpload.get(0).files.length) > 7 || count > 6) {
alert("You can only upload a maximum of 6 files");
count = count - parseInt($fileUpload.get(0).files.length);
evt.preventDefault();
evt.stopPropagation();
return false;
}
$("#taskbar").css("height", "auto");
var $preview = $('#preview').empty();
if (cur.files) $.each(cur.files, readAndPreview);
function readAndPreview(i, file) {
// if (!/\.(jpe?g|png|gif|mp4)$/i.test(file.name)){
// return alert(file.name +" is not an image");
// }
var reader = new FileReader();
$('#preview img').addClass('img-responsive');
$(reader).on("load", function() {
$preview.append($("<img/>", {
src: this.result,
height: 100
}));
});
reader.readAsDataURL(file);
}
}
Create a prePreviewImages function, and use that in your first approach. Inside that function, use the if-statement and call previewImages() or your other function.
The following should do..
$('#images').change(function(e) {
if(e == "some condition"){ // if else goes here
previewImages();
}else {
SomeOtherFun();
}
});
Both ways seem to work for me on the JSFiddle. Are you sure it is not a
browser compatibility issue?
If not are you getting errors logged in the console under developer tools?
The input named alternativa-*** will have the *** changed in the PHP that comes before. I'm not using a form on PHP only a onClick statement calling the respondeQuestao function. But this code seems to not work. Someone have any suggestion.
$(document).ready(function() {
function respondeQuestao(qid,resposta) {
var alternativa = document.getElementsByName('input[name = "aternativa-"' + qid ']:checked').value;
document.getElementById("demo").innerHTML = 5 + 6;
if(alternativa==resposta) {
$("#botao-questao"+qid).hide();
};
if(alternativa!=resposta) {
};
};
})
Defining a function within the jQuery Ready statement limits the accessibility - define it outside of the jQuery Ready statement but call it when you need it.
function respondeQuestao(qid, resposta) {
var alternativa = $("INPUT[name^='alternativa-']:checked").val();
$("#demo").html(5+6);
if (alternativa == resposta) {
$("#botao-questro" + qid).hide()
} else {
//
}
}
Call the function inside jQuery:
$(function() {
respondeQuestao("id", 11);
});
I hope this helps.
I have a little concern here
This comes from a service named BetSlipFactory
removeSlip: function(slip) {
return betSlipSelectionRequest('/betSlip/removeSelection', {
game: slip.game,
pair: slip.pair,
line: slip.line
});
}
Then I have this function in the controller for that service
$scope.removeSlip = function(slip) {
$rootScope.$broadcast('betSlip:removeLines', slip);
BetSlipFactory.removeSlip(slip)
}
Next I have a controller in a different scope named LinesCtrl and I have this function here which calls a couple functions from the service BetSlipFactory which is like a kind of toggle function
$rootScope.$on('betSlip:removeLines', function(event, slip) {
if (slip) {
BetSlipFactory.remove(line, row, type);
};
});
$scope.addLineToBetSlip = function(line, row, type) {
var spreadSelected = (row.spreadSelected && type === 'spread'),
totalSelected = (row.totalSelected && type === 'total'),
moneyLineSelected = (row.moneyLineSelected && type === 'moneyline');
if (spreadSelected || totalSelected || moneyLineSelected) {
BetSlipFactory.remove(line, row, type);
}else {
BetSlipFactory.add(line, row, type);
}
};
And then the HTML:
<button ng-click="removeSlip(slip)"></button>
And:
<td ng-class="!row.moneyLineSelected ? 'lines-hover' : 'line-selected'">
<a ng-click="addLineToBetSlip(line, row, 'moneyline')">
<span ng-hide="row.noMoneyLine">{{:: row.moneyLine}}</span>
</a>
</td>
What I need: combine the scopes, when the function $scope.removeSlip(slip) is call, also I need to call $scope.addLineToBetSlip(line, row, type) and then that function should call BetSlipFactory.remove(line, row, type); as it is within that if statement.
When I call $scope.removeSlip(slip) I need to kill slip parameter, within the scope of BetSlipFactory everything works great.
I recorded a video for you to see what I am talking about, let me explain the video a little bit.
In the first 2 tries you might see that I am able to select and deselect and everything works great, but in the 3rd and 4th try, you see that I select a line, and then I go a call and removeSlip(slip) when I play the X on the right, and in order to deselect the line on the left I have to do it manually.
So I started a fiddle showing this process dumbed way down compared to the plnkr you started after. Here I am using two separate controllers and a service (factory) to manage the data. This can be done without using $rootScope or $broadcast. Hopefully you can take what I have done here and integrate it into all that code you posted on plnkr. Below you can see it is quite a simple process
the jsfiddle
HTML:
<div ng-app="TestApp">
<div id="colLeft" ng-controller="LeftController">
<div ng-repeat="bet in possibleBets">
<button ng-class="!bet.moneyLineSelected ? 'lines-hover' : 'line-selected'" ng-click="addLineToBetSlip(bet)">{{bet.name}}</button>
</div>
</div>
<div id="colRight" ng-controller="RightController">
Your Bets:<br>
<div ng-repeat="bet in bets">
Active bet: {{bet.name}} - <button ng-click="removeLineFromBetSlip(bet)">×</button>
</div>
</div>
</div>
CSS:
.lines-hover {
}
.line-selected {
background:yellow;
}
#colLeft {
width:65%;
background:#f00;
float:left;
}
#colRight {
width:35%;
background:gray;
float:left;
}
and finally the JS
var app = angular.module('TestApp',[]);
app.controller('LeftController', function($scope, BetSlipFactory)
{
// this data is the data from your DB
$scope.possibleBets = [
{name:'Bet 1',moneyLineSelected:false},
{name:'Bet 2',moneyLineSelected:false},
{name:'Bet 3',moneyLineSelected:false}
];
// now that I think about it, addLineToBetSlip is not a good name
// since it actually toggles the bet
$scope.addLineToBetSlip = function(bet)
{
bet.moneyLineSelected = !bet.moneyLineSelected; // toggle the moneyLineSelected boolean
(bet.moneyLineSelected) ? BetSlipFactory.add(bet) : BetSlipFactory.remove(bet); // add or remove the bet
};
});
app.controller('RightController', function($scope, BetSlipFactory)
{
$scope.bets = BetSlipFactory.getAllBets(); // link to all the active bets
// remove the bet from the factory
$scope.removeLineFromBetSlip = function(bet)
{
bet.moneyLineSelected = false;
BetSlipFactory.remove(bet);
};
});
app.service('BetSlipFactory', function()
{
//a place to keep active bets
var theBets = [];
return {
add: function(bet)
{
// actually add the bet to this local array
theBets.push(bet);
},
remove: function(bet)
{
// you should do error checking of the index before removing it
var index = theBets.indexOf(bet);
theBets.splice(index,1);
},
getAllBets: function()
{
//simply return all active bets
return theBets;
}
}
});
function log(msg)
{
console.log(msg);
}
I've got a problem near that one.
Somewhere I've got a binding over a file input :
var file;
function initLoadImg(){
$('#test').on('change', function() {
file = event.target.files;
// block 1
console.log("hello");
center.html('<span id="Tamb">25°C</span>');
over = true;
});
}
And i'm triggering it with another javascript function :
var over = false;
var center;
function loadImg(){
var elem = $('<div class="widget simpleimgchart center"><div class="matable"><div class="center"></div></div></div>');
center = elem.children().children();
$("#test").trigger('click');
passIfOver();
// block 2
console.log("bye");
return elem;
}
function passIfOver() {
if (over) {
return;
} else {
setTimeout(passIfOver(), 1000);
}
}
This way, I'm able to see the "hello" before the "bye" in the console.
However I don't really like this solution, (it's not clean) and user can have to wait up to 1s before getting any feedback.
Would there be another way to ensure that the return elem is executed after the end of the callback on click?
edit : My code doesn't even work, because of the setTimeout, I lose the restraint...
edit 2 : My goal is to execute the part code 1 before the part code 2. I don't want my function loadImg() to return before the code 1 has finished to execute.
I recommend you to look at PubSub pattern (http://davidwalsh.name/pubsub-javascript).
Just move the return inside the Trigger function:
var over = false;
function loadImg(){
var elem = $('<div class="widget simpleimgchart center"><div class="matable"><div class="center"></div></div></div>');
var center = elem.children().children();
$("#test").trigger('click', function(){
center.html('<span id="Tamb">25°C</span>');
return elem;
});
}
The second argument to .trigger is a callback function everything inside it will be executed After the trigger is completed.