I'm trying to implement in-place editing in a Rails 3 app that takes the edited value and revises a calculation based on that value. For example:
Before edit of the "credits to donate" field:
You have 10 credits remaining. Credits to donate: 0.After edit of the "credits to donate" field:
You have 5 credits remaining. Credits to donate: 5.
I have looked into various options, and it looks like the jquery-in-place-editor does what I'm looking for. For reference:
The demo works. But I think what I need to do is use the callback function to call a ruby script, so I can do some more processing. I'm not entirely sure if that's what I need to do though, so I'm looking for some guidance.
Here is the jQuery javascript (from /public/javascripts/application.js in the Sample app) that I think is relevant:
// Using a callback function to update 2 divs
$("#editme4").editInPlace({
callback: function(original_element, html, original){
$("#updateDiv1").html("The original html was: " + original);
$("#updateDiv2").html("The updated text is: " + html);
return(html);
}
});
It looks like what I need to do is take original
and html
and play around with them a bit, then feed them back to the appropriate divs. The question is, how do I do this? I'm thinking of two possibilities:
A. There is a facility in the jquery-in-place-editor to call a url. Could I use this to call a ruby script and get a result? How would I do this in rails? Here is code to call a url (again from /public/javascripts/application.js
); but it calls a php script.
$("#editme1").editInPlace({
// callback: function(unused, enteredText) { return enteredText; },
url: 'server.php',
show_buttons: true
});
B. Modify the updated text directly in javascript, and pass it to the appropriate divs. I'd prefer to use a ruby script, but maybe this would be easier.
The solution to this problem is quite complex, but I have found a way to do it. It is surprising to me that the solution is not readily available, since it does seem, as r-dub says, something that is quite common. I ended up not using any of the edit-in-place facilities of a jQuery plugin, and instead modified a text field directly with the help of jQuery on the basis of a form text field. I other words, I followed (B) above.
I have a view that looks like this:
Available: <span id="available_cr"><%= @available_credits %></span>
Remaining: <span id="remaining_cr"><%= @remaining_credits %></span>
<%= form_for(@page, :html => { :id => 'do_fvalue' }, :remote => true) do |f| %>
<div class="field">
How many to buy at <%= @cost %> credits per unit? <%= f.text_field :fvalue, :autocomplete => :off %>
</div>
<div class="field">
How many to buy at <%= @cost_20 %> credits per unit? <%= f.text_field :gvalue, :autocomplete => :off %>
</div>
<div class="actions">
<%= f.submit "Update" %>
</div>
<% end %>
I then stuff the rails @-variables into a .html.erb partial (rendered at the beginning of my page .html.erb) so that javascript/jQuery can access them:
<script type="text/javascript">
var cost = parseInt(<%= @cost %>)
var cost_20 = parseInt(<%= @cost_20 %>)
var available_credits = parseInt(<%= @available_credits %>)
var remaining_credits = parseInt(<%= @remaining_credits %>)
</script>
Then, in public/javascripts/applications.js, I have the following code:
function checkFields(){
var to_buy_f = $("#page_fvalue").val();
var to_buy_g = $("#page_gvalue").val();
var subtract_f = to_buy_f * cost;
var subtract_g = to_buy_g * cost_20;
var remain = available_credits - subtract_f - subtract_g;
$("#remaining_cr").text(remain);
};
$("#page_fvalue").keyup(function () {
checkFields();
}).keyup();
$("#page_gvalue").keyup(function () {
checkFields();
}).keyup();
The checkFields function updates #remaining_cr based on the values found in #page_fvalue and #page_gvalue. Notice that it makes use of available_credits, cost, and cost_20, which we stuffed into the javascript variables above. The last two functions tell jQuery to monitor #page_fvalue and #page_gvalue for keyup events. When the user presses a key, it calls checkFields() to update #remaining_cr.
All of this aside, when the user clicks "submit" on the form, the whole form gets submitted with the current values. I don't know whether this is the most efficient way to do what I was trying to do, but it works!