Dynamic Tree Generation based on no. of children in JSON Object - javascript

I have a json response with multiple children. Form those children if the child node has more children then we print the SECTOR_NAME of that Child Node. However if that child node does not have any child we print the ELEMENT_LABEL of that child node. This is the JSON Response.
const dummy = {
header: {
status: 'success',
},
body: {
result: {
children: [
{
children: [
{
children: [],
element: {
ELEMENT_ID: '717',
SECTOR_NAME: 'Real Sector-Agriculture',
ELEMENT_LABEL: 'Agricultural Production',
ELEMENT_FREQUENCY_NAME: 'Monthly',
LEVEL: '2',
FLOW_TYPE_NAME: 'Stock',
SECTOR_SEARCH: 'Real Sector-Agriculture',
TYPE: 'ELEMENT',
DSD_CODE: 'AGR_PROD',
USAGE_NAME: 'Confidential',
},
},
],
element: {
SECTOR_NAME: 'Real Sector-Agriculture',
LEVEL: '1',
TYPE: 'SECTOR',
},
},
{
children: [
{
children: [
{
children: [],
element: {
ELEMENT_ID: '1763',
SECTOR_NAME: 'null',
ELEMENT_LABEL: 'Stressed MSME Sub-ordinate Debt Scheme',
ELEMENT_FREQUENCY_NAME: 'Monthly',
LEVEL: '3',
FLOW_TYPE_NAME: 'Stock',
SECTOR_SEARCH: 'null',
TYPE: 'ELEMENT',
DSD_CODE: 'SMSME',
USAGE_NAME: 'Confidential',
},
},
{
children: [],
element: {
ELEMENT_ID: '1763',
SECTOR_NAME: 'null',
ELEMENT_LABEL: 'Stressed MSME Sub-ordinate Debt Scheme',
ELEMENT_FREQUENCY_NAME: 'Monthly',
LEVEL: '3',
FLOW_TYPE_NAME: 'Stock',
SECTOR_SEARCH: 'null',
TYPE: 'ELEMENT',
DSD_CODE: 'SMSME',
USAGE_NAME: 'Confidential',
},
},
],
element: {
ELEMENT_ID: '1667',
SECTOR_NAME: 'null',
ELEMENT_LABEL:
'Investments of last Friday of reporting month',
ELEMENT_FREQUENCY_NAME: 'Last friday of reporitng month',
LEVEL: '2',
FLOW_TYPE_NAME: 'Stock',
SECTOR_SEARCH: 'null',
TYPE: 'ELEMENT',
DSD_CODE: 'INVTS_LFA',
USAGE_NAME: 'Confidential',
},
},
],
element: {
SECTOR_NAME: 'Others',
LEVEL: '1',
TYPE: 'SECTOR',
},
},
],
element: {
SECTOR_NAME: '<SECTOR_NAME>',
LEVEL: '0',
TYPE: '<TYPE>',
},
},
},
};
This is the HTML code.
<ul class="tree">
<li *ngFor="let l1 of arr_element">
<details>
<summary *ngIf="l1.element.TYPE == 'SECTOR'">
{{ l1.element.SECTOR_NAME }}
</summary>
<summary *ngIf="l1.element.TYPE == 'ELEMENT'">
{{ l1.element.ELEMENT_LABEL }}
</summary>
<ul>
<li *ngFor="let l2 of l1.children; let i = index">
<label
class="container"
style="margin-top:0%;padding:0px"
*ngIf="l2.children == ''"
>
<input
type="checkbox"
style="display: none;"
(change)="elementData(l2, $event, i)"
[checked]="sarr_elementData.includes(l2.element.DSD_CODE)"
/>
<span class="checkmark"></span>
<span style="color:var(--card-label-color);font-weight: 400">
{{ l2.element.ELEMENT_LABEL }} - ({{ l2.element.DSD_CODE }})
</span>
</label>
<details *ngIf="l2.children != ''">
<summary *ngIf="l2.element.TYPE == 'SECTOR'">
{{ l2.element.SECTOR_NAME }}
</summary>
<summary *ngIf="l2.element.TYPE == 'ELEMENT'">
{{ l2.element.ELEMENT_LABEL }}
</summary>
<ul>
<li *ngFor="let l3 of l2.children; let i = index">
<label
class="container"
style="margin-top:0%;padding:0px"
*ngIf="l3.children == ''"
>
<input
type="checkbox"
style="display: none;"
(change)="elementData(l3, $event, i)"
[checked]="sarr_elementData.includes(l3.element.DSD_CODE)"
/>
<span class="checkmark"></span>
<span style="color:var(--card-label-color);font-weight: 400">
{{ l3.element.ELEMENT_LABEL }} - ({{
l3.element.DSD_CODE
}})</span
>
</label>
<details *ngIf="l3.children != ''">
<summary *ngIf="l3.element.TYPE == 'SECTOR'">
{{ l3.element.SECTOR_NAME }}
</summary>
<summary *ngIf="l3.element.TYPE == 'ELEMENT'">
{{ l3.element.ELEMENT_LABEL }}
</summary>
<ul>
<li *ngFor="let l4 of l3.children; let i = index">
<label
class="container"
style="margin-top:0%;padding:0px"
*ngIf="l4.children == ''"
>
<input
type="checkbox"
style="display: none;"
(change)="elementData(l4, $event, i)"
[checked]="
sarr_elementData.includes(l4.element.DSD_CODE)
"
/>
<span class="checkmark"></span>
<span
style="color:var(--card-label-color);font-weight: 400"
>
{{ l4.element.ELEMENT_LABEL }} - ({{
l4.element.DSD_CODE
}})</span
>
</label>
<details *ngIf="l4.children != ''">
<summary *ngIf="l4.element.TYPE == 'SECTOR'">
{{ l4.element.SECTOR_NAME }}
</summary>
<summary *ngIf="l4.element.TYPE == 'ELEMENT'">
{{ l4.element.ELEMENT_LABEL }}
</summary>
<ul>
<li *ngFor="let l5 of l4.children; let i = index">
<label
class="container"
style="margin-top:0%;padding:0px"
*ngIf="l5.children == ''"
>
<input
type="checkbox"
style="display: none;"
(change)="elementData(l5, $event, i)"
[checked]="
sarr_elementData.includes(l5.element.DSD_CODE)
"
/>
<span class="checkmark"></span>
<span
style="color:var(--card-label-color);font-weight: 400"
>
{{ l5.element.ELEMENT_LABEL }} - ({{
l5.element.DSD_CODE
}})</span
>
</label>
<details *ngIf="l5.children != ''">
<summary *ngIf="l5.element.TYPE == 'SECTOR'">
{{ l5.element.SECTOR_NAME }}
</summary>
<summary *ngIf="l5.element.TYPE == 'ELEMENT'">
{{ l5.element.ELEMENT_LABEL }}
</summary>
<ul>
<li
*ngFor="let l6 of l5.children; let i = index"
>
<label
class="container"
style="margin-top:0%;padding:0px"
*ngIf="l6.children == ''"
>
<input
type="checkbox"
style="display: none;"
(change)="elementData(l6, $event, i)"
[checked]="
sarr_elementData.includes(
l6.element.DSD_CODE
)
"
/>
<span class="checkmark"></span>
<span
style="color:var(--card-label-color);font-weight: 400"
>
{{ l6.element.ELEMENT_LABEL }} - ({{
l6.element.DSD_CODE
}})</span
>
</label>
<details *ngIf="l6.children != ''">
<summary
*ngIf="l6.element.TYPE == 'SECTOR'"
>
{{ l6.element.SECTOR_NAME }}
</summary>
<summary
*ngIf="l6.element.TYPE == 'ELEMENT'"
>
{{ l6.element.ELEMENT_LABEL }}
</summary>
<ul>
<li
*ngFor="
let l7 of l6.children;
let i = index
"
>
<label
class="container"
style="margin-top:0%;padding:0px"
*ngIf="l7.children == ''"
>
<input
type="checkbox"
style="display: none;"
(change)="
elementData(l7, $event, i)
"
[checked]="
sarr_elementData.includes(
l7.element.DSD_CODE
)
"
/>
<span class="checkmark"></span>
<span
style="color:var(--card-label-color);font-weight: 400;"
>
{{ l7.element.ELEMENT_LABEL }} - ({{
l7.element.DSD_CODE
}})</span
>
</label>
</li>
</ul>
</details>
</li>
</ul>
</details>
</li>
</ul>
</details>
</li>
</ul>
</details>
</li>
</ul>
</details>
</li>
</ul>
</details>
</li>
</ul>
I have coded it to handle upto 7 levels as for now we have data only spanning upto 7 levels. However it can level up more than that and I dont want to keep on hard coding the html. Please suggest a way to handle the repetitive html part.
This is the sort of output I am expecting. Thanks in Advance

Related

Show value dropdown button with JavaScript in Laravel

I want to show my value when I click the button like this:
I want to show that value using JavaScript, but I can't. Because this is make me confused.
This is code in view blade:
<!-- Category Field -->
<div class="form-group col-sm-6">
{!! Form::label('category_id', 'Category:') !!}
<div class="dropdown dropdown-full-width dropdown-category">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
<span class="name">
<span id="category-select">Choose Category</span>
</span>
<span class="caret"></span>
</button>
<div class="dropdown-menu row">
<div class="col-md-4">
<li><strong>By {{ $category[1] }}</strong></li>
#foreach($category1 as $occasions)
<li>
<div class="checkbox">
<label><input type="radio" name="category['occasions']" class="category-radio"> {{ $occasions }}</label>
</div>
</li>
#endforeach
</div>
<div class="col-md-4">
<li><strong>By {{ $category[2] }}</strong></li>
#foreach($category2 as $types)
<li>
<div class="checkbox">
<label><input type="radio" name="category['types']" class="category-radio"> {{ $types }}</label>
</div>
</li>
#endforeach
</div>
<div class="col-md-4">
<li><strong>By {{ $category[3] }}</strong></li>
#foreach($category3 as $flowers)
<li>
<div class="checkbox">
<label><input type="radio" name="category['flowers']" class="category-radio"> {{ $flowers }}</label>
</div>
</li>
#endforeach
</div>
</div>
</div>
</div>
And this is code in Controller edit function
public function edit($id)
{
$product = $this->productRepository->findWithoutFail($id);
$store = Store::pluck('name', 'id')->all();
$photo = json_decode($product->photo_list);
$category = Category::pluck('name','id')->all();
$category1 = Category::where('parent_id','=',1)->pluck('name','id')->all();
$category2 = Category::where('parent_id','=',2)->pluck('name','id')->all();
$category3 = Category::where('parent_id','=',3)->pluck('name','id')->all();
if (empty($product)) {
Flash::error('Product not found');
return redirect(route('products.index'));
}
return view('products.edit',compact('product','store','category','photo','category1','category2','category3'));
}
UPDATE CODE
I try this code its work, but when I check 1 button or 2 button only. In other one give me result "undefined".
This is my update code in view blade:
<script src = "https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div class="dropdown dropdown-full-width dropdown-category">
<button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown">
<span class="name">
<span id="category-select">Choose Category</span>
</span>
<span class="caret"></span>
</button>
<div class="dropdown-menu row">
<div class="col-md-4">
<li><strong>By {{ $category[1] }}</strong></li>
#foreach($category1 as $occasions)
<li>
<div class="checkbox">
<label><input type="radio" name="category['occasions']" class="category-radio" value="{{ $occasions }}"> {{ $occasions }}</label>
</div>
</li>
#endforeach
</div>
<div class="col-md-4">
<li><strong>By {{ $category[2] }}</strong></li>
#foreach($category2 as $types)
<li>
<div class="checkbox">
<label><input type="radio" name="category['types']" class="category-radio" value="{{ $types }}"> {{ $types }}</label>
</div>
</li>
#endforeach
</div>
<div class="col-md-4">
<li><strong>By {{ $category[3] }}</strong></li>
#foreach($category3 as $flowers)
<li>
<div class="checkbox">
<label><input type="radio" name="category['flowers']" class="category-radio" value="{{ $flowers }}"> {{ $flowers }}</label>
</div>
</li>
#endforeach
</div>
</div>
</div>
<script type="text/javascript">
$('.category-radio').change(function() {
var category_occasions = $('input[name="category[\'occasions\']"]:checked').val();
var category_types = $('input[name="category[\'types\']"]:checked').val();
var category_flowers = $('input[name="category[\'flowers\']"]:checked').val();
var output = category_occasions + ((category_occasions && category_types) ? ' - ' : '') + category_types + ((category_types && category_flowers) ? ' - ' : '') + category_flowers;
$('#category-select').text(output);
});
</script>
Look my image for detail
You missed value attributes to your radio button. Checkout the below code and kindly repeat it for other fields also.
<label><input type="radio" name="category['occasions']" class="category-radio" value="{{ $occasions }}"> {{ $occasions }}</label>
Jquery
$('.category-radio').change(function() {
var category_occasions = $('input[name="category[\'occasions\']"]:checked').val() || '';
var category_types = $('input[name="category[\'types\']"]:checked').val() || '';
var category_flowers =$('input[name="category[\'flowers\']"]:checked').val() || '';
var output = category_occasions + ((category_occasions && category_types) ? ' - ' : '') + category_types + ((category_types && category_flowers) ? ' - ' : '') + category_flowers;
$('#category-select').text(output);
});

How do I add this code to make my table columns sortable on click?

I am using Vue.js to put together a simple CRUD app. I have a demo (followed a tutorial) working of it but for the life of me I don't understand how to sort the table columns by clicking on them. I have found a code example of how to do it but I do not understand how to integrate it. I would be so grateful for any help on how to do this.
demo so far: https://codepen.io/figaro/pen/XMWOyj
<div class="container">
<header class="page-header">
<div class="branding">
<img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/>
<h1>Vue.js 2 CRUD application</h1>
<p>Ported from: Vue.js CRUD application</p>
</div>
</header>
<main id="app">
<router-view></router-view>
</main>
</div>
<template id="product-list">
<div>
<div class="actions">
<router-link class="btn btn-default" v-bind:to="{path: '/add-product'}">
<span class="glyphicon glyphicon-plus"></span>
Add product
</router-link>
</div>
<div class="filters row">
<div class="form-group col-sm-3">
<label for="search-element">Product name</label>
<input v-model="searchKey" class="form-control" id="search-element" requred/>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th class="col-sm-2">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="product in filteredProducts">
<td>
<router-link v-bind:to="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</router-link>
</td>
<td>{{ product.description }}</td>
<td>
{{ product.price }}
<span class="glyphicon glyphicon-euro" aria-hidden="true"></span>
</td>
<td>
<router-link class="btn btn-warning btn-xs" v-bind:to="{name: 'product-edit', params: {product_id: product.id}}">Edit</router-link>
<router-link class="btn btn-danger btn-xs" v-bind:to="{name: 'product-delete', params: {product_id: product.id}}">Delete</router-link>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<template id="add-product">
<div>
<h2>Add new product</h2>
<form v-on:submit="createProduct">
<div class="form-group">
<label for="add-name">Name</label>
<input class="form-control" id="add-name" v-model="product.name" required/>
</div>
<div class="form-group">
<label for="add-description">Description</label>
<textarea class="form-control" id="add-description" rows="10" v-model="product.description"></textarea>
</div>
<div class="form-group">
<label for="add-price">Price, <span class="glyphicon glyphicon-euro"></span></label>
<input type="number" class="form-control" id="add-price" v-model="product.price"/>
</div>
<button type="submit" class="btn btn-primary">Create</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<template id="product">
<div>
<h2>{{ product.name }}</h2>
<b>Description: </b>
<div>{{ product.description }}</div>
<b>Price:</b>
<div>{{ product.price }}<span class="glyphicon glyphicon-euro"></span></div>
<br/>
<span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>
<router-link v-bind:to="'/'">Back to product list</router-link>
</div>
</template>
<template id="product-edit">
<div>
<h2>Edit product</h2>
<form v-on:submit="updateProduct">
<div class="form-group">
<label for="edit-name">Name</label>
<input class="form-control" id="edit-name" v-model="product.name" required/>
</div>
<div class="form-group">
<label for="edit-description">Description</label>
<textarea class="form-control" id="edit-description" rows="3" v-model="product.description"></textarea>
</div>
<div class="form-group">
<label for="edit-price">Price, <span class="glyphicon glyphicon-euro"></span></label>
<input type="number" class="form-control" id="edit-price" v-model="product.price"/>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<template id="product-delete">
<div>
<h2>Delete product {{ product.name }}</h2>
<form v-on:submit="deleteProduct">
<p>The action cannot be undone.</p>
<button type="submit" class="btn btn-danger">Delete</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<script>
var products = [
{id: 1, name: 'Angular', description: 'Superheroic JavaScript MVW Framework.', price: 100},
{id: 2, name: 'Ember', description: 'A framework for creating ambitious web applications.', price: 100},
{id: 3, name: 'React', description: 'A JavaScript Library for building user interfaces.', price: 100},
];
function findProduct (productId) {
return products[findProductKey(productId)];
};
function findProductKey (productId) {
for (var key = 0; key < products.length; key++) {
if (products[key].id == productId) {
return key;
}
}
};
var List = Vue.extend({
template: '#product-list',
data: function () {
return {products: products, searchKey: ''};
},
computed: {
filteredProducts: function () {
return this.products.filter(function (product) {
return this.searchKey=='' || product.name.indexOf(this.searchKey) !== -1;
},this);
}
}
});
var Product = Vue.extend({
template: '#product',
data: function () {
return {product: findProduct(this.$route.params.product_id)};
}
});
var ProductEdit = Vue.extend({
template: '#product-edit',
data: function () {
return {product: findProduct(this.$route.params.product_id)};
},
methods: {
updateProduct: function () {
var product = this.product;
products[findProductKey(product.id)] = {
id: product.id,
name: product.name,
description: product.description,
price: product.price
};
router.push('/');
}
}
});
var ProductDelete = Vue.extend({
template: '#product-delete',
data: function () {
return {product: findProduct(this.$route.params.product_id)};
},
methods: {
deleteProduct: function () {
products.splice(findProductKey(this.$route.params.product_id), 1);
router.push('/');
}
}
});
var AddProduct = Vue.extend({
template: '#add-product',
data: function () {
return {product: {name: '', description: '', price: ''}}
},
methods: {
createProduct: function() {
var product = this.product;
products.push({
id: Math.random().toString().split('.')[1],
name: product.name,
description: product.description,
price: product.price
});
router.push('/');
}
}
});
var router = new VueRouter({routes:[
{ path: '/', component: List},
{ path: '/product/:product_id', component: Product, name: 'product'},
{ path: '/add-product', component: AddProduct},
{ path: '/product/:product_id/edit', component: ProductEdit, name: 'product-edit'},
{ path: '/product/:product_id/delete', component: ProductDelete, name: 'product-delete'}
]});
app = new Vue({
router:router
}).$mount('#app')</script>
Working code sample:
<div class="container">
<header class="page-header">
<div class="branding">
<img src="https://vuejs.org/images/logo.png" alt="Logo" title="Home page" class="logo"/>
<h1>Vue.js 2 CRUD application</h1>
<p>Ported from: Vue.js CRUD application</p>
</div>
</header>
<main id="app">
<router-view></router-view>
</main>
</div>
<template id="product-list">
<div>
<div class="actions">
<router-link class="btn btn-default" v-bind:to="{path: '/add-product'}">
<span class="glyphicon glyphicon-plus"></span>
Add product
</router-link>
</div>
<div class="filters row">
<div class="form-group col-sm-3">
<label for="search-element">Product name</label>
<input v-model="searchKey" class="form-control" id="search-element" requred/>
</div>
</div>
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Price</th>
<th class="col-sm-2">Actions</th>
</tr>
</thead>
<tbody>
<tr v-for="product in filteredProducts">
<td>
<router-link v-bind:to="{name: 'product', params: {product_id: product.id}}">{{ product.name }}</router-link>
</td>
<td>{{ product.description }}</td>
<td>
{{ product.price }}
<span class="glyphicon glyphicon-euro" aria-hidden="true"></span>
</td>
<td>
<router-link class="btn btn-warning btn-xs" v-bind:to="{name: 'product-edit', params: {product_id: product.id}}">Edit</router-link>
<router-link class="btn btn-danger btn-xs" v-bind:to="{name: 'product-delete', params: {product_id: product.id}}">Delete</router-link>
</td>
</tr>
</tbody>
</table>
</div>
</template>
<template id="add-product">
<div>
<h2>Add new product</h2>
<form v-on:submit="createProduct">
<div class="form-group">
<label for="add-name">Name</label>
<input class="form-control" id="add-name" v-model="product.name" required/>
</div>
<div class="form-group">
<label for="add-description">Description</label>
<textarea class="form-control" id="add-description" rows="10" v-model="product.description"></textarea>
</div>
<div class="form-group">
<label for="add-price">Price, <span class="glyphicon glyphicon-euro"></span></label>
<input type="number" class="form-control" id="add-price" v-model="product.price"/>
</div>
<button type="submit" class="btn btn-primary">Create</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<template id="product">
<div>
<h2>{{ product.name }}</h2>
<b>Description: </b>
<div>{{ product.description }}</div>
<b>Price:</b>
<div>{{ product.price }}<span class="glyphicon glyphicon-euro"></span></div>
<br/>
<span class="glyphicon glyphicon-arrow-left" aria-hidden="true"></span>
<router-link v-bind:to="'/'">Back to product list</router-link>
</div>
</template>
<template id="product-edit">
<div>
<h2>Edit product</h2>
<form v-on:submit="updateProduct">
<div class="form-group">
<label for="edit-name">Name</label>
<input class="form-control" id="edit-name" v-model="product.name" required/>
</div>
<div class="form-group">
<label for="edit-description">Description</label>
<textarea class="form-control" id="edit-description" rows="3" v-model="product.description"></textarea>
</div>
<div class="form-group">
<label for="edit-price">Price, <span class="glyphicon glyphicon-euro"></span></label>
<input type="number" class="form-control" id="edit-price" v-model="product.price"/>
</div>
<button type="submit" class="btn btn-primary">Save</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<template id="product-delete">
<div>
<h2>Delete product {{ product.name }}</h2>
<form v-on:submit="deleteProduct">
<p>The action cannot be undone.</p>
<button type="submit" class="btn btn-danger">Delete</button>
<router-link class="btn btn-default" v-bind:to="'/'">Cancel</router-link>
</form>
</div>
</template>
<script>var vm = new Vue({
el: '#demo',
data: {
sections: [
{
id: 1,
city: 'Dallas',
state: 'TX',
zip: 75201,
price: 162500
}, {
id: 2,
city: 'Bevery Hills',
state: 'CA',
zip: 90210,
price: 319250
}, {
id: 3,
city: 'New York',
state: 'NY',
zip: 00010,
price: 962500
}
],
columns: {
city : {
displayname : "City",
sortorder : 1
},
zip : {
displayname : "Zip",
sortorder : 1
},
price : {
displayname : "Price ($)",
sortorder : 1
}
},
query: '',
sortkey: 'city',
sortOrders: {
city: 1,
zip: 1,
price: -1
}
},
computed: {
tableFilter: function () {
return this.orderBy(this.findBy(this.sections, this.query, 'city'),this.sortOrders[this.sortkey], this.sortkey)
}
},
methods: {
findBy: function (list, value, column) {
return list.filter(function (item) {
return item[column].includes(value)
})
},
orderBy: function (list, order, column) {
return list.sort(function (a, b) {
return order * (a[column] - b[column])
})
},
sort: function (colKey) {
this.sortkey = colKey
this.sortOrders[colKey] = this.sortOrders[colKey] * -1
}
}
})<script>
You need to add a v-on:click attribute to your <th>:
<th v-on:click="sortByColumn('name')">Name</th>
Then add a method that sets a variable for the column and update your computed property to use it:
data: function() {
return { products: products, searchKey: '', sortBy: '' };
},
computed: {
filteredProducts: function () {
return this.products.filter((product) => {
...
}).sort((a, b) => { return (a[this.sortBy] < b[this.sortBy]) ? -1 : 1; });
}
},
methods: {
sortByColumn: function(columnName) {
this.sortBy = columnName;
}
}
I updated your code example here, and also added in toggling between ascending and descending order. https://codepen.io/anon/pen/vxYMLE

Angular throw error $parse: ueoe Unexpected End of Expression

This part of my site is with an error and i can't figure out, since i didn't change that in months.
The error is:
Error: [$parse:ueoe] http://errors.angularjs.org/1.4.3/$parse/ueoe?p0=event._id%3FEventController
at Error (native)
at http://localhost:3000/scripts/libs.js:44598:416
at Object.q.consume (http://localhost:3000/scripts/libs.js:44801:157)
at Object.q.ternary (http://localhost:3000/scripts/libs.js:44794:497)
at Object.q.assignment (http://localhost:3000/scripts/libs.js:44794:284)
at Object.q.expression (http://localhost:3000/scripts/libs.js:44794:237)
at Object.q.filterChain (http://localhost:3000/scripts/libs.js:44794:145)
at Object.q.expressionStatement (http://localhost:3000/scripts/libs.js:44794:91)
at Object.q.program (http://localhost:3000/scripts/libs.js:44793:458)
at Object.q.ast (http://localhost:3000/scripts/libs.js:44793:257) <li class="controller__item controller__item--disabled" data-controller-range="[1, 1]" data-event-sidebar-to="false" ng-click="event._id ? EventController.update(event._id, event) : EventController.create(event)">
According to angular.js:
Error: $parse:ueoe
Unexpected End of Expression
Unexpected end of expression: event._id
Description
Occurs when an expression is missing tokens at the end of the expression. For example, forgetting a closing bracket in an expression will trigger this error.
To resolve, learn more about Angular expressions, identify the error and fix the expression's syntax.
The HTML template:
<main class="main">
<div ng-include src="'/admin/navbar/navbar.template.html'"></div>
<div ng-include src="'/admin/breadcrumb/breadcrumb.template.html'"></div>
<section class="events">
<div class="events__container">
<div class="events__row">
<div class="col-md-12">
<div class="events__box">
<div class="events__header">
<h2 class="events__title"> Todos os eventos - </h2>
</div>
<div class="events__body">
<table class="events__table" data-table>
<!-- directive:table-sorter-directive -->
<thead>
<tr>
<th class="events__th events__th--all">
<input type="checkbox" />
</th>
<th class="events__th"> Nome </th>
<th class="events__th"> Data </th>
<th class="events__th events__th--reservations"> Reservas </th>
</tr>
</thead>
<tbody>
<tr class="events__tr" ng-repeat="event in events">
<td class="events__td events__td--checkbox">
<input type="checkbox" data-controller-input ng-click="EventController.retrieveOne(event._id)"/>
</td>
<td class="events__td"> {{ event.name }} </td>
<td class="events__td"> {{ event.date }} </td>
<td class="events__td events__td--reservations"> 50 </td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<aside class="events__sidebar" data-event-sidebar>
<!-- directive:event-sidebar-directive -->
<form class="events__sidebar-form" method="POST" action="#">
<div class="events__sidebar-group">
<label class="events__sidebar-label" for="event_value"> Valores: </label>
<input class="events__sidebar-input event__sidebar-input--value" type="text" id="event_value" ng-model="event.men"/>
<input class="events__sidebar-input event__sidebar-input--value" type="text" id="event_value" ng-model="event.women"/>
</div>
<div class="events__sidebar-group">
<label class="events__sidebar-label" for="event_name"> Nome do evento: </label>
<input class="events__sidebar-input" type="text" id="event_name" ng-model="event.name"/>
</div>
<div class="events__sidebar-group">
<label class="events__sidebar-label" for="event_hour"> Hora: </label>
<input class="events__sidebar-input" type="text" id="event_hour" ng-model="event.hour"/>
</div>
<div class="events__sidebar-group">
<label class="events__sidebar-label" for="event_point"> Ponto de encontro: </label>
<input class="events__sidebar-input" type="text" id="event_point" ng-model="event.meeting"/>
</div>
<div class="events__sidebar-group">
<label class="events__sidebar-label" for="event_info"> Informações simples: </label>
<input class="events__sidebar-input" type="text" id="event_info" placeholder="1 Hora de Open Bar + 2 horas de loucura"/>
</div>
<div class="events__sidebar-group">
<label class="events__sidebar-label" for="event_hiw"> Como funciona: </label>
<input class="events__sidebar-input" type="text" id="event_hiw" ng-model="event.hiw"/>
</div>
</form>
</aside>
</div>
</section>
<aside class="controller" data-controller>
<!-- directive:controller-directive -->
<!-- directive:controller-action-directive -->
<div class="controller__controller" data-controller-indicator>
<i class="icon icon__cogs"></i>
</div>
<div class="controller__container">
<ul class="controller__list">
<li class="controller__item" data-controller-range="[0]" data-event-sidebar-to="true" ng-click="EventController.clean()">
<i class="icon icon__plus icon__2x"></i>
<span class="controller__legend"> Novo </span>
</li>
<li class="controller__item controller__item--disabled" data-controller-range="[1, 1]" data-event-sidebar-to="true">
<i class="icon icon__pencil icon__2x"></i>
<span class="controller__legend"> Editar </span>
</li>
<li class="controller__item controller__item--disabled" data-controller-range="[1, 1]" data-event-sidebar-to="false" ng-click="event._id ? EventController.update(event._id, event) : EventController.create(event)">
<i class="icon icon__cloud icon__2x"></i>
<span class="controller__legend"> Salvar </span>
</li>
<li class="controller__item controller__item--disabled" data-controller-range="[1]" data-event-sidebar-to="false" ng-click="EventController.delete(event._id)">
<i class="icon icon__trash icon__2x"></i>
<span class="controller__legend"> Deletar </span>
</li>
<li class="controller__item controller__item--email">
<i class="icon icon__search icon__2x"></i>
<span class="controller__legend"> E-mail </span>
</li>
<li class="controller__item controller__item--search">
<i class="icon icon__envelope icon__2x"></i>
<span class="controller__legend"> Pesquisar </span>
</li>
</ul>
</div>
</aside>
</main>
EventController.js:
'use strict';
var EventController = function(scope, EventModel) {
this.scope = scope;
this.EventModel = EventModel;
this.scope.store = [];
this.retrieve();
};
EventController.prototype = {
clean: function() {
this.scope.event = {};
},
create: function(newEvent) {
this.EventModel.Model.insert(newEvent)
.then(function(result) {
});
},
retrieve: function() {
var that = this;
this.EventModel.Model.find()
.then(function(result) {
that.scope.events = result;
});
},
retrieveOne: function(eventId) {
var that = this;
this.EventModel.Model.findOne(eventId)
.then(function(result) {
that.scope.event = result;
});
},
update: function(editedEvent, event) {
this.EventModel.Model.update(editedEvent, event)
.then(function(result) {
});
},
delete: function(eventId) {
this.EventModel.Model.remove(eventId)
.then(function(result) {
});
}
};
angular.module('adminApp').controller('EventController', ['$scope', 'EventModel', EventController]);
I can't figure out what is the problem. Anybody can help?
Thanks.
I believe the error might be cause of the src attribute
ng-include src="'/admin/navbar/navbar.template.html'"
ng-include src="'/admin/breadcrumb/breadcrumb.template.html'"
should be
ng-include="'/admin/navbar/navbar.template.html'"
ng-include="'/admin/breadcrumb/breadcrumb.template.html'"
src should be the attribute only when included as an element <ng-include
But in you case the ng-include is used as an attribute
For more info check the docs ng-include
hide this code in ng-grid.js - it add extra column when group is add.
Moved out of above loops due to if no data initially, but has initial grouping, columns won't be added
if(cols.length > 0) {
for (var z = 0; z < groups.length; z++) {
if (!cols[z].isAggCol && z <= maxDepth) {
cols.push(new ngColumn({
colDef: {
field: '',
width: 25,
sortable: false,
resizable: false,
headerCellTemplate: '<div class="ngAggHeader"></div>',
pinned: grid.config.pinSelectionCheckbox
},
enablePinning: grid.config.enablePinning,
isAggCol: true,
headerRowHeight: grid.config.headerRowHeight
}, $scope, grid, domUtilityService, $templateCache, $utils));
}
}
}

angular if all model values are not null show

I am trying to show text based on each of the input's in my form having a value entered or a box ticked.
I can't seem to figure out how to get this to work for all the input fields.
Any ideas?
<div class="container" ng-app ng-controller="OrderFormController">
<div class="row form-group">
<div class="well">
<label for="description" class="col-sm-3 control-label">Extinguisher Status</label>
<div ng-if="myForm.inputs != null">show something</div>
<div class="input-group"></div>
</div>
</div>
<form name="myForm">
<div class="row form-group" ng-repeat="input in inputs">
<div class="well">
<label for="description" class="col-sm-3 control-label">{{input.name}}</label>
<div class="input-group">
<input type="text" class="form-control" required placeholder="Enter {{input.name}}" ng-model="entered">
<!-- <span type="button" class="glyphicon glyphicon-ok" ng-if="input.name==' Geo Location:'"></span> -->
<span ng-class="{'input-group-addon danger' : !entered, 'input-group-addon success': entered}" ng-init="isActive = false">
<span ng-class="{'glyphicon glyphicon-remove': !entered, 'glyphicon glyphicon-ok': entered}" ng-init="isActive = false">
</span>
</span>
</div>
</div>
</div>
<div class="row form-group" ng-repeat="check in checks">
<div class="well">
<label for="description" class="col-sm-3 control-label">{{check.name}}</label>
<div class="btn-group" data-toggle="buttons">
<label ng-class="{'btn btn-danger': !isActive, 'btn btn-success': isActive}" ng-init="isActive = false" ng-click="isActive = !isActive">
<input type="checkbox" autocomplete="off" required ng-model="entered"> <span ng-class="{'glyphicon glyphicon-remove': !isActive, 'glyphicon glyphicon-ok': isActive}" ng-init="isActive = false" ng-click="isActive = !isActive">
</span>
</label>
</div>
</div>
</div>
</form>
</div>
Controller:
function OrderFormController($scope) {
$scope.inputs = [{
name: 'Fire Extinguisher Number:',
id: 1,
active: false
}, {
name: 'Extinguisher Location:',
id: 2,
active: false
}, {
name: 'Geo Location:',
id: 3,
active: false
}];
$scope.checks = [{
name: 'Visual Inspection:',
id: 4,
active: false
}, {
name: 'Weight:',
id: 5,
active: false
}, {
name: 'Gague:',
id: 6,
active: false
}, {
name: 'Hose:',
id: 7,
active: false
}, {
name: 'Service Complete:',
id: 8,
active: false
}];
}
The best what you can do, is to bind input fields and checkboxes to properties of the objects $scope.inputs and $scope.checks respectively. Like this:
for inputs:
<div class="row form-group" ng-repeat="input in inputs">
<div class="well">
<label for="description" class="col-sm-3 control-label">{{input.name}}</label>
<div class="input-group">
<input type="text" class="form-control" required="" placeholder="Enter {{input.name}}" ng-model="input.value" />
<span ng-class="{'input-group-addon danger' : !input.value, 'input-group-addon success': input.value}">
<span ng-class="{'glyphicon glyphicon-remove': !input.value, 'glyphicon glyphicon-ok': input.value}"></span>
</span>
</div>
</div>
</div>
and like this for checks:
<div class="row form-group" ng-repeat="check in checks">
<div class="well">
<label for="description" class="col-sm-3 control-label">{{check.name}}</label>
<div class="btn-group" data-toggle="buttons">
<label ng-class="{'btn btn-danger': !check.active, 'btn btn-success': check.active}" ng-click="check.active = !check.active">
<input type="checkbox" autocomplete="off" required="" ng-model="check.active" />
<span ng-class="{'glyphicon glyphicon-remove': !check.active, 'glyphicon glyphicon-ok': check.active}"></span>
</label>
</div>
</div>
</div>
After that it's easy to check that everything is entered and selected:
$scope.isValid = function() {
var inputsFilled = $scope.inputs.every(function(el) {
return el.value;
});
var allChecked = $scope.checks.every(function(el) {
return el.active;
});
return inputsFilled && allChecked;
};
HTML:
<div ng-if="isValid()">show something</div>
Demo: http://plnkr.co/edit/HDYK7cJqN8jkLvQmojB0?p=info

Angularjs Check all in scope of scope

I want all checkboxes checked, inside a loop of a loop. But how?
<section ng-repeat="user in users">
<p>{{ user.name }}</p>
<label for="#">
<input type="checkbox" ng-click="checkAllRoles(user)"> CHECK ALL
</label>
<ul>
<li ng-repeat="role in user.roles">
<input type="checkbox" value="{{ role.id }}"> {{ role.name }}
</li>
</ul>
</section>
What you can do is to use ngChange handler to loop through all roles changing some property like checked bound to ngModel directive:
$scope.checkAllRoles = function(user) {
user.roles.forEach(function(role) {
role.checked = user.allChecked;
});
};
Where HTML is this:
<section ng-repeat="user in users">
<p>{{ user.name }}</p>
<label for="#">
<input type="checkbox" ng-model="user.allChecked" ng-change="checkAllRoles(user)"> CHECK ALL
</label>
<ul>
<li ng-repeat="role in user.roles">
<input type="checkbox" value="{{ role.id }}" ng-model="role.checked">{{ role.name }}
</li>
</ul>
</section>
Demo: http://plnkr.co/edit/a3I4DKyz6DRUKTIt50Xj?p=preview
Just add checked to the end of your input.
<ul>
<li ng-repeat="role in user.roles">
<input type="checkbox" value="{{ role.id }}" checked> {{ role.name }}
</li>
</ul>

Categories