How can I sort a directive output? - angularjs

I have the following Directive:
app.directive('sidebar', function () {
return {
restrict: 'E',
replace: true,
template: '<li ng-repeat="(keymenu, valmenu) in menu"><i class="{{valmenu.image}}"></i><span class="hidden-sm">{{keymenu}}</span></li>',
link: function (scope, elem, attrs) {
scope.menu = {
"Home": {
"sort": 1,
"url": "/",
"image": "fa fa-bar-chart-o"
},
"Datasources": {
"sort": 2,
"url": "/datasources",
"image": "fa fa-dashboard"
},
"Logger": {
"sort": 3,
"url": "/Logger",
"image": "fa fa-dashboard"
}
}
}
}
});
Currently the order is: Datasources, Home, Logger I would like to order it either by the sort property or by it's 'natural' order as the elements are ordered within the scope.menu object.

You can use orderBy direcly into the <li /> template:
This code will sort your menu for the property name that you want:
'<li ng-repeat="(keymenu, valmenu) in menu| orderBy:myProperty">'
EDIT:
You should change the way your JSON looks, or you will have issues to access and order the menu. The way you did every menu entry is a different object, you should do like this:
scope.menu =[
{
"name": "Home",
"sort": 1,
"url": "/",
"image": "fa fa-bar-chart-o"
},
{
"name":"Datasources",
"sort": 2,
"url": "/datasources",
"image": "fa fa-dashboard"
},
{
"name": "Logger",
"sort": 3,
"url": "/Logger",
"image": "fa fa-dashboard"
}
]
Then sort by name for exemple:
'<li ng-repeat="(keymenu, valmenu) in menu| orderBy:name">'

Related

Generating forms dynamically using json schema with angularjs

I have a json schema which is something like below:
var schema = {
"type": "object",
"properties": {
"requestedFor": {
"type": "string"
},
"location": {
"type": "string"
},
"shortDescription":{
"type": "string"
},
"description": {
"type": "string"
}
}
};
var options = {
"fields": {
"requestedFor": {
"requestedFor": "text",
"label": "*Name"
},
"location": {
"type": "text",
"label": "*Location"
},
"shortDescription":{
"type": "text",
"label": "Short Description"
},
"description": {
"type": "textarea",
"label": "Description",
"rows": 5,
"cols": 60,
"label": "",
"wordlimit": 250
}
},
"form": {
"attributes": {
"method": "POST",
"action": "#",
"enctype": "multipart/form-data"
},
"buttons": {
"submit": {
"value": "Submit"
}
}
}
};
So i want to use this json schema to create a custom directive on the fly using angularjs. So for that i have created the code something like below:
var app = angular.module("app", [])
.directive("wrapper", function($compile, $interval) {
return {
scope: {
directiveName: "="
},
link: function(scope, elem, attrs) {
scope.$watch("directiveName", function() {
var html = "<" + scope.directiveName + "></" + scope.directiveName + ">";
elem.html(html);
$compile(elem.contents())(scope);
});
}
}
}).controller("addDirectives", function($scope, $interval) {
let directiveNames = ['d1', 'd2', 'd3', "d4"];
$scope.directiveName = directiveNames[0];
}).directive("d1", function() {
return {
template: "<input type='text'>Requested For</input>"
}
}).directive("d2", function() {
return {
template: "<input type='text'>Location</input>"
}
}).directive("d3", function() {
return {
template: "<input type='text'>Short Description</input>"
}
}).directive("d4", function(){
return {
template: "<input type='textarea'>Description</input>"
}
})
Here my intention is to use this json schema to generate the form dynamically because i have so many json files available so for that i need to create different custom directives.
<!DOCTYPE html>
<html ng-app="app">
<head>
<body ng-controller="addDirectives">
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="form"></div>
</div>
</div>
</div>
</body>
</html>
So can anybody provide any solution for this?

Iterating over a nested array in api - ReactJS

I am pulling API data as content for my ReactJS app i'm creating and i'd like to know the best method to iterate over a nested array within an array. Here's the JSON in question:
{
"code": 200,
"status": "Ok",
"copyright": "© 2015 MARVEL",
"attributionText": "Data provided by Marvel. © 2015 MARVEL",
"attributionHTML": "Data provided by Marvel. © 2015 MARVEL",
"etag": "5341faac8eb2f18f592309355057b1c40375545c",
"data": {
"offset": 0,
"limit": 20,
"total": 1,
"count": 1,
"results": [
{
"id": 1011179,
"name": "Pixie",
"description": "",
"modified": "2011-10-19T10:48:27-0400",
"thumbnail": {
"path": "http://i.annihil.us/u/prod/marvel/i/mg/8/e0/4c002f2d626ee",
"extension": "jpg"
},
"resourceURI": "http://gateway.marvel.com/v1/public/characters/1011179",
"comics": {
"available": 6,
"collectionURI": "http://gateway.marvel.com/v1/public/characters/1011179/comics",
"items": [
{
"resourceURI": "http://gateway.marvel.com/v1/public/comics/39737",
"name": "Magneto: Not a Hero (2011) #1"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/comics/24173",
"name": "Runaways (2008) #10"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/comics/36943",
"name": "Steve Rogers: Super Soldier Annual (2010) #1"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/comics/38083",
"name": "X-Men (2010) #19"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/comics/41118",
"name": "X-Men (2010) #19 (Mc 50th Anniversary Variant)"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/comics/38404",
"name": "X-Men: Second Coming Revelations (Trade Paperback)"
}
],
"returned": 6
},
"series": {
"available": 5,
"collectionURI": "http://gateway.marvel.com/v1/public/characters/1011179/series",
"items": [
{
"resourceURI": "http://gateway.marvel.com/v1/public/series/14683",
"name": "Magneto: Not a Hero (2011 - 2012)"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/series/5338",
"name": "Runaways (2008 - 2009)"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/series/13192",
"name": "Steve Rogers: Super Soldier Annual (2010 - Present)"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/series/9906",
"name": "X-Men (2010 - 2013)"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/series/13832",
"name": "X-Men: Second Coming Revelations (2011 - Present)"
}
],
"returned": 5
},
"stories": {
"available": 6,
"collectionURI": "http://gateway.marvel.com/v1/public/characters/1011179/stories",
"items": [
{
"resourceURI": "http://gateway.marvel.com/v1/public/stories/53571",
"name": "Interior #53571",
"type": "interiorStory"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/stories/81928",
"name": "Steve Rogers: Super Soldier Annual (2010) #1",
"type": "interiorStory"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/stories/90198",
"name": "Magneto: Not a Hero (2011) #1 - Int",
"type": "interiorStory"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/stories/90479",
"name": "X-MEN: SECOND COMING REVELATIONS TPB",
"type": "cover"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/stories/93085",
"name": "X-Men (2010) #19, Mc 50th Anniversary Variant",
"type": "cover"
},
{
"resourceURI": "http://gateway.marvel.com/v1/public/stories/94024",
"name": "X-Men #19 Interior",
"type": "interiorStory"
}
],
"returned": 6
},
"events": {
"available": 0,
"collectionURI": "http://gateway.marvel.com/v1/public/characters/1011179/events",
"items": [],
"returned": 0
},
"urls": [
{
"type": "detail",
"url": "http://marvel.com/characters/1758/pixie?utm_campaign=apiRef&utm_source=86e8919c441293aef435c128e5b5c53a"
},
{
"type": "wiki",
"url": "http://marvel.com/universe/Pixie_%28Eternal%29?utm_campaign=apiRef&utm_source=86e8919c441293aef435c128e5b5c53a"
},
{
"type": "comiclink",
"url": "http://marvel.com/comics/characters/1011179/pixie?utm_campaign=apiRef&utm_source=86e8919c441293aef435c128e5b5c53a"
}
]
}
]
}
and here's my MarvelBios.jsx file that contains the render of the data:
var React = require('react');
module.exports = React.createClass({
propTypes: {
username: React.PropTypes.string.isRequired,
bios: React.PropTypes.object.isRequired
// bios is the entireity of data from the JSON pulled in by Axios for the user inputted character name ("username")
},
render: function() {
var results = this.props.bios.data.results.map(function(result, index) {
return (
<div className="bios" key={index}>
<img src={result.thumbnail.path + "/landscape_xlarge." + result.thumbnail.extension} />
{result.name && <p>{result.name}</p>}
{result.description && <small> {result.description}</small>}
<p></p>
</div>
);
});
return (
<div>
{results}
</div>
)
}
});
I am able to successfully pull in the my first array of data from the JSON, which is results (contains character name, description and thumbnail image).
What i'd like to do is then reference the sub-array called items under that main results array, but i'm having difficulty constructing the proper code. For example I tried creating a var items = result.series.items.map(function(item, i) nested under the existing var results but that returned an undefined.
Thanks for any help.
Something like this perhaps.
module.exports = React.createClass({
propTypes: {
username: React.PropTypes.string.isRequired,
bios: React.PropTypes.object.isRequired
// bios is the entireity of data from the JSON pulled in by Axios for the user inputted character name ("username")
},
render: function() {
var results = this.props.bios.data.results.map(function(result, index) {
var items = results.comics.items.map(function(item) {
return <div>{item}</div>;
});
return (
<div className="bios" key={index}>
<img src={result.thumbnail.path + "/landscape_xlarge." + result.thumbnail.extension} />
{result.name && <p>{result.name}</p>}
{result.description && <small> {result.description}</small>}
<p>{items}</p>
</div>
);
});
return (
<div>
{results}
</div>
)
}
});

Doesn't show custom template with angularformly?

This is using angular-formly and i have created multiple-checkbox template as follows:
<script type="text/ng-template" id="multi-checkbox-template.html">
<div class="radio-group"
ng-class="{'has-error': options.formControl.$invalid}">
<label class="control-label">
{{options.label}}
{{options.required ? '*' : ''}}
</label>
<div class="radio"
ng-repeat="(key, option) in options.options">
<label>
<input type="checkbox"
formly-dynamic-name="id + '_'+ $index"
formly-custom-validation="options.validators"
id="{{id + '_'+ $index}}"
aria-describedby="{{id}}_description"
ng-value="option.value"
ng-required="options.required"
ng-model="$parent.model[$parent.options.key || $parent.index][option.name]">
{{option.name}}
</label>
<p id="{{id}}_description"
class="help-block"
ng-if="option.description">
{{option.description}}
</p>
</div>
</div>
</script>
This is config:
formlyConfigProvider.setType(
{
name: 'multi-checkbox',
templateUrl: 'multi-checkbox-template.html',
wrapper: ['bootstrapLabel', 'bootstrapHasError']
}
This is controller:
{
"key": "Q2",
"type":'multi-checkbox',
"templateOptions": {
"label": "What languages are you familiar with?",
"options": [
{ {
"name": "spanish",
"value": "spnsh"
},
{
"name": "french",
"value": "frnch"
},
{
"name": "more",
"value": "more"
}
]
}
}
];
Problem is that, doesn't show anything is the page even though error. I knew that path is correct regarding to the server response
`GET /multi-checkbox-template.html 200 1ms
This is warning i am getting,
angular-formly-bootstrap formly-field apiCheck failed! Required `label` not specified in `Argument 1/value/templateOptions`. Must be `String` https://github.com/formly-js/angular-formly/blob/6.10.0/other/ERRORS_AND_WARNINGS.md#formly-field-type-apicheck-failed
You passed:
{
"key": "Q2",
"type": "multi-checkbox",
"templateOptions": {
"to.label": "In what languages does your firm provide live chat support?",
"to.options": [
{
"name": "english",
"value": "eng"
},
{
"name": "spanish",
"value": "spnsh"
},
{
"name": "french",
"value": "frnch"
},
{
"name": "more",
"value": "more"
}
]
},
"$$hashKey": "object:592",
"data": {},
"validation": {
"messages": {}
},
"id": "formly_1_multi-checkbox_Q2_5"
}
With the types:
{
"key": "string",
"type": "string",
"templateOptions": {
"to.label": "string",
"to.options": {
"0": {
"name": "string",
"value": "string"
},
"1": {
"name": "string",
"value": "string"
},
"2": {
"name": "string",
"value": "string"
},
"3": {
"name": "string",
"value": "string"
}
}
},
"$$hashKey": "string",
"data": "Object",
"validation": {
"messages": "Object"
},
"value": "Function",
"runExpressions": "Function",
"resetModel": "Function",
"updateInitialValue": "Function",
"id": "string",
"initialValue": "undefined"
}
The API calls for:
{
"__apiCheckData": {
"strict": false,
"optional": false,
"type": "shape"
},
"shape": {
"templateOptions": {
"__apiCheckData": {
"strict": false,
"optional": false,
"type": "shape",
"error": "THIS IS THE PROBLEM: Required `label` not specified in `templateOptions`. Must be `String`"
},
"shape": {
"label": "String <-- YOU ARE MISSING THIS"
}
}
}
}
`
Please if there is any help i will be really thank you.
I think some of your references to options above should be referring to options.templateOptions instead (you can actually refer to this as to as a shortcut). For instance, options.label and options.options should be to.label and to.options. Not sure if this is the only issue though.
Also, the script tag business seems weird to me, but I always use:
template: require('path-to-my-template') and Webpack, so I can't be sure.
templateUrl in your formlyConfigProvider.setType() is not a directory link to your file.
the templateUrl is actually referring to the id attribute in your script tag
what you should do is:
formlyConfigProvider.setType(
{
name: 'multi-checkbox',
templateUrl: 'custom-template.html'
wrapper: ['bootstrapLabel', 'bootstrapHasError']
}
and in your template html file:
<script type="text/ng-template" id="custom-template.html">
<!-- your custom template should be here -->
</script>

AngularJS conditionally add a custom 'data-toggle' attribute

I have the following directive:
myDirective.directive('sidebar', function () {
return {
restrict: 'E',
replace: true,
template: '<li ng-repeat="m in menu" ng-class="{\'dropdown\':m.submenu}">' +
'<a href="{{m.url}}" ng-class="{\'dropdown-toggle\':m.submenu}" ng-attr="{\'data-toggle=dropdown\': m.submenu">' +
'<i class="{{m.image}}"></i>' +
' {{m.name}}' +
'<b class="caret" ng-if="m.submenu"></b>' +
'</a>' +
'<ul ng-if="m.submenu" class="dropdown-menu">' +
'<li ng-repeat="s in m.submenu"><i class="{{s.image}}"></i> {{s.name}}</li>' +
'</ul>' +
'</li>',
link: function (scope, elem, attrs) {
scope.menu = [
{
"name": "Home",
"url": "/",
"image": "fa fa-bar-chart-o"
},
{
"name": "Data Integration",
"url": "/manage/dataintegration/index",
"image": "fa fa-dashboard"
},
{
"name": "Users",
"url": "/manage/users/index",
"image": "fa fa-dashboard"
},
{
"name": "Logger",
"url": "/manage/logger/index",
"image": "fa fa-dashboard"
},
{
"name": "Drop",
"url": "",
"image": "fa fa-dashboard",
"submenu": [
{
"name": "Logger",
"url": "/manage/logger/index",
"image": "fa fa-dashboard"
},
{
"name": "Logger2",
"url": "/manage/logger/index",
"image": "fa fa-dashboard"
}
]
}
]
}
}
});
I'm trying to get the data-toggle='dropdown' attribute to the a tag only if m.submenu exists using ng-attr but it doesn't work.
Assuming that's verbatim:
ng-attr="{\'data-toggle=dropdown\': m.submenu"
Is missing a closing }
As for me, ng-attr doesn't work at all, you can try this one
ng-attr-data-toggle="{{m.submenu && 'dropdown' || null}}"
but it will the attribute without the value even if m.submenu is false. Hope it will help.

Backbone.js - Is my model is correct - in case of multiple level datas

I am getting json data from server for make the navigation menu (has the sublinks ) - for that, i am making my model as follow. is this correct..? any one help me please?
Here is the json i am getting from server:
[
{
"label": "General",
"link": "#/general",
"subLinks": [
{
"label": "Dashboard",
"link": "#/dashboard"
},
{
"label": "My Task",
"link": "#/mytask"
},
{
"label": "My Documents",
"link": "#/mydocuments"
},
{
"label": "My Templates",
"link": "#/mytemplates"
},
{
"label": "Search",
"link": "#/search"
}
]
},
{
"label": "Repositories",
"link": "#/reposotories",
"subLinks": []
},
{
"label": "SavedSearches",
"link": "#/savedSearches",
"subLinks": []
},
{
"label": "Favourites",
"link": "#/favourites",
"subLinks": []
},
{
"label": "Reports",
"link": "#/reports",
"subLinks": []
},
{
"label": "Preferences",
"link": "#/preferences",
"subLinks": []
}
]
after i receive my json i use the parse method to manipulate the models:
define(["backbone","models/model","collection/baseCollection"], function (Backbone,model,baseCollection) {
var mainLinkModel = model.extend({
defaults:{
label:"mainLink",
link:"#",
subLinks:[
label:"mainLink",
link:"#"
]
}
})
var headerCollection = baseCollection.extend({
url:function(){
return this.path + "edms/navigationLinksTest"
},
model:model,
initialize:function(){
},
parse:function(response){
var mainNavi = [];
_.each(response.navList, function(m){
// i am making new models.. but how to handle the sublinks?
mainNavi.push(new mainLinkModel(m));
})
}
});
return new headerCollection;
})
how to handle this kind of models.. any one help me in this please..?

Resources