2017-03-02 21 views
5

Mam combobox w którym można wybrać pewien przedział czasowy, np:combobox który automatycznie koryguje wartość

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

Zawsze transmituje liczbę minut do serwera, ale byłoby miło użytkownika t zrozumieć, co oznacza "10080" (zanim spróbujesz obliczyć: jest to tydzień).

Nowym wymaganiem jest to, że użytkownik powinien móc wpisywać dowolne wartości w tym polu. Na przykład. "20 minut", "1 godzina 5 minut", "2h 5m" lub "1d 6h 120m"; i że jeśli pole jest ustawione programowo na pewną wartość (np. 75), pole powinno pokazywać poprawny ciąg (1 godzina 15 minut).

Napisałem więc parser i funkcję formatowania (patrz poniżej), ale w jaki sposób mogę uzyskać moje combobox, aby z nich korzystać?

Próbowałem już nadrzędnymi parę funkcji rawToValue/valueToRaw, podobny do tego, co znalazłem w kodzie 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); 
}, 

ale nie są one nazywane, nie otrzymuję żadnych danych wyjściowych dziennika konsoli.

Są to funkcje parser/formater:

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

Czy możesz zapewnić skrzypce? – Harshal

+0

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

Odpowiedz

1

Główną ideą jest, że Ext.form.field.ComboBox wartość jest faktycznie instancja Ext.data.Model, więc swoją wartość i wartość wyświetlana jest tylko modelem wartości atrybutów i za każdym razem po zmianie wartości/wyświetlaną wartość musisz zaktualizować instancję binded modelu (to moja wizja, popraw mnie jeśli się mylę).

myślę że Ext.form.field.ComboBox.validator jest miłe miejsce analizować ręcznie wprowadzane wartości (i można natychmiast wyświetlić komunikat o błędzie, jeśli wprowadzone wartość jest niepoprawna), więc można zastąpić go tak:

   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; 
        } 
       } 

Jego dość surowy przykład, ale myślę, że ten pomysł jest jasny.

Do wartości formacie setted programowo poprzez setValue() metody można przesłonić tej metody, tak:

 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]); 
     } 

sprawdzić ten fork of your fiddle. Mam nadzieję, że trochę pomogłem.

Powiązane problemy