Set Value in Select Option of dynamic form - javascript

I have created dynamic form, in that form there is one dropdown. In that dropdown I want to have fiscal week for that I want to run loop inside ts function.
form.ts -
<div class="col-md-9" [ngSwitch]="field.type">
<dropdown *ngSwitchCase="'dropdown'" [field]="field" [form]="form"></dropdown>
</div>
dropdown.ts -
public field: any[] = [
{
type: 'dropdown',
name: 'fiscalweek',
label: 'fiscalweek',
placeholder: 'Fiscal Week',
required: true,
options: this.getWeek()
}
];
getWeek(){
this.week =
[
{ key: 'Select', label: 'ALL'},
{ key: '1', label: '1'},
{ key: '2', label: '2'},
{ key: '3', label: '3'},
{ key: '4', label: '4'},
{ key: '5', label: '5'},
{ key: '6', label: '6'},
.
.
.
{ key: '53', label: '53'}
]
;
return this.week;
}
I want to run a loop inside this getWeek from 1 to 53 instead of hardcoding.
Can someone please suggest me how to do that ?

You can populate week array by a simple for loop
Try like this:
Working Demo
getWeek() {
this.week = [];
this.week.push({ key: "Select", label: "ALL" });
for (var i = 1; i <= 53; i++) {
this.week.push({ key: i.toString(), label: i.toString() });
}
return this.week;
}

Related

Dynamic AntD Cascasder. Add and delete options? React Js

I am trying to add an onChange function that can add and delete options in the cascader menu. I would like to be able to select existing menu options and add options on to them as well.
My example data structure looks like this:
const [dataTitle, setDataTitle] = useState([
{
label: '2022',
value: '2022',
children: [
{
label: 'Fall',
value: 'Fall',
children: [
{
label: 'Week 1',
value: 'Week 1',
children: [
{
label: 'Practice 1',
value: 'Practice 1',
},
{
label: 'Practice 2',
value: 'Practice 2',
},
{
label: 'Practice 3',
value: 'Practice 3',
},
{
label: 'Practice 4',
value: 'Practice 4',
},
{
label: 'Game 1',
value: 'Game 1',
},
]
},
{
label: 'Week 2',
value: 'Week 2',
},
{
label: 'Week 3',
value: 'Week 3',
},
],
},
],
},
]);
I am using these onChange events below to add a 'create-new-option' button and to add the new option when prompted.
const handleLabelChange = (value, selectedOptions) => {
const lastOption = selectedOptions[selectedOptions.length - 1];
// Check if the last selected option has a value of 'create-new-option'
if (lastOption.value === 'create-new-option') {
// Prompt user for new option name
const newOptionName = prompt('Enter a name for the new option:');
// Add the new option to the options data
const newOption = {
label: newOptionName,
value: newOptionName,
};
let newDataTitle = [...dataTitle];
let parentOption = newDataTitle.find(o => o.value === lastOption.parentValue);
if (!parentOption) {
parentOption = { children: [] };
newDataTitle.push(parentOption);
}
// Check if parentOption.children is defined before trying to push
if (parentOption.children) {
parentOption.children.push(newOption);
}
setDataTitle(newDataTitle);
}
};
const addCreateNewOption = (options) => {
return options.map(option => {
return {
...option,
children: option.children
? [...addCreateNewOption(option.children), {value: 'create-new-option', label: 'Create new option', parentValue: option.value}]
: [{value: 'create-new-option', label: 'Create new option', parentValue: option.value}]
};
});
};
My issue is having the new option display in the correct spot and under the correct parents. It works correctly with the second level (I can add a 'Spring' Option and it correctly shows up under 2022 / Spring) but none others.
CodeSandbox Recreation

Looping array of object into array of object javascript

so i have two arrays of object like this:
var lab =[
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 }
];
var val = [ { label: '1', value: 42 },
{ label: '2', value: 55 },
];
lab.forEach(labs=>{
val.forEach(vals=>{
labs["columns"]=vals.value
})
})
console.log(lab)
i try to get the value like this
[ { label: '1', value: 42, columns: {42,55} },
{ label: '2', value: 55, columns:{42,55} },
{ label: '3', value: 51, columns: {42,55} },
{ label: '4', value: 22, columns: {42,55} } ]
but after i ran the code i get the value that i am not wanted like this:
[ { label: '1', value: 42, columns: 55 },
{ label: '2', value: 55, columns: 55 },
{ label: '3', value: 51, columns: 55 },
{ label: '4', value: 22, columns: 55 } ]
where do i did wrong actually on the loop..
Does this do what you want?
const lab = [
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 },
];
const val = [
{ label: '1', value: 42 },
{ label: '2', value: 55 },
];
// we get an array of stuff that the OP wants to add,
// as apparently it is identical for each object.
const columns = val.map(obj => obj.value);
const a = lab.map(labs => {
return {
// shallow copys for every item.
...labs,
columns: [...columns],
};
});
console.log({ a });
.as-console-wrapper { min-height: 100%!important; top: 0; }
map array method takes a function returns a new array where each element was updated by calling that function with element as it's argument.
This answer uses two calls of map, same amount as your answer, however in your answer map calls are nested, so the inner map would be called for each element, while it's result will be always the same, in my answer we call it once.
i have figured it out by using map function
var lab =[
{ label: '1', value: 42 },
{ label: '2', value: 55 },
{ label: '3', value: 51 },
{ label: '4', value: 22 }
];
var val = [ { label: '1', value: 10 },
{ label: '2', value: 55 },
];
const a = lab.map((labs)=>{
let ab={
label:labs.label,
value:labs.value,
columns:val.map((vals)=>{
return vals.value
})
}
return ab
})
console.log(a)
hope it will help

How do I create an array of objects with a nested array based on a similar key?

I have an array that looks something like this
const example = [
{ id: '1', name: 'Person 1', organization: { id: '11', name: 'Organization A' } },
{ id: '2', name: 'Person 2', organization: { id: '12', name: 'Organization A' } },
{ id: '3', name: 'Person 3', organization: { id: '13', name: 'Organization B' } },
];
As you can see, the organization name is something I want to key off of and create a data structure like this:
const output = [
// data.value will be their ID
{
organizationName: 'Organization A',
data: [
{ label: 'Person 1', value: '1' },
{ label: 'Person 2', value: '2' },
],
},
{
organizationName: 'Organization B',
data: [
{ label: 'Person 3', value: '3' },
],
},
]
What I've tried
I know I want to use reduce for something like this, but I feel like I'm off:
const providerOptions = externalPeople.data.reduce((acc, currentValue) => {
const {
organization: { name: organizationName },
} = currentValue;
if (organizationName) {
acc.push({ organization: organizationName, data: [] });
} else {
const { name: externalPersonName, id } = currentValue;
acc[acc.length - 1].data.push({ name: externalPersonName, value: id });
}
return acc;
}, [] as any);
However the output comes out to something like this:
[
{organizationName: 'Organization A', data: []},
{organizationName: 'Organization A', data: []},
{organizationName: 'Organization B', data: []},
];
data doesn't seem to get anything pushed inside the array in this reduce function, and the organization name get duplicated... what am I doing wrong?
Easiest way is to use an Map/Set/or object to keep track of orgs you create. This way you are not searching in the array to see if the organization was found already. After you are done, you can create the array you want from the object.
const externalPeople = {
data : [
{ id: '1', name: 'Person 1', organization: { id: '11', name: 'Organization A' } },
{ id: '2', name: 'Person 2', organization: { id: '12', name: 'Organization A' } },
{ id: '3', name: 'Person 3', organization: { id: '13', name: 'Organization B' } },
],
};
const providerOptions = Object.values(externalPeople.data.reduce((acc, currentValue) => {
const {
organization: { name: organizationName },
name: externalPersonName,
id
} = currentValue;
// Is the org new? Yes, create an entry for it
if (!acc[organizationName]) {
acc[organizationName] = { organization: organizationName, data: [] };
}
// push the person to the organization
acc[organizationName].data.push({ name: externalPersonName, value: id });
return acc;
}, {}));
console.log(providerOptions)
Here is another solution
const example = [
{ id: '1', name: 'Person 1', organization: { id: '11', name: 'Organization A' } },
{ id: '2', name: 'Person 2', organization: { id: '12', name: 'Organization A' } },
{ id: '3', name: 'Person 3', organization: { id: '13', name: 'Organization B' } },
];
const result = example.reduce((res, entry) => {
const recordIndex = res.findIndex(rec => rec.organizationName === entry.organization.name);
if(recordIndex >= 0) {
res[recordIndex].data.push({ label: entry.name, value: entry.id});
} else {
const record = {
organizationName: entry.organization.name,
data: [{ label: entry.name, value: entry.id }]
};
res.push(record);
}
return res;
}, []);
console.log(result);
You are not checking if the value is already present in your accumulation acc
You can check it with a simple find in the if statement since it's an array
const providerOptions = externalPeople.data.reduce((acc, currentValue) => {
const {
organization: { name: organizationName },
} = currentValue;
//Check if organization is not present already
if (!acc.find(a => a.organization === organizationName)) {
//Add also the data of the element your are processing
acc.push({ organization: organizationName, data: [{label: currentValue.name, value: currentValue.id}] });
} else {
const { name: externalPersonName, id } = currentValue;
acc[acc.length - 1].data.push({ label: externalPersonName, value: id });
}
return acc;
}, [] as any);
I also added the data of the first element of the group you create when adding the organization.
The result should be as your expected output:
[
{
organization: 'Organization A',
data: [
{ label: 'Person 1', value: '1' },
{ label: 'Person 2', value: '2' }
]
},
{
organization: 'Organization B',
data: [
{ label: 'Person 3', value: '3' }
]
}
]
Hope it helps!
Compare this solution (using Lodash) with other solutions. Which one emphasises your intentions at most? This is why we use Lodash in our company - to maintain code as declarative as we can, because code readability, with minimum cognitive overload, is most important goal during coding.
const persons = [
{ id: '1', name: 'Person 1', organization: { id: '11', name: 'Organization A' } },
{ id: '2', name: 'Person 2', organization: { id: '12', name: 'Organization A' } },
{ id: '3', name: 'Person 3', organization: { id: '13', name: 'Organization B' } },
];
const personsByOrganizations = _.groupBy(persons, 'organization.name')
const output = _.map(personsByOrganizations, (persons, organizationName) => ({
organizationName,
data: _.map(persons, ({ name, id }) => ({
label: name,
value: id
}))
}))
Something like that with using a Set?
result = [...new Set(example.map(d => d.organization.name))].map(label => {
return {
organizationName: label,
data: example.filter(d => d.organization.name === label).map(d => {
return {label: d.name, value: d.id}
})
}
})
`

Clone array of object removes class type

I have to deep clone an array of objects
filterList: Filter[] = [
new ChipsFilter('Rating', 'rating',
[
{
name: '5 ★',
key: '5',
value: true
},
{
name: '4 ★',
key: '4',
value: true
},
{
name: '3 ★',
key: '3',
value: true
},
{
name: '2 ★',
key: '2',
value: true
},
{
name: '1 ★',
key: '1',
value: true
}
]),
new CheckboxFilter('Country', 'country', [
{
name: 'India',
key: 'india',
value: true
},
{
name: 'Brazil',
key: 'brazil',
value: false
},
{
name: 'UAE',
key: 'uae',
value: true
},
{
name: 'Sri Lanka',
key: 'sri-lanka',
value: true
},
{
name: 'USA',
key: 'usa',
value: false
},
{
name: 'England',
key: 'england',
value: true
},
{
name: 'South Africa',
key: 'south-africa',
value: true
}
]),
new CalendarFilter('Date', 'createdAt', [
{
name: 'Start Date',
key: 'startDate',
value: ''
},
{
name: 'End Date',
key: 'endDate',
value: ''
}
]),
];
After clone I want the data type of objects to be same but I get the object as the type instead, have tried below methods for cloning.
Using JSON stringify
this.filterList = this.filterList.map(a => Object.assign({}, a));
Using object.assign
this.filterList = this.filterList.map(a => Object.assign({}, a));
The first argument to Object.assign() is the target object. That object effectively is the result. What Object.assign() does is just copy over own enumerable properties of your CalendarFilter instances to that target.
What you could do instead is create new instances of your objects in array.map() instead of assigning them to a generic object with Object.assign().
this.filterList = this.filterList.map(a => new CalendarFilter(...))
Of course, you need to use the right constructor for each type you encounter in your array.
This will take into account the variable Object types:
class ChipsFilter {constructor(){this.chipsProp="chipsProp"}}
class CheckboxFilter {constructor(){this.checkboxProp= "checkboxProp"}}
class CalendarFilter {constructor(){this.calendarProp= "calendarProp"}}
const filterList = [
new ChipsFilter(),
new CheckboxFilter(),
new CalendarFilter(),
];
let out = filterList.map(obj=>Object.assign(new obj.constructor, obj));
console.log(out[0].constructor, out[0]);
console.log(out[1].constructor, out[1]);
console.log(out[2].constructor, out[2]);

Javascript - Assign object item with values from another object

I have an object with few items and I want to update the values of one property options from another object.
Object 1 :
structure = [
{
id: 'name',
label: 'Name',
filterType: 'text',
filterOn: 'contains'
},
{
id: 'address',
label: 'Address',
filterType: 'text',
filterOn: 'contains'
},
{
id: 'phone',
label: 'Phone',
filterType: 'select',
filterOn: 'contains',
options: [{ label: 'abc', value: 'abc' },
{ label: 'xyz', value: 'xyz' },
{ label: 'mno', value: 'mno' }]
}
];
if the id is phone then I want to get the values from the object 2 phoneList and assign it to the options instead of hard coding it.
options: [{ label: 'abc', value: 'abc' },
{ label: 'xyz', value: 'xyz' },
{ label: 'mno', value: 'mno' }]
}
];
object 2 is
this.props.phoneList = [{name: 'aaa', age: 11},{name : 'bbb' , age : 12}, and so on
]
label and values will be this.props.phoneList[i].name
how to loop over this and get the latest values from the other object
First use filter to identify the object with id phone. Then use map to transform this.probs.phoneList in the desired format and assign to options.
structure.filter (x => x.id == 'phone')[0].options = this.probs.phoneList.map (x => ({label: x.name, value: x.name}));

Categories