How do I save clicked node in cytoscape.js? - angularjs

I want to show the details about a selected node in a side panel in my AngularJS application. How can I dynamically bind the selected Node with the data in the side panel?

I designed this to use with a pretty old Cytoscape.js version (2.0.2), but as far as I could check in the documentation, it stills the same. Below you can find a minimal example.
You could do something like this:
var cy = cytoscape({
container: document.getElementById('cy'),
showOverlay: true,
minZoom: 1,
maxZoom: 1,
layout: {
fit: true
},
elements: {
// nodes
"nodes": [{
"data": {
"id": "n1",
"name": "node 1",
"description": "Ars Gratia Artis 1"
}
}, {
"data": {
"id": "n2",
"name": "node 2",
"description": "Ars Gratia Artis 2"
}
}],
"edges": [{
"data": {
"source": "n1",
"id": "e1",
"target": "n2",
"type": "belongs-to"
}
}]
},
ready: function() {
var stringStylesheet = "node {"
+"content: data(name);"
+"text-valign: center;"
+"color: white;"
+"text-outline-width: 2;"
+"text-outline-color: #888;"
+"}"
+"edge {"
+" target-arrow-shape: triangle;"
+"content: data(type);"
+"text-outline-color: #FFF;"
+"text-outline-opacity: 1;"
+" text-outline-width: 2;"
+" text-valign: center;"
+" color: #777;"
+"width: 2px;"
+"}"
+":selected {"
+"background-color: black;"
+"line-color: black;"
+"target-arrow-color: black;"
+"source-arrow-color: black;"
+"color: black;"
+"}"
+".faded {"
+" opacity: 0.25;"
+"text-opacity: 0;"
+"}";
cy = this;
cy.style( stringStylesheet );
//You can have different panels for editing edges and nodes.
var nodeClicked = cy.on('tap', 'node', function(e) {
//var edgeClicked = cy.on('tap', 'edge', function(e) {
//Here I use pure jQuery to hide the edge-edition panel
//and show the node-edition one.
//$('div.edge-edition').hide();
$('div.node-edition').show();
//if you click in a specific node, unselect any other
//previously selected element from the graph
cy.elements().unselect();
//* identify which node was clicked
var node = e.target;
console.log("node clicked: " + node.data('name'));
//finally, fullfills forms of the panel with node data
$('.node-name').val(node.data('name'));
$('.node-description').val(node.data('description'));
});
}
});
html {
height: 98%;
}
body {
font-family: Verdana, Arial, Times New Roman;
font-size: 11px;
height: 100%;
}
*,
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
#cy {
height: 85%;
width: 60%;
float: left;
position: relative;
top: 10px;
left: 0px;
border: 1px solid #aaa;
border-radius: 5px;
-webkit-border-radius: 5px;
padding: 0px;
display: block;
z-index: 1;
}
#edition {
float: right;
height: 85%;
width: 39.5%;
position: relative;
top: 10px;
border: 1px solid #aaa;
border-radius: 5px;
-webkit-border-radius: 5px;
padding: 0px;
display: block;
z-index: 1;
}
input,
textarea {
border: 1px solid #aaa;
border-radius: 5px;
-webkit-border-radius: 5px;
padding: 5px;
z-index: -1;
}
.node-name,
.node-description {
max-width: 350px;
width: 250px;
}
<script src="https://rawgit.com/cytoscape/cytoscape.js/master/dist/cytoscape.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en-us">
<head>
</head>
<body>
<div id="cy"></div>
<div id="edition">
<div class="node-edition">
<form>
<table>
<tr>
<td>Name</td>
<td>
<input type="text" class="node-name">
</td>
</tr>
<tr>
<td>Description</td>
<td>
<textarea class="node-description"></textarea>
</td>
</tr>
</table>
</form>
</div>
</div>
</body>
</html>

Like anything else, update your model appropriately such that the template renders the data you want. You could pass node.json() to a component, for example.

Related

$index in md-chips do not update in AngularJS

$index in md-chips do not update in AngularJS. How could I overcome this? I need to place a comma before every chip except for the chip with the $index 0.
You can see that the $index do no update over here, for instance.
On the screenshot above the index should be 0, while it is 2 after I removed the first two chips.
Here is the code.
template
<div ng-controller="BasicDemoCtrl as ctrl" layout="column" ng-cloak="" class="chipsdemoBasicUsage" ng-app="MyApp">
<md-content class="md-padding" layout="column">
<md-chips class="custom-chips" ng-model="ctrl.vegObjs" readonly="ctrl.readonly" md-transform-chip="ctrl.newVeg($chip)" md-removable="ctrl.removable" input-aria-label="Vegetables">
<md-chip-template>
<span>
<strong>[{{$index}}] {{$chip.name}}</strong>
<em>({{$chip.type}})</em>
</span>
</md-chip-template>
<button md-chip-remove="" class="md-primary vegetablechip" aria-label="Remove {{$chip.name}}">
<md-icon md-svg-icon="md-close"></md-icon>
</button>
</md-chips>
<br>
</md-content>
</div>
css
.chipsdemoBasicUsage .errors {
font-size: 12px;
color: #dd2c00;
margin-top: 10px; }
.chipsdemoBasicUsage .custom-chips md-chip {
position: relative; }
.chipsdemoBasicUsage .custom-chips md-chip .md-chip-remove-container {
position: absolute;
right: 4px;
top: 4px;
margin-right: 0;
height: 24px; }
.chipsdemoBasicUsage .custom-chips md-chip .md-chip-remove-container button.vegetablechip {
position: relative;
height: 24px;
width: 24px;
line-height: 30px;
text-align: center;
background: rgba(0, 0, 0, 0.3);
border-radius: 50%;
border: none;
box-shadow: none;
padding: 0;
margin: 0;
transition: background 0.15s linear;
display: block; }
.chipsdemoBasicUsage .custom-chips md-chip .md-chip-remove-container button.vegetablechip md-icon {
position: absolute;
top: 50%;
left: 50%;
transform: translate3d(-50%, -50%, 0) scale(0.7);
color: white;
fill: white; }
.chipsdemoBasicUsage .custom-chips md-chip .md-chip-remove-container button.vegetablechip:hover, .chipsdemoBasicUsage .custom-chips md-chip .md-chip-remove-container button.vegetablechip:focus {
background: rgba(255, 0, 0, 0.8); }
.chipsdemoBasicUsage .custom-chips md-chips-wrap.md-removable md-chip md-chip-template {
padding-right: 5px; }
js
(function () {
'use strict';
angular
.module('MyApp', ['ngMaterial', 'ngMessages', 'material.svgAssetsCache'])
.config(['$mdIconProvider', function($mdIconProvider) {
$mdIconProvider.icon('md-close', 'img/icons/ic_close_24px.svg', 24);
}])
.controller('BasicDemoCtrl', DemoCtrl);
function DemoCtrl ($timeout, $q, $log) {
var self = this;
self.readonly = false;
// Lists of fruit names and Vegetable objects
self.fruitNames = ['Apple', 'Banana', 'Orange'];
self.ngChangeFruitNames = angular.copy(self.fruitNames);
self.roFruitNames = angular.copy(self.fruitNames);
self.editableFruitNames = angular.copy(self.fruitNames);
self.tags = [];
self.vegObjs = [
{
'name' : 'Broccoli',
'type' : 'Brassica'
},
{
'name' : 'Cabbage',
'type' : 'Brassica'
},
{
'name' : 'Carrot',
'type' : 'Umbelliferous'
}
];
self.newVeg = function(chip) {
return {
name: chip,
type: 'unknown'
};
};
self.onModelChange = function(newModel) {
$log.log('The model has changed to ' + newModel + '.');
};
}
})();
Here is the pen.
You can have custom function to get the index like below.
self.getIndex = function(chipName) {
for (var i = 0; i < self.vegObjs.length; i++) {
if (self.vegObjs[i].name === chipName) {
return i;
}
}
}
<md-chip-template>
<span>
<strong>[{{ctrl.getIndex($chip.name)}}] {{$chip.name}}</strong>
<em>({{$chip.type}})</em>
</span>
</md-chip-template>

Cannot get Angular Routing Working

I'm trying to build a SPA using AngularJS. However, I cannot get the routing working for the life of me. Basically I cannot get it to where when you click on one of the list items it routes the view to display different content.
I'm thinking that maybe one of the angularJS files is cancelling itself out or that I am messing up something in the directive.
index.html:
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(
["$stateProvider", "$urlRouterProvider",
function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/home");
$stateProvider
.state("home", {
url: "/home",
templateUrl: "assetView.html",
controller: "MainController"
})
.state("assetView", {
url: "/assetView",
templateUrl: "assetView.html",
controller: "MainController"
})
;
}
]);
var myApp = angular.module('myApp', ['ui.bootstrap']);
myApp.controller('MainController', function MainController($scope){
console.log("inside of MainController");
var vm = this;
$scope.selectedAsset = undefined;
$scope.startDate;
$scope.endDate;
// Current array for testing typeahead feature
// This needs to be an ajax call in the future to populate
// the asset array w/ all ticker symbols
$scope.asset = ['AAAP', 'AABA', 'AABA', 'AAME', 'AAOI',
'AAON', 'AAPL', 'AAWW', 'AAXJ', 'BMTC', 'BNCL',
'BNDX', 'BNFT', 'BNSO', 'CAKE', 'CALA', 'CALD', 'CALI',
'CALL', 'CALM', 'DWTR', 'DXGE', 'DXJS', 'ERII',
'ESBK', 'ESCA'];
/* Datepicker Functions */
$( function() {
var dateFormat = "mm/dd/yy",
from = $( "#from" )
.datepicker({
defaultDate: "+1w",
changeMonth: true,
changeYear: true,
numberOfMonths: 1
})
.on( "change", function() {
to.datepicker( "option", "minDate", getDate( this ) );
startDate = getDate(this);
console.log("start date: " + startDate);
}),
to = $( "#to" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
changeYear: true,
numberOfMonths: 1
})
.on( "change", function() {
from.datepicker( "option", "maxDate", getDate( this ) );
endDate = getDate(this);
console.log("end date: " + endDate);
});
function getDate( element ) {
var date;
try {
date = $.datepicker.parseDate( dateFormat, element.value );
} catch( error ) {
date = null;
}
return date;
}
} );
/* End of Datepicker functions */
/* Chart Data */
var myChart = Highcharts.chart('highchartsContainer', {
chart: {
type: 'column'
},
title: {
text: 'Stock Header Here'
},
colors: ['#4BA2EA', '#CBCBCB', '#266FAD'],
xAxis: {
categories: ['Div', 'EL Fix', 'LTT']
},
yAxis: {
title: {
text: ''
}
},
series: [{
name: 'Sample1',
data: [1, 4, 4]
}, {
name: 'Sample2',
data: [5, 7, 3]
},{
name: 'Sample3',
data: [2, 3, 4]
}]
});
/* End Chart Data */
/* Highchart 2 */
var myChart2 =
Highcharts.chart('highchartsContainer2', {
chart: {
type: 'column'
},
title: {
text: 'Stock Header Here'
},
colors: ['#4BA2EA', '#CBCBCB', '#266FAD'],
xAxis: {
categories: ['Div', 'EL Fix', 'LTT']
},
yAxis: {
title: {
text: ''
}
},
series: [{
name: 'Sample1',
data: [3, 1, 1]
}, {
name: 'Sample2',
data: [9, 8, 2]
},{
name: 'Sample3',
data: [9, 2, 5]
}]
});
/* End Highchart 2 */
/* Highchart 3 */
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=goog-c.json&callback=?', function (data) {
Highcharts.stockChart('highchartsContainer3', {
rangeSelector: {
selected: 1
},
title: {
text: 'GOOG Stock Price'
},
series: [{
name: 'GOOG Stock Price',
data: data,
marker: {
enabled: true,
radius: 3
},
shadow: true,
tooltip: {
valueDecimals: 2
}
}]
});
});
/* End Highchart 3 */
});
/* Body Styling */
body {
background-image: url("images/background_image1.png");
}
/* End Body Styling */
/* help.html div */
#helpDiv{
height: 500px;
width: 500px;
background-color: red !important;
}
/* End help.html div */
/* Wrapper Styling */
.wrapper{
background-color: #FFFFFF;
box-shadow: 0px 30px 40px rgba(0,0,0,.5);
margin: 0 auto;
margin-top: 60px;
margin-bottom: 80px;
width: 1200px;
height: 1350px;
}
/* End Wrapper Styling */
/* Header Styling */
.header{
background-color: #66A8EA;
margin: 0 auto;
width: 1250px;
height: 100px;
position: absolute;
margin-left: auto;
margin-right: auto;
margin-top: 40px;
left: 0;
right: 0;
}
.leftTriangle{
width: 0;
height: 0;
margin-top: 46px;
border-style: solid;
border-width: 0 25px 20px 0;
border-color: transparent #054e9c transparent transparent;
}
.rightTriangle{
width: 0;
height: 0;
border-style: solid;
border-width: 20px 25px 0 0;
border-color: #054e9c transparent transparent transparent;
margin-top: -20px;
margin-left: 1225px;
}
#stockImageSVG{
height: 65px;
width: 65px;
margin-left: 40px;
margin-top: 20px;
position: absolute;
}
#uncImageSVG{
margin-left: 150px;
margin-top: 10px;
height: 80px;
width: 300px;
position: absolute;
}
#searchBar{
margin-left: 760px;
margin-top: 20px;
width: 388px;
margin-right: 60px;
}
#searchBarButton{
margin-top: -1px;
}
/* Typeahead Dropdown Styling */
.dropdown-menu .active > a,
.dropdown-menu .active > a:hover {
color: #333333;
text-decoration: none;
background-color: #B9DDFA !important;
}
/* End Typeahead Dropdown Styling */
#dateRangeSelector{
position: absolute;
color: white;
margin-left: 760px;
margin-top: 60px;
}
#from, #to{
color: #5B5B5B;
border-radius: 2px 2px 2px 2px;
border-style: solid;
border-width: thin;
border-color: #D4D4D4;
font-family: Arial;
}
#toLabel{
margin-left: 26px;
}
/* End Header Styling */
/* Navbar Styling */
#custom-bootstrap-menu{
position: absolute;
margin-top: 140px;
margin-left: 30px;
margin-right: 30px;
}
#custom-bootstrap-menu.navbar-default .navbar-brand {
color: rgba(119, 119, 119, 1);
}
#custom-bootstrap-menu.navbar-default {
font-size: 12px;
background-color: rgba(230, 225, 225, 0.51);
border-width: 0px;
border-radius: 0px;
}
#custom-bootstrap-menu.navbar-default .navbar-nav>li>a {
width: 93px;
text-align: center;
color: rgba(119, 119, 119, 1);
background-color: rgba(247, 247, 247, 1);
margin: 0 auto;
}
#custom-bootstrap-menu.navbar-default .navbar-nav>li>a:hover,
#custom-bootstrap-menu.navbar-default .navbar-nav>li>a:focus {
color: rgba(51, 51, 51, 1);
background-color: rgba(169, 207, 242, 1);
}
#custom-bootstrap-menu.navbar-default .navbar-nav>.active>a,
#custom-bootstrap-menu.navbar-default .navbar-nav>.active>a:hover,
#custom-bootstrap-menu.navbar-default .navbar-nav>.active>a:focus {
color: rgba(85, 85, 85, 1);
background-color: rgba(219, 219, 219, 1);
}
#custom-bootstrap-menu.navbar-default .navbar-toggle {
border-color: #dbdbdb;
}
#custom-bootstrap-menu.navbar-default .navbar-toggle:hover,
#custom-bootstrap-menu.navbar-default .navbar-toggle:focus {
background-color: #dbdbdb;
}
#custom-bootstrap-menu.navbar-default .navbar-toggle .icon-bar {
background-color: #dbdbdb;
}
#custom-bootstrap-menu.navbar-default .navbar-toggle:hover .icon-bar,
#custom-bootstrap-menu.navbar-default .navbar-toggle:focus .icon-bar {
background-color: #e6e1e1;
}
/* End Navbar Styling */
/* Data Table Styling */
#tableArea{
display: inline-block;
background-color: #EBEBEB;
border-radius: 0px 0px 0px 0px;
margin-top: 190px;
margin-left: 30px;
height: 500px;
width: 500px;
}
#tableContainer{
position: absolute;
margin-top: 10px;
margin-left: 40px;
width: 500px;
height: 480px;
background-color: #fff;
}
#dataTable2{
margin-top: 20px;
margin-left: 50px;
margin-right: 10px;
width: 400px;
background-color: #F9F9F9;
}
/* End Data Table Styling */
/* Chart Area Styling */
#chartArea{
display: inline-block;
background-color: #EBEBEB;
border-radius: 0px 0px 0px 0px;
margin-left: -10px;
margin-top: 190px;
height: 500px;
width: 621px;
}
#chartContainer{
background-color: #fff;
margin-top: 10px;
margin-left: 80px;
height: 480px;
width: 500px;
}
/* End Chart Area Styling */
/* customArea3 Styling */
#customArea3{
display: inline-grid;
height: 520px;
width: 555px;
margin-left: 30px;
margin-top: -10px;
background-color: #EBEBEB;
border-radius: 0px 0px 0px 5px;
}
#customArea3Container{
height: 480px;
width: 500px;
margin-top: 10px;
margin-left: 40px;
background-color: #fff;
}
/* End Custom Area 3 Styling */
/* customArea4 Styling */
#customArea4{
display: inline-grid;
position: relative;
margin-top: -10px;
height: 520px;
width: 561px;
margin-left: -5px;
background-color: #EBEBEB;
border-radius: 0px 0px 5px 0px;
}
#customArea4Container{
height: 480px;
width: 500px;
margin-top: 10px;
margin-left: 20px;
background-color: #fff;
}
/* End Custom Area 4 Styling */
/* Highcharts Styling */
#highchartsContainer{
position: absolute;
margin-top: 60px;
margin-left: 10px;
width: 480px;
height: 350px;
}
#highchartsContainer2{
position: absolute;
margin-top: 60px;
margin-left: 10px;
width: 480px;
height: 350px;
}
#highchartsContainer3{
position: absolute;
margin-top: 60px;
margin-left: 10px;
width: 480px;
height: 350px;
}
/* End Highcharts Styling */
/* Print Button Styling */
#printButton{
position: absolute;
margin-top: 200px;
margin-left: 1150px;
}
#printButton:hover{
background-color: #99badd;
border-color: #fff !important;
}
/* End Print Button Styling */
<!doctype html>
<html lang="en" ng-app="myApp">
<head>
<meta charset="utf-8">
<title>c426</title>
<!-- jQuery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.css" />
<!-- Angular JS / Angular JS UI Router CDN -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/1.0.3/angular-ui-router.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.5.0/ui-bootstrap-tpls.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-animate.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular-sanitize.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-2.5.0.js"></script>
<!-- Bootstrap 3.3.7 -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<!-- Style Sheets -->
<link rel="stylesheet" href="project.css">
<!-- Controllers -->
<script src="js/app.js" type="text/javascript"></script>
<script src="js/MainController.js" type="text/javascript"></script>
<!-- SweetAlert2 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/limonte-sweetalert2/6.10.1/sweetalert2.all.min.js"></script>
<!-- Highcharts CDN -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/5.0.14/adapters/standalone-framework.js"></script>
<script src="https://code.highcharts.com/stock/highstock.js"></script>
<!-- Favicon for Browser Tab -->
<link rel="shortcut icon" type="image/x-icon" href="images/uncIcon2.ico">
</head>
<body ng-controller="MainController">
<div class="header">
<img id="stockImageSVG" src="images/stock_bar_image.svg"/>
<a href="http://www.unc.edu/" target="_blank">
<img id="uncImageSVG" src="images/UNC_logo_white.png"/>
</a>
<div id="dateRangeSelector">
<label for="from">From</label>
<input type="text" id="from" name="from">
<label id="toLabel" for="to">To</label>
<input type="text" id="to" name="to">
</div>
<div class="row">
<div class="col-lg-6">
<div id="searchBar" class="input-group">
<input type="text" class="form-control" placeholder="Search for asset..."
uib-typeahead="name for name in asset | filter:$viewValue | limitTo:8" class="form-control"
ng-model="selectedAsset"/>
<span class="input-group-btn">
<button id="searchBarButton" class="btn btn-default glyphicon glyphicon-search" type="button"></button>
</span>
</div>
</div>
</div>
<div class="leftTriangle"></div>
<div class="rightTriangle"></div>
</div>
<div class="wrapper">
<div id="custom-bootstrap-menu" class="navbar navbar-default" role="navigation">
<ul class="nav navbar-nav navbar-left">
<li>GOOGL</li>
<li><a ui-sref="assetView">BIDU</a></li>
<li><a ui-sref="home">YNDX</a></li>
<li>AAPL</li>
<li>IBM</li>
<li>TWTR</li>
<li>VZ</li>
<li>WIFI</li>
<li>FB</li>
<li>IAC</li>
<li>GDDY</li>
<li>AOL</li>
</ul>
</div> <!-- Ends Custom Navbar -->
<button type="button" id="printButton" onclick="window.print();"
class="btn btn-default glyphicon glyphicon-print"
title="Print Page"></button>
<!-- MAIN CONTENT -->
<!-- THIS IS WHERE WE WILL INJECT OUR CONTENT ============================== -->
<div class="container">
<div ui-view></div>
</div>
<div id="assetView">
<div id="tableArea">
<div id="tableContainer">
<table id="dataTable2" class="table table-bordered">
<thead>
<tr>
<th>{{asset[0]}}</th>
<th>{{asset[11]}}</th>
<th>{{asset[17]}}</th>
<th>{{asset[20]}}</th>
<th>{{asset[25]}}</th>
</tr>
</thead>
<tbody>
<tr>
<td>a</td>
<td>0.001</td>
<td>0.002</td>
<td>0.001</td>
<td>0.002</td>
</tr>
<tr>
<td>b</td>
<td>0.002</td>
<td>0.003</td>
<td>0.001</td>
<td>0.002</td>
</tr>
<tr>
<td>c</td>
<td>0.2</td>
<td>0.3</td>
<td>0.001</td>
<td>0.002</td>
</tr>
</tbody>
</table>
</div>
</div>
<div id="chartArea">
<div id="chartContainer">
<div id="highchartsContainer"></div>
</div>
</div>
<div id="customArea3">
<div id="customArea3Container">
<div id="highchartsContainer2"></div>
</div>
</div>
<div id="customArea4">
<div id="customArea4Container">
<div id="highchartsContainer3"></div>
</div>
</div>
</div>
</div>
</body>
</html>

Angular custom directive bindings & validation

I am constructing form, and my markup is repeating all the time, so I tough I could make ng generate it for me.
Here is my partial
<div class="row fieldset">
<div class="column column-3">
<label for="{{params.fieldId}}">
{{params.labelText}}
</label>
</div>
<div class="column column-5">
<input type="text" ng-required="{{params.required}}" id="{{params.fieldId}}" name="{{params.fieldId}}" ng-model="params.ngModel" />
<small class="error" ng-show="????">{{params.validatioMessage}}</small>
</div>
<div class="column column-4" >
<div class="hint">
<p>{{params.hintTitle}}</p>
<p>{{params.hintText}}</p>
</div>
</div>
</div>
JSON object
$scope.paramz = {
fieldId: "firstname",
labelText: "First Name",
validatioMessage: "This field is required",
hintTitle: "First name",
hintText: "Please enter your first name",
ngModel: "form.firstName",
required: true
}
Directive:
<inputfield params="paramz"></inputfield>
My form consists of several steps, each in its own ng-formI need to validate each input field based on input state. As far as I am aware I can't just use dynamic variables in expressions what are my options, validation simply consists of $diry && $invalid
/*------------------------------*\
Grid System
\*------------------------------*/
.row,
.column {
box-sizing: border-box;
}
.row {
margin-bottom: 5px;
}
.row:before,
.row:after {
content: " ";
display: table;
}
.row:after {
clear: both;
}
.column {
position: relative;
float: left;
display: block;
padding: 0 7px;
}
.column-1 {
width: calc(100% / 12 * 1);
}
.column-2 {
width: calc(100% / 12 * 2);
}
.column-3 {
width: calc(100% / 12 * 3);
}
.column-4 {
width: calc(100% / 12 * 4);
}
.column-5 {
width: calc(100% / 12 * 5);
}
.column-6 {
width: calc(100% / 12 * 6);
}
.column-7 {
width: calc(100% / 12 * 7);
}
.column-8 {
width: calc(100% / 12 * /);
}
.column-9 {
width: calc(100% / 12 * 9);
}
.column-10 {
width: calc(100% / 12 * 10);
}
.column-11 {
width: calc(100% / 12 * 11);
}
.column-12 {
width: 100%;
margin-left: 0;
}
#media only screen and (max-width: 550px) {
.column-1,
.column-2,
.column-3,
.column-4,
.column-5,
.column-6,
.column-7,
.column-8,
.column-9,
.column-10,
.column-11,
.column-12 {
float: none;
width: auto;
}
.column + .column {
margin-left: 0;
}
}
section.ng-valid.ng-dirty h1.header:after {
content: "\f00c";
margin-left: 10px;
font-family: fontawesome;
}
body {
font-family: Arial;
}
.column input[type=radio] {
display: none;
}
input[type=text] {
border: 1px solid #569e48;
width: 100%;
font-size: 14px;
line-height: 1em;
padding: 0 7.5px;
min-height: 36px;
position: relative;
}
input.ng-invalid.ng-touched {
border: 1px solid #a90041;
background: #f9f2f4;
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='#d9534f' viewBox='-2 -2 7 7'%3E%3Cpath stroke='%23d9534f' d='M0 0l3 3m0-3L0 3'/%3E%3Ccircle r='.5'/%3E%3Ccircle cx='3' r='.5'/%3E%3Ccircle cy='3' r='.5'/%3E%3Ccircle cx='3' cy='3' r='.5'/%3E%3C/svg%3E");
background-position: center right .625em;
background-repeat: no-repeat;
padding-right: 2.25rem;
background-size: 1.25rem 1.25rem;
}
input.ng-valid.ng-touched {
background: #f9fcf5;
background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='#5cb85c' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");
background-position: center right .625rem;
background-repeat: no-repeat;
padding-right: 2.25rem;
background-size: 1.25rem 1.25rem;
}
.fieldset {
display: flex;
}
.fieldset .column {
flex: 1;
padding: 5px 7px;
line-height: 35px;
}
.fieldset:hover {
background: #ebf5de;
box-sizing: border-box;
outline: 1px solid #60a250;
}
.fieldset:hover .hint {
display: block;
}
.hint {
position: absolute;
display: none;
}
input {
box-sizing: border-box;
}
<div class="content-body">
<div class="row fieldset">
<div class="column column-3">
<label for="fistName">Name</label>
</div>
<div class="column column-5">
<input id="fistName" type="text" required name="lasttName" ng-model="form.lasttName" />
</div>
<div class="column column-4">
<span class="hint">
Name
Please enter your name
</span>
</div>
</div>
<div class="row fieldset">
<div class="column column-3">
<label for="lastName">Surname</label>
</div>
<div class="column column-5">
<input id="lastName" type="text" required name="lasttName" ng-model="form.lasttName" />
</div>
<div class="column column-4">
<span class="hint">
Surname
Please enter your surname
</span>
</div>
</div>
</div>
If I just copy paste code and adjust markup it is all fine, but I don't want to repeat all that code, so I created custom directive.
Working with 1st and 3rd col is easy, it is just text string I need to display,
2nd col is pain...
I need to check input state, for most of the time without using directive it is as mentioned before $invalid && $dirty, but I have no idea how can I do that in directive. If someone is interested in helping me out I can send you archieved solution with my exact issue

Why the message can't be pushed in the array?

I'm using AngularJS v1.6.0-rc.2. I am making a modal-like chat box and I've found a major problem. I wonder why the message can't be pushed into an array when I clicked on a button 'Send' like this. I assume that the message is sent as "sender".
View
<html>
<head>
<!-- I've included the script, CSS file, and fonts -->
</head>
<body ng-app='ModalDemo'>
<div ng-controller='MyCtrl'>
<b ng-click='toggleModal()'><label>username</label></b>
<modal-dialog show='modalShown' width='250px' height='370px'>
<name>
<span>username</span>
</name><hr>
<content>
<div width=100% ng-repeat='message in messages'>
<div ng-if='message.u==1'><span class='sender'>{{message.m}}</span></div>
<div ng-if='message.u==0'><span class='receiver'>{{message.m}}</span></div>
</div><span class='sender'>{{textmsg}}</span>
</content>
</modal-dialog>
</div>
</body>
</html>
Model & Controller
<script>
var app = angular.module('ModalDemo',[]);
app.directive('modalDialog', function() {
return {
scope: {
show: true;
},
replace: true,
transclude: {
'name': '?name',
'content': '?content'
},
link: function(scope, element, attrs) {
scope.dialogStyle = {};
if (attrs.width)
scope.dialogStyle.width = attrs.width;
if (attrs.height)
scope.dialogStyle.height = attrs.height;
scope.hideModal = function() {
scope.show = false;
};
},
template: "<div class='ng-modal' ng-show='show'>\n\
<div class='ng-modal-overlay' ng-click='hideModal()'></div>\n\
<div class='ng-modal-dialog' ng-style='dialogStyle'>\n\
<div class='ng-modal-name' ng-transclude='name'></div>\n\
<div class='ng-modal-close' ng-click='hideModal()'>_</div>\n\
<div class='ng-modal-dialog-content' ng-transclude='content'></div>\n\
<div class='ng-modal-textbox'>\n\
<input class='textinput' ng-model='textmsg'>
<button ng-click='send()' class='send'>Send</button>\n\
</div></div></div>"
};
});
app.controller('MyCtrl', ['$scope', function($scope) {
$scope.modalShown = false;
$scope.toggleModal = function() {
$scope.modalShown = !$scope.modalShown;
};
$scope.messages=[
{'m':'hi','u':1},
{'m':'hello', 'u':1},
{'m':'is it username?', 'u':1},
{'m':'yeah!','u':0}];
$scope.send = function(){
$scope.messages.push(
{'m':$scope.textmsg, 'u':1 }
);
$scope.textmsg="";
};
}]);
</script>
Here is my CSS file if needed.
CSS
.ng-modal-overlay {
position:absolute;
z-index:9999;
top:0;
left:0;
width:100%;
height:100%;
background-color:#000000;
opacity: 0.0;
}
.ng-modal-dialog {
z-index:10000;
position: fixed;
width: 50%;
bottom: 0px;
left: 75%;
box-shadow: 1px 1px 2px #000000;
background-color: #fff;
}
.ng-modal-dialog-content {
text-align: left;
overflow-y: scroll;
height: 300px;
width:100%;
}
.ng-modal-close {
position: absolute;
top: 3px;
right: 5px;
padding: 3px 6px;
cursor: pointer;
font-size: 120%;
display: inline-block;
font-weight: bold;
font-family: 'arial', 'sans-serif';
color: white;
}
.ng-modal-name{
background:#4A86E8;
padding:10px;
color: white;
}
.ng-modal-textbox{
width:100%;
height: 25px;
border-top: 1px solid black;
bottom:0px;
position:absolute;
}
.send{
background: #4a86e8;
border: 0;
font-size: 1em;
color: white;
float: right;
height:inherit;
font-family: 'Montserrat';
}
.textinput{
width: 185px;
font-size: 1em;
border: 0;
padding-left: 3px;
}
.sender{
float: right;
margin:8px;
padding: 5px 8px;
border-radius: 6px;
font-family: arial;
background: #8eb5f2;
box-shadow: 1px;
color: white;
font-size: 0.8em;
box-shadow: 1px 1px 6px #000;
max-width: 60%;
}
.receiver{
float:left;
margin:8px;
padding: 5px 8px;
border-radius: 6px;
font-family: arial;
box-shadow: 1px;
color: black;
font-size: 0.8em;
background: #eaebed;
box-shadow: -1px 1px 6px #000;
max-width: 60%;
}
Here is his working PLUNKER for his problem
I have fixed all the errors but ever thing is working fine.
Every thing goes fine,
You missed a lot of brackets here that messed your code.
return {
scope: {
show: true,
replace: true,
transclude: {
'name': '?name',
'content': '?content'
},
link: function(scope, element, attrs) {
scope.dialogStyle = {};
if (attrs.width)
scope.dialogStyle.width = attrs.width;
if (attrs.height)
scope.dialogStyle.height = attrs.height;
scope.hideModal = function() {
scope.show = false;
};
},
Also your push
var obj= {
'm':$scope.textmsg,
'u':1
}
$scope.messages.push(obj);
Please tell me one thing which the place your clicking to toggle in this HTML, Also do you think it is clickable?
<b ng-click="toggleModal()">
<label>username</label>
</b>

Dynamically insert list and items. Items should be draggable from one list to another. Also sort them with sequence number after dragging

var myapp = angular.module('sortableApp', ['ui.sortable']);
myapp.controller('sortableController', function($scope) {
var tmpList = [];
for (var i = 1; i <= 6; i++) {
tmpList.push({
text: 'Item ' + i,
value: i
});
}
$scope.list = tmpList;
$scope.sortingLog = [];
$scope.sortableOptions = {
update: function(e, ui) {
var logEntry = tmpList.map(function(i) {
return i.value;
}).join(', ');
$scope.sortingLog.push('Update: ' + logEntry);
},
stop: function(e, ui) {
// this callback has the changed model
var logEntry = tmpList.map(function(i) {
return i.value;
}).join(', ');
$scope.sortingLog.push('Stop: ' + logEntry);
}
};
});
.list {
list-style: none outside none;
margin: 10px 0 30px;
}
.item {
width: 200px;
padding: 5px 10px;
margin: 5px 0;
border: 2px solid #444;
border-radius: 5px;
background-color: #EA8A8A;
font-size: 1.1em;
font-weight: bold;
text-align: center;
cursor: pointer;
}
.ui-sortable-helper {
cursor: move;
}
.well {
cursor: move;
}
/*** Extra ***/
body {
font-family: Verdana, 'Trebuchet ms', Tahoma;
}
.logList {
margin-top: 20px;
width: 250px;
min-height: 200px;
padding: 5px 15px;
border: 5px solid #000;
border-radius: 15px;
}
.logList:before {
content: 'log';
padding: 0 5px;
position: relative;
top: -1.1em;
background-color: #FFF;
}
.container {
width: 1100px;
margin: auto;
}
h2 {
text-align: center;
}
.floatleft {
float: left;
}
.clear {
clear: both;
}
.nestedDemo ul[dnd-list],
.nestedDemo ul[dnd-list] > li {
position: relative;
}
.nestedDemo .dropzone ul[dnd-list] {
min-height: 42px;
margin: 0px;
padding-left: 0px;
}
.nestedDemo .dropzone li {
background-color: #fff;
border: 1px solid #ddd;
display: block;
padding: 0px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js"></script>
<script src="https://rawgithub.com/angular-ui/ui-sortable/master/src/sortable.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-route.min.js"></script>
<div ng-app="sortableApp">
<div ng-controller="sortableController" class="container">
<h2>ui.sortable demo</h2>
<div class="col-md-12">
<div class="span4">
<div ui-sortable="sortableOptions" ng-model="list">
<div ng-repeat="item in list" class="well">
{{item.text}}
</div>
</div>
</div>
</div>
<div class="floatleft" style="margin-left: 20px;">
<ul class="list logList">
<li ng-repeat="entry in sortingLog track by $index">
{{entry}}
</li>
</ul>
</div>
<div class="clear"></div>
</div>
</div>
Dynamically insert items on this list and it should be able to add list dynamically. List and items should be added on button click event. On each button click, a pop up should arise and ask for corresponding item/list name. List cannot be dragged into an item. They can only be draged above or below existing list. view of output
List and items should be sorted after each drag as shown in the attached image. In the attached image section stands for list and lecture stands for image.

Resources