Filtering with a multi-select menu - javascript

So I have a select menu that lets the user select multiple options. the selected options correspond to actorModel.
Then I have an object array and I wish to filter it according to the selected options.
If the user selected option A and B , then it will return two objects from actorDocs.
The one that has a label value 'A' and the one that has the label value 'B'.
If no option is selected (actorModel is null) then it will return all objects from actorDocs.
The problem I am encountering in this code is that it only works if the user selects one option.
If the user selects more than one, then I tink it is trying to locate an object that has several labels instead of several objects with each label.
Any help is more than welcome
const actorModel = ref({ 0:'label1', 1:'label2', 3:'label3'})
const actorDocs = ref([{'label':'label1'},{'label':'label2'},{'label':'label3'},{'label':'label4'}])
const actorListTest2 = computed(() => {
if (actorModel.value == null){var ttt = actorDocs.value}
else {
var ttt = actorDocs.value.filter(obj => {
return (
(!actorModel.value.length || obj.label.includes(actorModel.value) )
) })}
lenActordata.value = ttt.length
return ttt
});

Try like following snippet:
const actorModel = {0:'label1', 1:'label3'}
const actorDocs = [{'label':'label1'}, {'label':'label2'}, {'label':'label3'}, {'label':'label4'}]
const actorListTest2 = () => {
if (actorModel == null){
return actorDocs
} else {
return actorDocs.filter(obj => [...Object.values(actorModel)].includes(obj.label))
}
};
console.log(actorListTest2())

Related

how to add a specific number of items as long as the condition is true JavaScript Arrays

I'm working on column selection from a table. I have a limit of 20 elements. I need to be able to select all items until the limit is passed.
Scenario:
18/20
next column has 10 elements
click on select whole column
it should select only the first two elements
What I've tried:
const myArray = selectedColumn.some(() => itemsOnArray.length <= 20)
? selectedLaborer.map((laborer) => laborer)
: [];
Can you provide more context to your question?
Personally when it comes to selections, i usually gives an id to the object i wish to select if they don't have one (An unique identifier) and store this value in an array as my selected objects.
Adding and removing values is quite easy then :
(This is typescript for more explicit reading, but doesnt change anything)
let selectedItems: string[] = [];
const MAX_ALLOWER_SELECTED = 20;
const selectItem = (itemId: string): void => {
//You might want to check for duplicates before inserting
if (selectedItems.length > MAX_ALLOWED_SELECTED)
return;
selectedItems.push(itemId);
}
const unselectItem = (itemId: string): void => {
selectedItems = selectedItems.filter(id => itemId !== id);
}
const isItemSelected = (itemId: string): boolean => {
return selectedItems.includes(itemId);
}

How to filter values of an array inside an array?

I will describe the situation for more clarity. I have an array
like this
animalsArray = {
animalID : number,
animalName: string,
animalDescription: string,
animalChild: animalsArray[]
}
Now I have to filter these animals using animalName from user input by textfield. Some animals can have n number of animalChild or non at all or animalChild can have another animalChild inside it.
I already have a code like this
public animalsArray:animalsArray[]
this.filteredanimalsArray.next(
this.animalsArray.filter(item => (item.animalName.toLowerCase().indexOf(search) > -1))
);
To filter the main animalsArray and it works fine but the user input doesn't go through the child arrays.
How can I solve this problem? Thanks in advance
Maybe you could use recursivity like this :
function filterAnimals(animals, name) {
return animals.filter(animal => {
const matching = animal.animalName.toLowerCase() === name.toLowerCase();
const hasChildMatch = Array.isArray(animal.animalChild) && filterAnimals(animal.animalChild, name).length > 0;
return matching || hasChildMatch;
});
}
const search = 'leon';
const filterdAnimals = filterAnimals(animalsArray, search);

How to set rest values based on default checkbox using Angular2

Hi i am using Angular8 with Bootstrap, here i have used reactive forms, when i check on Make Default checkbox, then values present in Flowers row (Mail, Electronic,Delivery and Receipent)should be copied same to rest rows.
If the fax number format is not proper, how to show error message just below particular row recepient.
Ts:
checkAll(ev) {
const control = <FormArray>this.exampleForm.get("printList");
if (!this.all) {
this.printListArray.forEach(x => (x.value = false));
control.patchValue(this.printListArray);
} else {
this.printListArray.forEach(x => (x.value = true));
control.patchValue(this.printListArray);
}
console.log(control.value);
}
isAllChecked() {
this.all = !this.all;
}
DEMO
Your code should work more like the following
checkAll(ev) {
const control = <FormArray>this.exampleForm.get("printList");
console.log(this.all);
if (this.all) {
this.all = false;
this.printListArray.forEach(x => (x.electronics = false));
control.patchValue(this.printListArray);
} else {
this.all = true;
this.printListArray.forEach(x => (x.electronics = true));
control.patchValue(this.printListArray);
}
}
The main difference is that instead of changing the value field of x I'm changing the electronics fields, so when you are patching the form latter on, this.printListArray will have the appropriate data in the appropriate state.
In the implementation that I'm suggesting you will be able to toggle all checboxes in the row Electronics
Keep in mind that the printListArray is not an array form FormGroup/FormControl, its an array of regular objects, so the field value that usually exists in the FormControl is not present.

How can I write a For loop from dropdown box to populate second dropdown box from JSON file?

I have a Jinja for loop populating one dropdown box for countries. This allows a user to select a country. But I have second Jinja for loop populating a second dropdown box for states. At the moment, the second dropdown box just iterates every state in the list (which is 1000s).
So I am building a JavaScript to iterate through the JSON file and collect the data of the user chosen country to populate the state's list with only states that are associated with that particular country.
Unfortunately, this is where I get stuck. I am not too familiar with the common concept of a for loop in JS.
So far I can pick this:
document.getElementById("country").addEventListener("change", function() {
const country_change = document.getElementById("country").value;
console.log(country_change);
console.log(countries);
});
Where country_change is the user-chosen country and countries is the entire JSON file.
Clicking on the countries log first entry I get:
This is what I want to iterate through to:
I can call all the countries from the JSON file into JS, now when a user selects a country I have that variable, so now I want to look through states for that country and its associated states.
I tried a simple for loop from w3 schools just to see what comes out - but there wasn't anything really useful that I could gather. I think I just need a bit more of a shove in the right direction.
Edit: Just experimenting with:
document.getElementById("country").addEventListener("change", function() {
const country_change = document.getElementById("country").value;
console.log(country_change);
console.log(countries);
const Ind = countries.findIndex(e => {
return e['name'] === country_change
})
if(Ind != -1){
countries[Ind]['states'].forEach(e=>console.log(e))
}
});
But still not producing the desired results.
You could do something like this:
Every time the country dropdown value changes, update all state options.
function updateSelect({ node, values }) {
while (node.hasChildNodes()) node.removeChild(node.lastChild)
for (const value of values) {
const option = document.createElement("option")
option.value = option.textContent = value
node.appendChild(option)
}
}
// Sample data
const countries = [
{
name: "Germany",
states: ["Bavaria", "Berlin", "Saxony"]
},
{
name: "Austria",
states: ["Tyrol", "Vienna"]
}
]
const coutriesSelect = document.querySelector("#country")
const statesSelect = document.querySelector("#state")
updateSelect({
node: coutriesSelect,
values: countries.map(country => country.name),
})
// Update it on initialization
updateStatesSelect()
coutriesSelect.addEventListener("change", updateStatesSelect)
function updateStatesSelect() {
const countryName = coutriesSelect.value
const country = countries.find(country => country.name === countryName)
const states = country.states
updateSelect({
node: statesSelect,
values: states
})
}
<select name="country" id="country"></select>
<select name="state" id="state"></select>
It appears this will iterate through that list and produce the states:
const Ind = countries.findIndex(e => {
return e['name'] === country_change
})
if(Ind != -1){
countries[Ind]['states'].forEach(e=>console.log(e))
}
Based on the data I have given.

push dynamically coming id's and value's in javascript

The question may seem a little confusing so let me explain the situation, i have a category field, that when it's chosen, i get data from api based on that category, for example when you choose category A, you may get the id's 1 to 3 or when you chose category B, you get the id's of 8 to 11, so what i'm trying to do is create a Filter array that pushes these values with id's so when user types something like sth in input with the id of 1, this objects gets pushed to the array, something like below:
Filters = [
{
id:1,
value: sth
}
]
so what i have basically done is something like this:
this.props.Filters.map(item => (
<div className="from" key={item.id} id={item.id} >
<span className="title">{item.feature}</span>
<input type="text" placeholder="..." id={item.id} onChange={FilterPush}></input>
</div>
))
and the function is:
const Filters = []
const FilterPush = (e) => {
const filter = {
id: e.currentTarget.getAttribute("id"),
value: e.currentTarget.value
}
Filters.push(filter)
}
the problem i'm having here is every time a user is typing something an object is pushed to Filters,
so when user tries to type sth the Filter gets equal to:
Filters={
{id:1,value:s},
{id:1,value:st},
{id:1,value:sth}
}
but i want it to be equal to this
Filters={
{id:1, value:sth}
}
bear in mind that the id's are dynamic and i don't know them, and there's not just one input, i mean we can have 3 inputs with diffrent id's that should get send to the server.
Just filter out existing id:
const FilterPush = (e) => {
let id = e.currentTarget.getAttribute("id")
const filter = {
id,
value: e.currentTarget.value
}
Filters = Filters.filter(item => item.id !== id) // filter out existing id
Filters.push(filter)
}
It's very simple all you have to do is just check the pushing element's id is already in the Filters array before pushing the element.
const FilterPush = (e) => {
let id = e.currentTarget.getAttribute("id")
const filter = {
id: e.currentTarget.getAttribute("id"),
value: e.currentTarget.value
}
Filters.map(item=>{
if(id == item.id){
available = true;
}
})
if(!available){
Filters.push(filter)
}
}

Categories

Resources