Update request with in place select editor

Following the train of my past two posts, I am continuing to work on enabling a page to handle multiple in place editors with a RESTful controller on the backend. Today, I needed to utilize an in place select editor (instead of text) to allow the user to pick from a collection of options (in this case, cities).

Earlier in the project, I had used a script that I found on the Scriptaculous wiki on the Ajax.InPlaceEditor page. For my purposes at the time, it was adequate. In today’s scenario, I found that I would not be able to (1) make a PUT request and (2) include the parameters needed by my RESTful controller – the new value and the name of the attribute to be updated.

After some digging, I found that Scriptaculous had added an Ajax.InPlaceCollectionEditor in version 1.5.3 (or something) that seemed to be more robust, being based on the InPlaceEditor. I quickly put together the following code, based on my earlier work in creating a similar in place text editor:

new Ajax.InPlaceCollectionEditor('user_profile_1_office',
'http://myurl/profiles/1',
{
collection:[[1, 'Chicago'],[2, 'Bangalore'],[3, 'London']],
ajaxOptions:{ method:'put' },
callback:function(form, value) { return 'attr=office&value='+escape(value) }
});

Unfortunately, this did not work. Upon reviewing the Rails logs, I found that while the value was submitted (as the parameter “value”), the attribute name was not. This indicated that my callback (used to include the additional parameter in the request) was not being called.

A review of the Scriptaculous library’s control.js file showed that the Ajax.InPlaceCollectionEditor was in fact overriding my callback with one of its own that only submitted the value. I commented out of the following lines and my callback worked as expected:


this.options.callback = function(form, value) {
return "value=" + encodeURIComponent(value);
}

This does, of course, open a question around long term support for the solution. Although a ticket has been opened against this issue, it has not been fixed yet. If we upgrade to a new version of Scriptaculous, we will also break our user profile update functionality. For now, we’ll go with it.

Finally, we wrapped the Javascript above in a Rails helper and we were ready to roll.

Advertisements

Generating a PUT request for an AJAX in place editor – part II

Looks like I jumped the gun on my post yesterday afternoon, I did end up needing to include a parameter name for another AJAX in place editor…

Changing the parameter name of the submitted value in the AJAX in place editor required a bit of trickery that I have used before – using the :with option in the Rails tag to include some inline Javascript to “look up” the value on the page before sending the request.

To illustrate, let’s take an example of wanting to change a user’s job title using an inline editor from “supervisor” to “manager” via the UserProfilesController that follows REST principles.

Controller

# assumes request is from an in place editor with only one attribute to update
def update
@user_profile = UserProfile.find(params[:id])
@user_profile.update_attribute(params[:attr].to_sym, params[:value])
end

View

<span id="<%= dom_id(@user_profile) %>"><%= @user_profile.jobtitle %></span>
<%= in_place_editor dom_id(@user_profile),
:url => user_profile_url(@user_profile),
:options => "{ method:'put' }",
:with => "'jobtitle='+escape($F(Form.findFirstElement(form)))" %>

The magic here is in the :with option in the in_place_editor tag. We are leveraging the callback option in the Ajax.InPlaceEditor, which creates a function that will be called just before the request is sent to the server. The Rails helper only passes one parameter to the callback function that is a pointer to the HTML form element, we need to utilize a little Javascript to look up the value of the in place input field.

Now, our controller will receive a parameter with the correct name in the request. Although I did not do it here, our controller code could also be made to handle arbitrary parameter names in the #update action.


Generating a PUT request for an AJAX in place editor

Earlier today, I was working on adding an in place editor field to our application (my manager is a big fan) and found (1) that they don’t mesh well with REST principles and (2) getting them to generate PUT requests for RESTful updates isn’t overly intuitive.

After some quick Googling, I found a comment from Josh Susser on the same problem – not being able to create a PUT request nor change the parameter name. For me, the latter is not as much of an issue as the field I am trying to change in my model is in fact called “value,” which just happens to be the parameter that the in place editor sends in the request. The remaining question was how to generate a PUT request. Another comment on the aforementioned site claimed to offer a solution, but it did not work for me. After digging through the Rails Javascript macro helpers, I found the following solution:


in_place_editor "my_dom_id",
:url => "my_url",
:options => "{ method:'put' }"

This in place editor does in fact generate a PUT request that is routed (correctly) to the #update action in my controller. Since the parameter name is not an issue for me, I have not tried to figure that one out yet, but you might be able to use the :with option in the Rails helper to pass the parameter correctly.


Styling "Browse…" button on file input fields

So this first post isn’t about Ruby or Rails, but something that I’ve struggled to figure out for some time now…how to style that silly “Browse…” button that appears when you create a file upload field in an HTML form.

Quirksmode proposes two solutions, one CSS-based and other reliant on Javascript. My preference is the CSS technique as Javascript tends to be more hit or miss:


div.fileinputs {
position: relative;
}

div.fakefile {
position: absolute;
top: 0px;
left: 0px;
z-index: 1;
}

input.file {
position: relative;
text-align: right;
-moz-opacity:0 ;
filter:alpha(opacity: 0);
opacity: 0;
z-index: 2;
}

<div class=”fileinputs”>
<input type=”file” class=”file” />
<div class=”fakefile”>
<input />
<img src=”search.gif” />
</div>
</div>


Getting Started

I’ve been meaning to start posting my Rails learnings/thoughts somewhere for awhile now. Being to busy (and cheap) to get a new domain name and set-up blogging software on my hosting provider, I decided to do it for free on Blogger.

More to come…