Category Archives: javascript

Angular2 – REST sample app, part 1

It’s time to learn angular2. Stay on trend 🙂 So I decided to play with it and I wanted to make some app that uses REST API. IMO it’s most common example. But unfortunately I didn’t find good sample apps or articles to start. It’s very likely that this article become outdated very soon. But right now I think this could be very useful, because still angular2 in beta personally I faced with a few pitfalls. Going to implement something very simple. But simple is not easy.

Continue reading

RBAC in Meteor

Meteor development fascinated me. So I continue to play with it. And again I found the case that made me think that I can try to do that a little better. So let’s talk about access control in meteor js.

Meteor allows us to control low level mongo operations via collection.allow and collection.deny. But obviously that it’s not convenient because there’s no way how could I check certain right before actual DB operation. I mean I cannot check if user with “author” role can update its own article.

Ok let’s see what can we do to improve situation with access control in meteor.

Continue reading

Meteor pagination

I was intrigued by meteor  and continue to play with it. Remember my previous post Meteor js first impressions

Be ready that even for the most common things you won’t have existed tools. Or you’ll need to spend much more efforts in comparison with you favorite language/framework.

Today I will tell you about one of such examples – pagination in meteor js.

Continue reading

Meteor.js first impressions

Continue to write and learn server javascript. Recently I had a chance to read “Discover meteor” book and would like to share my first impressions about meteor.js

06637ff9d61e52470242fc6ce718ed3b

When I first knew about meteor.js from their promo video it looked fantastic. But I understood that it’s too young. Recently I’ve got an email that they launch stable 1.0 version. And they kindly provide their book(although for a limited time). So I didn’t miss opportunity to grab and read it.

Continue reading

Crop image before upload

Let’s talk about cropping and resizing today. This quite common task on any web app. And as a rule there are 2 issues with image size.

original image is too big and it doesn’t make sense to return original to client. We need to make it smaller.
image size is not proportional i.e. width is much bigger than height or vice versa.
too_wide

Dynamically resize images.

Let’s think how we can solve issue #1. The easiest solution is resize image on upload. And then return to client resized images. This will works fine until you need to get same image with bigger or smaller size. We can use browser resizing but you know it sucks. This lead us to decision that allow us to return image with different sizes on fly.

For example we can use such URLs:
/uploads/users/1.png
/uploads/cache/users/1_200_x_200.png
/uploads/cache/users/1_500_x_500.png

You got the idea, right? We will check do we have image with required size in cache if yes- just return it, otherwise create and return. We keep the originals and can easily clean cache folder.

With php we can use https://github.com/avalanche123/Imagine nice library that allows you to make various actions with your images.

Cropping images.

We can use suggested logic but still we have an issue with proportions. For example I’m uploading my another selfie. And I’m not the best photographer. What do we get using logic described below.

bad_cropping

Resizing libraries don’t know how to crop your image and will use center and provided proportions to crop your image. As a result you’ll get image like this. But where is my mouth? 🙂

In such examples when user uploads his avatar or image is quite important and you need to get best of it you can combine first approach with manual cropping.

There’s a dozen of cropping plugins http://www.jqueryrain.com/demo/jquery-crop-image-plugin/ but they work in pretty similar way. They allow use to crop image and then will provide width, height and x,y  points.  Personally I used this one http://fengyuanchen.github.io/cropper/

Finally I provide a piece of javascript code that I used. Ok so you click “Update avatar” we ask user to provide image. After that show popup with cropping dialog. Ask user to crop image and send received data – image, and cropping params to server (x, y, width, height). On server crop the image – save original and then using original cropped image return copies of different sizes.

<!-- our trigger -->
<div class="fileinput-wrapper">
    <button class="block-btn btn text-uppercase btn-primary browse-files fileinput-button">
        Change Icon
        <input type="hidden" name="Profile[avatar_url]" value="">
        <input type="file" id="profile-avatar_url" class="change_profile_avatar" name="Profile[avatar_url]" data-id="70">
        <input type="hidden" id="profile-crop_params" name="Profile[crop_params]" value="">
    </button>
</div>

<!-- cropper dialog -->
<div class="modal fade" style="" id="crop-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal">
                    <span aria-hidden="true">&times;</span>
                    <span class="sr-only">Close</span>
                </button>
                <h4 class="modal-title" id="myModalLabel">Crop Image</h4>
            </div>
            <div class="modal-body">
                <div class="eg-main">
                    <div class="eg-wrapper" id="cropper_original_wrapper">

                    </div>
                    <div class="eg-preview clearfix">
                        <h3>Large Preview</h3>
                        <div class="preview preview-md"></div>
                    </div>
                    <div class="eg-preview clearfix">
                        <h3>Small Preview</h3>
                        <div class="preview preview-xs"></div>
                    </div>
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" id="save_profile_avatar">CROP & FINISH</button>
                <button type="button" class="btn btn-inverse" data-dismiss="modal">Cancel</button>
            </div>
        </div>
    </div>
</div>
 function initAvatarUpdate() {
        $('.change_profile_avatar').fileupload({
            dataType: 'json',
            add: function (e, data) {
                var $element = $(this);
                data.url = "/profile/update?id=" + $element.data("id");
                $("#cropper_original_wrapper").empty();
                if (data.files && data.files[0]) {
                    var reader = new FileReader();
                    reader.onload = function(e) {
                        var newImg = $("<img>", {"class": "cropper", "src": e.target.result});
                        $("#cropper_original_wrapper").append(newImg);
                        initCropper($element);
                    }
                    reader.readAsDataURL(data.files[0]);
                    $("#crop-modal").modal("show");

                    $("#save_profile_avatar").off('click').on('click', function () {
                        data.submit();
                        return false;
                    });
                }
            },
            done: function (e, data) {
                var newSrc = data._response.result.model.fileUrl;
                $(this).closest('.profile-avatar').find("img").attr("src", newSrc);
                $("#crop-modal").modal("hide");
                $("#profile_avatar").trigger("profile_changed", [ $(this).data("id"), newSrc])
            }
        });

        function initCropper($element) {
            var $cropper = $(".cropper")
            $cropper.cropper({
                aspectRatio: 1,
                data:
                {
                    x: 1,
                    y: 1,
                    width: 500,
                    height: 500
                },
                preview: ".preview",
                // autoCrop: false,
                // dragCrop: false,
                // modal: false,
                // moveable: false,
                // resizeable: false,
                // maxWidth: 480,
                // maxHeight: 270,
                // minWidth: 160,
                // minHeight: 90,
                done: function(data) {
                    $element.next().val(JSON.stringify({
                        "x": data.x,
                        "y": data.y,
                        "width": data.width,
                        "height":data.height
                    }));
                }
            });
        }
    }

Finally we got

good_cropping

Socket IO authorization

I’d like to finish my story about my experiments with nodejs and socket.io. Check out my previous post http://radzserg.com/2014/07/01/socket-io-1-0-emitting-events-from-php/ .The last thing that I wanted to do is authorization. So imagine the following task we want to get updates for specific organization. My idea was quite simple in this case we can send authorization data (username:password or oauth token) to server plus send extra param like organization id

// let's add this param on frontend 
 var socket = io('http://localhost:8000', {
    query: "token=[oauth token]&organizationId=" + organizationId,
    transports: ['websocket']
});

Let’s add DB service that actually will perform authorization

var config = require('./src/config.json')
var pg = require('pg')
client = new pg.Client(config.pg.cdn);
client.connect(function (error) {
    if (error) {
        return console.error('could not connect to postgres', error);
    }
})

var dbService = require('./src/services/postgres_service.js')(client);

io.set('authorization', function (handshakeData, cb) {
    dbService.isUserAuthorized(handshakeData._query, function (result, error) {
        if (error) {
            return cb(error, false);
        }
        return cb(null, result);
    });
});

io.on('connection', function (socket) {
    // if we pass authorization join socket to organization room 
    socket.join("organization." + socket.request._query.organizationId);
});

An example of DB service could looks like this


module.exports = function (client) {

    return {
        isUserAuthorized: function (data, next) {
            var token = data.token ? data.token : null;
            if (!token) {
                return next(false, "Token must be specified");
            }
            var organizationId = data.organizationId ? data.organizationId : null;
            if (!organizationId) {
                return next(false, "organizationId must be specified");
            }

            var sql;
            sql = 'SELECT user_id FROM oauth_access_tokens WHERE access_token = $1 AND expires > NOW()';
            var query = client.query(sql, [token], function (error, result) {
                if (error) {
                    return next(false, error);
                }
                var userId = typeof result.rows[0] !== 'undefined' ? result.rows[0]['user_id'] : null;
                if (!userId) {
                    return next(false);
                }
                // then required queries to check if user has access to required organization. 
                // ... 
                return next(true)              
            });
        }
    }
};

Finally on PHP side we also can send events to specific room

$this->_emitter()->in("organization.{$orgnizationId}")->emit("news", [
     'data' => $data
]);

For now that’s it. Make a pause with nodejs. Although it was nice to play with it.

Bootstrap form helpers get instances

Worked with bootstrap form helpers library. Looks nice and great integration with twitter bootstrap. But spent a lot of time to figure out how to access bfhdatepicker and bfhtimepicker objects. Unfortunately googling didn’t get any answer. As usual key was simple 🙂 Hope this will save time for someone else.

   var datePicker = $('#datepicker_id').data('bfhdatepicker');
   datePicker.setDate('today')

   var timePicker = $('#timepicker_id').data('bfhtimepicker');
   timePicker.setTime('now')

Simple node WAMP with redis pubsub

Tried to play with node. It’s always interesting to try something new.

My basic problem was to get new updates from redis queue using subscribe to channel. And pushing this message to client via websockets. I found http://socket.io/ and decide to use is as example.

Everything was brand new for me so today my story will be quite detailed.

Ok let’s go step by step.

1. Initiate our new project

  • mkdir wamptest
  • npm init (follow instructions)

2 Then as I mentioned I need some 3rd party libraries. Let’s add them

  • npm install redis –save
  • npm install socket.io –save

Here’s what I have in package.json

{
  "name": "radzserg-wamp-play",
  "description": "WAMP server toy project",
  "version": "0.0.1",
  "main": "server.js",
  "dependencies": {
    "redis": "^0.10.3",
    "socket.io": "0.8.x"
  },
  "private": "true"
}

Let’s finally start coding

We will use 2 files. Client and server. Client will be simple

index.html

Basically we set up socket connection and will just show what we got from server.

<html>
<head>
    <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
<!-- And yes we don't need to create this file. Node will do that for us. Some kind of magic that I didn't get at the beginning and was completely confused -->
    <script>
        $(function () {
            var socket = io.connect(null, {
                query: 'token=' + 123 + '&channelId=' + 1
            });
            socket.on('connect', function () {
                socket.on('message', function (message) {
                    console.log(message)
                    $('#messages').append($('<li></li>').text(message));
                });
                socket.on('disconnect', function () {
                    $('#messages').append('<li>Disconnected</li>');
                });
            });
        });
    </script>
</head>
<body>
<ul id="messages"></ul>
</body>
</html>

And the server.js

var fs = require('fs'),
    http = require('http'),
    redis = require("redis"),
    sio = require('socket.io');

var server = http.createServer(function (req, res) {
    res.writeHead(200, { 'Content-type': 'text/html'});
    res.end(fs.readFileSync('./index.html'));
});
server.listen(8000, function () {
    console.log('Server listening at http://localhost:8000/');
});

// Attach the socket.io server
io = sio.listen(server);

var chanelId = null
io.set('authorization', function (data, accept) {
    if (!data.query.token) {
        return accept('No token transmitted.', false);
    }
    if (!data.query.chanelId) {
        return accept('No chanelId transmitted.', false);
    }
    var token = data.query.token;
    chanelId = data.query.chanelId;
    // @todo authorize via token
    // to be continued ))
    accept(null, true);
});

var client = redis.createClient();

// Define a message handler
io.sockets.on('connection', function (socket) {

    client.subscribe("channel." + chanelId);
    client.on("message", function (channel, message) {
        //message = JSON.parse(message)

        // just catch and emit to the client
        console.log(channel + ": " + message);
        socket.broadcast.emit('message', message);
    });

});

For publishing events http://redis.io/commands/publish
For checking the queue redis-cli > monitor
Run the our server node server.js
Here’s what I eventually got

sockets

Twitter bootstrap confirm dialog

Much time has passed since my last post. Had a lot of job… So I decided to write at least a small post. Today I share with you how I implemented analog of javascript confirm dialog using twitter bootstrap.

Nothing fancy 🙂

So let’s go. As usual I like to create base app object, that will handle common tasks – dislpay errors, keep some app data etc. And I implement it confirm function for it

$(document).ready(function() {
    window.app = {
      ...
      confirm: function(title, text, callback) {
        var confirmPopupHtml;
        confirmPopupHtml = JST['app/confirm']({
          'title': title,
          'confirm_message': text
        });
        $(window.document.body).append(confirmPopupHtml);
        $('#confirmModal').modal({});
        return $('#confirm_yes').on('click', function() {
          $('#confirmModal').modal('hide');
          return callback.call();
        });
      },
    }
    ...
})

What is interesting here – as you see I use underscore _.template function to render dialog. And i just pass callback function if user confirms the action. Javascript template is following

<!-- Modal -->
<div id="confirmModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="conrirm_label" aria-hidden="true">
  <div class="modal-header">
    <button type="button" class="close" data-dismiss="modal" aria-hidden="true">Ă—</button>
    <h3 id="conrirm_label"><%= title %></h3>
  </div>
  <div class="modal-body">
    <p><%= confirm_message %></p>
  </div>
  <div class="modal-footer">
    <button class="btn danger" id="confirm_yes">OK</button>
    <button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
  </div>
</div>

And finally the example of usage.

window.app.confirm("Confirm delete", "Are you sure you want to delete selected row?", function() {
    // delete functionality
});