Showing posts with label Web. Show all posts
Showing posts with label Web. Show all posts

Thursday, May 22, 2008

make_resourceful and odd controller names

I've been debugging make_resourceful to try to figure out why it fails to generate an index action for a controller named NewsController. After a couple of hours I found the now slightly obvious reason in lib/resourceful/default/accessors.rb...

The singular? method returns true for "News".

A simple solution would be to define singular? in your controller and let it return false.

Example:

class NewsController < ApplicationController
def singular?; false end

make_resourceful do
actions :all
end
end


See also: More on odd controller names

Monday, March 31, 2008

In Place Editor using Scriptaculous and Prototype in Rails 2.0

I've been using the scriptaculous InPlaceEditor and thought I would share some useful snippets.

The code is setup to save on blur and being able to handle empty fields.

The creation script:

var inplace_editor_edit_hint = 'Click to edit...';

function createInplaceEditor(field, update_path, highlightcolor,
highlightendcolor, width)
{
fillIfEmpty($(field));

new Ajax.InPlaceEditor(field, update_path, {
highlightcolor: highlightcolor,
highlightendcolor: highlightendcolor,
okButton: false,
cancelLink: false,
submitOnBlur: true,
cols: width,
callback: function(form) {
input_field = form.elements[0];

// This is to ensure we don't save the edit hint if
// the user accidentally clicked an empty field
if(input_field.value == inplace_editor_edit_hint)
input_field.value = '';

return Form.serialize(form);
},
onComplete: function(transport, element)
{
fillIfEmpty(element);

if(transport.statusText != "Internal Server Error")
onEditorSuccess(); // cb

new Effect.Highlight(element, {
startcolor: this.options.highlightcolor,
endcolor: this.options.highlightendcolor
});
},
onFailure: function(element, transport) {
onEditorFailure(transport.responseText); // cb
}
});
}

function fillIfEmpty(element)
{
if(element.innerHTML == '')
element.innerHTML = inplace_editor_edit_hint;
}


In the view I have a bit of script that binds the callbacks for success and failure.

The validation errors is displayed in the error notice, this isn't exactly ideal, but works as an example of how to handle validation.


function onEditorSuccess()
{
$('error').innerHTML = '';
$('notice').innerHTML = 'Model was successfully updated.';
}

function onEditorFailure(response)
{
response = response.evalJSON();

var lines = new Array();

for(var i = 0; i < response.length; i++)
lines.push(response[i][0] + ' ' + response[i][1]);

$('notice').innerHTML = '';
$('error').innerHTML = 'Error: ' + lines.join('. ')
}


The controller code looks something like this:

def update_field
model = Model.find(params[:id])
if model.update_attributes(field_to_update => params[:value])
render :text => params[:value]
else
render :text => model.errors.to_json, :status => 500
end
end

private

def field_to_update
params[:editorId].split('_')[1]
end


And finally I create them using something like this:


<p id="prefix_title"><%= model.title %></p>
<script type="text/javascript">
createInplaceEditor("prefix_title", '/path/to/action',
"#FFFFFF", "#AAAAAA", 10);
</script>


Though I recommend wrapping it in a helper to keep it nice and DRY...

Thursday, November 8, 2007

Degrading link_to_remote

I've been learning RubyOnRails and I noticed that the 'link_to_remote' helper didn't degrade gracefully...

Here's the fix I used (Inspired by this blog post).

(in helpers/application_helper.rb)

def link_to_remote(name, options = {}, html_options = {})
unless html_options[:href]
html_options[:href] = url_for(options[:url])
end

link_to_function(name, remote_function(options),
html_options)
end

Just keep in mind that this uses a HTTP GET when javascript is disabled. A HTTP GET should not have side effects. I can't think of a good way to do a HTTP POST from a link (trigger a form-post) without using javascript.

Friday, August 17, 2007

Just a heads up on some Opera browser behavior...

I just discovered a bit of a quirk of Opera (9.01). When you read the .value of a text field and the text field contains something like "Hello <b>world</b>", opera returns "Hello <B>world</B>". I did not find any way of fixing this, except to not assume lowercase input (which seems obvious to me now :). However, I found this interesting blog post about this upcase behavior and other similar things. Just hope this post can help someone avoid the premature assumption that the browser would return what's actually there :).