Boban Jovanoski

javascript handle paste event BobiYo Mar 26

1 comment Latest by nallebjörnarna

Tags: paste   javascript   rte  

How to handle the paste event in javascript. I've used this for a Rich Text Editor(RTE) paste event for a case when you don't want to paste html content but text only. Here are the steps:

First you need to bind event listener to the container (in my case body of the iframe where content is entered for the RTE.

  if (body.addEventListener){
    body.addEventListener("paste", handlepaste, false);
  } else if (el.attachEvent){
    body.attachEvent("paste", handlepaste);            
  }

The handlePasteFunction:

  function handlepaste(e) {
    var clipboardBuffer = '';

    if (e && e.clipboardData && e.clipboardData.getData) {
      if (/text\/html/.test(e.clipboardData.types)) {
        clipboardBuffer = e.clipboardData.getData('text/html');
      }
      else if (/text\/plain/.test(e.clipboardData.types)) {
        clipboardBuffer = e.clipboardData.getData('text/plain');
      }
      //using 'text/plain' is enough
    }
    else {
      clipboardBuffer = window.clipboardData.getData("Text");
      // This is how IE handles the clipoardData;
    }
    waitForPasteData(clipboardBuffer);
    if (e.preventDefault) {
      e.stopPropagation();
      e.preventDefault();
    }
    e.returnValue = false;
    return false;
  }

The waitForPasteData function actually is for making sure you have the pasted Data so it can be processed later.

      function waitForPasteData (clipboardBuffer) {
        if (clipboardBuffer != '' || body.childNodes && body.childNodes.length > 0) {
          processPaste(clipboardBuffer);
        }
        else {
          var self = {
            c: clipboardBuffer,
            timer: ''
          }
          self.timer = setTimeout(function(){
            waitForPasteData(self.c);
            clearTimeout(self.timer);
          },20);
        }
      }

      function processPaste (clipboardBuffer) {
        var postedData = sanitize(clipboardBuffer);
        if($.browser.msie === true){
          var range = iframe.contentWindow.document.selection.createRange();
          range.text = postedData;
          iframe.contentWindow.focus();
        } else {
          formatText('insertHTML', postedData);
        }
      }

In case of IE we need to use range in order to paste the data properly from the caret.

That's about it, I hope this helps somebody :)

Generating SHTML with middleman BobiYo Mar 11

6 comments Latest by remomos

Tags: shtml   frontend   middleman   haml  

Introduction

Because I wanted to improve my css skills, I've decided to spend time learning css, optimizations, the whole front-end development shebang. The latest project I worked on, the client required static web site done using SSI/Server Side Includes.

SSI/Server Side Includes ???

I knew it was something old, but I never touhght 15 years back :) as Rolad pointed that out. It is same as html but you can include content from other files (think of it as using partials in html). You can also use "bash scripting" syntax in your html, I have not look deeply into it, all I needed was to use shtml just for including content.

How to turn on SSI? Simply open your apache conf file and add +Includes in your apache options and add shtml to the known file types.

Options  +Includes
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml

How to include content using shtml? It is very simple, the syntax that the includes module will recognize is almost the same as writing comments in html. Example: (notice there is no empty space before the #):

<!--#include file="includes/header.shtml" -->

It's middleman time

After creating your middleman project (how to create new project and how to use middleman, you can check on the middleman wiki), you need to setup middleman to generate shtml files.

Middleman already does this for you, so you'll just need to name your files ending with ".shtml.haml".

The next thing that you'll need to do is to make middleman insert the required shtml syntax to include content from other files (I've used this for header.shtml and footer.shtml which were put inside the includes directory). To do this, I've defined an alias for the partial method inside middlemans config.rb file.

alias_method :shtml_partial, :partial

When the content is build I've defined the shtml_partial method like this:

def shtml_partial(*args)
   "<!--#include file=\"includes/#{args.first}.shtml\" -->"
end

Wherever the shtml_partial method is used (same as partial) instead of rendering the partials content, it will generate the required shtml include content from file. But the files inside the includes directory don't exist yet?!! For solving this, on build time, I've just copied the partials files that are used inside the includes directory.

File.copy_stream("views/_header.haml", 'views/includes/header.shtml.haml');
File.copy_stream("views/_footer.haml", 'views/includes/footer.shtml.haml');

Hint - Remember to use relative links when building :)

activate :relative_assets

Happy using Server Side Includes in 2011 :)

Feel free to comment about new sugestions. Thank you in advance.

Haml, Compass, Front-end development BobiYo Feb 19

5 comments Latest by Guido

Tags: haml   scss   sass   compass   staticmatic  

Update

Thanks to Arthur Gunn I've checked out the middleman gem and by my humble opinion it is better than staticmatic, it is sinatra based and the helpers it provides are with the same names as in rails so you'll feel right at home. I still have not played with the frank gem, I'll update this post after I take a closer look at it.

Introduction - Staticmatic

During my recent work, I needed to create only the front-end (html, css, javascript) for an application. As you may guess, I've decided to use haml and compass, but creating a rails app for doing this seamed to me just like killing an alien with Justin Bieber's music.

Implementation

So I thought...there must be an easier way to to this (save the aliens)...so I did some research and discovered Staticmatic (all features are still not well documented).

gem install staticmatic

It's very easy to use. You just need to create your new staticmatic project:

staticmatic setup project_name

Compass and haml are supported, and a default layout is already setup for you to play with. All additional configuration for staticmatic and compass is done inside the config directory. Inside the compass configuration file I've only added

http_images_path = '/images'

because when css files are generated by compass the default directory is set to stylesheets.

If you wish to use other compass plugins like 960gs or whatever simply add the scss, sass files inside the src/stylesheets dir.

So now all you need to do is power up you favorite code editor, than start compass watch and the web server and start coding :)

#on separate consoles
compass watch 
staticmatic preview project_name

When you're done with that, you can generate the html with:

staticmatic build project_name

Explore the documentation how to use the layouts etc.

Things that I missed while using staticmatic

Features that I really missed and by my opinion need to be included are:

  1. Generating sprites for images - with the sprite_css or limonade gems

  2. yield :sidebar

  3. Using other gems :) I just wanted this usability to be implemented in staticmatic rather than hacking around and doing it manually.

Easier way?

I really like using haml and compass for front-end development, if you know a better way for doing this pls comment or email me, I'll be glad to update the post.

Some Tips And Tricks BobiYo Jan 28

Post a comment

Tags: rails   console   ubuntu   tip   trick  

List Rake Routes

rake routes | sed -e "1d" -e "s,[/]*,,g" | awk '{print $1}' | sort | uniq

Remove old kernel versions - Ubuntu

I'm using Ubuntu and RubyMine for developing ror apps and after some period of time after many ubuntu updates, I feel the need to remove old kernel versions :) and this is the command I use (10x @gemidjy):

sudo apt-get remove --purge `dpkg --get-selections 'linux-*.*' | awk '$2 == "install" { print $1 }' | grep -v "$(uname -r | sed 's/\(.*\)-.*/\1/')"`

Which process is using your port?

Sometimes you can't start a server/service because the port has been already taken? - In the example we search which process is using port 3000. You can check that with:

netstat -nlp | grep 3000 
#OR
fuser -n tcp 3000

List previous commands in rails console

While developing a rails app and meanwhile experimenting in the console :), sometimes you write a bunch of stuff which are chained and hitting the up arrow can sometimes be hurtful so using this command will show you a list of your previously entered commands:

puts Readline::HISTORY.entries.split("exit").last[0..-2].join("\n")

Use last result

After you execute some command in the console lets say User.first and you forgot to put it in a variable, instead of (up arrow, home, add variable name =) you can simply write:

user = _
# _ is the result of your last command :)

SQL to Rails Console

The simple way of doing this is after starting the rails console:

ActiveRecord::Base.logger = Logger.new(STDOUT)

If you want your console to be colorful and you can see all the db queries in all your rails project without writing this all the time after starting your console, you need to add changes to your .irbrc file in your home directory. I haven't added my .dotfiles on github yet...I'll update this post and set up a link after I do that :), meanwhile you can try putting this in your .irbrc file (It's old code that I found in my tips_and_tricks.txt file - email me or comment for an update I'll gladly change it. There is a gem for doing this but I forgot which one was the coolest).

script_console_running = ENV.include?('RAILS_ENV') && IRB.conf[:LOAD_MODULES] && IRB.conf[:LOAD_MODULES].include?('console_with_helpers')
rails_running = ENV.include?('RAILS_ENV') && !(IRB.conf[:LOAD_MODULES] && IRB.conf[:LOAD_MODULES].include?('console_with_helpers'))
irb_standalone_running = !script_console_running && !rails_running
if script_console_running
   require 'logger'
   Object.const_set(:RAILS_DEFAULT_LOGGER, Logger.new(STDOUT))
end

Routes In Console

To use routes methods in your rails console you need to include and set:

include ActionController::UrlWriter
default_url_options[:host] = 'whatever'

Listing controller routes

I got this tip from my friend Dalibor. You can list routes for a single controller by running:

rake routes CONTROLLER=projects

I hope that some of the tips help. Feel free to comment, add suggestions, etc.

Build Your Own Twitter Widget BobiYo Jan 20

Comments are closed

Tags: rails   twitter   widget  

Introduction

So, You've decided to create your own auto-updating twitter widget using rails? :) I won't bla bla what and why, let me just show you how I've done it: I've used the twitter gem and I didn't use rails's periodic updater for the tweets update :)

Implementation

  • Include the twitter gem in your Gemfile
  • Include and install jquery-rails gem
  • Add a loading gif image and your tweets container(the code for the views is haml).

= image_tag "loading.gif", :id => 'twitter_loading', :alt => "Loading", :style => "display: none"
#tweets_container

  • Map a route to controller/action by your choice, in this case services/twitter and you simply get the tweets

 #inside routes.rb
 match 'services/twitter', :to => 'services#twitter', :as => 'twitter_service' 

 #inside services_controller.rb
 def twitter
   @tweets = Twitter.user_timeline(USERNAME).first(NUM_TWEETS)
    render :layout => false
  end

 #inside twitter.html.haml
 - @tweets.each do |tweet|
   %p
     = auto_link tweet.text
     %span.time= link_to time_ago_in_words(tweet.created_at + ' ago' , "http://twitter.com/#{USERNAME}/status/#{tweet.id}"

This was easy :) now all we need is to show and auto-update the widget. So in your application.js or a js file that is loaded in your page :)

var twitter = {
    container: $('#tweets_container'),
    loading_image: $('#twitter_loading'),
    update_interval: 420000, //7 minutes
    clearTimeout: function() {
        if (this.timer_id) {
            clearTimeout(this.timer_id)
        }
    },
    autoUpdate: function() {
        var self = this;
        self.clearTimeout();
        self.timer_id = setTimeout(function() {
            self.initialize();
        }, self.update_interval);
    },
    initialize: function() {
        var self = this;
        self.clearTimeout();
        if ($('#tweets_container').size() > 0) {
            $.ajax({
                type: 'post',
                url: "/services/twitter",
                data: {},
                dataType: 'html',
                ifModified: true,
                beforeSend: function() {
                    self.container.hide('slow');
                    self.loading_image.show('fast');
                },
                success: function(data, status) {
                    if (status != 'notmodified') {
                        self.container.fadeOut(1200, function() {
                            $(this).html(data);
                            $(this).fadeIn(1200);
                        });
                    }
                    self.loading_image.hide('fast');
                    self.autoUpdate();
                },
                error: function() {
                    self.loading_image.hide('fast');
                    self.autoUpdate();
                }
            });
        }
    }
};
twitter.initialize();

That's it, I hope this helps :) Your comments and suggestions are welcomed.