Trying to delete Row from table using react.js - javascript

So what I have done here is created a table with 5 ByDefault rows for that aI created a array with 5 elements and mapped over it and I got the rows. After that I created an input field in which user can enter the number of extra rows they want, using the "increaseRow" function and the user input I push Elements in the array so that i can get that number of rows and got it as well. But when I Keep the By Default rows as it is and some new rows e.g 5 rows and try to DELETE all 10 rows it creates problem
All I want is the rows should get DELETED.
import { useState } from "react";
import Table from "react-bootstrap/Table";
import './App.css'
const App = () => {
const row1 = [];
const [row, setRow] = useState();
const [NewRow, setNewRow] = useState([1,2,3,4,5]);
const [allRowsAdded, updateAllRows] = useState(0);
const addRow = (e) => {
e.preventDefault();
setRow(e.target.value);
};
const increaseRow = () => {
for (let i = 0; i < parseInt(row); i++) {
row1[i] = allRowsAdded + i;
}
updateAllRows((allRowsAdded) => allRowsAdded + parseInt(row));
setNewRow([...NewRow, ...row1]);
};
const deleteRow = (id) => {
const updatedRows = [...NewRow].filter((rowId) => {
return rowId !== id;
});
setNewRow(updatedRows);
};
return (
<>
<div>
<form>
<input type="text" onChange={addRow} placeholder="Enter Number Of Row's" /><br />
</form>
<button onClick={increaseRow}> Add </button>
</div>
<div className="container">
<form >
<Table striped bordered hover responsive variant="light">
<thead>
<tr>
<th>
{" "}
<h6> No. </h6>{" "}
</th>
<th>
{" "}
<h6> Injection Speed </h6>{" "}
</th>
<th>
{" "}
<h6> Fill Time </h6>{" "}
</th>
<th>
{" "}
<h6> Peak Inj Press </h6>{" "}
</th>
<th>
{" "}
<h6> Viscocity </h6>{" "}
</th>
<th>
{" "}
<h6> Shear Rate </h6>{" "}
</th>
<th>
{" "}
<h6> AbsoluteDropViscocity </h6>{" "}
</th>
<th>
{" "}
<h6> %DropViscocity </h6>{" "}
</th>
<th>
{" "}
<h6> Action </h6>{" "}
</th>
</tr>
</thead>
<tbody className="grid_style">
{NewRow.map((rowId) => {
return (
<tr key={rowId}>
<td> {rowId} </td>
<td>
<input type="text" className="form-control" />
</td>
<td>
<input type="text" className="form-control" />
</td>
<td>
<input type="text" className="form-control" />
</td>
<td>
<input type="text" className="form-control" readOnly />
</td>
<td>
<input type="text" className="form-control" readOnly />
</td>
<td>
<input type="text" className="form-control" readOnly />
</td>
<td>
<input type="text" className="form-control" readOnly />
</td>
<td>
<i
className="fa fa-trash viscocity_icons"
onClick={() => deleteRow(rowId)}
>
</i>
</td>
</tr>
);
})}
</tbody>
</Table>
</form>
</div>
</>
);
};
export default App;
https://codesandbox.io/s/silly-allen-iun6b?file=/src/App.js

This is just a logical error (rowId clashes) that you are doing.
const increaseRow = () => {
for(let i=0; i < row; i++){
row1[i] = i;
}
setNewRow([...NewRow, ...row1]);
}
Here when u are assigning value to a row, you are taking index as id for that row. According to which, this is happening with rowId
and on removing a row and filtering based on rowId, for eg: id=1
const deleteRow = (id) => {
const updatedRows = NewRow.filter((rowId) => {
return rowId!== id;
})
setNewRow(updatedRows)
}
2 rows are removed with rowId=1, ie. at serial number 1 and 6.
Solution
You can correct this by adding anything for unique Keys, like uuid. Here I have used an extra state variable const [allRowsAdded, updateAllRows] = useState(0); which stores the total number of rows added from now and add the rowIds next to the addedRows.
const increaseRow = () => {
for (let i = 0; i < parseInt(row); i++) {
row1[i] = allRowsAdded + i;
}
updateAllRows((allRowsAdded) => allRowsAdded + parseInt(row));
setNewRow([...NewRow, ...row1]);
};
Now, rowIds becomes
And there will be no rowId clashes.
Code Link : https://codesandbox.io/s/quiet-snowflake-26v1o?file=/src/App.js

here is by my understanding will work,
const deleteRow = (id) => {
const updatedRows = NewRow.filter((index) => {
return index !== id;
})
setNewRow(updatedRows)
}
change your html code,
<td> <i className="fa fa-trash viscocity_icons" onClick={() => deleteRow(index)}></i> </td>
i dont know about datastructure or json of array,
const deleteRow = (id) => {
const updatedRows = NewRow.filter((e) => {
return e.id !== id;
})
setNewRow(updatedRows)
}

Related

React-Redux: Add quantity value to a table in order/cart

I am trying to create a purchase order screen and I am facing issues while adding the quantity of the product.
Workflow
a)Fetch the product details from state and get in the drop down. Select the product from drop down
b)Add the quantity in the text field. Click on Add
c)This will add the product details to a table.
But I am not sure how to set a constant quantity for each product selected.
Now when I am not sure how to add the quantity to the product selected.
Sorry, the code might be messed up, I am still learning. Adding the code below.
let count=0;
const [validated, setValidated] = useState(false);
const dispatch = useDispatch()
const [medicineName, setMedicineName] = useState('')
const [quantity, setQuantity] = useState(0)
const [tableData, setTableData] = useState([])
const productList = useSelector( state => state.productList )
const { loading, error, products } = productList
const userLogin = useSelector(state => state.userLogin)
const {userInfo} = userLogin
const [dropDownData, setDropDownData] = useState(products)
useEffect(()=>{
setDropDownData(products)
},[products])
useEffect(() => {
if(!userInfo){
history.push('/login')
}
dispatch(listProducts())
},[dispatch, history, userInfo])
const submitHandler = (e) => {
e.preventDefault()
const arr = dropDownData.filter((product) =>
product.medicineName.toLowerCase().indexOf(medicineName.toLowerCase()) > -1)
setTableData(tableData => tableData.concat(arr))
const arr2 = dropDownData.filter((product) =>
product.medicineName.toLowerCase().indexOf(medicineName.toLowerCase()))
setDropDownData(arr2)
}
return(
<>
<h2>PurchaseOrderScreen</h2>
<Form onSubmit={submitHandler} validated={validated} noValidate>
<Row>
<Col md={7}>
<Form.Group controlId='medicineName'>
<FloatingLabel controlId="floatingSelect" label="Medicine">
<Form.Control as='select' value={medicineName} className="mb-3"
onChange={(e) => setMedicineName(e.target.value)}
required
>
<option value=''>Select Medicine</option>
{dropDownData.map(product => (
<option value={product.medicineName}>{product.medicineName}</option>
)) }
</Form.Control>
</FloatingLabel>
</Form.Group>
</Col>
<Col md={3}>
<Form.Group className="mb-3" controlId='quantity'>
<FloatingLabel controlId="floatingInput" label="Quantity" >
<Form.Control type="text" placeholder="Quantity"
value={quantity}
onChange = {(e)=> setQuantity(e.target.value)}
required
/>
</FloatingLabel>
</Form.Group>
</Col>
<Col md={2}>
<Button type='submit' variant='primary'>
>Add
</Button>
</Col>
</Row>
</Form>
<Table striped bordered hover responsive='md' className='table-sm mt-3' id="table-to-xls">
<thead>
<tr>
<th><span className='btn'>Remove</span></th>
<th ><span className='btn'>Sl</span></th>
<th ><span className='btn'>Medicine</span></th>
<th ><span className='btn'>C.stock</span></th>
<th ><span className='btn'>Quantity</span></th>
<th ><span className='btn'>Low Stock</span></th>
<th ><span className='btn'>Reorder Quantity</span></th>
</tr>
</thead>
<tbody>
{tableData.map(product => (
<tr key={product._id} >
<td> X </td>
<td>{count+1}</td>
<td>{product.medicineName}</td>
<td>{product.currentStock}</td>
<td>{quantity}</td>
<td>{product.lowStockValue}</td>
<td>{product.reOrderValue}</td>
</tr>
)) }
</tbody>
</Table>
Can you please let me know how the quantity can be added. Please let me know if you need any details.
In order to add the quantity to the table, you need to store it somewhere. You have an array called tableData that you currently are adding your products to. Maybe instead of adding the products, you could add an object:
// Inside the submitHandler function
const productToAdd = dropDownData.find((product) =>
product.medicineName.toLowerCase().indexOf(medicineName.toLowerCase()) > -1);
const rowToAdd = {product: productToAdd, quantity: quantity};
setTableData(tableData => [...tableData, rowToAdd])
and then later in your render:
{tableData.map(row => (
<tr key={row.product._id} >
<td> X </td>
<td>{count+1}</td>
<td>{row.product.medicineName}</td>
<td>{row.product.currentStock}</td>
<td>{row.quantity}</td>
<td>{row.product.lowStockValue}</td>
<td>{row.product.reOrderValue}</td>
</tr>
)) }

How to dynamically update the components in ReactJS

I am new to React and I don't know how to overcome the below situation.
Let say I have to display a table.In Table <td> i have one dropdown which I got from my child component.And also have some <div> next to the dropdown.
So,for each dropdown change, i have to bind some html into that <div>.Below line is working for very first dropdown change.
ReactDOM.render(myHtml, document.getElementById(myID));
So For a second time it is not render the new html.
Kindly correct me If I did anything wrong and give me some suggestion to overcome the above issue.
Thanks in Advance.
class Home extends Component{
state = {
tableDetails:'',
};
LoadTableDetails = () => {
const getUrl = "Some API Url";
let dd= fetch(getUrl);
dd.then(response => {
return response.json();
}).then(items => {
var body = this.getTableBody(items);
this.setTableDetails(body);
});
}
getTableBody(items){
let body ;
if(items != null){
body = items.map((folder,index) =>
<tr key={index}>
<td>{folder.FolderName}</td>
<td>
<MyDropDown fileNames={folder.FileNames} folderFiles={folder.FolderFiles} id={folder.FolderName.replace(/ /g,'_')} setSelectedFile = {this.setSelectedFile}/> // Here I get dropdown selected value and see setSelectedFile method
</td>
<td>
<div id={folder.FolderName.replace(/ /g,'_')}>
////I need some html here based on the above dropdown change
</div>
</td>
<td></td>
</tr>
);
}
return folderItems;
}
setTableDetails(body){
let dd = (<div className="container" >
<h2 class="text-center">Server Details</h2>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Folder</th>
<th scope="col">Config Files</th>
<th scope="col">Config Section</th>
<th scope="col">App Settings</th>
</tr>
</thead>
<tbody>
{body}
</tbody>
</table>
</div>);
this.setState({tableDetails:dd});
}
setSelectedFile = (val) =>{
const getUrl = 'my url';
let loadItems = fetch(getUrl);
loadItems.then(response=>{
return response.json();
}).then(data=>{
let configHtml = (
<div>
<MyDropDown fileNames={data} id={val.id + path.replace('\\','_').replace('/\//g','_')} path={path} setSelectedFile = {this.getConfigSectionDetails}/>
<div className="mt-4" id={val.id + path.replace('\\','_').replace('/\//g','_')}>
</div>
</div>
);
let id = val.id; //This is the id where my new
ReactDOM.render(configHtml, document.getElementById(id)); //this line is working for my first dropdown change.If I change the dropdown again then it is not rerenered
});
}
render(){
return (
<div class="mt-4">
<div class="input-group-append">
<button class="btn btn-info" type="button" onClick={this.LoadTableDetails}>Load Table Details</button>
</div>
{this.state.tableDetails}
</div>
);
}
}
export default Home;
I got my Answer.We have to use our states to update the values and not html.
class Home extends Component{
state = {
tableDetails:'',
dropdownDetails:''
};
LoadTableDetails = () => {
const getUrl = "Some API Url";
let dd= fetch(getUrl);
dd.then(response => {
return response.json();
}).then(items => {
this.setState({
tableDetails:items
});
});
}
getTableDetails = (items)=>{
return (<div className="container" >
<h2 class="text-center">Server Details</h2>
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col">Folder</th>
<th scope="col">Config Files</th>
<th scope="col">Config Section</th>
<th scope="col">App Settings</th>
</tr>
</thead>
<tbody>
{
items.map((folder,index) =>{
return (<tr key={index}>
<td>{folder.FolderName}</td>
<td>
<MyDropDown fileNames={folder.FileNames} folderFiles={folder.FolderFiles} id=index setSelectedFile ={this.setSelectedFile}/>
</td>
<td>
<div>
{this.getConfigHtml(this.state.dropdownDetails)}
</div>
</td>
<td></td>
</tr>)
})
}
</tbody>
</table>
</div>);
}
getConfigHtml =(val)=>{
return (
<div>
<MyDropDown fileNames={val.data} path={val.path} setSelectedFile = {this.getConfigSectionDetails}/>
</div>
);
}
setSelectedFile = (val) =>{
const getUrl = 'my url';
let loadItems = fetch(getUrl);
loadItems.then(response=>{
return response.json();
}).then(data=>{
let val={
data:data,
path:val.path
};
this.setState({dropdownDetails:val});
});
}
render(){
return (
<div class="mt-4">
<div class="input-group-append">
<button class="btn btn-info" type="button" onClick={this.LoadTableDetails}>Load Table Details</button>
</div>
{this.getTableDetails(this.state.tableDetails)}
</div>
);
}
}
export default Home;

Highlighting duplicate words in an HTML page

I have a table that contains v-html results (thus the text inside the table would not be there until the page is rendered). I would like to compare two rows and if they have duplicate words then they should be highlighted.
Here is an example project of what I wanted, but way beyond the scope of what I need. My question seems most like this one in the stacks but it requires that the words be defined, I want the page to find them itself.
For example, this would be the expected output:
<table>
<tr>
<td v-html="link.orderdesciption">
order:<br />
<mark> TV </mark><br /> <!--note that the contents of the td would not appear in markup due to being v-html-->
PS3 <br />
Laptop
</td>
<td>
qty:<br />
1<br />
2<br />
1<br />
</td>
</tr>
<tr>
<td>
----------------
</td>
<td>
----------------
</td>
</tr>
<tr>
<td v-html="link.orderrecieved">
recieved:<br /> <!--same note as above, v-html only shows-->
<mark> TV </mark><br />
Desktop<br />
</td>
</tr>
</table>
I've been working on this but I have really no idea where to go from here:
var text = $('td').text(),
words = text.split(' '),
sortedWords = words.slice(0).sort(),
duplicateWords = [];
for (var i=0; i<sortedWords.length-1; i++) {
if (sortedWords[i+1] == sortedWords[i]) {
duplicateWords.push(sortedWords[i]);
}
}
duplicateWords = $.unique(duplicateWords);
Thanks for any advice,
Use reduce to get the duplicate words, then you can iterate over tds to check in the text in it is present
within the duplicate words Array. If yes, then wrap the the text in mark tag.
const tds = document.querySelectorAll('td');
const groupByOccurence = [...tds].reduce((accu, td) => {
const textArr = td.innerHTML.split('<br>').map((word) => word.trim()).filter((word) => word.length > 0 && word.match(/[a-zA-Z]+/g));
textArr.forEach((text) => {
accu[text] = (accu[text] || 0) + 1;
});
return accu;
}, {});
const duplicateWords = Object.entries(groupByOccurence).filter(([_, val]) => val > 1).map(([key, _]) => key);
tds.forEach((td) => {
const textArr = td.innerHTML.split('<br>').map((word) => word.trim());
let str = "";
textArr.forEach((text) => {
if (duplicateWords.includes(text)) {
str += '<mark>' + text + '</mark><br>';
} else {
str += text + '<br>';
}
td.innerHTML = str;
})
});
const trs = document.querySelectorAll('tr');
trs.forEach((tr, i) => {
const specialChartds = [...tr.querySelectorAll('td')].filter((td) => !td.textContent.match(/[a-zA-Z]+/g));
if (!specialChartds) {
tr.append(tds[i]);
}
});
<table>
<tr>
<td>
order:<br /> TV
<br /> PS3 <br /> Laptop
</td>
<td>
qty:<br /> 1
<br /> 2
<br /> 1
<br />
</td>
</tr>
<tr>
<td>
----------------
</td>
<td>
----------------
</td>
</tr>
<tr>
<td>
recieved:<br /> TV <br /> Desktop
<br />
</td>
</tr>
</table>
To achieve expected result, use below option
Getting all words from table by looping $('table') with each
Creating array with all duplicate words from step1 using filter method
Looping all tds with each and adding mark tag for duplicate words
var text = $('table');
var arr = [];
//Step 1: Getting All words from table
var words = text.each(function(){
let val = $(this).text().replace(/\n|\r/g,' ').split(' ').filter(Boolean);
arr.push(...val)
})
//Step 2: Finding duplicate words
let duplicate = arr.filter(function(value,index,self){ return (self.indexOf(value) !== index && isNaN(parseInt(value)) && value.match(/[A-Za-z]/) !== null)})
//Step 3: Marking duplicate words in each row
$('td').each(function(){
let val = $(this).text();
let openMark = '<mark>'
let closeMark = '</mark>'
duplicate.forEach(v => {
if(val.indexOf(v) !== -1){
var html = $(this).html().replace(v, openMark + v + closeMark)
$(this).html(html)
}
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tr>
<td>
order:<br />
TV<br />
PS3 <br />
Laptop
</td>
<td>
qty:<br />
1<br />
2<br />
1<br />
</td>
</tr>
<tr>
<td>
----------------
</td>
<td>
----------------
</td>
</tr>
<tr>
<td>
recieved:<br />
TV<br />
Desktop<br />
</td>
</tr>
</table>
codepen - https://codepen.io/nagasai/pen/YoPPMv?editors=1010

Result of map not re-rendering

I'm looking to update an array like this :
// JSX in Render
<Table size="sm" responsive striped bordered hover>
<tbody>
<tr key={-1} className="defTabCra">
<th>Date</th>
<th>Morning</th>
<th>Afternoon travaillée</th>
</tr>
{this.generateMonth()}
</tbody>
</Table>
My function generateMonth() :
generateMonth = () => {
return MyArrayOfMomentJs.map((item,i) => { // Item is a momentJS object
var jour = item.format("ddd");
jour = jour.charAt(0).toUpperCase() + jour.slice(1);
if (item.isoWeekday() > 5 || item.CheckIfholiday()) {
return (
<tr key={i} className="NotWorked">
<th>{jour + ' ' + item.format("D")}</th>
<td />
<td />
</tr>
);
}
else {
var rowContainer = [];
//Morning
if (ArrayOfBooleanForTheMorning[i] !== null) { //null means that no choices has been made
if (ArrayOfBooleanForTheMorning[i]) {
rowContainer.push(
<td key={i}>
<input type="checkbox" value="true" />
<MaterialIcon color="green" icon="check" />
</td>
);
}
else rowContainer.push(
<td key={i}>
<input type="checkbox" value="false" />
<MaterialIcon icon="close" color="red" />
</td>
);
}
else rowContainer.push(<td key={i}>
<input type="checkbox" />
<MaterialIcon icon="remove" />
</td>);
//Afternoon
if (ArrayOfBooleanForTheAfternoon[i] !== null) {
if (ArrayOfBooleanForTheAfternoon[i])
rowContainer.push(
<td key={i + 31}>
<input type="checkbox" value="true" />
<MaterialIcon color="green" icon="check" />
</td>
);
else rowContainer.push (
<td key={i + 31}>
<input type="checkbox" value="false" />
<MaterialIcon icon="close" color="red" />
</td>
);
}
else rowContainer.push(<td key={i+31}> // If null
<input type="checkbox" />
<MaterialIcon icon="remove" />
</td>);
var row = [<tr key={i}><th>{jour + ' ' + item.format("D")}</th>{rowContainer}</tr>];
return row;
}
}, this);
}
The goal is quite simple : Everytime I make a change in the ArrayOfBooleanForTheAfternoon or ArrayOfBooleanForTheMorning, I would like to re-render the component.
And now things get strange (or maybe not, you guys will tell me :p) : The function is called everytime I make a change, which is good. The map function returns an array of JSX and the content of is good aswell. However, this new array doesn't replace the actual array already rendered.
I tried to put my jsx array in a state, to put directly my funtion in the code. Nothing works.
Anyone has any idea of what is going on ?
PS: I'm using bootstrap-react for the style of the page and his layout.
Wrong usage of key prop looks to be the likely issue.
Do you have something unique in the item object.You could use that.
Instead of
<td key={i}...>
try
<td key = {item.id} ...>
where id is the key for the unique entity in the item object.
Same for the tr tag.

Sorting on a column in a table isn't working

I have a table displaying search results and I need to sort one of the columns alphabetically. When I click on a column I want the entries in that column to be sorted, but the method I implemented did not work. I also tried using Lodash's sortBy method but that still did not sort the column properly.
import React, { PropTypes, Component } from 'react';
import {
Panel,
Button,
Col,
PageHeader,
ControlLabel,
FormControl,
HelpBlock,
FormGroup,
Checkbox,
Form,
Radio,
InputGroup,
Glyphicon
} from 'react-bootstrap';
import FormControlFeedback from 'react-bootstrap/lib/FormControlFeedback';
import FormControlStatic from 'react-bootstrap/lib/FormControlStatic';
import InputGroupAddon from 'react-bootstrap/lib/InputGroupAddon';
class App extends Component {
constructor(props) {
super(props);
this.state = {
respData: []
};
this.handleSubmit = this.handleSubmit.bind(this
this.myFunction = this.myFunction.bind(this);
this.setArrow = this.setArrow.bind(this);
this.onSort = this.onSort.bind(this);
}
handleSubmit(event) {
event.preventDefault();
const form = event.target;
const data = new FormData(form);
const arrayValue = [];
var i = 0;
console.log('Data from Form:', data);
for (let name of data.keys()) {
const input = form.elements[name];
const parserName = input.dataset.parse;
const parsedValue = data.get(name);
console.log('name', name);
console.log('parsedValue', parsedValue);
if (typeof parsedValue == 'undefined' || parsedValue == null) {
console.log('Not Undefined or Not Null');
arrayValue[i] = '';
data.set(name, arrayValue[i]);
} else {
data.set(name, parsedValue);
arrayValue[i] = parsedValue;
}
i = i + 1;
}
var response_data = '';
var response_jsonObj;
var txt = '';
var req = {
RequestString: [
{
field1: arrayValue[0],
field2: arrayValue[1],
field3: arrayValue[2],
field4: arrayValue[3],
field5: arrayValue[4],
field6: arrayValue[5],
field7: arrayValue[6],
field8: arrayValue[7],
field9: arrayValue[8],
field10: arrayValue[9],
field11: arrayValue[10],
field12: arrayValue[11],
field13: arrayValue[12]
}
]
};
console.log('req string :' + req);
fetch('API_URL', {
headers: {
Accept: 'application/json, text/plain, application/xml, */*',
'Content-Type': 'application/json',
'Access-Control-Allow-Headers': 'Content-Type'
},
method: 'POST',
body: JSON.stringify(req)
})
.then(response => {
if (response.status !== 200) {
console.log('Problem in fetching');
return;
}
// this.setState({respData: response.data});
response.text().then(data => {
console.log('Data in Console', data);
response_data = data;
console.log('Response Data', response_data);
response_jsonObj = JSON.parse(response_data);
console.log('Response JSON Object', response_jsonObj);
});
})
.catch(error => this.setState({ error }));
}
myFunction() {
var input, filter, table, tr, td, i;
input = document.getElementById('search');
filter = input.value.toUpperCase();
console.log('input in searchFunction:', input);
console.log('filter in searchFunction:', filter);
table = document.getElementById('Search-Table');
console.log('table in searchFunction:', table);
tr = table.getElementsByTagName('tr');
console.log('tr in searchFunction:', tr);
for (i = 0; i < tr.length; i++) {
td = tr[i].getElementsByTagName('td')[0];
console.log('td in for before if:', tr);
if (td) {
if (td.innerHTML.toUpperCase().indexOf(filter) > -1) {
tr[i].style.display = '';
} else {
tr[i].style.display = 'none';
}
}
}
}
onSort = (column) => (e) => {
const direction = this.state.sort.column ? (this.state.sort.direction === 'asc' ? 'desc' : 'asc') : 'desc';
const sortedData = this.state.respData.sort((a, b) => {
if (column === 'Field1') {
const nameA = a.Field1.toUpperCase(); // ignore upper and lowercase
const nameB = b.Field1.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
}
});
if (direction === 'desc') {
sortedData.reverse();
}
this.setState({
respData: sortedData,
sort: {
direction,
column,
}
});
};
setArrow = (column,className) => {
let current_className = className;
if (this.state.sort.column === column) {
current_className += this.state.sort.direction === 'asc' ? ' asc' : ' desc';
}
console.log(current_className);
return current_className;
};
render() {
return (
<div id="SampleDiv">
<form onSubmit={this.handleSubmit}>
<table cellspacing="30">
<tr>
<td>
<FormGroup>
<ControlLabel>Field 1</ControlLabel>
<FormControl
id="field1"
name="field1"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td>
<FormGroup>
<ControlLabel>Field 2</ControlLabel>
<FormControl
id="field2"
name="field2"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td>
<FormGroup>
<ControlLabel>Field 3</ControlLabel>
<FormControl
id="field3"
name="field3"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
</tr>
<tr>
<td>
<FormGroup>
<ControlLabel>Field 4</ControlLabel>
<FormControl
id="field4"
name="field4"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td>
<FormGroup>
<ControlLabel>Field 5</ControlLabel>
<FormControl
id="field5"
name="field5"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td>
<FormGroup>
<ControlLabel>Field 6</ControlLabel>
<FormControl
id="field6"
name="field6"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
</tr>
<tr>
<td>
<FormGroup>
<ControlLabel>Field 7</ControlLabel>
<FormControl
id="field7"
name="field7"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td>
<FormGroup>
<ControlLabel>Field 8</ControlLabel>
<FormControl
id="field8"
name="field8"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td>
<FormGroup>
<ControlLabel>Field 9</ControlLabel>
<FormControl
id="field9"
name="field9"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
</tr>
<tr>
<td>
<FormGroup>
<ControlLabel>Field 10</ControlLabel>
<FormControl
id="field10"
name="field10"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td>
<FormGroup>
<ControlLabel>Field 11</ControlLabel>
<FormControl
id="field11"
name="field11"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td>
<FormGroup>
<ControlLabel>Field 12</ControlLabel>
<FormControl
id="field12"
name="field12"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
</tr>
<tr>
<td>
<FormGroup>
<ControlLabel>Field 13</ControlLabel>
<FormControl
id="field13"
name="field13"
type="text"
placeholder="Enter Text"
/>
</FormGroup>
</td>
<td />
<td>
<FormGroup>
<Button bsStyle="primary" type="submit">
Search{' '}
</Button>
{' '}
<Button bsStyle="primary" type="reset">
Clear{' '}
</Button>
</FormGroup>
</td>
</tr>
</table>
<div className="row ng-scope">
<div className="col-lg-15">
<Panel header={<span>Search Results</span>}>
<div
id="dataTables-example_filter"
className="dataTables_filter"
>
<label htmlFor={'search'}>
Search:
<input
type="search"
className="form-control input-sm"
placeholder=""
aria-controls="dataTables-example"
id="search"
onKeyUp={this.searchFunction}
/>
</label>
</div>
<div className="table-responsive">
<table
id="Search-Table"
className="table table-striped table-bordered table-hover"
>
<thead>
<tr>
<th className="sorting_asc" onClick={this.onSort('Field 1','asc')} aria-sort="ascending"
aria-label="Field1 :activate to sort column descending"
aria-controls="dataTables-example"
rowSpan="1"
colSpan="1"
tabIndex="0">Field 1
<span className={this.setArrow('Field 1')}></span>
</th>
<th>Field 2</th>
<th>Field 3</th>
<th>Field 4</th>
<th>Field 5</th>
<th>Field 6</th>
<th>Field 7</th>
<th>Field 8</th>
<th>Field 9</th>
<th>Field 10</th>
</tr>
</thead>
<tbody>
{this.state.respData.map((item, i) => {
return (
<tr key={i}>
<td> {item.Field1}</td>
<td> {item.Field2}</td>
<td> {item.Field3}</td>
<td> {item.Field4}</td>
<td> {item.Field5}</td>
<td> {item.Field6}</td>
<td> {item.Field7}</td>
<td> {item.Field8}</td>
<td> {item.Field9}</td>
<td> {item.Field10}</td>
</tr>
);
})}
</tbody>
</table>
</div>
</Panel>
</div>
</div>
</form>
</div>
);
}
}
export default App;
In your code
if (column === 'Field1') {
const nameA = a.Field1.toUpperCase(); // ignore upper and lowercase
const nameB = b.Field1.toUpperCase(); // ignore upper and lowercase
if (nameA < nameB) {
return -1;
}
if (nameA > nameB) {
return 1;
}
// names must be equal
return 0;
}
You're comparing strings as if they were numbers. This is not the right way to compare strings in javascript.
You should use
if (column === 'Field1') {
return a.Field1.toUpperCase().localeCompare(b.Field1.toUpperCase());
}
You can read more about localeCompare on the MDN docs

Categories