For Loop Iteration Inside of Javascript Variable (Django) - javascript

I am trying to implement a dropdown menu with selectors inside of django. I have made good progress in finding a piece of software that looks great!
http://nelrohd.github.io/bootstrap-dropdown-checkbox/
However, i am getting stuck on how to make it more dynamic.
The end goal is to have a filter option that consists of a list of applications that i can select and unselect in order to change what is outputted to the screen.
The way the software works is that it takes in a single variable through a jQuery selector:
var myData = [{id: 1, label: "Test" }];
$(".myDropdownCheckbox").dropdownCheckbox({
data: myData,
title: "Dropdown Checkbox"
});
Right now i can only use hardcoded properties for the vars
var data =[
{ id: "1", label: "Option 1", isChecked: true },
{ id: "2", label: "Option 2", isChecked: true },
{ id: "3", label: "Option 3", isChecked: true},
{ id: "4", label: "Option 4", isChecked: true },
{ id: "5", label: "Option 5", isChecked: true },
{ id: "6", label: "Option 6", isChecked: true},
{ id: "7", label: "Option 7", isChecked: true },
{ id: "8", label: "Option 8", isChecked: true },
{ id: "9", label: "Option 9", isChecked: true },
{ id: "10", label: "Option 10", isChecked: true },
];
I would like to find a way to make these properties iterable and able to pull a list from the django database: (something like:)
var data=[
for( var i = 0; i<=10, i++)
{id: (i), label: (list(i)), isChecked: true},
]
I have tried to use django template tags, but cant seem to get that working either. My question is: is it possible to iterate over a for loop to create properties for a variable?

Have you tried:
var data = [];
for (var i = 0; i <= 10; i++) {
data[data.length] = { id: (i + 1), label: 'Option ' + (i + 1), isChecked: true };
}

If you generate the list in Django, you can do like:
I will assume you have a list of arbitrary objects you want to serialize in Javascript. When you are ready to pass it to the response context, convert it with stuff like this: mark_safe(json.dumps([{'id': element.id, 'label': element.label, 'isChecked': element.is_checked} for element in mylist])). This is just an example since I don't know which objects you want to render.
Assuming such safe and dumped json is sent to the foo context variable:
var data = {{ foo }};
if you want to generate the options in pure javascript, there's nothing djangoish on it. A simple js for loop like #AlexandreThebaldi answer will work.

I would double check to make sure you had the Django tags set up correctly. It should look like this by passing in the set of options as your context:
{% for opt in options %}
{id: {{ forloop.counter }}, label: {{ opt }}, isChecked: true}
{% endfor %}

Related

How to combine data from an array and object and put together into an array in JavaScript?

I have an array in which I have some string value holding the id along with answer selected and I have different object in which I have the detail about answer which is selected. The below array keep updated whenever we select an option from question.
arr = ["Q1A1", "Q2A3"]
assume Q1 is Question no. 1 and A1 is option selected from the question. And below I have an object for the corresponding Q1 which contained the detail about answers and this object also get change as we move over to Q2
{
id: "Q1",
answers: [
{
id: "Q1A1",
text: "Yes"
},
{
id: "Q1A2",
text: "No"
}
]
}
same way I have any another object for Q2 if we select the answer in Q1, now we have different object for Q2
{
id: "Q2",
answers: [
{
id: "Q2A1",
text: "Test 1"
},
{
id: "Q2A2",
text: "Test 2"
},
{
id: "Q2A3",
text: "Test 3"
},
{
id: "Q2A4",
text: "Test 4"
}
]
}
I need to lookup the object with the help of array which contain question and answer(eg, "Q1A1") with selected and need to find the text for answer selected i.e ("Yes") if u look into the above object for question 1. Hence I need put into the array like this way.
result = ["Q1_Yes","Q2_Test3"]
This code will help you to get those results.
let selected = ["Q1A1", "Q2A3"];
let QA = [
{
id: "Q1",
answers: [
{
id: "Q1A1",
text: "Yes"
},
{
id: "Q1A2",
text: "No"
}
]
},
{
id: "Q2",
answers: [
{
id: "Q2A1",
text: "Test 1"
},
{
id: "Q2A2",
text: "Test 2"
},
{
id: "Q2A3",
text: "Test 3"
},
{
id: "Q2A4",
text: "Test 4"
}
]
}
];
let all_answers = QA.reduce((allanswers,qa)=>(qa.answers.map(d=> allanswers[d.id]=[qa.id,d.text]),allanswers),{});
const result = selected.map(selected => all_answers[selected].join('_'))
console.log(result)

AngularJS: get object property in array by matching a different property?

I have an array of products, displayed in a table with an AngularJS ng-repeat.
The products are an array of objects returned from a Wordpress REST API call, and each object has a "category", which returns as a number.
Example: { "name": "Foo", "cat": 12 }
I can't simply bind to the "cat" property, since it displays "12" and I want to display the category label instead.
I can query for the list of all categories, and get an array like so:
[
{ label: 'Customer Engagement Solutions', id: 2 },
{ label: 'Small and Medium Business', id: 13 },
{ label: 'Customer Information Management', id: 4 },
{ label: 'eCommerce', id: 25 },
{ label: 'Location Intelligence', id: 16 },
{ label: 'Enterprise', id: 12 }
]
My product above, "Foo" should display "Enterprise", which is 12.
I know I can bind to a function, as in {{ctrl.getCat(product)}} but I'm not sure how to do the matching of the ID in the product to the one in the category array, and return the category label.
This is trivial to do in actual Wordpress PHP as they provide a function for this very task.
Use Array#find() or even more performant is create a hashmap of the category labels using id as property keys
Using find()
ctrl.getCat = function(product){
let cat = categories.find(e => e.id === product.cat)
return cat ? cat.label : 'Unknown';
}
Or as hashmap:
ctrl.catLabels = categories.reduce((a,c) => { a[c.id] = c.label; return a;},{})
Then in view:
{{ctrl.catLabels[product.cat]}}
The easiest way would be to create a new array of products that already maps the categories. When you initialize the controller with the products and categories, create a new array the maps it.
var app = angular.module('app', []);
app.controller('MainCtrl', function($scope) {
const _categories = [
{ label: 'Customer Engagement Solutions', id: 2 },
{ label: 'Small and Medium Business', id: 13 },
{ label: 'Customer Information Management', id: 4 },
{ label: 'eCommerce', id: 25 },
{ label: 'Location Intelligence', id: 16 },
{ label: 'Enterprise', id: 12 }
];
const _products = [
{ "name": "Foo", "cat": 12 },
{ "name": "Bar", "cat": 16 },
{ "name": "Foo Bar", "cat": 12}
]
let categoryMap = {}
_categories.forEach( (category)=>{
categoryMap[category.id] = category.label;
})
this.products = _products.map( (product)=>{
return {
"name": product.name,
"category": categoryMap[product.cat]
}
})
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.5.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.11/angular.min.js" data-semver="1.5.11"></script>
</head>
<body ng-controller="MainCtrl as ctrl">
<div ng-repeat="product in ctrl.products">
<span>Name: {{product.name}}</span> <span>Category: {{product.category}}</span>
</div>
</body>
</html>

AngularJS TreeView From JSON Object

I am newbie in AngularJS. I need to create a TreeView Structure From JSON Object.
My Return JSON Object is looks like below.
var categoryTree = [{Name:'Item1', Childnodes : {}, id: 1},
{Name:'Item2', Childnodes : {
items = [
{Name:'Sub Item21', Childnodes : {}, id: 21}
{Name:'Sub Item22', Childnodes : {}, id: 22}
]
}, id: 2}];
Could you please help me to create a AngularJS Tree View.
Thanks in Advance.
You can create a Tree view using the Webix framework along with AngularJS.
https://github.com/TheAjinkya/webixTreeWithJava-
https://github.com/TheAjinkya/AngularWebixApplication
treedata = [{
id: "1",
value: "Book 1",
data: [{
id: "1.1",
value: "Part 1"
},
{
id: "1.2",
value: "Part 2"
}
]
},
{
id: "2",
value: "Book 2",
data: [{
id: "2.1",
value: "Part 1"
}]
}
];
tree = new webix.ui({
view: "tree"
});
tree.parse(treedata)
<script src="https://cdn.webix.com/edge/webix.js"></script>
<link href="https://cdn.webix.com/edge/webix.css" rel="stylesheet" />
Please use some sort of tree view module. They can make your life much easier. The only thing is that you need to re-format your data structure to the tree module style. You can write a service and do all re-formatting inside a service.
Some tree view module and plugin:
http://ngmodules.org/modules/angular.treeview
https://angular-ui-tree.github.io/angular-ui-tree/#/basic-example

Filter an array of objects by a property containing a substring in AngularJS

Let's say i have an array like:
array = [{
title: "foo1",
content: "bar1"
},{
title: "foo2",
content: "bar2"
},{
title: "foo3",
content: "bar3"
}];
Now i want to filter this array to have the objects that their title contains a character like '3'.
So now my filtered array should be
filteredArray = [{
title:"foo3",
content: "bar3"
}];
I've tried
filteredArray = $filter('filter')(array, {
title: "foo3"
});
But the problem with this is that title needs to be exactly "foo3". if i put "3" it won't filter that because it doesn't check if it contains it, it looks for an exact match.
Any ideas how to achieve this?
The filter filter (yeah, I know) does a contains filtering...
I pasted your code (working) into PLNKR and filtered on 3 and got back the title: 'foo3' element
array = [{
title: "foo1",
content: "bar1"
},{
title: "foo2",
content: "bar2"
},{
title: "foo3",
content: "bar3"
}];
$scope.filteredData = $filter('filter')(array, {
title: "3",
});
You would need to write your own filter. Check this answer on how to achieve what you want.

Dynamically add attributes as object properties

I'm working on bootstrap-multiselect, I'm trying to add data attributes in the dataprovider method.
Current
var options = [
{label: 'Option 1', title: 'Option 1', value: '1', selected: true},
{label: 'Option 2', title: 'Option 2', value: '2'}];
In the code it maps these an <option> tag like so:
$tag = $('<option/>').attr({
value: option.value,
label: option.label || option.value,
title: option.title,
selected: !!option.selected,
disabled: !!option.disabled
});
Desired
var options =[
{
"label": "Item 1",
"value": 1,
"selected": false,
"attributes": [
{
"some-attribute": 10001
},
{
"another-attribute": "false"
}
]
}
]
So it will render on the HTML element as data-some-attribute="10001" data-another-attribute="false".
I started out adding this to the code (which I know won't work):
$tag = $('<option/>').attr({
value: option.value,
label: option.label || option.value,
title: option.title,
selected: !!option.selected,
disabled: !!option.disabled,
forEach(option.attributes, function(attribute){
})
});
The problem of course is you can't add a loop as an objects properties.
Once this is working I can add a pull request to the repository. I did ask a question on the repo but decided to try and tackle it myself Issue #592
Any ideas?
I would suggest changing attributes from an array to an object, since attribute names should be unique. It also simplifies how you would get the data attributes on the element.
var attributes = {
value: option.value,
label: option.label || option.value,
title: option.title,
selected: !!option.selected,
disabled: !!option.disabled
};
for (key in option.attributes) {
attributes['data-' + key] = option.attributes[key];
}
$tag = $('<option/>').attr(attributes);
If you wanted to keep it as an array, you can do the following:
var attributes = {
value: option.value,
label: option.label || option.value,
title: option.title,
selected: !!option.selected,
disabled: !!option.disabled
};
for (var i = 0; i < option.attributes.length; i++) {
var key = Object.keys(option.attributes[i])[0],
val = option.attributes[i][key];
attributes['data-' + key] = val;
}
$tag = $('<option/>').attr(attributes);
Doing this, however, provides no benefit and introduces complexity. If each object can have multiple keys, the code will need to change further.
You need to create the element first then add the attributes to it.
So your code should be like this:
var options = [{
"label": "Item 1",
"value": 1,
"selected": false,
"attributes": [{
"some-attribute": 10001
}, {
"another-attribute": "false"
}]
}]
console.log(options.length);
$.each(options, function(option) {
var $tag = $('<option/>').attr({
value: options[option].value,
label: options[option].label || options[option].value,
title: options[option].title,
selected: options[option].selected,
disabled: options[option].disabled
});
console.dir(option);
$.each(options[option].attributes, function(att) {
$tag.attr("data" + Object.keys(att)[0], att[0])
});
$("#mySelect").append($tag);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select id="mySelect">
</select>

Categories