21 Aug
duccio

duccio il 21 August 2006 parla di Ajax/Web 2.0

InPlaceEditor Select Tag

Come avrete avuto modo di osservare il controllo InplaceEditor fornisce solo il meccanismo per la generazione di text box per la modifica dei contenuti, di seguito troverete una versione modificata della ricetta presente sul libro Rails Recipes, in grado di funzionare correttamente anche con Internet Explorer.

I passi da seguire per la reazlizzazione dell’in place editor per i tag select sono i seguenti:

  • realizzare una classe javascript inplaceselecteditor
  • creare un helper ad hoc
  • utilizzare l’InplaceSelectEditor

Realizzare la classe javascript

Creare un file inplaceselect_editor.js per poterlo poi includere nei vostri progetti nella cartella /public/javascript e incollare il seguente codice:

    1 Ajax.InPlaceSelectEditor = Class.create();
    2 Object.extend(Object.extend(Ajax.InPlaceSelectEditor.prototype,
    3   Ajax.InPlaceEditor.prototype), {
    4     createEditField: function() {
    5       var text;
    6       if(this.options.loadTextURL) {
    7         text = this.options.loadingText;
    8       } else {
    9         text = this.getText();
   10       }
   11       this.options.textarea = false;
   12       var selectField = document.createElement("select");
   13       selectField.name = "value";
   14       var options=this.options.selectOptionsHTML;   
   15       var pvalue = this.options.passedValue;     
   16       for (var x=0; x < options.length; x++)
   17       {
   18         var option = document.createElement("option");
   19         option.appendChild(document.createTextNode(options[x]));
   20         option.setAttribute("value",pvalue[x]);
   21         selectField.appendChild(option);
   22       }
   23 
   24       $A(selectField.options).each(function(opt, index){
   25         if(text == opt.text) {
   26           selectField.selectedIndex = index;
   27         }
   28       }
   29     );
   30     selectField.style.backgroundColor = this.options.highlightcolor;
   31     this.editField = selectField;
   32     this.editField.style.backgroundColor="";
   33     this.editField.className= "editor_field";
   34     if(this.options.loadTextURL) {
   35       this.loadExternalText();
   36     }
   37     this.form.appendChild(this.editField);
   38   }
   39 });
   40 

Il file in_place_select_editor.js è una versione modificata di quello presente nella ricetta del Rails Recipe, che non consentiva la generazione corretta degli elementi option della select con il Browser internet Explorer.

Di seguito l’estratto della riga che creava problemi:

    1 ...
    2 selectField.innerHTML=this.options.selectOptionsHTML  ||  "<option>" + text + ""; 
    3 ...

Usando innerHTML Internet Explorer non visualizza le option una volta renderizzate, mentre con la seguente modifica non si verifica più il problema:

    1 for (var x=0; x<options .length; x++) 
    2 {
    3   var option = document.createElement("option");
    4   option.appendChild(document.createTextNode(options[x]));
    5   option.setAttribute("value",pvalue[x]);
    6   selectField.appendChild(option);
    7 }

Includere il costruttore

Includere il javascript nel layout del vostro progetto

    1 ...
    2 <%= javascript_include_tag "in_place_select_editor" %>
    3 ...

Creare un helper ad hoc

Nell’ApplicationHelper

    1 def in_place_select_editor_field(object, method, tag_options = {}, in_place_editor_options = {}) 
    2     tag = ::ActionView::Helpers::InstanceTag.new(object, method, self) 
    3     tag_options = { :tag => "span", 
    4     :id => "#{object}_#{method}_#{tag.object.id}_in_place_editor", 
    5     :class => "in_place_editor_field"}.merge!(tag_options) 
    6     in_place_editor_options[:url] = 
    7     in_place_editor_options[:url] || 
    8     url_for({ :action => "set_#{object}_#{method}", :id => tag.object.id }) 
    9     tag.to_content_tag(tag_options.delete(:tag), tag_options) + 
   10     in_place_select_editor(tag_options[:id], in_place_editor_options)
   11   end
   12 
   13   def in_place_select_editor(field_id, options = {})
   14     function =  "new Ajax.InPlaceSelectEditor("
   15     function < < "'#{field_id}', "
   16     function < < "'#{url_for(options[:url])}'"
   17     js_options = {}
   18     js_options['cancelText'] = %('#{options[:cancel_text]}') if options[:cancel_text]
   19     js_options['okText'] = %('#{options[:save_text]}') if options[:save_text]
   20     js_options['loadingText'] = %('#{options[:loading_text]}') if options[:loading_text]
   21     js_options['rows'] = options[:rows] if options[:rows]
   22     js_options['cols'] = options[:cols] if options[:cols]
   23     js_options['size'] = options[:size] if options[:size]
   24     js_options['externalControl'] = "'#{options[:external_control]}'" if options[:external_control]
   25     js_options['loadTextURL'] = "'#{url_for(options[:load_text_url])}'" if options[:load_text_url]        
   26     js_options['ajaxOptions'] = options[:options] if options[:options]
   27     js_options['evalScripts'] = options[:script] if options[:script]
   28     js_options['callback']   = "function(form) { return #{options[:with]}}" if options[:with]
   29     select_options = options[:select_options].map{|opt| escape_javascript(opt[0])}
   30     val = options[:select_options].map{|opt| opt[1]}
   31     js_options['passedValue'] = "new Array('"+val.join("','") +"')";
   32     js_options['selectOptionsHTML']= "new Array('"+select_options.join("','") +"')"
   33     function < < (', ' + options_for_javascript(js_options)) unless js_options.empty?
   34     function < < ')'
   35     javascript_tag(function)
   36   end

Utilizzare l’InplaceSelectEditor

Adesso è possibile utilizzare editor in line per i tag select, semplicemente, in un file .rhtml potrete utilizzarlo cosi:

    1 <p> 
    2     <b>Nazione: </b> 
    3     <%= in_place_select_editor_field(:contact, 
    4     :country, 
    5     {}, 
    6     :select_options => country_options_for_select) %>
    7     <%= link_to ' Back ' , :action => ' list ' %>
    8 </p>

Adesso serve la funzione che esegua la modifica del campo interessato. Siccome mi occorrevano altre funzionalità, provate a leggere questa soluzione se vi può interessare lavorare con l’in-place-select-editor e gli Array.

Scrivi un commento