to change ui onChange event of dynamically created input boxes in react redux application

Hi There,

I have 3 dynamically constructed Textboxes (input) (Location, keyword, Contributor) on a reactjs application.   I want to filter the below list of checkboxes onChange event of input boxes (Text box).  It is a react redux application.  Please see the embedded image to have a complete idea about UI.   Please suggest how to achieve this result.

to handle onChange event of dynamically created input boxes
Please see the below code which I had done to create this gui on reactjs.

export default class SearchOptions extends Component {
  constructor(props) {
     super(props);
     //this.updateFacet = this.updateFacet.bind(this);
     this.onInputBoxChange = this.onInputBoxChange.bind(this);
  }

  /*updateFacet(key,value,isChecked) {
      console.log("updateFacet - " + isChecked);
      this.props.actions.updateFacet(key,value,isChecked,false);
  }*/

  onInputBoxChange(e,items,key) {
     items.map(i => console.log(i.value + " count (" + i.count + ")" ));
     console.log("target - " + e.target.value);
     var keysList = items.filter(i => i.value.toLowerCase().indexOf(e.target.value.toLowerCase().toString()) >= 0 ? true : false);
     console.log(keysList);
  }

  createListKeyValues() {
        const listKeyValues = (
          <div style={{marginLeft:10}}>
          {(()=>{
               return i.items.slice(0,3).map((j) => {

                  const label = j.value.charAt(0).toUpperCase() + j.value.slice(1);
                  const count = j.count && j.count > 0 ? ` (${j.count})` : '';
                        return (<label className="full-checkbox"> { `${label}${count}`}
                              <input type="checkbox" value={j.value}  checked={j.selected} key={j.value}
                                   onClick = {(e) => this.props.actions.updateFacet(i.key,j.value,e.target.checked,false)} />
                                   <span className="checkmark"></span>
                                  </label>)
                      });
          })()}
          </div>
       );

       return listKeyValues;
  }


  render() {
    
    const facet_list2 = this.props.facets.filter(i => i.items.length > 0).map((i) => {
        let inputName =  createSwitchKeySearchBox(i.key);

        //const inputBox = (<input type="text" name={inputName} placeholder={inputName} style={{marginBottom:10}} onChange={(e)=>this.onInputBoxChange(e,i.items)}/>);

        const inputBox = (<div class="inner-addon left-addon">
                             <i class="glyphicon gluphicon-search form-control-search"></i>
                             <input type="text" name={inputName} placeholder={inputName} style={{marginBottom:10}} onChange=
                                 {(e) => this.onInputBoxChange(e,i.items,i.key)} class="form-control" />
                          </div>);

        const keyText = (i.key === "subject")? "keyword":i.key;
        const byKeyText = (<span> By {keyText} </span>);

        const keySearchBox = (
               <div>
                   <div style={{textTransform: "capitalize", marginBottom: 8, display: "inline-block"}}>
                        {byKeyText}
                   </div>
                   {(inputName !== "Default") ? inputBox:null}
               </div>

        );

        const listKeyValues = (
          <div style={{marginLeft:10}}>
          {(()=>{
               return i.items.slice(0,3).map((j) => {

                  const label = j.value.charAt(0).toUpperCase() + j.value.slice(1);
                  const count = j.count && j.count > 0 ? ` (${j.count})` : '';
                        return (<label className="full-checkbox"> { `${label}${count}`}
                              <input type="checkbox" value={j.value}  checked={j.selected} key={j.value}
                                   onClick = {(e) => this.props.actions.updateFacet(i.key,j.value,e.target.checked,false)} />
                                   <span className="checkmark"></span>
                                  </label>)
                      });
          })()}
          </div>
        );

        return (
          <div key={i.key} style={{marginTop: 15}}>
             {keySearchBox}
             {listKeyValues}
             <a href="#" style={{marginLeft: 10, marginTop: 5,fontSize:"14px",fontWeight:"bold",color:'#C25518'}} onClick={() =>
                     this.props.actions.showAdvancedFacets(i.key)}>
                     {i.key === "date" ? "Specify date" : "MORE"}
             </a>
          </div>);
        });

    return (
      <div className="left-sidebar">
        <div className="title">Refine my results</div>
        <div className="facets">
          <div>
            <div className="drop_down_label">Thumbnails</div>
            <DropDownMenu value={this.props.thumbnailSize} onChange={(e, i, size) => this.props.actions.changeThumbnailSize(size)} style={{verticalAlign: "bottom"}}>
              <MenuItem value={0} label="Descriptive" primaryText="Descriptive" />
              <MenuItem value={.5} label="Small" primaryText="Small" />
              <MenuItem value={.75} label="Medium" primaryText="Medium" />
              <MenuItem value={1} label="Large" primaryText="Large" />
            </DropDownMenu>
          </div>

          <div>
            <div className="drop_down_label">Sort by</div>
            <DropDownMenu value={this.props.sortOrder} onChange={(e, i, sort) => this.props.actions.updateSort(sort)} style={{verticalAlign: "bottom"}}>
              <MenuItem value="relevance" label="Relevance" primaryText="Relevance" />
              <MenuItem value="date" label="Oldest first" primaryText="Oldest first" />
              <MenuItem value="date_descending" label="Newest first" primaryText="Newest first" />
            </DropDownMenu>
          </div>

          {facet_list2}

          {/*
            this.props.facets.length === 0 ? null :
            (
              <div style={{marginTop: 20}}><a href="#" onClick={() => this.props.actions.updateFacetBatch({})}>Reset Filters</a></div>
            )*/
          }
          {
              this.props.facets.length === 0 ? null :
              (
                  <button className="btn" onClick={() => this.props.actions.updateFacetBatch({})}>
                      <div id = "btn_container">
                          <img src="../../../static/images/reset-filters.jpg" style={{width:"30px",height:"30px"}}/>
                      </div>
                      <span>RESET FILTERS</span>
                  </button>
              )
          }
        </div>
      </div>);
  }
}

Open in new window

LVL 1
Bharath A.KAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Zakaria AcharkiAnalyst DeveloperCommented:
I'm sorry but the posted code not helping too much, If you can produce the generated HTML code I could suggest a pure JS solution.
Bharath A.KAuthor Commented:
Hi Zakaria,

      Thanks for your response.   It is an react redux application.  Basically, I am updating the state(facets) and this state should be reflected(changes) on the GUI.  I had created Actions, reducers and also updated the react components code.  I had checked the console logs on actions and reducers, it is working fine.  Now the only problem is the state (facets) is updating the components.  Once the state is updated, GUI will change.  

With Many thanks,

Bharath AK
Bharath A.KAuthor Commented:
Hi there,

Please refer the screen shot for reference

image1.png
in this react application left hand side items are stored in state called facets.  It one of text boxes I had typed Abor when I type Abor or aborigines it should filter the list of checkboxes based on what I type in the textboxes.  All complete list is stored in the state. facets.  I want to search this state.facets and filter as I type in the textbox and gui (the list of checkboxes) should change to filtered list as I type in the text box.

Could you please help in, how to do it in redux.  

It that search component

@connect ((state) => {
      return {
      facets: state.search.facets,
      }
},(dispatch) => {
     actions: bindActioncreators(action,dispatch),
 }
})

export default class SearchOptions extends Component {
  constructor(props) {
     super(props);
     //this.updateFacet = this.updateFacet.bind(this);
     this.onInputBoxChange = this.onInputBoxChange.bind(this);
  }


 onInputBoxChange(e,items,key) {
     var keysList = items.filter(i => i.value.toLowerCase().indexOf(e.target.value.toLowerCase().toString()) >= 0 ? true : false);
     var lowercaseItems = Array.from(keysList);
     var finalKeyList = [];
     items.forEach((e1)=>lowercaseItems.forEach((e2)=>{
       var item1 = e1.value;
       var item2 = e1.value.toLowerCase();
       if(item2 === e2.value) {finalKeyList.push(e1)}}));

     var facet = {
                   Key: key,
                   items: finalKeyList,
                 };

     var newFacets = Array.from(this.props.facets);
     var updatedFacets = [];

     newFacets.map((i)=> {
      if(i.key === facet.Key)
          updatedFacets.push(facet);
      else
          updatedFacets.push(i);
     });

     //this.setState(facets);
     this.props.actions.updateFacetsOnChange(updatedFacets);
}

 const inputBox = (<div className="inner-addon left-addon">
                             <i className="glyphicon gluphicon-search form-control-search"></i>
                             <input type="text" name={inputName} placeholder={inputName} style={{marginBottom:10}} onChange=
                                 {(e) => this.onInputBoxChange(e,i.items,i.key)} className="form-control" />
                          </div>);

Open in new window


in action/search.js

export function updateFacetsOnChange(facets) {
  return {type: SEARCH_UPDATE_FACETS_ONCHANGE,facets};
}

Open in new window


on reducer/search.js

export default function search(state=initialState, action) {
  switch (action.type) {

case SEARCH_UPDATE_FACETS_ONCHANGE:
      console.log('reducer - update facets ',action.facets);
      return action.facets;

    default:
      return state;
  }
}

Open in new window



But this code is not working.  Facets is not updated on the GUI I am able to see on the reducers and actions the updated list of items for checkboxes but not able to update on the components.

secondly I am doing all the update logic on components and afterward I call the action with updated list.  Please suggest me where should I code the updated logic list,  in the component, or actions or on the reducers?

Please suggest me and help me in resolving this issue.

With Many thanks,

Bharath AK
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

Bharath A.KAuthor Commented:
Hi Zakaria,

  Application is built with reacts, redux and with some Django,  Javascript is pretty less, All reactjs redux converted to a javascript file with webpack.

do you need that javascript file?  Its pretty complex to analyze that javascript file?  the file has the code of more than 10000 lines

Secondly,  I am able to get the filter list when I type in the keyword.  I get the filtered list but not able to update the gui.
When I type Abor I can get aborgines list of 3 keywords for subject. you can see from the console logs windows.  But not able the list as 3 checkboxes below Abor search keyword.

Please refer the embeded image for reference.

image1.png
Please help me in resolving this issue.

With Many thanks,

Bharath AK
Bharath A.KAuthor Commented:
Hi Zakaria,

Please find attached screen capture for reference

screen capture

I want to filter the keyword or location based on what I type on the input box with the list in the modal dialog.

I am able to get the filtered list you can see from following console log.  but I am not able to update the GUI(make the filtered list of Checkboxes) on the main window.

image1.png
When I type Abor on the input box it filters with the complete list base on the model dialog and gets the list. but not able to update the GUI on the main screen with the list of checkboxes.

you can see the html code for displaying  "by keyword" div

<div style="margin-top:15px;" data-reactid="863"><div data-reactid="864"><div style="text-transform:capitalize;margin-bottom:8px;display:inline-block;" data-reactid="865">
	<span data-reactid="866"><!-- react-text: 867 --> By <!-- /react-text --><!-- react-text: 868 -->keyword<!-- /react-text --><!-- react-text: 869 --> <!-- /react-text --></span></div><div class="inner-addon left-addon" data-reactid="870">
	<i class="glyphicon gluphicon-search form-control-search" data-reactid="871"></i>
	<input type="text" name="Keyword" placeholder="Keyword" style="margin-bottom:10px;" class="form-control" data-reactid="872">
	</div>
	</div>
	<div style="margin-left:10px;" data-reactid="873"><label class="full-checkbox" data-reactid="874"><!-- react-text: 875 --> <!-- /react-text --><!-- react-text: 876 -->Aboriginal peoples (australians) (2)<!-- /react-text --><input type="checkbox" value="aboriginal peoples (australians)" data-reactid="877">
	<span class="checkmark" data-reactid="878"></span></label><label class="full-checkbox" data-reactid="879"><!-- react-text: 880 --> <!-- /react-text --><!-- react-text: 881 -->Agriculture (1)<!-- /react-text -->
	<input type="checkbox" value="agriculture" data-reactid="882">
	<span class="checkmark" data-reactid="883"></span></label>
	<label class="full-checkbox" data-reactid="884"><!-- react-text: 885 --> <!-- /react-text --><!-- react-text: 886 -->Australian newspapers (1)<!-- /react-text --><input type="checkbox" value="australian newspapers" data-reactid="887">
	<span class="checkmark" data-reactid="888"></span></label></div>
	<a href="#" style="margin-left:10px;margin-top:5px;font-size:14px;font-weight:bold;color:#C25518;" data-reactid="889">MORE</a></div>
	
	<div style="margin-top:15px;" data-reactid="890"><div data-reactid="891">
	<div style="text-transform:capitalize;margin-bottom:8px;display:inline-block;" data-reactid="892"><span data-reactid="893"><!-- react-text: 894 --> By <!-- /react-text --><!-- react-text: 895 -->contributor<!-- /react-text --><!-- react-text: 896 --> <!-- /react-text --></span></div><div class="inner-addon left-addon" data-reactid="897">
	<i class="glyphicon gluphicon-search form-control-search" data-reactid="898"></i><input type="text" name="Contributor" placeholder="Contributor" style="margin-bottom:10px;" class="form-control" data-reactid="899"></div></div><div style="margin-left:10px;" data-reactid="900">
	<label class="full-checkbox" data-reactid="901"><!-- react-text: 902 --> <!-- /react-text --><!-- react-text: 903 -->Aagaard, jane (1)<!-- /react-text --><input type="checkbox" value="aagaard, jane" data-reactid="904"><span class="checkmark" data-reactid="905"></span></label>
	<label class="full-checkbox" data-reactid="906"><!-- react-text: 907 --> <!-- /react-text --><!-- react-text: 908 -->Carney, jodeen (1)<!-- /react-text --><input type="checkbox" value="carney, jodeen" data-reactid="909">
	<span class="checkmark" data-reactid="910"></span></label><label class="full-checkbox" data-reactid="911"><!-- react-text: 912 --> <!-- /react-text --><!-- react-text: 913 -->Cheater, graeme, 1955- (1)<!-- /react-text -->
	<input type="checkbox" value="cheater, graeme, 1955-" data-reactid="914"><span class="checkmark" data-reactid="915">
	</span></label>
	</div>
	<a href="#" style="margin-left:10px;margin-top:5px;font-size:14px;font-weight:bold;color:#C25518;" data-reactid="916">MORE</a>
	</div>

Open in new window


Please get back to me if you are unclear with the problem.

Thanks your help

With Kind Regards,

Bharath AK
Bharath A.KAuthor Commented:
Hi Zakaria,

I was not updating the state on the reducer.

once I update the state it got reflected on the main screen.

the code I had done to update the state is

return {...state,facets:updatedFacets};

Open in new window



in the component, file state is received the following code

@connect((state) => {
  return {
    facets: state.search.facets,
    initialFacets: state.search.initialFacets,
    thumbnailSize: state.search.thumbnailSize,
    sortOrder: state.search.sortOrder,
  }
}, (dispatch) => {
  return {
    actions: bindActionCreators(actions, dispatch),
  }
})

Open in new window



I missed updated the state on the reducers once updated it started to reflect on the components then it started working.

Initially, I misunderstood that, you are asking for javascript code.  apologies for the confusion.

now it is working fine.

Thanks for your help.

with kind regards,

Bharath AK

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
UI/UX

From novice to tech pro — start learning today.