jagenjo / litegraph.js

A graph node engine and editor written in Javascript similar to PD or UDK Blueprints, comes with its own editor in HTML5 Canvas2D. The engine can run client side or server side using Node. It allows to export graphs as JSONs to be included in applications independently.
MIT License
5.63k stars 634 forks source link

Validate Widget Input #489

Closed rafaellandimuux closed 2 days ago

rafaellandimuux commented 4 days ago

I am trying to validate user input in a "text" type widget. Basically, if the current value is empty, I want to signal the error and prevent the user from proceeding.

I tried exploring the onPropertyChanged method, but all without success. The user can always change the property...

`

onPropertyChanged(propertyName, currentValue, previousValue) {
    //attempt 1
    if (currentValue) {
        return false;
    }

    //attempt 2
    if (currentValue) {
        throw new Error('invalid property value'); 
    }

    //attempt 3
    if (currentValue) {
        this.setProperty(propertyName, previousValue);
    }
}

`

The closest attempt to success was the second one, where I intentionally trigger an error.

However, even in this case, if the user tries the first time, the validation works well, but if the user tries to click "OK" right after, they can enter an empty text.

I would like to know if this is the correct way to apply input validations to widgets?

atlasan commented 4 days ago

It is true that the functionality to prevent the change of the property is there but that the property menu will not use it https://github.com/jagenjo/litegraph.js/blob/0555a2f2a3df5d4657593c6d45eb192359888195/src/litegraph.js#L12196

Alternative is to custom code in the node the check and restoring of the last value (need to save internally as it is not passed in that case),

eg. this demo code should assign only the first time ( tiny code < 256 characters because was testing inside the script node :p )

this.onPropertyChanged=(prop,value,pv)=>{
  if(typeof(this.last_pv)=="undefined"){
    alert('**FIRST SET**',prop,value,pv);
    this.last_pv = value; // or whatever, just a boolean
  }else{
    alert('**PREVENT**');
    this.properties[prop] = this.last_pv;
    return false;
  }
}

image

rafaellandimuux commented 2 days ago

thanks @atlasan