Avatar of coder
coder
Flag for Australia asked on

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

UI/UXHTMLCSSJavaScriptWeb Development

Avatar of undefined
Last Comment
coder

8/22/2022 - Mon
Zakaria Acharki

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.
coder

ASKER
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
coder

ASKER
Hi there,

Please refer the screen shot for reference

 

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
Experts Exchange has (a) saved my job multiple times, (b) saved me hours, days, and even weeks of work, and often (c) makes me look like a superhero! This place is MAGIC!
Walt Forbes
coder

ASKER
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.

 

Please help me in resolving this issue.

With Many thanks,

Bharath AK
coder

ASKER
Hi Zakaria,

Please find attached screen capture for reference


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.

 

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
ASKER CERTIFIED SOLUTION
coder

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question