Posts Tagged With “ajax”

In Place Link Editing

Comment

I've been working on a new project that has some content management features lately. It's a pretty big project and will take months to complete. I was messing with in-place editing with prototype and scriptaculous and found that I couldn't use the default editor for managing links. Normally when you're doing in-place editing you have a single piece of text/content that you want to edit. You click on it and it brings up the form. For editing links I need to edit the URL and the anchor text. I needed to have two separate fields for this and Ajax.InPlaceEditor from controls.js wasn't entirely up to the task.

I ended up inheriting from Ajax.InPlaceEditor and altering some of the behavior to handle link editing. I feel like it's pretty much a hack job but it does what I need it to do, so it seems good enough. I felt that it would be somewhat beneficial to upload the code for in-place link editing.

I only uploaded the javascript and a html demo. The server-side stuff isn't included since this will work across different web languages. I use Pylons and Mako, for example.

You can grab the demo here: http://alwaysmovefast.com/public_svn/in_place_link_editor.

To give a short example of what I did for the server-side stuff, this could be my controller/action:

class LinksController(BaseController):
    def create(self):
        c.link = {
            'url': request.params['url'],
            'anchor': request.params['anchor'],
            'id': 'some_id'
        }
        return render('/links/create.mako')

And this is what '/links/create.mako' could look like to update the page:

<a href="${c.link['url']}">${c.link['anchor']}</a>

This is a very basic example. My create.mako actually looks something like this:

<script src="/javascripts/prototype.js"></script>
<script src="/javascripts/scriptaculous.js"></script>
<script src="/javascripts/application.js"></script>

<script>
    li = $('newlink');
    li.id = '${c.link['id']}';

    li.innerHTML = '<a href="${c.link['href']}">${c.link['anchor']}</a>';

    new_link = document.createElement('li');
    new_link.id = 'newlink';
    new_link.innerHTML = 'Insert Link';

    li.parentNode.appendChild(new_link);

    new InPlaceLinkEditor('newlink', '/links/create');
</script>

Basically what it does is update 'newlink' by changing its id to the id of the newly-created link on the server side and update the innerHTML of that object. It then creates a brand new link object and appends it to the old link's parent node. I then create a new InPlaceLinkEditor for the new 'newlink'. That's about it.

Hopefully you can find this stuff useful.

AJAX in Rails with Authenticity Token

Comment

When you use active_record_store instead of the cookie-based default, you need to uncomment the line in controllers/application.rb that says protect_from_forgery :secret => 'blah'. This makes sure all your HTML and JavaScript requests are coming from your web application. It essentially protects you from something called "Cross-site request forgery" by embedding a token into your web forms.

As a side note, it's really not giving you much security at all, but that might be better left for another blog post.

I was banging my head against the wall yesterday trying to figure out why a custom Ajax.Updater wasn't working and I kept getting an ActionController::InvalidAuthenticityToken exception. I decided to dig into the request_forgery_protection.rb file in actionpack-*/lib/action_controller and found that for custom requests, you need to include the authenticity_token yourself by taking advantage of the form_authenticity_token helper. When building the updater's request url I just added "&authenticity_token=<%= form_authenticity_token %>" to the end and everything was fine.

Another way would be to not use the forgery protection at all for that action by including this in your controller: protect_from_forgery :except => :updater

You can also completely remove forgery protection from a controller by doing skip_before_filter :verify_authenticity_token

Back to the vulnerability of your web forms: I imagine this does protect your web application from someone hosting a form on their site that posts to your site. However, if someone really wants to spam some stuff they'll scrape your page with cookies enabled on their scraping software, scrape your form's fields (which include the authenticity_token hidden field) and POST to their heart's desire.

Tagged with: ajax, ruby, rails
Twitter

davidreynolds: I just became the mayor of Uncle Jack's Billiards on @foursquare! http://4sq.com/a6yEqh