2017-03-02 1 views
5

J'ai un combobox dans lequel on peut choisir un certain laps de temps, par exemple:Une combobox qui corrige automatiquement la valeur

5 minutes 
15 minutes 
1 hour 
2 hours 
1 day 
2 days 
1 week 
2 weeks 

Il transmet toujours le nombre de minutes au serveur, mais l'utilisateur wouldn » t comprendre ce que signifie "10080" (avant d'essayer de calculer: c'est une semaine).

Une nouvelle exigence est que l'utilisateur devrait être capable de taper des valeurs arbitraires dans cette boîte. Par exemple. "20 minutes", "1 heure 5 minutes", "2h 5m" ou "1d 6h 120m"; et que, si le champ est fixé à une certaine valeur (par exemple 75) par programme, le champ doit montrer la chaîne correcte (1 heure 15 minutes)

J'ai donc écrit un analyseur et une fonction de formatage (voir ci-dessous), mais comment puis-je obtenir ma combobox pour les utiliser?

je l'ai déjà essayé redéfinissant la paire de fonction rawToValue/valueToRaw, semblable à ce que je trouve dans le code datefield:

rawToValue:function(rawValue) { 
    console.log('rawToValue'); 
    console.log(rawValue); 
    return this.parse(rawValue) || rawValue || null; 
}, 
valueToRaw:function(value) { 
    console.log('valueToRaw'); 
    console.log(value); 
    return this.format(value); 
}, 

mais ils ne sont pas appelés, je ne suis pas sortie du journal de la console.

Ce sont les parser/fonctions formatter:

Ext.define('AlarmTimeField',{ 
    extend:'Ext.form.field.ComboBox', 
    format:function(minutes) { 
     var a = []; 
     Ext.each(this.units, function(unit) { 
      if(minutes >= unit.minutes) { 
       var unitCount = Math.floor(minutes/unit.minutes); 
       console.log(unitCount); 
       minutes = minutes-unitCount*unit.minutes; 
       a.push("" + unitCount + " " + (unitCount==1?unit.singular:unit.plural)); 
      } 
     }); 
     return a.join(' '); 
    }, 
    parse:function(input) { 
     if(!input) return 0; 
     var me=this, 
      inputSplit = input.split(' '), 
      value = 0, 
      lastNum = 0; 
     Ext.each(inputSplit,function(input) { 
      if(!input) return; 
      else if(Ext.isNumeric(input)) lastNum = input; 
      else if(Ext.isNumeric(input[0])) { 
       var inputUnit = input.slice(-1), 
        inputValue = input.slice(0,-1); 
       Ext.each(me.units,function(unit) { 
        if(inputUnit==unit.abbr) { 
         value+=unit.minutes*inputValue; 
        } 
       }); 
      } 
      else { 
       Ext.each(me.units,function(unit) { 
        if(input==unit.singular || input==unit.plural || input==unit.abbr) { 
         value+=unit.minutes*lastNum; 
        } 
       }); 
      } 
     }); 
     return value; 
    }, 
    units:[{ 
     minutes:10080, 
     abbr:'w', 
     singular:'week', 
     plural:'weeks' 
    },{ 
     minutes:1440, 
     abbr:'d', 
     singular:'day', 
     plural:'days' 
    },{ 
     minutes:60, 
     abbr:'h', 
     singular:'hour', 
     plural:'hours' 
    },{ 
     minutes:1, 
     abbr:'m', 
     singular:'minute', 
     plural:'minutes' 
    }] 
}); 
+0

Pouvez-vous fournir un violon pour cela? – Harshal

+0

https://fiddle.sencha.com/#view/editor&fiddle/1r95 – Alexander

Répondre

1

L'idée principale est que Ext.form.field.ComboBox valeur est en fait instance de Ext.data.Model, de sorte que votre valeur et la valeur affichée est l'attribut juste modèle valeurs et chaque fois que vous changez la valeur/valeur affichée, vous devez mettre à jour l'instance du modèle lié (c'est ma vision, corrigez-moi si je me trompe).

Je pense que Ext.form.field.ComboBox.validator est bel endroit pour analyser les valeurs entrées manuellement (et vous pouvez afficher instantanément un message d'erreur si la valeur entrée est incorrecte), de sorte que vous pouvez remplacer comme ceci:

   validator: function (value) { 
        // TODO: Add regexp value format validator 

        var minutes = me.parse(value); 
        // Add check for zero/empty values if needed 
        if (minutes === 0) 
        // Add meaningful error message 
         return 'Incorrect input'; 
        else { 
         me.setValue(Ext.create('Ext.data.Model', { 
          value: minutes, 
          text: value 
         })); 
         return true; 
        } 
       } 

Son tout à fait exemple brut, mais je pense que cette idée est claire.

Pour les valeurs de format setted via setValue() programatically méthode, vous pouvez remplacer cette méthode, comme ceci:

 setValue: function (value) { 
      // TODO: Add array of values support 
      if (Ext.isNumber(value)) 
       value = Ext.create('Ext.data.Model', { 
        value: value, 
        text: this.format(value) 
       }); 

      this.callParent([value]); 
     } 

Cocher cette fork of your fiddle. J'espère que j'ai aidé un peu.