Select to view content in your preferred language

JimuLayerViewSelector multi selection doesnt work as expected

785
6
10-28-2024 07:12 AM
IkelosDev
Emerging Contributor

Using ExB DE v.1.15.0

I'm currently working on a custom widget that needs to select multiple layers and get their IDs in a string array. The JimuLayerViewSelector component seemed like a suitable choice because it allowed selecting multiple layers with its isMultiSelection attribute

But, when I use the onChange callback, I noticed that it only gives me the ID of the last selected layer , and is completely empty if something is de-selected, regardless of if there are other selected layers .

This is okay for single selections, but for multi-selection, I expected to get all selected layer IDs in the array. I dont want to have to manually implement this behaviour from scratch if i dont have to.

This is my code currently:

 

import { JimuMapView, JimuMapViewComponent } from "jimu-arcgis";
import { React, type AllWidgetProps, } from "jimu-core"
import { Loading } from "jimu-ui"
import { JimuLayerViewSelector } from 'jimu-ui/advanced/setting-components';
import { useState } from "react";

const Widget = (props: AllWidgetProps<any>) => {

  const [jimuMapViewId, setJimuMapViewId] = useState<string>()
  const [selectedMapLayers, setSelectedMapLayers] = useState<string[]>()
  const activeViewChangeHandler = (jmv: JimuMapView) => {
    if (jmv) {
      setJimuMapViewId(jmv.id)
    }
  }

  const onMapLayerSelected = (selectedLayerViewIds: string[]) => {
    //selectedLayerViewIds only contains the last selection, or empty if you 
    //de-selected  a layer
    console.log(selectedLayerViewIds);
    setSelectedMapLayers(selectedLayerViewIds)
  }

  return (
    <div className="jimu-widget">
      {props.useMapWidgetIds && props.useMapWidgetIds.length === 1 && (
        <JimuMapViewComponent useMapWidgetId={props.useMapWidgetIds?.[0]} onActiveViewChange={activeViewChangeHandler} />
      )}
      
      {jimuMapViewId ? (
        <JimuLayerViewSelector jimuMapViewId={jimuMapViewId} isMultiSelection={true} onChange={onMapLayerSelected} />
      ) : (<Loading />)}
    </div>

  )
}

export default Widget

 

Tags (2)
0 Kudos
6 Replies
JeffreyThompson2
MVP Frequent Contributor

https://react.dev/learn/updating-arrays-in-state

The way you have written this, you are replacing the array every time with a new array containing a single item. You will need to re-write your function so that you are adding new items using the spread operator and removing them with the filter method. This page from the React docs should help clarify what is going on and how to fix it.

GIS Developer
City of Arlington, Texas
0 Kudos
IkelosDev
Emerging Contributor

I thought about that and i did do it that way initially

But doing it like that only tells me if a layer has been selected at some point , but i need to be able to toggle the selections.

Deselecting a layer calls the onChange callback with an empty array, not specifying which layer has been deselected, which as i said works fine with the single selection mode , but not with the multiple one

 

0 Kudos
JeffreyThompson2
MVP Frequent Contributor

You could check the selected value against the items already in the array. Something like this.

const [selectedViews, setSelectedViews] = useState([])

const handleSelection = (selected) => {
    const found = selectedViews.includes(selected)
    if (found) {
        // remove view
        setSelectedViews(selectedViews.filter(s => s !== selected))
    } else {
        // add view
        setSelectedViews([...selectedViews, selected])
}

https://www.w3schools.com/jsref/jsref_includes_array.asp

GIS Developer
City of Arlington, Texas
0 Kudos
IkelosDev
Emerging Contributor

Again, that wont work because the onChange callback passes in an empty array if anything is deselected.

this :

const found = selectedViews.includes(selected)

will always return false 

Cant check if its already in my selected array because it doesnt return anything. Its impossible to know , with this component, when a layer is deselected, or at least i havent found a way.

I ended up just recreating the component myself from scratch without using anything from jimu-ui and handling the selection the way i need it. 

0 Kudos
WenpingWang
Esri Contributor

Hi @IkelosDev 

Have you set the props `selectedValues`?

When you get values from `onChange`, you need pass it to `selectedValues`.

0 Kudos
IkelosDev
Emerging Contributor

selectedValues isnt a prop for this component, It has defaultSelectedValues, but that only gets set on first render and then never again

0 Kudos