nivo slider effects, in order rather than random firing of selected efects - nivo-slider

is there a way of getting the nivo slider to use effects in order ie:
slideUp --> then slideDown --> then slide slideUp ect...
rather then using effect: "slideUp,slideDown" which randomly fires either effect.
regards sam

I wrote this for you. (Note, I have not tested it or validated it works, but the theory is sound)
<script>
var slideEffects = new Array('fade', 'slide', 'fade');
var currentEffectIndex = 0;
$(document).ready(function(){
$('#slider').nivoSlider({
effect: slideEffects[0],
afterChange: function(){
currentEffectIndex++;
$(this).effect = slideEffects[currentEffectIndex % slideEffects.length];
},
};
});
</script>

Here is a correct version.
<script type="text/javascript">
var slideEffects = new Array('fade', 'slide', 'fade');
var currentEffectIndex = 0;
$(document).ready(function(){
$('#slider').nivoSlider({
effect: slideEffects[0],
afterChange: function(){
currentEffectIndex++;
$(this).effect = slideEffects[currentEffectIndex % slideEffects.length];
},
});
});
</script>

Related

get data from nodejs to frontend js for google maps but stuck in retrieving it looking for ways to solve it

My NodeJS GET route:
router.get('/stores', function (req, res, next) {
errorMsg = req.flash('error')[0];
successMsg = req.flash('success')[0];
Product.find(function (err, products) {
// console.log(products)
res.render('admin/stores', {
layout: 'admin-map.hbs',
stores: products,
errorMsg: errorMsg,
GOOGLE_APIKEY: process.env.GOOGLE_APIKEY,
noErrors: 1
});
});
The route /stores returns json data which holds latitude and longitude and I want it in my script tag of map.html with loop, to render the pins on the map. Below, the script:
<!DOCTYPE html>
<html>
<head>
<script src = "https://maps.googleapis.com/maps/api/js"></script>
<script>
function loadMap() {
alert(this.stores);
var mapOptions = {
center:new google.maps.LatLng(17.433053, 78.412172),
zoom:5
}
var map = new google.maps.Map(document.getElementById("sample"),mapOptions);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(17.433053, 78.412172),
map: map,
draggable:true,
icon:'/scripts/img/logo-footer.png'
});
marker.setMap(map);
var infowindow = new google.maps.InfoWindow({ });
infowindow.open(map,marker);
}
</script>
<!-- ... -->
</head>
</html>
How can I do it?
It seems you need to follow two steps
1. Pass data from hbs to script
Using triple brackets syntax
<script>
let stores = {{{ stores }}}; // the triple brackets
console.log('Data : ', stores);
function loadMap() {
...
Check if data is being printed in console? If yes your data is available in the front-end script and you can
2. Loop through it
...
for (let i = 0; i < stores.length; i++) {
// the JS loop instead of hbs one, because we are on front-end
var marker = new google.maps.Marker({
position: new google.maps.LatLng(stores[i].lat, stores[i].lng), // whatever applies
map: map,
draggable:true,
icon:'/scripts/img/logo-footer.png'
});
}
And donot need to call setMap(), you have already set the map in map: map above
the answer is inside fronted script i can have an object declared globally and this double flower brackets works fine with them
<script>
function loadMap() {
alert(this.stores);
var mapOptions = {
center:new google.maps.LatLng(17.433053, 78.412172),
zoom:5
}
var map = new google.maps.Map(document.getElementById("sample"),mapOptions);
{{#each stores}}
var marker = new google.maps.Marker({
position: new google.maps.LatLng(17.433053, 78.412172),
map: map,
draggable:true,
icon:'/scripts/img/logo-footer.png'
});
{{/each}}
marker.setMap(map);
var infowindow = new google.maps.InfoWindow({ });
infowindow.open(map,marker);
}
</script>

How to update paginated dgrid periodically

I am trying to display and refresh periodically some server data using dgrid and derivative of Request dstore. The data are paginated and needs to be updated periodically. As a first naive approach I tried to call Dgrid.refresh() with setInterval. However, that results in complete rebuilding of grid rows which visually creates flickering effect. Using Trackable to the store does not help. Can anyone advise me how to refresh rows in the dgrid which would only update changed rows?
Here is my code reproducing the issue:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>DGrid flickering on slow updates</title>
<style>
#import "./dojo-release-1.11.1/dojo/resources/dojo.css";
#import "./dojo-release-1.11.1/dijit/themes/claro/claro.css";
#import "./META-INF/resources/webjars/dgrid/1.0.0/css/dgrid.css";
#import "./META-INF/resources/webjars/dgrid/1.0.0/css/skins/claro.css";
html, body {
padding: 10px;
width: 100%;
height: 100%;
}
</style>
<script>
var dojoConfig = {
async:true,
baseUrl: "./",
packages:[
{ name:"dojo", location:"dojo-release-1.11.1/dojo" },
{ name:"dijit", location:"dojo-release-1.11.1/dijit" },
{ name:"dgrid", location:"META-INF/resources/webjars/dgrid/1.0.0" },
{ name:"dstore", location:"META-INF/resources/webjars/dstore/1.1.1" }
]
};
</script>
<script src="dojo-release-1.11.1/dojo/dojo.js"></script>
<script>
require(["dojo/parser",
"dojo/dom",
"dojo/_base/declare",
"dstore/Store",
"dstore/Trackable",
"dstore/Cache",
"dstore/Memory",
"dstore/QueryResults",
"dojo/Deferred",
"dgrid/Grid",
"dgrid/Keyboard",
"dgrid/Selection",
"dgrid/extensions/Pagination",
"dojo/domReady!"],
function(parser, dom, declare, Store, Trackable, Cache, Memory, QueryResults, Deferred, Grid, Keyboard, Selection, Pagination)
{
parser.parse();
console.log("Parsed");
var makeSlowRequest =
function(kwArgs)
{
var responseDeferred = new Deferred();
var responsePromise = responseDeferred.promise;
// resolve promise in 2 seconds to simulate slow network connection
setTimeout(function ()
{
console.log("Generating response");
var data = {items: [], total: 100};
kwArgs = kwArgs || {start:0, end:100};
for(var i = kwArgs.start; i < kwArgs.end; i++)
{
data.items.push({id: "id-" + i,
name: "test-" + i,
value: Math.floor((Math.random() * 10) + kwArgs.start)
});
}
responseDeferred.resolve(data);
}, 2000);
return new QueryResults(responsePromise.then(function (data) { return data.items; }),
{ totalLength: responsePromise.then(function (data) { return data.total;}) });
};
var SlowStore = declare("SlowStore",
[Store, Trackable],
{ fetch: function (kwArgs) { return makeSlowRequest(kwArgs); },
fetchRange: function (kwArgs) { return makeSlowRequest(kwArgs); }
});
var store = new SlowStore();
var TestGrid = declare([Grid, Keyboard, Selection, Pagination]);
var grid = new TestGrid({
collection: store,
columns: {name: "Name", value: "Value"},
rowsPerPage: 10,
selectionMode: 'single',
cellNavigation: false,
className: 'dgrid-autoheight',
pageSizeOptions: [10, 20],
adjustLastColumn: true
}, dom.byId("grid"));
grid.startup();
// update grid every 5 seconds
var timer = setInterval(function(){console.log("Refreshing grid"); grid.refresh();}, 5000);
});
</script>
</head>
<body class="claro">
<div id="grid"></div>
</body>
</html>
I am guessing that instead of calling refresh I need get the request range from the dgrid (possibly using aspect on gotoPage) and call store.fetchRange(), iterate over the results, compare each item with previous results and invoke store.update or store.add or store.delete. I suppose that would give me what I want but before taking this approach I wondering if there is an easier way to refresh dgrid with updated data. Using Cache store does not work as it expects to fetch all the data from the server:
var store = Cache.create(new SlowStore(), {
cachingStore: new (Memory.createSubclass(Trackable))()
});

Overlapping in Masonry onload

I'm having the classic overflow problem with masonry. I'm trying to load twitter cards but onload, they are still overlapping each other. They work once the screen is resized. FYI, I have imageLoad and masonry in there for sure. I'm doing this in rails so not sure how I would make a jsfiddle. Any help is much appreciated. Thanks!
here is my js code:
$(document).ready(function() {
$('.container').imagesLoaded( function(){
$('.container').masonry({
columnWidth: '.tweet-box',
itemSelector: '.tweet-box'
});
});
});
index.html.erb:
<main class="container">
<% #tweet.search("cnn").take(9).each do |j| %>
<section class="tweet-box">
<p>
<blockquote class="twitter-tweet"><p></blockquote>
<script src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
</p>
</section>
<% end %>
</main>
I ended up fixing my problem with some recursion. FYI, I don't know if this is the best fix but it got it working for me. Open to a better answer if someone has anything.
$(document).ready(function() {
check_size();
check_width();
});
function check_size()
{
if($('.tweet-box').first().height() == 0)
{
// alert('loop called: ' + $('.tweet-box').first().height())
setTimeout('check_size()', 20);
}
else
{
// alert('initialized!!!! boo-ya')
var $container = $('.container').imagesLoaded( function() {
$container.isotope({
// options
itemSelector: '.tweet-box',
layoutMode: 'masonry'
});
});
}
}
This Worked for me, with the imagesloaded script installed.
<script src="/js/masonry.pkgd.min.js"></script>
<script src="/js/imagesloaded.pkgd.min.js"></script>
<script>
docReady(function() {
var grid = document.querySelector('.grid');
var msnry;
imagesLoaded( grid, function() {
// init Isotope after all images have loaded
msnry = new Masonry( grid, {
itemSelector: '.grid-item',
columnWidth: '.grid-sizer',
percentPosition: true
});
});
});
</script>
For me a combination of the small script "imagesloaded" and a few additional lines of jQuery that fire masonry after all images are loaded did the trick. My page footer now looks like this:
<script src="/js/masonry.pkgd.min.js"></script>
<script src="/js/imagesloaded.pkgd.min.js"></script>
<script>
$('#catalogue').imagesLoaded( function(){
$('#catalogue').masonry({
columnWidth: 10,
itemSelector: '.item',
isAnimated: !Modernizr.csstransitions
/* isFitWidth: true */
});
});
</script>
I don't remember where I got the pinter from, but the script imagesloaded can be found here: https://github.com/desandro/imagesloaded

RealTime Collaborative Text-Editor in Nodejs & Socket.io

I am developing a real-time text editor with paragraph locking property similar to https://quip.com/. in socket.io and nodejs.
It means when you write onto a given paragraph, other collaborators cant edit it.
Moment you hit enter or move cursor to a new line that paragraph becomes Editable for other Collaborators.
I am quite stuck after this. I am thinking a nice approach to move further. Suggestions please.
Below is my code which works perfectly. Till now i can get list of all collaborators and broadcast the content of editor to other collaborators.
index.html
<!DOCTYPE html>
<html>
<head>
<title>Connected Clients</title>
<!--<meta charset="UTF-8"> -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!--<script type="text/javascript" src="jquery.js"></script> -->
<script src="/socket.io/socket.io.js"></script>
</head>
<body>
<textarea id="editor" style="height:200px;width:300px">
Thinknest Pragraph locking Test sample !
</textarea>
<script>
function msgReceived(msg){
//clientCounter.html(msg.clients);
document.getElementById('people').innerHTML=msg.uid;
//console.log(msg.id);
}
var clientCounter;
$(document).ready(function () {
clientCounter = $("#client_count");
var socket = io.connect(
'http://localhost:5000',
{'sync disconnect on unload':true}
);
var uId=prompt("enter your userId",'');
socket.emit('collabrator',uId);
socket.on('message', function(msg){
msgReceived(msg);
});
socket.on('online_collabs',function(data){
$('#online_ppl').html(data);
clientCounter.html(data.length);
});
socket.on('remained_collabs',function(data){
$('#online_ppl').html(data);
clientCounter.html(data.length);
});
socket.on('note_collabs',function(data){
$('#note_colabs').html(data);
});
socket.on('updated_para',function(data){
//$('#editor').append(data);
document.getElementById('editor').innerHTML=data;
});
$('#editor').on('keydown',function(){
//var para=$('#editor').value;
var para= $('#editor').val();
//var para=document.querySelector('[contenteditable]');
// var text=para.textContent;
socket.emit('para',{paragraph:para});
});
});
</script>
<p><span id="client_count">0</span> connected clients</p><br/>
<ul id="people"></ul>
<h3>Online Collaborators</h3>
<span id="online_ppl"></span> <br>
<h3>Note Collaborators</h3>
<span id="note_colabs"></span>
</body>
</html>
server.js
var app = require('express')()
, server = require('http').createServer(app)
, io = require('socket.io').listen(server);
server.listen(5000);
app.get('/',function(req,res){
res.sendfile("./index.html");
});
var activeClients = 0;
var Collaborators=['Colab1','Colab2','Colab3'];
var people=[];
io.sockets.on('connection', function(socket){
clientConnect(socket);
socket.on('disconnect', function(){
clientDisconnect(socket);
});
socket.on('para',function(data){
//io.sockets.emit('updated_para',data.paragraph);
socket.broadcast.emit('updated_para',data.paragraph);
});
});
function clientConnect(socket){
//activeClients +=1;
var userSocketId=socket.id;
check_Collaborator(socket);
io.sockets.emit('message', {uid:userSocketId});
}
var online_collabs=[];
function check_Collaborator(socket){
socket.on('collabrator',function(data){
if(Collaborators.indexOf(data)!=-1){
socket.data=data;
if(online_collabs.indexOf(data)==-1) {
online_collabs.push(data);
}
io.sockets.emit('online_collabs',online_collabs);
io.sockets.emit('note_collabs',Collaborators);
} else {
console.log("collabrator not found");
}
});
}
function clientDisconnect(socket){
var index=online_collabs.indexOf(socket.data)
if(index>-1)
online_collabs.splice(index,1);
//activeClients -=1;
//io.sockets.emit('message', {clients:activeClients});
io.sockets.emit('remained_collabs',online_collabs);
}
I saw this yesterday already. What exactly is your question? Do you want to know how to 'lock' a text area with javascript? I am confused as to why you put such a strong emphasis on node/socket.io in your question.
Also, next time please format your code. You want help, I get it, but then make it easier for others to help you.
What you have to do in order to make a paragraph not editable by others, I don't know. But let me suggest what I'ld do in socket.io:
Store each paragraph separately and remember who has a lock on it. For locking, I would use the sessionID in case users don't have to register. This would look something like this:
var paragraphs = {
data : [
{
text: "this is an unlocked paragraph",
lock: ""
},
{
text: "this is a locked paragraph",
lock: "oWEALlLx5E-VejicAAAC"
}
]
}
Now, users will likely be allowed to add a paragraph before an existing one. Therefore you should keep an additional index like:
var paragraphs = {
index : [
1,
0
],
data : [
{
text: "this the second paragraph",
lock: "oWEALlLx5E-VejicAAAC"
},
{
text: "this is the first paragraph",
lock: ""
}
]
}
The amount of data being sent over the sockets should now be very small - altough with additional client/server-side logic.
Paragraph lock can be easily achieved by adding a class to the currently editing paragraph. Transfer this paragraph with the class to the other user. so that if the user tries to write over that prevent him by validate with the class.
Generate a class name look like - className_userid (className_1).

how to scale my textlayer

i wish to scale a text layer by button click.
var messageLayer = new Kinetic.Layer();
function writeMessage(message, xx, yy) {
var context = messageLayer.getContext();
context.font = '12pt Calibri';
context.fillStyle = 'white';
wrapText(context, message, xx, yy, seat_size, seat_size);
}
stage.add(messageLayer);
writeMessage(text, xx, yy);
document.getElementById('zoomInBtn').onclick = function zoomInStage(){
stage.setScale(2);
stage.draw();
}
I'm not sure why but this seems not working..
Thanks for helping.
Hi thanks for pointing out my mistake.
but after i add the y value and this is still not working ....
below are my code:
enter <!DOCTYPE HTML>
<html>
<body>
<div id="container"></div>
<button id="scaleme" style="margin-left:10px;">Scale</button>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.0-beta2.js"></script>
<script>
function writeMessage(messageLayer, message) {
var context = messageLayer.getContext();
messageLayer.clear();
context.font = '18pt Calibri';
context.fillStyle = 'black';
context.fillText(message, 10, 25);
}
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var messageLayer = new Kinetic.Layer();
stage.add(messageLayer);
writeMessage(messageLayer, 'text text text');
document.getElementById('scaleme').onclick = function scale(){
messageLayer.setScale(2,2);
}
</script>
</body>
</html>
please helppp....thanks!
From the API docs:
this is the format:
setScale(x, y)
So you are missing the y parameter it seems.
If you do
stage.setScale(2,2);
then the whole stage will be scaled, but if you want just the text layer to be scaled:
messageLayer.setScale(2,2);
lastly, if you want to be fancy, you can do a transition to zoom to the text:
messageLayer.on('click', function(){
messageLayer.transitionTo({
scale: {
x: 2,
y: 2
},
duration: 1,
easing: 'elastic-ease-out' // this one is not really necessary, just for show
});
});
EDIT:
Since you are using canvas primitives, do this: http://jsfiddle.net/mmqXK/
var context = messageLayer.getContext();
context.scale(1, 0.5);
messageLayer.draw();
writeMessage(messageLayer, 'text text text');

Resources