Angularjs Sortable items and categories based on json data - angularjs

I have this json structure:
{
"items":[
{
"category":"Category 1",
"name":"01",
"id":"46701a72410c"
},
{
"category":"Category 2",
"name":"02",
"id":"9a18ffe9f148"
},
{
"category":"Category 2",
"name":"03",
"id":"de3a49a458cc"
},
{
"category":"Category 3",
"name":"04",
"id":"bb06b1eec9c8"
},
{
"category":"Category 3",
"name":"05",
"id":"92973f4cfbfc"
},
{
"category":"Category 3",
"name":"06",
"id":"b06bbb86d278"
}
],
"categories":[
{
"isCollapsed":false,
"name":"Category 1"
},
{
"isCollapsed":false,
"name":"Category 2"
},
{
"isCollapsed":false,
"name":"Category 3"
}
]
}
and I'm trying to add sorting behavior using angularjs ui.sortable. I want both categories and items to be sortable.
I created two nested ordered lists based on this json, but I have no idea how to solve sortable settings. Is it possible for this json structure?
With these settings I solved only categories sorting to work. The problem is when items are moved (wrong positions or undefined are taken).
$scope.sortableOptionsCategories = {
stop: function(ev, ui) {
console.log("Category moved.");
}
};
$scope.sortableOptionsItems = {
connectWith: '.items-container',
start: function(e, ui) {
$(this).attr('data-previndex', ui.item.index());
console.log("Start: from position " + ui.item.index());
},
update: function(e, ui) {
var newIndex = ui.item.index();
var oldIndex = $(this).attr('data-previndex');
$(this).removeAttr('data-previndex');
console.log("Update: " + oldIndex + " -> " + newIndex);
},
stop: function(ev, ui) {
console.log("Item moved.");
}
};
UPDATE:
Here is my code:
http://codepen.io/anon/pen/LpGmeY
A solution that keeps the json as it is would perfect for me, but if not possible I will accept any other solution.

Have you tried using this library - https://github.com/angular-ui-tree/angular-ui-tree
I created a jsfiddle - http://jsfiddle.net/450fk7wp/5/ - that handles the nested, sortable, draggable items.
You will have to transform your JSON so that it looks like this:
$scope.rows = [{
"name":"Category 1",
"columns": [
{
"category":"Category 1",
"name":"01",
"id":"46701a72410c"
}
],
}, {
"name":"Category 2",
"columns": [
{
"category":"Category 2",
"name":"02",
"id":"9a18ffe9f148"
},
{
"category":"Category 2",
"name":"03",
"id":"de3a49a458cc"
}
],
}, {
"name":"Category 3",
"columns": [
{
"category":"Category 3",
"name":"04",
"id":"bb06b1eec9c8"
},
{
"category":"Category 3",
"name":"05",
"id":"92973f4cfbfc"
},
{
"category":"Category 3",
"name":"06",
"id":"b06bbb86d278"
}
]
}];
Just not exactly sure what type of sorting functionality you are looking for.
Hope this helps!

Provided I've understood this correctly you have nested lists, are you using nested ng-repeats?
If so it seems you can't do this with sortable (from https://github.com/angular-ui/ui-sortable)
ng-model is required, so that the directive knows which model to
update.
ui-sortable element should only contain one ng-repeat and not
any other elements (above or below).
Can you paste your HTML?

Related

Nested query in Reactive Component - ReactJS

I try to update query of the component by using setQuery() prop. My data is structured like this.
{
root : {
category 1: {
item 1 {...},
item 2 {...},
},
category 2: {
item 1 {...},
item 2 {...},
},
...
}
}
I need to get item 1 under the category 1. When user select item 1 I update query like this. But it doesn't work.
this.props.setQuery({
"query": {
"bool": {
"must": [
{
"query_string": {
"query": 'category 1 AND item 1',
"fields": ["item", "category", "keywords"],
"analyzer": "standard"
}
}
]
}
}
});
I try find out how to solve this using nested query. But I couldn't find any use full thing. Please give me any clue to achieve this.
I found a solution for this.
this.props.setQuery({
query: {
bool: {
must: [
{
terms: {
'parentName': ['category 1']
},
},
{
terms: {
'childName': 'item 1',
},
},
],
},
},
});
I think this will helps to someone.

Arrange lists of lists on button click Angularjs

I have data, two input fields with a button and on clicking the button I want to move the data to certain position:
i.e
two input fields = source and destination it's basically the indexes to move a certain item from source to destination
data=
{
"0": [
{
"key": "Survey Meta Data"
}
],
"1": [
{
"key": "New Section"
}
],
"2": [
{
"key": "Tax Authority"
}
]
}
explaining what I want
the input field source=2destination=0
now my data will be
{
"0": [
{
"key": "Tax Authority"
}
],
"1": [
{
"key": "Survey Meta Data"
}
],
"2": [
{
"key": "New Section"
}
]
}
As it's moved to the first index and other items are pushed
any help will be greatly appreciated
index.html
Source=<input ng-model="source" type="number>
Destination<input ng-model="destination" type="number>
<button ng-click="arrange(source,destination)></button>
{{model|json}}
index.js
$scope.model=[[{"key":'Survey Meta data'}],[{key:'New Section'}],[{key:Tax Authority'}]]
$scope.arrange(src,dest)
{
//trick to push
}
You just have to use splice to achieve this.
JS:
$scope.myObj = {
"0": [{
"key": "Survey Meta Data"
}],
"1": [{
key: 'New Section'
}],
"2": [{
"key": "Tax Authority"
}]
};
$scope.model = [];
for (var i in $scope.myObj) {
if ($scope.myObj.hasOwnProperty(i)) {
$scope.model.push($scope.myObj[i]);
}
}
Array.prototype.insert = function(index, item) {
this.splice(index, 0, item);
};
$scope.arrange = function(src, dest) {
var temp = [];
temp = $scope.model.splice(parseInt(src), 1);
$scope.model.insert(parseInt(dest), temp[0]);
for (var i = 0; i < $scope.model.length; i++) {
$scope.myObj[i] = $scope.model[i];
}
}
Demo:
http://jsfiddle.net/yj9sswq1/5/

Add optgroups to angular-selectize asynchronously

I am using angular-selectize directive in my project. For this, I need to load optgroups asynchronously. So far I have tried multiple approaches but none of them works. The problem is, you cannot use the data returned by a promise synchronously. On the flip side, I have also been unable to initialize selectize from inside a promise callback. Given below is the code I currently have. Note that it is only to be used to get the idea of the data I'm playing with, not to present it as something you can consider right.
app.js
$http
.get('/get-categories')
.then(getCategoriesSCB, getCategoriesFCB);
function getCategoriesSCB(response) {
if(typeof(response.data) === 'object') {
posControl.menuCategories = response.data[0];
posControl.menuCategoryGroups = response.data[1];
}
else {
getCategoriesFCB(response);
}
}
function getCategoriesFCB(response) {
console.log(response);
}
posControl.menuConfig = {
valueField: 'id',
labelField: 'title',
placeholder: 'Select Category',
optgroupField: 'class',
optgroupLabelField: 'label',
optgroupValueField: 'value',
optgroups: posControl.menuCategoryGroups,
maxItems: 1,
searchField: ['title', 'category'],
onInitialize: function(selectize) {
console.log('selectize is here');
},
}
index.html
<selectize config="POSCtrl.menuConfig" options="POSCtrl.menuCategories" ng-model="POSCtrl.menuModel"></selectize>
data returned by ajax call
[
// this array has to be used for options.
[{
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855b23f9",
"title": "Beverages"
}, {
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855c05de",
"title": "Cuisines"
}, {
"class": "57b83830babb9",
"category": "Food Menu",
"id": "57b83855cdcb4",
"title": "Steaks"
}, {
"class": "57b83830d0899",
"category": "Wholesale Coffee",
"id": "57b83830d0899",
"title": "Wholesale Coffee"
}],
// this array has to be used for optgroups
[{
"value": "57b83830babb9",
"label": "Food Menu"
}, {
"value": "57b83830d0899",
"label": "Wholesale Coffee"
}]
]
You should be able to load a selectize asynchronously by setting the values directly on the posControl.menuConfig:
function getCategoriesSCB(response) {
if (typeof(response.data) === 'object') {
posControl.menuConfig.options = response.data[0];
posControl.menuConfig.optgroups = response.data[1];
}
}

how to use ellipses in highcharts in angular to deal with long names?

i am having a high chart having email ids on x axis that are very long i have included ellipses to cut it short but the problem is it is now showing me email ids like this : " <A HREF="mailto:james.cla... " i am not able to understand why it is appending anchor tag in front of the email ids , kindly help.
here is my controller code :
$scope.chart = {
"type": $scope.chartType,
"series": chartData[0],
"xAxis": {
//labels tilted down to view properly
labels: {
rotation: -20,
// using ellipses in highcharts
formatter: function() {
return(this.value.substring(0,25) + "...");
}
},
"categories": chartData[1],
"title": {
"text": 'Approver name'
}
},
"chart": {
"plotBackgroundColor": 'transparent'
},
"yAxis": {
"title": {
"text": "Record count"
}
},
"title": 'aging data'
};
}
i have only included the formatter: function to make it done .

AngularJS filter on multiple lists of multiple checkboxes

I apologise if this has been answered already, but I'm new to Angular so might have missed it.
I have a need to provide multiple sets of checkbox lists, which need to be combined to create an AND query.
It's on Plunker here http://plnkr.co/OGmGkz22n4J4T8p74yto but enclosed below. At the moment I can select the bottom row and the correct names appear from storeArray, but I cannot work out how to add the Format array into the filter.
I've tried:
<div ng-repeat="store in storeArray | filter:(formatFilter && tillFilter)">
and
<div ng-repeat="store in storeArray | filter:formatFilter:tillFilter">
but they don't work.
Any suggestions please?
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.formatFilter = function(a) {
for (var fmt in $scope.formatsArray) {
var f = $scope.formatsArray[fmt];
if (f.on && a.format.indexOf(f.name) > -1) {
return true;
}
}
};
$scope.tillFilter = function(a) {
for (var till in $scope.tillsArray) {
var t = $scope.tillsArray[till];
if (t.on && a.tills.indexOf(t.name) > -1) {
return true;
}
}
};
$scope.formatsArray = [{
name: "Super",
on: false
}, {
name: "Express",
on: false
}, {
name: "Other",
on: false
}];
$scope.tillsArray = [{
name: "Main",
on: false
}, {
name: "Service",
on: false
}, {
name: "Petrol",
on: false
}];
$scope.storeArray = [{
"id": "1",
"name": "101",
"format": "Super",
"tills": ["Main", "Service", "Petrol"]
}, {
"id": "2",
"name": "102",
"format": "Express",
"tills": ["Main", "Service"]
}, {
"id": "3",
"name": "103",
"format": "Other",
"tills": ["Main", "Petrol"]
}, {
"id": "4",
"name": "104",
"format": "Super",
"tills": ["Service", "Petrol"]
}];
}
While you can chain filters together like this:
<div ng-repeat="store in storeArray | filter:formatFilter | filter:tillFilter)">
This won't fix your problem since the first filter will do it's job, and filter items out that you may want to include in your second filter. I'm not sure of any way to do an "or" filter. Is there any reason you can't do a custom filter that includes both? I modified your plunker with a custom filter:
http://plnkr.co/edit/han1LFl7toTsSX27b9Q0?p=preview
The code isn't super clean... it does the job. :) You may want to polish it up a bit.

Resources