How to control other elements on page using sp-checkbox

How i can control sp-checkbox status using another sp-checkbox button? I need to make Cyan, Magenta, Yellow and Black checked automatically when I click on CMYK, please help me how to that using react?

Here is my code

import ps from "photoshop";

const Channels = () => {
var channelsArray = []
function channels() {
    var channelsLength = ps.app.activeDocument.channels.length;
    var channels = ps.app.activeDocument.channels;
    for(var i=0; i<channelsLength; i++){
            (channels[i].kind === "component"||channels[i].kind === "spot")? channelsArray.push(channels[i].name):null;
    }
}
channels()
    return(
        <>
            <div className="toolName">Channels</div>
            <div className="board">
            {
                 <sp-checkbox>CMYK</sp-checkbox>
            }
            {channelsArray.map((e,index)=>{
                        return(
                                <sp-checkbox key={index} size="m">{e}</sp-checkbox>
                        )
                    })}
            </div>
        </>
    )
}

export default Channels;

For example, this is a component written with the following rules

  • If CMYK is checked, then Cyan/Magenta/Yellow/Black will all be checked
  • If CMYK is not checked, then the check status of each color is used
  • Spot will have a state regardless of CMYK

This is probably not the rule you intend, but look at it as an example of how to write a condition. And this is written in Preact, but it should work if you replace the import statement and Fragment for React.

import { h, Fragment } from 'preact' ;
import { useState } from 'preact/hooks' ;

import photoshop from 'photoshop' ;
const { app } = photoshop ;

export const Channels = () => {
  const tempChannelsState = Array.from(app.activeDocument.channels)
    .filter((aChannel) => {return ['component', 'spot'].includes(aChannel.kind)})
    .map((aChannel) => { return {name: aChannel.name, kind: aChannel.kind, checked: false} }) ;

  const [cmykChecked, setCmykChecked] = useState(false) ;
  const [channels, setChannels] = useState(tempChannelsState) ;

  return (
    <Fragment>
      <div className='toolName'>Channels</div>
      <div className='board'>
        <sp-checkbox
          checked={cmykChecked}
          onClick={ (event) => {setCmykChecked(event.target.checked)} }
        >
          CMYK
        </sp-checkbox>

        { channels.map( (aChannel, index) => {
            return (
              <sp-checkbox
                key={index}
                size='m'
                checked={ (cmykChecked && aChannel.kind !== 'spot') ? true : aChannel.checked } // write your rules here
                onClick={ (event) => {
                  const newChannelsState = JSON.parse(JSON.stringify(channels)) ;
                  newChannelsState[index].checked = event.target.checked ;
                  setChannels(newChannelsState) ;
                } }
              >
                {aChannel.name}
              </sp-checkbox>
            ) ;
        }) }
      </div>
    </Fragment>
  )
} ;
2 Likes

Thank you for answering, you really helped me.
I removed fragment and code works, but it’s not toggle off and on when clicking again.
I make some changes and it works now, I believe that my code must be much cleaner, but it is enough for my needs :blush:

import ps from "photoshop";

const Channels = () => {
var channelsArray = []
function channels() {
    var channelsLength = ps.app.activeDocument.channels.length;
    var channels = ps.app.activeDocument.channels;
    for(var i=0; i<channelsLength; i++){
            (channels[i].kind === "component"||channels[i].kind === "spot")? channelsArray.push(channels[i].name):null;
    }
}
channels()
var cmykArray = ["Cyan","Magenta","Yellow","Black"]
function checkHandler(){
  if( document.querySelector("#cmyk").checked === true ){
      cmykArray.forEach(function(e) {
          document.querySelector(`#${e}`).checked = true;
        });
  }
  else if( document.querySelector("#cmyk").checked === false ){
     cmykArray.forEach(function(e) {
          document.querySelector(`#${e}`).checked = false;
        });
  }
}
    return(
        <>
            <div className="toolName">Channels</div>
            <div className="board">
            {
                 <sp-checkbox id="cmyk" onClick={()=>checkHandler()}>CMYK</sp-checkbox>
            }
            {channelsArray.map((e,index)=>{
                        return(
                                <sp-checkbox key={index} id={e} size="m">{e}</sp-checkbox>
                        )
                    })}
            </div>
        </>
    )
}

export default Channels;

You shouldn’t use JS to manipulate DOM in React. Use state instead - much cleaner and more simpler when you get it. That whole JS block with loops would be gone

2 Likes