I'm creating a node application and having trouble updating a global variable.
Here is my code (ejs file):
<% include ../partials/header %>
<div class="page container">
<div id="campgroundsRow" class="row">
</div> <!-- row end -->
<button id="loadMore">Load More</button>
</div> <!-- Container End -->
<% include ../partials/footer %>
<script>
var numGroundsToLoad = 1;
var numGroundsLoaded = 0;
loadCampgrounds(numGroundsLoaded, numGroundsToLoad);
function loadCampgrounds(numGroundsLoaded, numGroundsToLoad) {
var grounds = <%-JSON.stringify(campgrounds) %>
for(var i=numGroundsLoaded + 1; i<numGroundsLoaded + numGroundsToLoad; i++) {
//code to add grounds[i] to campgroundsRow div
}
numGroundsLoaded += numGroundsToLoad;
}
$("#loadMore").on("click", function() {
loadCampgrounds(numGroundsLoaded, numGroundsToLoad);
});
</script>
The problem I'm having is the loadCampgrounds function is not actually updating numGroundsLoaded. So when I click the load more button (#loadMore), it thinks that I am adding ground[0].
What I want is that each time I click load more, the next ground is added. I.e, ground[0] gets added by default. Then on load more, ground[1]. Then on load more, ground[2] and so on (assume there are unlimited grounds for now).
As you can see, the problem is related to both scope and when stuff is being loaded.
Because you update the local variable. In this case, to update global variable you need to access it through window.numGroundsLoaded.
Related
I am computing data inside a function that loop over two different json files, but even with the async tag in front of my function if the function did not finish to compute all the data, my front end will still be loading.
So i was wondering, is there a way to do it fully asynchronous ?
Or is it just not possible in this case ?
What i'v tried so far is :
JS part
mounted() {
// Count line inside appsession.json
this.findMatch()
},
... Inside Methods :
async findMatch(){
var result=[]
this.loading=true
var x=0
var z=0
console.log('test:',Object.keys(this.session).length)
var l=Object.keys(this.session).length
for(var i in this.session)
{
this.percentage=((i/l)*100)
//console.log((i*Object.keys(this.session).length)*100)
for(var y in this.users)
{
if(this.session[i]._source.deviceID==this.users[y].device_id){
result.push(this.session[i]._source.deviceID)
if(this.session[i]._source.deviceOS=="ios"){
this.ios=this.ios+1
}
else if(this.session[i]._source.deviceOS=="android"){
this.android=this.android+1
}
}
}
}
this.InitPieChartMobiles()
this.loading=false
},
Front end Part :
loading : {{ percentage }}%
<template>
<div v-if="loading">
<div class="lds-hourglass"></div>
</div>
<div class="small">
<line-chart :chart-data="datacollection"></line-chart>
</div>
<div class="small">
<pie-chart :chart-data="usercollection"></pie-chart>
</div>
<div class="small">
<pie-chart :chart-data="mobiles"></pie-chart>
</div>
</template>
I guess there is some way to do it since i already used components that whould show if a v-if is a true. But i can't point my finger on what to do or how to do it.
Thanks for you time !
Can somebody please give me some guidance with a problem I am having with the JQuery Guillotine? I have spent hours working on this and cannot identify the correct solution. The issue I am having is eventOnChange fires multiple times after I have changed the image. Each event is fired +1 for each successive image swap.
I have studied this link and am still unable to find a working solution: jQuery Guillotine - Swap Image
I've worked around this by killing the event and just capturing the relevant information I need when the form is posted, but it's really bothering me that I cannot find a solution that will allow me to take advantage of the event.
Here is a brief summary of what is going on:
page loads with default user avatar
user is able to manipulate avatar inside guillotine and one onchange event fires per manipulation (zoom in, zoom out, rotate, fit, etc.)
user opens file reader to select new avatar
new avatar is successfully loaded (correct scaling and dimensions)
user manipulates image but each manipulation event fires multiple times. For example, rotate right will rotate the image twice (180 degrees) after the user has selected a new avatar.
If the user opens the file reader again, the image will fire three times. And so one. 1 + x times the user selects a new avatar...
I have tried unbinding the event before reloading the image and initialing the plugin, but it has not solved the problem. Any help is greatly appreciated!
Relevant code is below.
JavaScript:
<script type="text/javascript" charset="UTF-8">
function showData (data) {
data.scale = parseFloat(data.scale.toFixed(4))
for(var k in data) { $('#'+k).html(data[k]) }
}
function loadInterface(picture) {
showData(picture.guillotine('getData'))
// Bind button actions
if(!picture.data('isBound')){
picture.data('isBound', true)
$('#rotate_left').click(function(){ picture.guillotine('rotateLeft') })
$('#rotate_right').click(function(){ picture.guillotine('rotateRight') })
$('#fit').click(function(){ picture.guillotine('fit') })
$('#zoom_in').click(function(){ picture.guillotine('zoomIn') });
$('#zoom_out').click(function(){ picture.guillotine('zoomOut') })
}
// Update data on change
picture.on('guillotinechange', function(e, data, action) {
console.log('guillotine onchange event called!')
showData(data);
console.log(action);
})
}
function loadGuillotine (picture, data) {
if(picture.guillotine('instance')){ picture.guillotine('remove') }
// Load plugin
picture.guillotine({
width: data['w'],
height: data['h'],
init: data,
eventOnChange: 'guillotinechange'
})
}
$(document).ready(function() {
var picture = $('#useravatar')
var data = { w: 250, h: 250, angle: 0, scale: 1 }
picture.on('load', function() {
// Load guillotine and controls
picture.guillotine('remove')
loadGuillotine(picture, data)
loadInterface(picture)
// Transform picture to fit, center
picture.guillotine('fit').guillotine('center')
})
})
function ReloadImage(){
var reader = new FileReader();
reader.readAsDataURL(document.getElementById("avatar_input").files[0]);
reader.onload = function (oFREvent){
document.getElementById("useravatar").src = oFREvent.target.result;
}
}
</script>
And inside Ruby Page:
<div id='content'>
<h1>Select Avatar</h1>
<%= form_for(#avatar, url: save_avatar_path, method: :patch) do |f| %>
<%= render 'shared/errors', object: #avatar %>
<div class='frame'>
<%= image_tag 'default-user-avatar.jpg', :id => :useravatar %>
</div>
<div id='controls'>
<button id='rotate_left' type='button' title='Rotate left'> < </button>
<button id='zoom_out' type='button' title='Zoom out'> - </button>
<button id='fit' type='button' title='Fit image'> [ ] </button>
<button id='zoom_in' type='button' title='Zoom in'> + </button>
<button id='rotate_right' type='button' title='Rotate right'> > </button>
</div>
<div id='controls'>
<%= f.hidden_field :image, value: #avatar.cached_image_data %>
<%= f.file_field :image, :class => :form_field, :id => :avatar_input, :onChange => "ReloadImage()" %>
</div>
<ul id='data'>
<div class='column'>
<li>x: <span id='x'></span></li>
<li>y: <span id='y'></span></li>
</div>
<div class='column'>
<li>width: <span id='w'></span></li>
<li>height: <span id='h'></span></li>
</div>
<div class='column'>
<li>scale: <span id='scale'></span></li>
<li>angle: <span id='angle'></span></li>
</div>
</ul>
<% end %>
</div>
I have not tested your code but believe/guess you have fallen into a trap that I once found myself in.
.click() applies your function event with every iteration of the loop hence why you get multiple change events fireing (thus if the loop calls three times then the event is added sequentially three times).
Try using .one() instead of .click()
Another potential solution is to use .off().click() but it creates overhead.
I've set of html codes, I want to have a function for each set where I can pull some data or do some activities, so basically I need to be calling function according to the html codes present in DOM, suppose I've header section I want to collect menu items and I've sliders where I want to collect slider information, So I need to call header function to do the activity accordingly and slider function to do the activity, I went across some info about eval() but I guess it has lot of demerits and is being obsolete. Please suggest me how can I achieve it.
HTML Code:
Header
<div class="header" data-nitsid="1">
<div class="branding">
<h1 class="logo">
<img src="images/logo#2x.png" alt="" width="25" height="26">NitsOnline
</h1>
</div>
<nav id="nav">
<ul class="header-top-nav">
<li class="has-children">
Home
</li>
</ul>
</nav>
</div>
Slider
<div id="slideshow" data-nitsid="2">
<div class="revolution-slider">
<ul> <!-- SLIDE -->
<!-- Slide1 -->
<li data-transition="zoomin" data-slotamount="7" data-masterspeed="1500">
<!-- MAIN IMAGE -->
<img src="http://placehold.it/1920x1200" alt="">
</li>
</ul>
</div>
</div>
Now I want to collect data from both elements and pass the data to my views of laravel framework where it will generate a popup for each section for editing purpose.
$('.page-content-wrapper').find('[data-nitsid]').each(function() {
// getting data to call function
var nits = $(this).data("nitsid");
// calling function
design.nits();
}
var design = {};
design.1 = function() {
// do ajax request to views of header
}
design.2 = function() {
// do ajax request to views of slider
}
You canot use literal number as a property name. If you want to call property 1 of object design use design[1] instead. Also, you cannot assing property to non-initialized variable, you must use var design = {}; to make it object. If your property of design object is stored in nits variable, then call it as design[nits]();. Also, next time don't forget to test your code before posting it here. You've forget ) after your first function.
$('.page-content-wrapper').find('[data-nitsid]').each(function() {
// getting data to call function
var nits = $(this).data("nitsid");
// calling function
design[nits]();
});
var design = {};
design[1] = function() {
// do ajax request to views of header
};
design[2] = function() {
// do ajax request to views of slider
};
You want to use design[nits]();.
This will get the property nits of design and execute it with ().
But there is another problem. Your design will be declared after the each loop, so it is not available inside. You have to place it before.
$(function() {
var design = {};
design.funcOne = function() {
alert("funcOne called");
}
design.funcTwo = function() {
alert("funcTwo called");
}
$('div[data-nitsid]').each(function() {
var nits = $(this).data("nitsid");
design[nits]();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-nitsid="funcOne">
I will call 'funcOne'!
</div>
<div data-nitsid="funcTwo">
I will call 'funcTwo'!
</div>
I am working on a website for school, and am currently implement some sort of admin dashboard. For that, I decided to dynamically load 'modules' (actually simply .php files) into a div designed to hold them.
This works fine for modules that don't depend on specific js files, but there's one that needs the 'participation.js' file.
I had tested the module in a whole window where there was an 'onload="initSelectable()"' on the body directive, but calling this function when the module is loaded in the admin dashboard doesn't do anything.
Here is the content of participation.js (it is simply copy/pasted from the JQuery selectable, and I slightly modified the behaviour):
var selectedPlayerIDs = [];
function initSelectable(){
$('#selectable').selectable();
$('#submitParticipationBtn').hide();
console.log("initSelectable");
$("#selectable").selectable({
stop: function() {
var count = 8;
var result = $("#selectedPlayersCount").empty();
$(".ui-selected", this).each(function() {
count--;
selectedPlayerIDs.push($(this).attr("data-playerid"));
});
if(count > 1)
$('#selectedPlayersCount').html(count + " more players");
else if(count === 1)
$('#selectedPlayersCount').html(count + " more player");
else if(count === 0)
$('#selectedPlayersCount').html("no more player. You're good to go !");
else if(count === -1)
$('#selectedPlayersCount').html(-count + " player less");
else
$('#selectedPlayersCount').html(-count + " players less");
if(count === 0)
$('#submitParticipationBtn').show();
else
$('#submitParticipationBtn').hide();
}
});
}
function submitParticipation(){
alert( "JS loaded" );
$.post("participation.php", {selectedIDs : JSON.stringify(selectedPlayerIDs)}, function() {
})
.onSuccess(function() {
alert( "onSuccess" );
})
.fail(function() {
alert( "error" );
});
}
So basically this code initializes the JQuery Selectable environment. When loading the module in the div, I use $('#dynamicPage').hide().load("module1.php").fadeIn('500'); directly followed by $.getScript("participation.js");
The thing is, the module correctly loads (at least the HTML part), and I can see in the console log ("initSelectable"). But I need to manually re-execute initSelectable() from the command for it to be effective. And when I do that, I see there's an undefined getting logged in the console, before the second ("initSelectable") log (this might be due to the fact that I'm trying to call $('#selectable').selectable(); a second time).
For example, here is the participation module .php file:
<div class="well">
<h3>Create a participation</h3>
<h4>Please select <span id="selectedPlayersCount">8 players</span></h4>
<div class="row">
<div class="col-sm-4">
<ol id="selectable">
<?php include_once "../Ctrl/rankingList.php" ?>
</ol>
<button class="btn btn-success" id="submitParticipationBtn" onclick="submitParticipation()">Submit</button>
</div>
</div>
</div>
I've tried countless different way to call the initSelectable function (callbacks, events, timeOuts, etc...) and no matter what, even if it gets executed by the browser, I still need to manually re-execute it for it to be working...
So basically, my question is:
What is the correct way to load HTML and dependant JS files into a div ?
What is the correct way to load HTML and dependant JS files into a div ?
So, this would be a good start and you can take it from here.
$(function() {
$("#myDiv").load("myfile.php", function() {
console.log("HTML has been injected!");
//Get dependencies
$.getScript( "myscript.js" )
.done(function( script, textStatus ) {
//Call methods from within myscript.js
initSelectable();
})
.fail(function( jqxhr, settings, exception ) {
console.log("There was an error!");
});
});
// Remove inline event handler and bind it like below.
$("#myDiv").on("click", "#submitParticipationBtn", submitParticipation);
function submitParticipation() {
//...
//...
}
});
I am not sure why $('#selectable').selectable() is being duplicated. But, it's left you to fix :)
Okay so I was doing it wrong. I thought that putting the <script src "path/to/script.js"></script> in the module file didn't work. But actually, it does, and I simply needed to call $(document).ready(initSelectable()) in the JS file to be sure the initSelectable was executed at the right time.
So now my .php file looks like this:
<div class="well">
<h3>Create a participation</h3>
<h4>Please select <span id="selectedPlayersCount">8 players</span></h4>
<div class="row">
<div class="col-sm-4">
<ol id="selectable">
<?php include_once "../Ctrl/rankingList.php" ?>
</ol>
<button class="btn btn-success" id="submitParticipationBtn" onclick="submitParticipation()">Submit</button>
</div>
</div>
<script src="../Ctrl/participation.js"></script>
</div>
Thanks all for your help :P
I'm creating 5 divisions in for loop, each division have one image and one button.
Button's action is to perform like/vote. But, the images and buttons being in for loop, i don't know which button is linked with which image id. So that i can put it into database that image have been voted.
<%
for(until resultSet has next){
%>
<img id="img" src="resultsetValue" />
<button id="btn" >VOTE</button>
<%
}
%>
In JavaScript file:
document.getElementById("btn").onclick = function(){
//WHICH IMAGE NEEDS VOTE NOW
}
Now, if you see, i gave them id's too. An id must be unique to each element, but i gave id in for loop, which makes every image and every button have same id. How can i resolve this or is it ok?
i don't want to use jQuery, i have to learn it yet.
First of all, make sure buttons don't have duplicated ids. Better to use classes in this case:
<% for(until resultSet has next) { %>
<img id="img<%= index %>" src="resultsetValue" />
<button class="btn" data-index="<%= index %>">VOTE</button>
<% } %>
Then you can do something like this using iteration index to refer currently clicked element:
var buttons = document.querySelectorAll('.btn');
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
var index = this.getAttribute('data-index');
var img = document.querySelector('#img' + index);
};
}
this one will work