Iterating over a complex object using ngRepeat to generate inputs - javascript

Using AngularJS, I need to generate settings for a web app using ngRepeat to generate each input. An example of the settings object is as follows:
// in HostController where var host = this
host.settings = {
section: {
property: {name: "Option title", value: 1024},
property: {name: "Option title", value: false},
property: {name: "Option title", value: "#000000"},
},
section: {
dropdownPproperty: {name: "Option title", value: "a", values: ["a", "b", "c", "d"]},
dropdownProperty: {name: "Option title", value: "g", values: ["e", "f", "g", "h"]},
},
section: {
group: {
property: {name: "Option title", value: 0.9},
property: {name: "Option title", value: 1.2},
},
group: {
property: {name: "Option title", value: 1},
group: {
property: {name: "Option title", value: 0.5},
},
},
},
section: {
property: {name: "Option title", value: false},
}
};
Note that in this example the parts of the object have been named what they're supposed to be, eg section/property/group - therefore these names can't be used for identification.
The settings object is divided into different sections. All sections are on the first level of the object. Each section should have its own <div> at the very least.
Each property should have its own <input> - the type of input should depend on the value of the property (eg number/boolean(checkbox)/text).
If the property should be a dropdown (ie has a values array) then it should be a dropdown.
I'd like to ignore groups - the properties of each group should iterated over as if the group wasn't present at all.
I've used ngRepeat a good few times before but only ever to iterate over something simple - a task like this just seems to complex to me, I don't even know if it's possible. How would I go about this?
Thank you very much for any advice and/or help!

you can use a filter to exclude the groups like this
https://docs.angularjs.org/api/ng/filter/filter

Related

How can I make a Search String to search like an IN filter on an Array of Object

The filter on UI allows a user to search using the IN criterion. The search string will then become the property of the condition Object.
The search string will look like "1234,5436,8765" and then the condition Object will be like ```
condition: {
field: "Id",
operator: "in",
value: "1234,5436,8765"
}
Now as this is going to be IN filter, so whar criterion should I use so as to make the value search like IN criterion from the results Array.
e.g. for a like filter, I will set my value property like this %1234% so as to search this in the results Array.
Your question isn't clear so try to edit it to make it clearer.
I made a huge assumption here in my answer (as it is not clear from the question):
You could do it with a switch statement and then your various filter methods for each case.
You could do it more robustly, but until the question is clearer, it doesn't make much sense to build this solution out.
const myArrOfObs = [
{Id: 1234, title: "some title 1", other: "some other val 1"},
{Id: 2468, title: "some title 2", other: "some other val 2"},
{Id: 8240, title: "some title 3", other: "some other val 3"},
{Id: 9371, title: "some title 4", other: "some other val 4"},
{Id: 5436, title: "some title 5", other: "some other val 5"},
{Id: 8365, title: "some title 6", other: "some other val 6"},
{Id: 8765, title: "some title 7", other: "some other val 7"},
{Id: 3946, title: "some title 8", other: "some other val 8"}
];
const condition = {
field: "Id",
operator: "in",
value: "1234,5436,8765"
};
function filterArr(arr, cond) {
switch (cond.operator){
case "in":
const valueArr = cond.value.split(',');
return arr.filter(item => valueArr.includes(item[cond.field].toString()));
//case "like":
//return arr.filter( ... );
default:
return null;
}
}
const myFilteredArr = filterArr(myArrOfObs, condition);
console.log(myFilteredArr);

Unflattening line items in inputData when rendered by function

I have dynamic children input fields that need to be rendered in a function, but when they are, then they are not included in inputData properly/not under the parent input field's key. When the children are included directly in the inputFields, it works as expected, but I can't use a function within the children array with Zapier.
Here is the inputData currently, when the line items are rendered in a function, the LI_ denotes that it is a child input key -
"inputData": {
"supplier": "1",
"LI_budget": 1,
"LI_tax": 1,
"company": "1",
"currency": "1",
"LI_price": "1",
"LI_description": "1"
}
I'm expecting ("parent" is the inputField parent key here):
"inputData": {
"supplier": "1",
"parent": [{
"LI_budget": 1,
"LI_tax": 1,
"LI_price": "1",
"LI_description": "1"
}],
"company": "1",
"currency": "1",
}
This is the function I'm using to pull in the parent and children input fields:
const getLineItems = async (z, bundle) => {
let lineItem = {
key: 'parent',
children: [{
key: 'LI_description',
label: 'Description',
required: true
},
{
key: 'LI_budget',
required: true,
label: 'Budget',
dynamic: 'budget.id'
},
{
key: 'LI_price',
required: true,
type: 'number',
label: 'Unit price',
helpText: 'Example: 50.25'
},
{
key: 'LI_tax',
required: true,
label: 'Tax Rate',
dynamic: 'tax_rate.id'
},
]
}
return [lineItem];
};
There are dynamic fields generated in the getLineItems function that I took out to simplify. TIA
Caleb here from Zapier Platform Support. This is a tough one! We have a pretty long-standing issue report on our platform for supporting custom fields with parent keys (it boils down to a chicken vs the egg problem that really makes my head spin when I read the discussion on the issue). Your inputFields function is spot-on, it's just a matter of properly storing it in the bundle on our part.
I think we could cobble together a workaround to unflatten it. Before I do that though, could you give this a test in the editor and submit actual line items from a previous step to this step? I'm not sure what the inputData looks like (e.g. if multiple items are split like 1,2,3 or in some other fashion). If you want to iterate on this, it might be better to switch over to our public developer Slack (http://zpr.io/ttvdr); then we can post the results here for the next person to run into this. 😁

Apply CSS style within .js var

I'm currently building a game which relies on a random number to show a particular string from an array within a .js file. What I want to do is effectively apply a span element to certain text within the array - eg. make positive outcomes green & negative red, however I can't figure out how to do this outside of html. Eg:
var data = [
{"label": "Question 1", "value": 1, "question": "Awareness: High, Consistency: Low."},
{"label": "Question 2", "value": 1, "question": "Consistency: High, Awareness: Low."},
]
A separate set of code, after selecting a random number, returns data[i].label. How would I set a span within js so that the "High" strings return in green, and "Low" return in red?
Cheers.
You have not specified much, but I went and did what I could.
First, your span
<span id="result">here we go</span>
The CSS file, minimalist, I did not include Bootstrap for this.
span {color:green}
.red{color:red}
The JS, the is no event, or event handler.
var data = [
{"label": "Question 1", "value": 1, "question": "Awareness: High, Consistency: Low."},
{"label": "Question 2", "value": 1, "question": "Consistency: High, Awareness: Low."}
]
The array, I have removed the trailing comma after the second object.
let outputs = data[0].question; This will hold the result from the array, data[0] targets the first object, you can also get map over the properties, but you have not entirely specified the scope and desired functionality.
var output = document.getElementById('result'); // the span element
output.innerText = outputs; // i prefer innerText to innerHTML
if (outputs.includes("Consistency: Low")) { // new string method includes, you can pass the whole ("Consistency: Low")in with no worries.
output.classList.toggle("red"); // if condidtion is true, toggle the red class
}
Codepen
https://codepen.io/damPop/pen/ZwvvGV?editors=0010
Uses classes
var data = [
{label: "Question 1", value: 1, awareness: 'High', consistency: 'Low' },
{label: "Question 2", value: 1, awareness: 'Low', consistency: 'High' },
{label: "Question 3", value: 1, awareness: 'Low', consistency: 'Low' },
{label: "Question 4", value: 1, awareness: 'High', consistency: 'High' }
];
const questionElement = document.getElementById('question');
const awarenessElement = document.getElementById('awareness');
const consistencyElement = document.getElementById('consistency');
document.getElementById('select').addEventListener('click', select);
select();
function select() {
const question = data[Math.floor(Math.random() * 4)];
questionElement.innerText = question.label;
awarenessElement.innerText = `Awareness: ${question.awareness}`;
awarenessElement.className = question.awareness;
consistencyElement.innerText = `Consistency: ${question.consistency}`;
consistencyElement.className = question.consistency;
}
.High {
background-color: green;
}
.Low {
background-color: red;
}
<span id="question"></span>
<div id="awareness"></div>
<div id="consistency"></div>
<button id="select">Select</button>

hiding the Inactive Items form the Suggestions in kendo Multiselect

I have a multiselect in our application. I have a requirement where we should not show the Inactive users in the multi-select dropdown suggestions list. We have the flag in the model. So need to know we can filter the dropdown using that flag. Please find the attached screenshot to get the Idea.
We can filter the data in the ajax call using that flag. But need to get the Names of the already selected Inactive users. So I am trying to hide the Inactive users from the suggestions list only.
So need to show the selected Inactive users, but from the suggestions need to hide inactive users.
Not sure if this is the best way, but you can try applying a filter on the dataSource in open event and removing it in close event:
$("#multiselect").kendoMultiSelect({
dataSource: {
data: [{Name: "test 1", Active: true, Id: 1},
{Name: "test 2", Active: true, Id: 2},
{Name: "test 3", Active: false, Id: 3},
{Name: "test 4", Active: true, Id: 4},
{Name: "test 5", Active: false, Id: 5}]
},
value: [1, 3],
dataTextField: "Name",
dataValueField: "Id",
filter: "startswith",
open: function(e) {
this.dataSource.filter({ field: "Active", operator: "eq", value: "true" });
},
close: function() {
this.dataSource.filter(null);
}
});
Demo

Using an input element to reference a json

bit of background: when a user clicks an element, it loads a form retrieved by an ajax call. I save a copy of the json in the controller, and when they change a value, it is to update the local json.
Let's say the json is something like this:
{
name: "questions!",
id: "0",
questions: [{
id: "1",
text: "ninjas or pirates?",
type: "radio",
answers: [{
id: "1",
text: "ninjas"
} , {
id: "2",
text: "pirates"
}],
}, {
id: "3",
text: "why?",
type: "text"
answers: []
}]
}
the element returned is a jquery-ized version of the input that was selected.
While I could iterate through each field and check, I can't help but feel like there is a better way to do it and reference it more directly. How would this be done?

Categories

Resources