Páginas

Showing posts with label jQuery. Show all posts
Showing posts with label jQuery. Show all posts

Sunday, September 18, 2011

Dynamic HTML container size with CSS + JS

Have you ever tried to make a container (let's say a span) have the size of the text dynamically, without you having to har code it? Here's how I've done it using JavaScript (actually JQuery) and some CSS.

First let's define the markup:

<span id="ruler"></span>
<div class="wrapper">
    <span class="name">Hello World</span>
    <span class="name">I am a very very very very very big string.......................</span>
    <span class="name">I am a normal string</span>
</div>  


The only thing of notice here is the span with the id ruler, this span is empty and is what is going to help us measure the string size in pixels.

Now for the javascript:


String.prototype.visualLength = function() {
    $("#ruler").html(this.toString());
    var width = $("#ruler").width();
    $("#ruler").text("");
    return width;
};

$("span.name").each(function() {
    $(this).css("width", $(this).text().visualLength());
});

This defines a new function for Strings called visualLength that puts the string in the ruler span, gets the width in pixels and cleans it. Then there is an iterator that sets the width for each of the spans we've defined to the one returned by the function.

And that is it. Now we just need some CSS, to make use of this:

span.name{
    display: block;
    border: 3px solid #FF0000; 
    margin-right:auto;
    margin-left:auto;
}    


div.wrapper{
    width: 500px;
    border: 3px solid #000;  



span#ruler{
    visibility: hidden;
    white-space:nowrap;
}  


This code makes the ruler invisible and impedes the text from wrapping. The rest is just an example of how to use this feature to center your text in an outer container. Here is a demo.

Note: The javascript code was based on a blog somewhere, but I cannot seem to find it. If someone knows the link, I'll be happy to refer it.

Thursday, February 3, 2011

jQuery-UI datepicker dynamic internationalization in Rails

The jQuery UI datepicker is internationalizable, by chosing from one of the languages in the regional array, as such:

$(selector).datepicker($.datepicker.regional['en-GB']);

As is easy to see, this changes the datepicker language to english. In order for any other language, apart from english (which is the default), to work, we need to include a javascript file that defines the strings to be shown.

We can either include all the languages (http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.8/i18n/jquery-ui-i18n.min.js), or just the ones we need, that can be found here.

So far so good. But what if we want to include only the file we need, according to the system's locale?

It's pretty simple, and it prevents a user from having to download files he is not going to use, but just the one for the language he is viewing the site.

First, you'll have to create a helper that checks the current locale and includes the file accordingly, so it can be called from the views that use the datepicker.


def include_i18n_calendar_javascript
  content_for :head do
    javascript_include_tag case I18n.locale
      when :en then "jquery.ui.datepicker-en-GB.js"
      when :pt then "jquery.ui.datepicker-pt-BR.js"
      else raise ArgumentError, "Locale error"
    end
  end
end


As you can see, this has a case that chooses the file according to the locale, an returns it to the javascript_include_tag helper that generates the HTML for the inclusion of a javascript file and places it in the header with the content_for helper.

Now you only have to call the helper in the view and add some javascript.

var counter = 0;
var locale = "
for(i in $.datepicker.regional){
  if(counter == 1)
  { locale=i; break; }
  counter++;
}


Because the regional array is not exactly an array, but an hash (or an associative array, in javascript terms), we will have to iterate through each of it's objects. The one we want is the second, that the reason for the break. This object is the string the key in that associative array for the definitions of the locale we want. In the case of the first example, it would be "en-GB".

Now, we just initialize the datepicker with this variable:


$.datepicker.setDefaults( $.datepicker.regional[ '' ] );
$( ".datepicker" ).datepicker($.datepicker.regional[locale]);


And that's it. Now your datepickers are internationalized in a dynamic way.

PS: Of course you'll need a textfield that has the HTML class datepicker (or any other you choose).

Saturday, November 6, 2010

Passing data from a jQuery script to a controller method in Rails using Ajax

First of all you have to write your script to get the data and store it in variables. This code should be written either in public/javascripts/application.js or in a new file in the same directory and then included in the HTML, like so:

<%= javascript_include_tag 'name_of_file' %>
or

<%= javascript_include_tag :defaults %>

to include the application.js file.

Have in mind though that this includes must be done after including the jquery.js, and that jQuery can affect other scripts that use prototype. Therefore, if you are using any code that needs prototype or just as a good practice, the first line of your jQuery script should be jQuery.noConflict();.

This being said, the way you pass your data to the controller is through an Ajax post, which is something like this:

$.post(path,{ "string1": variable1,"string2": array1},null,"script");

Check the jQuery documentation for more details.

The path variable should be in the form controller/action, so that the message is sent to the desired action.

The next thing to do is to create the action in the controller that will receive the message. This action can respond to different kind of requests in different ways, what I mean is that if it is an HTTP request it behaves one way, and if it is our Ajax request it behaves another.

This separation of behaviours is achieved with respond_to like this:

respond_to do |format|
format.html { redirect_to :action=>"list" }
format.js
end


As it is easily perceivable, for an HTTP request it redirects to the action named list of the same controller and renders it. What it does in the case it receives an Ajax request might not be that obvious, because the code that will be run can be written in a file called action_name.js.erb that has to be in the views/controller directory.

This file can be something as simple as this:

$("#justForTest").html('
params[:actions]
');


One last thing for this to work is that the post request in our client side script must be an Ajax request. This can be done by adding .js to each path or by adding this setup code to the top of your scripts file:


jQuery.ajaxSetup({
'beforeSend':function(xhr) {xhr.setRequestHeader('Accept','text/javascript')}
})


This should make your request work as intended. Have fun with jQuery and Ruby on Rails, which are very powerful tools for any web developer.