Scoller Infinite Wheel Implementation

Hey Elod,

I have some implementaion query for infinte wheel.

Below is my OLD implementaion which I have to convert NEW implementaion.
See below code, Created data from getAmountWheelData() method

How to handle below things in infinite ‘data’ in function.

  • START VALUE of WHEEL ?? - User Defined

  • STEP OF WHEEL ? - User Define

  • WHEEL VALUE SHOULD DESCENDING - [100-99-98-97…]

  • NEGATIVE VALUE NOT REQUIRED.

      wheels: [
      		[{
      			//OLD IMPLEMENTATION
      			data: this.getAmountWheelData(),
      			label: 'OLD Amount',
      		},{ 
      			// An infinite wheel
      			// How can I make my requirement here?
                  label: 'NEW Amount',
                  data: function (i) {
      				value: i,
                      display: i.toString(),
                  },
                  getIndex: function (value) {
      				return value;
                  }
      		}]
      	
      getAmountWheelData() {
      	// This is currunt implementation which need to change.
      	let amountArray :Array<{display: string, value: any}>;
      	
      	let amountMinimum = 0; // Will get from API response
      	let amountMaximum = 1000000; // This is not needed, Since have to implement infinite wheel
      	let step = 100; // Will get from API reponse
      
      	amountArray = [];
      	for (let i =  amountMinimum; i <= amountMaximum; i+= step) {
      	  amountArray.push({display:i.toString(), value:i});
      	}
      	
      	return amountArray.reverse();
    }
    

// Might be my question is not clear to you… Can we discuss over chat/call if not understood.

Hi @CNB_Procurement :wave:

I have some questions to better understand this use-case:

  1. What exactly should be the functionality of this wheel?
  2. What type of values ​​does the wheel contain and which values ​​do you want to disable?
  3. What exactly do you want to validate?
  4. Do you want to use an infinite wheel or a circular wheel? For the infinite wheel, the values ​​go to infinity - / +. In the case of a circular wheel, the values ​​are repeated circularly: when the wheel reaches the last value, it continues with the first.

Hello @Elod,

Please see my #Answer below according to my project requirement.

1. What exactly should be the functionality of this wheel?

#Answer :
So there will be 2 wheel
Wheel A - Labelled as ‘TotalAmount’
Wheel B - Labelled as ‘MinimumAmount’

Both Wheel display Amount value on wheel
.

2a.What type of values ​​does the wheel contain?

#Answer :
So both wheel value start from ‘startValue’ [API driven : Integer] to infinite, Interval of ‘step’ [API driven : Integer]

Eg.
startValue = 100 //Received some value from API
step = 10 //Received some value from API
So wheel value should be => 100 110 120 130 … up to infinite

Eg 2.
startValue = 500
step = 1
So wheel value should be => 500 501 502 503 … up to infinite
.

2b. Which values ​​do you want to disable?
3. What exactly do you want to validate?

#Answer :
$Validation
Validation only on Wheel B (MinimumAmount)

Wheel B (MinimumAmount) should not be greater than Wheel A (TotalAmount)

All greater values of Wheel B (MinimumAmount) should be disabled - User can’t select those value - If user try to select disabled value it should bounce back to last valid value.

//Lets understand the validation Use case

pre-requisite: Assume Both the Wheel has Values => 100 200 300 400 500 … up to infinite

case :
You open the page and see Wheel A (TotalAmount) is selected to 700 & Wheel B (MinimumAmount) is selected 500.

Now user scrolled Wheel A (TotalAmount) to 300

Then Because of $Validation - Wheel B (MinimumAmount) automatically gets selected to 300
.
4. Do you want to use an infinite wheel or a circular wheel? For the infinite wheel, the values ​​go to infinity - / +. In the case of a circular wheel, the values ​​are repeated circularly: when the wheel reaches the last value, it continues with the first.

#Answer :
Wheel should be infinite, as I said above its depend on start value (startValue) up to infinite (Positive numbers only). So this will never be circular.

##I hope it’s clear to you, If you still have doubt please let me know.

Hi @Elod OR any one from Team ,
Can you please assist here ? Need to implement on project.
Appreciate your response.

Hi @CNB_Procurement,

Here’s an example, based on your requirements. Some explanations to the code:

  • the infinite wheel values are generated by a function, which gets an index. With this index, we can generate the values on the wheels. The getIndex function is the inverse of the generate function: returns the index of a wheel value.

  • in the validation function, we need to get the max index, to update the maximum value on the second wheel. This validate function returns an object with the valid property, in which we return the values to be set on the first and the second wheel. The Math.min(values[1], maxValue) serves to, that the second wheel does not scroll up to the initial value when we change the values on the first wheel.

Code:

const startValueTotal = 20; // start value of wheel - user defined
const startValueMinim = 15; // start value of wheel - user defined

const stepTotal = 10;
const stepMinim = 5;

...

export class AppComponent {

    wheel1: any = {
        label: 'TotalAmount',
        circular: false,
        min: 0,
        data: this.generateInfiniteValuesTotal,
        getIndex: function (value) {
            return (value - startValueTotal) / stepTotal;
        }
    };

    wheel2: any = {
        label: 'MinimumAmount',
        circular: false,
        min: 0,
        data: this.generateInfiniteValuesMinim,
        getIndex: function (value) {
            return (value - startValueMinim) / stepMinim;
        }
    };

    scrollerOptions: MbscScrollerOptions = {
        display: 'inline',
        width: 150,
        wheels: [
            [this.wheel1, this.wheel2]
        ],
        showLabel: true,
        validate: (event, inst) => {

            const values = event.values;
            const maxIndex = Math.floor((values[0] - startValueMinim) / stepMinim);
            const maxValue = this.generateInfiniteValuesMinim(maxIndex).value;

            this.wheel2.max = maxIndex;

            inst.changeWheel({
                1: this.wheel2
            });

            return {
                valid: [values[0], Math.min(values[1], maxValue)]
            };
        },

        parseValue: (valueText) => {
            if (valueText) {
                return valueText.replace(/\s/gi, '').split('-');
            }
            return [startValueTotal, startValueMinim];
        }
    };

    generateInfiniteValuesTotal(i) {
        return {
            value: i * stepTotal + startValueTotal,
            display: i * stepTotal + startValueTotal
        };
    }

    generateInfiniteValuesMinim(i) {
        return {
            value: i * stepMinim + startValueMinim,
            display: i * stepMinim + startValueMinim
        };
    }
}

Hey @Elod,
I tried to implement above code to my project.
It gives below error -

  1. Cannot read property ‘stepMinim’ of undefined at generateInfiniteValuesMinim
  2. Cannot read property ‘option’ of null at mobiscroll.angular.min.js:2350

What I am missing here ? why this error on console ?