Showing posts with label prototype. Show all posts
Showing posts with label prototype. Show all posts

Wednesday, May 18, 2011

Scriptaculous Slider in Rails3 form

So there is an excellent slider. http://madrobby.github.com/scriptaculous/slider/ It is perfect to set up a select form element where values are predefined numbers or integers. First you have to download http://script.aculo.us/downloads the slider.js file and move it to the /public/javascripts directory. Then insert this row in your layout, /app/views/layouts/application.html.erb after the defaults.

<%= javascript_include_tag "slider.js" %>

Then we define CSS style for the slider as the same as at the script.aculo.us homepage. (/app/public/stylesheets/style.css)

div.slider {
 width:256px;
 margin:10px 0;
 background-color:#ccc;
 height:10px;
 position: relative;
}

div.slider div.handle {
 width:10px;
 height:15px;
 background-color:#f00;
 cursor:move;
 position: absolute;
}

Then we create a helper for it. (/app/helpers/application_helper.rb)

def slider(attributes={})
  unless attributes.nil? then
  values=attributes[:values]
  default_value=attributes[:default_value].to_s
  object=attributes[:object].to_s
  instance=attributes[:instance].to_s
  unit=attributes[:unit] || ""
  text_div_id=object + "_" + instance + "_slider_text_div"
  slider_id=object + "_" + instance + "_slider"
        
  concat(raw(
    "<div id=\"#{slider_id}\" class=\"slider\">
       <div class=\"handle\"></div>
     </div>"
  ))

  concat(raw(hidden_field(object, instance, :value => default_value.to_i)))
  concat(raw("<div id=\"#{text_div_id}\">" + default_value + " " + unit + "</div>"))
        
  js_text = <<JS3
  (function() {
    var zoom_slider = $('#{slider_id}');
    var text_div = $('#{text_div_id}');
    var hidden_item = $('#{object + "_" + instance}');
    var values=#{values.inspect};
    
    var values_length = values.length;
    var min=40;
    var max=200;

    var unit = Math.ceil((max - min) / values_length);
    var range = $R(min, max - unit);

    var pix_values = new Array();
    for(i=1;i<=values_length;i++){
      pix_values[i-1]=min + (unit * (i - 1));
    }
        
    var default_value=pix_values[#{values.index(default_value.to_i)}];

    new Control.Slider(zoom_slider.down('.handle'), zoom_slider, {
      range: range,
      sliderValue: default_value,
            increment: unit,
            values: pix_values,
      onSlide: function(value) {
                text_div.innerHTML=values[pix_values.indexOf(value)] + " #{unit}";
                hidden_item.value=values[pix_values.indexOf(value)];
      },
      onChange: function(value) { 
                text_div.innerHTML=values[pix_values.indexOf(value)] + " #{unit}";
                hidden_item.value=values[pix_values.indexOf(value)];
      }
    });
  })();
        
JS3
      concat(raw(javascript_tag(js_text)))
  end
end

Then just define your form element in your view / form:

<table><tbody><tr><td>
<% slider :object        => "config",
          :instance      => "mem_size",
          :unit          => "MB",
          :values        => [512, 1024, 1536, 2048, 2560, 3072, 4096].sort,
          :default_value => 1024 %>
</td></tr></tbody></table>

That"s all! Questions?

Thursday, March 3, 2011

How to submit an ajax form in javascript with Rails3 and Prototype

So there is a Rails 3 problem, when you want to submit a form in javascript (without a submit button), it is working on normal way, not ajax. But we can do creating a hidden submit button and then initializing a click event on it what is exactly doing ajax submission. The submit(); is not working anymore because it doesn't call the rails.js functions. It just works when you simple want to create a not ajax post without any confirmation. Let's see an ajax example in view's index.html.erb file:

<%= form_tag "some_url",
 :remote  => true,
 :method  => :post,
 :name  => "some_procedure",
 :id   => "some_procedure" %>
<%= submit_tag 'procedure_submit_button', :id =>"procedure_submit_button" , :style => "display: none" %>

You can add here your html code for form and create some element what is doing the submission inside a table, for a td:

<td onclick="javascript: procedure_init();" style="cursor: pointer;">

put here an image for example

</td>

</form>

<%= javascript_tag <<-RUBY
function procedure_init()
{
 var submit_button="procedure_submit_button";
 var form_name="some_procedure";
 // here you can build the form, or modify form parameters
 $(submit_button).click();
}
RUBY
%>

If you have problems with sessions or current_user quits within ajax rendering, put this code to public/javascripts/application.js. /thanks to this answer/

document.observe("dom:loaded", function() {
 Ajax.Responders.register({
  onCreate: function(request) {
   var csrf_meta_tag = $$('meta[name=csrf-token]')[0];
   if (csrf_meta_tag) {
    var header = 'X-CSRF-Token',
      token = csrf_meta_tag.readAttribute('content');

    if (!request.options.requestHeaders) {
     request.options.requestHeaders = {};
    }
    request.options.requestHeaders[header] = token;
   }
  }
 });
});

That's all. Questions?