I have to display Image albums . Till #media element width 700px I can display 3 images per slide , below #media width :700px i need to display 1 image per slide.
For displaying 3 image per slide , I written a function showfilteredImages();
$scope.imagemaindiv
will have all images from backend
$scope.imagemaindiv = [{
'img': "image1.png",
"id": 1
}, {
'img': "image2.png",
"id": 2
}, {
'img': "image3.png",
"id": 3
}, {
'img': "image4.png",
"id": 4
}, {
'img': "image5.png",
"id": 5
}, {
'img': "image6.png",
"id": 6
}]
$scope._firstImgIndex = 0;
$scope._lastImgIndex = 2;
$scope.showFilteredImages = function() {
$scope.filteredImages = [];
for (var i = $scope._firstImgIndex; i <= $scope._lastImgIndex; i++) {
$scope.filteredImages.push($scope.imagemaindiv[i]);
}
};
Following code might work for you.:).Try for this.
var data=angular.element($window);
data.bind('resize',function(){
//call your another function here:
});
try this code
<!DOCTYPE html>
<html ng-app="app">
<head>
<meta charset="utf-8" />
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
</head>
<body>
<my-directive></my-directive>
</body>
</html>
app.js
'use strict';
var app = angular.module('app', []);
app.directive('myDirective', ['$window', function ($window) {
return {
link: link,
restrict: 'E',
template: '<div>window size: {{width}}px</div>'
};
function link(scope, element, attrs){
scope.width = $window.innerWidth;
angular.element($window).bind('resize', function(){
alert();
scope.width = $window.innerWidth;
// manuall $digest required as resize event
// is outside of angular
scope.$digest();
});
}
}]);
Related
I have a simple UI-Grid application that defines a grid like this
<div ui-grid="gridOptions" ui-grid-pagination class="grid clsVendorsGrid" ui-grid-selection ui-grid-exporter right-click="rightClick($event)" context-menu="menuOptions" context-menu-class="custom_class"></div>
And then the right click event is like this
$scope.rightClick = function (event) {
$scope.gridApi.selection.clearSelectedRows();
var element = angular.element(event.toElement);
var id = element[0].parentElement.id;
This was working fine for the past few years. But since last week the event is now always null. What gives ?
I am using angular-ui-grid version 3.2.9
The error I get on right click is
TypeError: Cannot read property 'parentElement' of undefined
at m.$scope.rightClick (administrativeController.js:281)
Appreciate any inputs on this
EDIT:
I am trying to get the ID on right click, I am binding the ID like this
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
//Register this to Capture Selected Item on right click
gridApi.selection.on.rowSelectionChanged($scope,
function (row) {
if (row.isSelected) {
$scope.selectedId = row.entity.iTempId;
$scope.selectedVendor = row.entity.sBusinessnameLegal;
}
});
}
You just need to change event.toElement to event.target:
$scope.rightClick = function (event) {
var element = angular.element(event.target);
var id = element[0].parentElement.id;
...
}
Here is working snippet:
angular.module("ng-context-menu",[]).factory("ContextMenuService",function(){return{element:null,menuElement:null}}).directive("contextMenu",["$document","ContextMenuService",function(e,n){return{restrict:"A",scope:{callback:"&contextMenu",disabled:"&contextMenuDisabled",closeCallback:"&contextMenuClose"},link:function(t,l,c){function o(n,t){t.addClass("open");var l=e[0].documentElement,c=(window.pageXOffset||l.scrollLeft)-(l.clientLeft||0),o=(window.pageYOffset||l.scrollTop)-(l.clientTop||0),u=t[0].scrollWidth,i=t[0].scrollHeight,a=l.clientWidth+c,d=l.clientHeight+o,p=u+n.pageX,s=i+n.pageY,r=Math.max(n.pageX-c,0),f=Math.max(n.pageY-o,0);p>a&&(r-=p-a),s>d&&(f-=s-d),t.css("top",f+"px"),t.css("left",r+"px"),m=!0}function u(e){e.removeClass("open"),m&&t.closeCallback(),m=!1}function i(e){!t.disabled()&&m&&27===e.keyCode&&t.$apply(function(){u(n.menuElement)})}function a(e){t.disabled()||!m||2===e.button&&e.target===n.element||t.$apply(function(){u(n.menuElement)})}var m=!1;l.bind("contextmenu",function(e){t.disabled()||(null!==n.menuElement&&u(n.menuElement),n.menuElement=angular.element(document.getElementById(c.target)),n.element=e.target,e.preventDefault(),e.stopPropagation(),t.$apply(function(){t.callback({$event:e})}),t.$apply(function(){o(e,n.menuElement)}))}),e.bind("keyup",i),e.bind("click",a),e.bind("contextmenu",a),t.$on("$destroy",function(){e.unbind("keyup",i),e.unbind("click",a),e.unbind("contextmenu",a)})}}}]);
var app = angular.module('app', ['ui.grid','ui.grid.selection']);
app.config(['$compileProvider', function ($compileProvider) {
$compileProvider.debugInfoEnabled(false);
}]);
app.controller('MainCtrl', ['$scope', '$interval', function ($scope, $interval) {
var myData = [
{
"firstName": "Cox",
"lastName": "Carney",
"company": "Enormo",
"employed": true,
iTempId: 1,
sBusinessnameLegal:"sBusinessnameLegal1"
},
{
"firstName": "Lorraine",
"lastName": "Wise",
"company": "Comveyer",
"employed": false,
iTempId: 2,
sBusinessnameLegal: "sBusinessnameLegal2"
},
{
"firstName": "Nancy",
"lastName": "Waters",
"company": "Fuelton",
"employed": false,
iTempId: 3,
sBusinessnameLegal: "sBusinessnameLegal3"
}];
$scope.gridOptions = {
data: myData,
enableRowSelection: true,
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope,
function (row) {
if (row.isSelected) {
debugger
$scope.selectedId = row.entity.iTempId;
$scope.selectedVendor = row.entity.sBusinessnameLegal;
}
});
}
};
$scope.rightClick = function (event) {
var element = angular.element(event.target);
//get cellId which should look like
//1464688691229-2-uiGrid-0006-cell
var id = element[0].parentElement.id;
var regex = /(\d+)/g
var result = id.match(regex);
var rowIndex = parseInt(result[1]); //extract second numic match
// console.log(id);
//console.log("rowIndex=%d", rowIndex);
$scope.gridApi.selection.selectRowByVisibleIndex(rowIndex);
};
}]);
app.directive('rightClick', function ($parse) {
return function (scope, element, attrs) {
var fn = $parse(attrs.rightClick);
element.bind('contextmenu', function (event) {
scope.$apply(function () {
event.preventDefault();
fn(scope, { $event: event });
});
});
};
});
<!doctype html>
<html ng-app="app">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/csv.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/pdfmake.js"></script>
<script src="http://ui-grid.info/docs/grunt-scripts/vfs_fonts.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.1.1/ui-grid.min.js"></script>
<script src="ng-context-menu.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.1.1/ui-grid.min.css" type="text/css">
<link rel="stylesheet" href="main.css" type="text/css">
</head>
<body>
<div ng-controller="MainCtrl">
<p>selectedId: {{selectedId}}</p>
<p>selectedVendor: {{selectedVendor}}</p>
<div id="grid1" ui-grid="gridOptions" ui-grid-selection right-click="rightClick($event)" class="grid"></div>
</div>
</body>
</html>
I'm trying to use variable declared in directive' link: function in directive view html.
Variable which I'm trying to use is int from object which is (this object) declared as $scope variable named slider.
I'm trying to display it:
<div>
{{ slider.step }}
</div>
And printed value is aa : 1 and it's not changing althougt it should be. It's constantly 1 and it don't want to rebind :( although I'm changing this value in code later on. Take a look at full directive code. I'm changing its value in few places:
..in directive link function..
link: function($scope, el) {
$scope.slider = {
step: 1,
changeSlide: function (step) {
if(step === 1) {
this.step = 1;
console.log('changed step to 1: ' + $scope.slider.step);
}
if(step === 2) {
this.step = 2;
console.log('changed step to 2: ' + $scope.slider.step);
}
}
}
$timeout(function () {
var i = 1;
$scope.slider.changeSlide(i);
setInterval(function () {
i++; if(i === 3) i = 1;
$scope.slider.changeSlide(i);
}, 5000);
});
}
I'm chaning step in if(step === 2).
Basically that's correctly working vertical slider. The only missing thing is that I can't access current step from view and I can't display correct active dot of "which slide is currently selected". That's why I need to get this step int in view but I can not.
Here is plnkr demo.
You must use $timeout(function(){ $scope.$apply(); }); after data changed
Working example
angular.module('plunker', []);
function MainCtrl($scope) {
$scope.hello = 'World';
}
angular.module('plunker').directive('elements', function($timeout) {
return {
restrict: 'E',
scope: {
name: '='
},
template: `<div>
{{ slider }}
</div>`,
link: function($scope, el) {
$scope.slider = {
step: 1,
changeSlide: function(step) {
console.log(11, step)
if (step === 1) {
this.step = 1;
console.log('changed step to 1: ' + $scope.slider.step);
}
if (step === 2) {
this.step = 2;
console.log('changed step to 2: ' + $scope.slider.step);
}
$timeout(function(){ $scope.$apply(); });
}
}
var i = 1;
$timeout(function() {
$scope.slider.changeSlide(i);
setInterval(function() {
i++;
if (i === 3) i = 1;
$scope.slider.changeSlide(i);
}, 5000);
});
}
};
});
<!doctype html>
<html ng-app="plunker">
<head>
<meta charset="utf-8">
<title>AngularJS Plunker</title>
<link rel="stylesheet" href="style.css">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script>
document.write("<base href=\"" + document.location + "\" />");
</script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.2/angular.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<elements></elements>
</body>
</html>
How should i access URL json array data using angular.forEace.
i am trying to get data but giving some error please check below code i have added
[{
"flightsDepartur":[
{
"fare":"9,000",
"route":[
{
"source":"Delhi",
}
],
},
]
}]
$http.get('data.json').then(function(response) {
$scope.allData = response;
},function(dataStatus){
console.log(dataStatus);
});
angular.forEach($scope.allData, function(flidata) {
angular.forEach(flidata[0].flightsDepartur, function(flidatIn) {
console.log(flidatIn.fare);
});
});
check the below to get fare and route data
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = [{
"flightsDepartur":[
{
"fare":"9,000",
"route":[
{
"source":"Delhi",
}
],
},
]
}];
angular.forEach($scope.name, function(k,v) {
angular.forEach(k, function(k,v) {
console.log(k[0].fare);
console.log(k[0].route[0].source)
});
});
});
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://code.angularjs.org/1.4.12/angular.js" data-semver="1.4.9"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
</body>
</html>
The problem is you are assigning values to $scope.allData inside a promise. since the javascript asynchronous before the data being assign to $scope.allData for each loop start to execute. at that time $scope.allData was undefined. so it produces an error.
create a function and call that inside the promise to prevent the error
$http.get('data.json').then(function(response) {
$scope.allData = response.data;
callLoop()
},function(dataStatus){
console.log(dataStatus);
});
function callLoop(){
angular.forEach($scope.allData, function(flidata) {
angular.forEach(flidata.flightsDepartur, function(flidatIn) {
console.log(flidatIn.fare);
});
});
}
Try change
angular.forEach(flidata[0].flightsDepartur, function(flidatIn) {..
to
angular.forEach(flidata.flightsDepartur, function(flidatIn) {..
and when using then function to get response change to this.
$http.get('data.json').then(function(response) {
$scope.allData = response.data;
},function(dataStatus){
console.log(dataStatus);
});
Demo
var app = angular.module('anApp', []);
app.controller('ctrl', function($scope) {
$scope.allData = [{
"flightsDepartur": [{
"fare": "9,000",
"route": [{
"source": "Delhi",
}],
}, ]
}]
angular.forEach($scope.allData, function(flidata) {
angular.forEach(flidata.flightsDepartur, function(flidatIn) {
console.log(flidatIn.fare);
console.log(flidatIn.route[0].source);
});
});
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
<div ng-app="anApp" ng-controller="ctrl">
</div>
I am working in a MEAN project.
At the back end I need tinymce for cms editing.
I am using ng-view for each page content. but tiny mce is not working inside ng-view
here is my index.html file here it is working fine
<html lang="en" ng-app="AdminApp" >
<head>
<script type="text/javascript" src="/asset/tiny/tiny_mce/tiny_mce.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<script type="text/javascript" src="includes/tinymce.js"></script>
<script type="text/javascript">
tinyMCE.init({
// General options
width : "505",
height : "150",
mode : "textareas",
theme : "advanced",
extended_valid_elements : "iframe[src|width|height|name|align|type|class|frameborder]",
plugins : "autolink,lists,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,fullscreen,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount,advlist,autosave,imagemanager",
// Theme options
theme_advanced_buttons1 : "bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,search,replace,|,media,|,bullist,numlist,|,blockquote,|,undo,redo,|,link,unlink,|,",
theme_advanced_buttons2 : "fontsizeselect,forecolor,backcolor,|,preview,fullscreen,code,insertimage",
theme_advanced_buttons3 : "",
theme_advanced_buttons4 : "",
theme_advanced_toolbar_location : "top",
theme_advanced_toolbar_align : "left",
theme_advanced_statusbar_location : "bottom",
theme_advanced_resizing : true,
relative_urls : false,
remove_script_host : false,
document_base_url : "",
// Example content CSS (should be your site CSS)
content_css : "css/content.css",
// Style formats
style_formats : [
{title : 'Bold text', inline : 'b'},
{title : 'Red text', inline : 'span', styles : {color : '#ff0000'}},
{title : 'Red header', block : 'h1', styles : {color : '#ff0000'}},
{title : 'Example 1', inline : 'span', classes : 'example1'},
{title : 'Example 2', inline : 'span', classes : 'example2'},
{title : 'Table styles'},
{title : 'Table row 1', selector : 'tr', classes : 'tablerow1'}
],
// Replace values for the template plugin
template_replace_values : {
username : "Some User",
staffid : "991234"
}
});
</script>
<base href="/admin/" />
</head>
<body>
<!--div ng-view></div-->
<textarea>hello</textarea>
</body>
</html>
inside ng-view code
<textarea>home</textarea>
I am using node.js server
Please help me to solve this
Thank you
You can't use tinymce as is in angularjs applications. You should create first directive for that.
However there is already directive for that which you can use: https://github.com/angular-ui/ui-tinymce
Here is the steps to get started with it once you have downloaded ui-tinymce:
index.html
<!DOCTYPE html>
<head>
<script type="text/javascript" src="bower_components/tinymce-dist/tinymce.js"></script>
<script type="text/javascript" src="bower_components/angular/angular.js"></script>
<script type="text/javascript" src="bower_components/angular-ui-tinymce/src/tinymce.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-app="myApp">
<form method="post" ng-controller="TinyMceController">
<textarea ui-tinymce="tinymceOptions" ng-model="tinymceModel"></textarea>
<button ng-click="getContent()">Get content</button>
<button ng-click="setContent()">Set content</button>
</form>
</body>
app.js
var myAppModule = angular.module('myApp', ['ui.tinymce']);
myAppModule.controller('TinyMceController', function($scope) {
$scope.tinymceModel = 'Initial content';
$scope.getContent = function() {
console.log('Editor content:', $scope.tinymceModel);
};
$scope.setContent = function() {
$scope.tinymceModel = 'Time: ' + (new Date());
};
$scope.tinymceOptions = {
plugins: 'link image code',
toolbar: 'undo redo | bold italic | alignleft aligncenter alignright | code'
};
});
Hope, it works for you. Reference Link - http://embed.plnkr.co/vL7MqL/
Index.html
<script src="//tinymce.cachefly.net/4.0/tinymce.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular-route.min.js"></script>
<script type="text/javascript" src="tinymce.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<script src="example.js"></script>
<link href="//netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css" rel="stylesheet">
<div ng-app="plunker">
<ng-view></ng-view>
</div>
view.html
<textarea data-ui-tinymce data-ng-model="modal.one"></textarea>
change in the input doesn't change the textarea<br>
<input ng-model="modal.one">
tinymce.js
/**
* Binds a TinyMCE widget to <textarea> elements.
*/
angular.module('ui.tinymce', [])
.value('uiTinymceConfig', {})
.directive('uiTinymce', ['uiTinymceConfig', function(uiTinymceConfig) {
uiTinymceConfig = uiTinymceConfig || {};
var generatedIds = 0;
return {
require: '?ngModel',
link: function(scope, elm, attrs, ngModel) {
var expression, options, tinyInstance;
// generate an ID if not present
if (!attrs.id) {
attrs.$set('id', 'uiTinymce' + generatedIds++);
}
options = {
// Update model when calling setContent (such as from the source editor popup)
setup: function(ed) {
ed.on('init', function(args) {
ngModel.$render();
});
// Update model on button click
ed.on('ExecCommand', function(e) {
ed.save();
ngModel.$setViewValue(elm.val());
if (!scope.$$phase) {
scope.$apply();
}
});
// Update model on keypress
ed.on('KeyUp', function(e) {
console.log(ed.isDirty());
ed.save();
ngModel.$setViewValue(elm.val());
if (!scope.$$phase) {
scope.$apply();
}
});
},
mode: 'exact',
elements: attrs.id
};
if (attrs.uiTinymce) {
expression = scope.$eval(attrs.uiTinymce);
} else {
expression = {};
}
angular.extend(options, uiTinymceConfig, expression);
setTimeout(function() {
tinymce.init(options);
});
ngModel.$render = function() {
console.log("render")
if (!tinyInstance) {
tinyInstance = tinymce.get(attrs.id);
}
if (tinyInstance) {
tinyInstance.setContent(ngModel.$viewValue || '');
}
};
}
};
}]);
example.js
var myApp = angular.module('plunker', ['ngRoute','ui.tinymce','ui.bootstrap']).
config(['$routeProvider', function($routeProvider) {
console.log("init angular");
$routeProvider.when('/', {templateUrl: 'view.html', controller: 'View'});
$routeProvider.otherwise({redirectTo: '/'});
}]);
myApp.controller('View', ['$scope', function ($scope) {
console.log("View Controller");
$scope.modal = {one:"hello"};
}])
Someone asked a similar question (How to use ng-class in select with ng-options), but I'm adding mine too, because it's related to the answer of the other guy's question.
The solution is awesome, but I don't quite understand it.
The answer was creating a directive - http://plnkr.co/edit/rbc4GWBffi4eFYhbvS6u?p=preview.
I would like do the same, but the class added should be the same as items.name. How do I do that?
console.clear();
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope) {
$scope.items = [
{ name: 'foo', id: 1, eligible: true },
{ name: 'bar', id: 2, eligible: false },
{ name: 'test', id: 3, eligible: true }
];
});
app.directive('optionsClass', function ($parse) {
return {
require: 'select',
link: function(scope, elem, attrs, ngSelect) {
// get the source for the items array that populates the select.
var optionsSourceStr = attrs.ngOptions.split(' ').pop(),
// use $parse to get a function from the options-class attribute
// that you can use to evaluate later.
getOptionsClass = $parse(attrs.optionsClass);
scope.$watch(optionsSourceStr, function(items) {
// when the options source changes loop through its items.
angular.forEach(items, function(item, index) {
// evaluate against the item to get a mapping object for
// for your classes.
var classes = getOptionsClass(item),
// also get the option you're going to need. This can be found
// by looking for the option with the appropriate index in the
// value attribute.
option = elem.find('option[value=' + index + ']');
// now loop through the key/value pairs in the mapping object
// and apply the classes that evaluated to be truthy.
angular.forEach(classes, function(add, className) {
if(add) {
angular.element(option).addClass(className);
}
});
});
});
}
};
});
/* CSS goes here */
.is-eligible {
color: green;
}
.not-eligible {
color: red;
}
<!DOCTYPE html>
<html ng-app="angularjs-starter">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.2/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script>
document.write('<base href="' + document.location + '" />');
</script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<select ng-model="foo" ng-options="x.name for x in items"
options-class="{ 'is-eligible' : eligible, 'not-eligible': !eligible }"></select>
</body>
</html>
Thanks in advance
One way hard-coding this logic into the directive using option.text():
angular.element(option).addClass(option.text()); //
However, this would ignore the expression. http://plnkr.co/edit/46HndjYtg6HUbblnceNr?p=preview
Fix
app.directive('optionsClass', function ($parse) {
return {
require: 'select',
link: function(scope, elem, attrs, ngSelect) {
var optionsSourceStr = attrs.ngOptions.split(' ').pop(),
getOptionsClass = $parse(attrs.optionsClass);
scope.$watch(optionsSourceStr, function(items) {
var options = elem.find("option");
angular.forEach(items, function(item, index) {
var classes = getOptionsClass(item);
var option = options.eq(index);
angular.forEach(classes, function(add, className) {
if(add) {
angular.element(option).addClass(className);
}
});
});
});
}
};
});
https://jsfiddle.net/AndersBillLinden/ne0z9vwm/32/