1

I am trying to enable row edit for a particular array of People Picker and Dropdown controls. Below is what I have so far,

<table cellSpacing="1">
            <div className={styles.tableStyle} >  
            <tr>
              <td className={styles.CellStyle}>Division</td>
              <td className={styles.CellStyle}>Assignee</td>
              <td className={styles.CellStyle}>Added by</td>
            </tr>
          </div> 
            {this.state.ListItems.reverse().map(function(item,key){
              return(<div className={styles.rowStyle} key={item.Id}> 
                <tr>
                  <td><div><Stack tokens={stackTokens}><Dropdown required={true} 
                  onChange={this._getDropdownItem1} 
                  placeholder="Select a Division" 
                  options={this.state.DivisionListItems} 
                  selectedKey={item.Division} 
                  styles={dropdownStyles}  
                  disabled={this.state.isEdit}/>
                  </Stack></div></td>
                  <td>
                    <div><PeoplePicker context={this.props.context} 
                  personSelectionLimit={3} 
                  groupName={""}  
                  showtooltip={true} 
                  tooltipMessage="Select multiple users for assigning the item" 
                  isRequired={true} 
                  disabled={this.state.isEdit} 
                  ensureUser={true} 
                  selectedItems={item.Assignee.map(assigne=>assigne.Title)} 
                  showHiddenInUI={false} 
                  principalTypes={[PrincipalType.User]} 
                  defaultSelectedUsers={item.Assignee} 
                  resolveDelay={1000} /></div></td>
                  <td></td>
                  <td><div><label className='ms-Label'>{item.Author.Title}</label></div></td>
                </tr>
                 <div className={styles.editdiv}><DefaultButton className={styles.button} onClick={()=>{this.handleEdit(item,key)}} iconProps={{iconName:'Edit'}}></DefaultButton><DefaultButton className={styles.button} onClick={()=> { if (window.confirm('Are you sure you wish to delete this item?')){this.handleDelete(item.Id)}  this.onCancel(item) }} iconProps={{iconName:'Delete'}}></DefaultButton></div>
              </div>
                 );
            }.bind(this))}
          </table>

Handle edit function below

@autobind
public handleEdit(Division,Users){
  let selectedUsers = [];
   for (let item in Users) {
     selectedUsers.push(Users[item].Title);
   }
  this.setState({editusers:selectedUsers,Dropdownvalue:Division,isEdit:false });
  console.log("event is" + event);
}

How do I give unique id to dropdown control and people picker to be able to edit and perform operations only for that row in the array map? I have already given a key for each div which is the unique item.id.

Below is the rendering : Edit is editing the entire dropdown rows instead of that selected one. enter image description here

2
  • your button's onClick is bound to {this.handleEdit(item,key)}}, but handleEdit accepts (Division,Users) as parameters. Is this intentional? Is Division equivalent to an item and Users also the key?
    – willman
    Commented Mar 9, 2020 at 17:22
  • @willman I was able to make it work like that, Yeah the naming in handleedit function parameters need to be changed :). I was able to instantiate another array and fill it up with true on start. Then on edit, I took the index and set the array[index/key] for that row and set it to false. on change wil pass the index and the true or false is set up disabled={this.state.isEdit[index]} but it is still not working even though I am able to see the change in the array from true to false.
    – ssspfx
    Commented Mar 9, 2020 at 19:02

1 Answer 1

1

In general, rather than trying to reference the control, it is better to have your controls reference unique values in State so that you just need to call setState when you want to change the way it is rendering.

I would suggest removing the isEdit State value, and adding a value such as editingItemId to your state, possibly defaulted in your constructor to zero (0) or negative one (-1).

Then, in your <Dropdown> and <PeoplePicker> control rendering, instead of setting the disabled attribute to {this.state.isEdit}, set the it with a conditional expression

disabled={item.Id === this.state.editingItemId}

You will then need to modify the setState() in your handleEdit to set editingItemId instead of isEdit. In fact, since you are already using an arrow function to pass the values, you probably no longer need a separate function, just modify the the onClick attribute in your <DefaultButton> control to the following:

onClick={()=>{this.setState({editingItemId:item.Id })}}

You haven't posted what your _getDropdownItem1 looks like, but I suspect you are going to need it to also accept the current item to know which item's value to change.

onChanged={selectedOption => { this._getDropdownItem1(item, selectedOption) }} 

You'll want to do something similar when the value of your <PeoplePicker> changes.

1
  • You are awesome!! Worked like a charm....
    – ssspfx
    Commented Mar 9, 2020 at 19:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.