React Js select list to have own value - reactjs

I have rows of selects lists, when I change a list on one row, the lists for the whole table column change, is there a way each select list can have its own selected option?
I an rendering each row component use the following schema:
tableRowScheme: [
{"column":"levelId",
"title":"Level",
"type": "select",
"optionData": this.state.gradeOptions,
"afterChange": this.onLevelSelect,
"className": "col-md-1"},
{"column":"subjectId",
"title":"Subject",
"type": "select",
"optionData": this.state.subjects,
"afterChange": this.onSubjectSelect,
"className": "col-md-1"},
Then Im rendering each select list
case 'select': {
var optionsData = cellData.optionData ? cellData.optionData : [];
if(cellData.isRowInEditMode && !cellData.isNonEditable) {
return (
<div>
<TableDropdown columnName={cellData.column}
staticElements={this.props.staticElements}
optionsData={optionsData}
staticElementId={cellData.selectTypeId}
defaultValue={parseInt(this.state.rowDataStack[cellData.column])}
className="input-sm"
handleSelect={this.onDropdownChange}/>
<Input type="hidden" ref={cellData.column} standalone={true}
defaultValue={parseInt(this.state.rowDataStack[cellData.column])} />
</div>
);
Then each dropdown has this.onDropdownChange :
onDropdownChange: function(data){
var localRowDataStack = _.cloneDeep(this.state.rowDataStack);
localRowDataStack[data.filterName] = data.filterVal;
this.setState({
rowDataStack: localRowDataStack,
isOmitReRender: false
});
for (var i=0; i<this.props.rowScheme.length;i++) {
if(this.props.rowScheme[i].afterChange != undefined && this.props.rowScheme[i].column == data.filterName) {
this.props.rowScheme[i].afterChange(data.filterVal);
break;
}
}
},

Related

Filter angular table data by selecting dropdown values

Here I have a JSON array
demoList = [
{ name:"asian003", model:"hyper20", class:"selina0127" },
{ name:"asian003", model:"hyper21", class:"selina0127" },
{ name:"norva", model:"hyper21", class:"gowri.14" },
{ name:"sparks007", model:"NNc22", class:"gowri.14" },
{ name:"asian003", model:"NNc22", class:"selina0127" }
]
This array showing in an HTML table using Angular. I want to add dropdowns separately such as name dropdown, model dropdown, class dropdown. When I select drop-down values I want to filter table records.
For example, if I select asian003 from name and selina0127 from class and do not select the value model dropdown, I want to get the below result into the table preview
demo1List = [
{name:"asian003",model:"hyper20",class:"selina0127"},
{name:"asian003",model:"hyper21",class:"selina0127"},
{name:"asian003",model:"NNc22",class:"selina0127"}
]
You can create and bind one property to each dropdown. Then on any dropdown change, you can call filter_demo_list() function:
const demoList = [
{ name:"asian003", model:"hyper20", class:"selina0127" },
{ name:"asian003", model:"hyper21", class:"selina0127" },
{ name:"norva", model:"hyper21", class:"gowri.14" },
{ name:"sparks007", model:"NNc22", class:"gowri.14" },
{ name:"asian003", model:"NNc22", class:"selina0127" }
]
public table_data;
public selected_name;
public selected_class;
public selected_model;
filter_demo_list() {
this.table_data = demoList;
if (this.selected_name) this.table_data.filter((item)=> item.name === this.selected_name);
if (this.selected_class) this.table_data.filter((item)=> item.class === this.selected_class);
if (this.selected_model) this.table_data.filter((item)=> item.model === this.selected_model);
}

Items in array are returned in only one JSX element using .map()

New to react and still learning. I have an assignment to create a filter component with three dropsdowns that takes information from a JSON file. The idea is the results in the second dropdown will be filtered once the first dropdown has a selected value. The JSON format is:
"destinations": [
{
"id": 8375,
"name": "Bordeaux",
"country": "France",
"category": "wine"
}, ETC
"seasonCategories": {
"spring": [
"wine",
"wonder",
"forest",
"adventure",
"food"
], ETC
I've created a function that feeds the data into the dropdown component and filters it, but it's not returning as I expect: it's creating only one JSX <option> element with the values of all array items listed inside. I need it to generate a new JSX element with the current value of every item in the array. If I call {el[index]} on the last map function I get the right value, so I'm lost as to why it's not generating each in their own <option> tag. The function I'm using is:
function funcCategories(src, val) {
return Object.keys(src)
.filter((flag) => {
return flag === val;
})
.map((el) => {
let v = [];
for (let i = 0; i < src[el].length; i++) {
v.push(src[el][i]);
}
return v;
})
.map((el) => {
return <option className="Dropdown__option">{el}</option>;
});
}
My Dropdown component:
import React from 'react';
class Dropdown extends React.Component {
constructor(props) {
super(props);
this.value = '';
}
render() {
return (
<div className="Dropdown__wrapper">
<label className="Dropdown__label">{this.props.label}</label>
<select
className="Dropdown__select"
value={this.props.value}
onChange={this.props.handleSelect}
>
<option className="Dropdown__option">{this.props.label}</option>
{this.props.func}
</select>
</div>
);
}
}
export default Dropdown;
For you visual thinkers, this is what I'm seeing in the window:
Dropdown result of my current code
I figured it out! I was pushing the array object in the .filter() method and not the elements of each. Not the cleanest code but it works:
let keys = Object.keys(src);
let j = [];
for (let i = 0; i < keys.length; i++) {
if (keys[i] === val) {
alert(keys[i] + ' === ' + src[keys[i]].length)
for (let h = 0; h < src[keys[i]].length; h++) {
j.push(src[keys[i]][h]);
}
}
}
return j.map((el) => {
return <option className="Dropdown__option">{el}</option>;
});

How Can I Make All Checkboxes "Checked" By Default

How can I ensure by default all by checkboxes (output from my data) are all checked by default on load?
Output checkbox
<div v-for="(category, index) in remove_category_duplicates" class="form-check">
<input type="checkbox" class="form-check-input" v-model="cat_data" :id="category" :value="category">
<label class="form-check-label">{{ category }}</label>
</div>
Setup checkbox values from data
remove_category_duplicates: function () {
// Get all categories and remove duplicates
let data = {}
this.info.forEach(i=>{
Object.assign(data,i.category_data);
})
return data;
},
Data:
{
"id": 1,
"title": "Title one",
"category_data": {
"2": "Team",
"7": "Queries"
}
},
CodePen: https://codepen.io/anon/pen/XxNORW?editors=1011
Thanks
To initialize the checkboxes to true/checked, their v-model array (cat_data) should contain the true-value of each checkbox. In this case, it would be:
["Team", "Questions", "Queries", "Fax"]
Here's how I would update your code:
Add a computed property to return an array of available categories:
computed: {
categories() {
const cats = this.remove_category_duplicates;
return Object.keys(cats).map(k => cats[k]);
}
}
Update select() to set cat_data based on selectAll. If selectAll is true, set cat_data to the category array computed above (thus marking all boxes checked), or else an empty array (thus unchecking all boxes):
methods: {
select() {
this.cat_data = this.selectAll ? this.categories : [];
}
}
Add a method (e.g., named "toggleSelectAll") to toggle selectAll based on whether all checkboxes are checked, keeping the Select All checkbox in sync with the state of the other checkboxes:
methods: {
toggleSelectAll(e) {
const checked = e.currentTarget.checked;
if (checked) {
this.selectAll = this.arrayContains(this.categories, this.cat_data);
} else {
this.selectAll = false;
}
}
}
Add a change-handler on each checkbox (except the Select All box) that calls toggleSelectAll defined above:
<div v-for="category in remove_category_duplicates">
<input type="checkbox" #change="toggleSelectAll">
demo

Angular.js count item iterations when filtering objects with ng-options

working on a list filtering with Angular, where listing the items based on region and creating an option select to list these regionsm where I have to remove duplications, and will need a count number next to the region name, which represents how many items from the same region.
I found this thread : How to count unique results based on a particular properties within ng-options but its not working when removing the duplications.
Heres is my select
<select ng-options="item.region as item.region for item in items | unique: 'region'" ng-model="catFilter">
Here is my app.js
var regionSort = angular.module('regionSort', [
'regionSort.controllers'
]);
regionSort.filter('unique', function() {
return function(items, filterOn) {
if (filterOn === false) {
return items;
}
if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
var hashCheck = {},
newItems = [];
var extractValueToCompare = function(item) {
if (angular.isObject(item) && angular.isString(filterOn)) {
return item[filterOn];
} else {
return item;
}
};
angular.forEach(items, function(item) {
var valueToCheck, isDuplicate = false;
var count = 0;
for (var i = 0; i < newItems.length; i++) {
if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
newItems.push(item);
}
});
items = newItems;
}
return items;
};
});
Does anybody have any idea how should I solve this? Thanks in advance!!
Item structure is pretty simple like :
[
{
"name": "Name",
"desc": "Description",
"price": 700,
"priceold": 1080,
"persons": 10,
"discount": 35,
"vote": "9,3",
"image": "https://someige.jpg",
"url": "http://someurl.com",
"region": "XXX"
}, ...
]

AngularJS filter already selected option from dynamic field

I have a form where you can add x number of fields. Each field contains option select. I want to filter out the already chosen option when this option is already chosen in one or multiples field before. Each field has a remove button and the form has 1 add button.
How can I filter out the dynamic fields?
Any help,guidance is most welcome.Thanks in advance. :)
This is how my HTML looks like:
<div data-ng-repeat="choice in choices">
<select data-ng-model="choice.option"
data-ng-options="item as item.Value for item in options">
</select>
<button data-ng-click="removeChoice(choice)">Remove choice</button>
<div>
<button data-ng-show="choices.length <= 4" data-ng-click="addNewChoice()">Add Choice</button>
</div>
</div>
And my controller:
$scope.options = [
{
"Key": "0",
"Value": "Select an option"
},
{
"Key": "Option1",
"Value": "Option1"
},
{
"Key": "Option2",
"Value": "Option2"
},
{
"Key": "Option3",
"Value": "Option3"
},
{
"Key": "Option4",
"Value": "Option4"
},
{
"Key": "Option5",
"Value": "Option5"
}
];
$scope.choices = [{ id: '1' }];
$scope.addNewChoice = function () {
var newItemNo = $scope.choices.length + 1;
$scope.choices.push({ id: newItemNo, option: $scope.option, value: $scope.value });
};
$scope.removeChoice = function () {
var index = $scope.choices.indexOf(choice);
$scope.choices.splice(index, 1);
};
ok
i can give simple recommendation which will be this.
1: add variable $scope.selectedOptions = [];
this will contain list of already selected options from all select elements .
2: create function $scope.AddSelectedOption(item);
this will add the selected object when we change option from any select element because we are going to use for all selects ng-change= "AddSelectedOption(item);"
3: add checkIfSelected(item); this will check if given object value is already selected or not ..
will user in
hope you understand what it will do just check like this
$scope.checkIfSelected = function (item) {
$scope.selectedFound = $scope.selectedOptions.filter(function
(option) {
if(option.value == item.value)
{
return day;
}
});
if($scope.selectedFound.length == 0 ) { return false; } else {
return true; }
}
This will return true if give item found in the options.
if not out.. you can invite me to help again .
This is possible. I'm explaining a basic version of this requirement. See the working example here http://plnkr.co/edit/S9yZpjhY55lXsuifnUAc?p=preview
What wer are doing is maintaining another options which is the copy of the original options. Copying the options will make it to not reference existing options since objects are pass by reference in Javascript.
The main logic is in this function, which modify the options on selection:
$scope.optionSelected = function(choice) {
$scope.availableOptions = $scope.availableOptions || angular.copy($scope.options);
if (choice.option) {
var index = -1;
// See if available options has that key
angular.forEach($scope.availableOptions, function(item, i) {
if (item.Key === choice.option.Key) {
index = i;
}
});
if (index > -1) {
// And then remove it
$scope.availableOptions.splice(index, 1);
}
}
};

Resources