How to set border style for img element in AngularJS - javascript

This is a beginners question in AngularJS.
I'm writing a simple application to show a few images and allow the user to toggle selection. Only one image should be selected at any one time.
Anyway, how to set the style to change the border for the img tag. When the user clicks on an image the style should be set. Neither setting the style or custom style myStyle is working (style not applied).
<!DOCTYPE html>
<html ng-app>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script >
function myCtrl($scope, $window) {
$scope.vm = {};
$scope.vm.Courses = [
{ Id: 1, Name: "Course 1"},
{ Id: 2, Name: "Course 2"}
];
$scope.ToggleCourse = function(imageElement) {
console.log("id = " + imageElement.id);
imageElement.style = "{border:'2px solid blue'}"; // doesnt work
imageElement.myStyle = "{border:'2px solid blue'}"; // neither does this///
}
}
</script>
</head>
<body ng-controller="myCtrl">
<div>
<div ng-repeat="course in vm.Courses">
<div>
<div ng-click="ToggleCourse($event.target)">
<label>{{course.Name}}</label>
<img id="card{{course.Id}}" src="course.png" ng-style="myStyle">
</div>
</div>
</div>
</div>
</body>
</html>

You are doing it wrong. Don't use DOM manipulations at all. Just forget about this possibility until you understand why. Instead use ngClass directives (also don't use ngStyle):
<!DOCTYPE html>
<html ng-app>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script >
function myCtrl($scope, $window) {
$scope.vm = {};
$scope.vm.Courses = [
{ Id: 1, Name: "Course 1"},
{ Id: 2, Name: "Course 2"}
];
$scope.ToggleCourse = function(course) {
$scope.selected = course;
}
}
</script>
<style>
.selected img {border: 2px solid blue;}
</style>
</head>
<body ng-controller="myCtrl">
<div>
<div ng-repeat="course in vm.Courses">
<div>
<div ng-click="ToggleCourse(course)" ng-class="{selected: course === selected}">
<label>{{course.Name}}</label>
<img id="card{{course.Id}}" src="course.png" ng-style="myStyle">
</div>
</div>
</div>
</div>
</body>
</html>

Replace the ng-style="myStyle" with:
ng-class="myStyle"
And define the class in CSS:
.myStyle {border: 2px solid #999;}
The above is the cleaner method as it just sets the necessary class for the <img /> element and you can style it, so that the presentation and styles are separated. You can also use the $scope and define a function and inject the styles.

Related

Create multiple divs using ng-repeat

I want to create 'n' red blocks with text (n here means the number of elements in array). But, I am getting a blank page.
<html>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<style>
.card-main {
width: 100px;
height: 100px;
border: 1px solid red;
background-color: red;
}
</style>
<!-- look here start -->
<div class="card-main" ng-app="myApp" ng-controller="myCtrl" ng-repeat="x in type">
<p>{{x}}</p>
</div>
<!-- look here end -->
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.type = ["Any", "T1", "T2", "T3"];
$scope.state = ["Any", "S1", "S2"];
});
</script>
</body>
</html>
ng-repeat has very high priority, it is applied before ng-controller e.g.
<div ng-repeat="..." ng-controller="..."
will render several divs with several controller instances, not several divs inside one controller.
To start, just put ng-app, ng-controller and ng-repeat on different elements:
<div ng-app ...
<div ng-controller ...
<div ng-repeat ...

On change input in parent send val to iframe with update

I need update iframe's content on input[text] changed(or on some another event).
For example: I'm typing in parent's input "Hello World!!!", and iframe's <h1>Hi</h1> is changing to
<h1>Hello World!!!</h1> symbol by symbol.
Better if solution will be on jQuery, but vanilla js is ok, too))
Thank you very much.
P.S. Sorry for my bad English(
better way is using Window.postMessage => https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
parent Page:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>a Page..</title>
<style>
body { font-size: 16px; font-family: Arial, Helvetica, sans-serif; }
iframe { width: 300px; height: 200px; border: 1px solid #4593c6; }
</style>
</head>
<body>
<p>parent input :
<input id="in-Txt" type="text" placeholder="type something">
<button id="Bt-Send2iFrame">Send2iFrame</button>
</p>
<iframe id="in-Frame" src="xyz_frame.html" ></iframe>
<script>
const inText = document.querySelector('#in-Txt')
, btSend = document.querySelector('#Bt-Send2iFrame')
, inFramW = document.querySelector('#in-Frame').contentWindow
btSend.onclick=_=>{
let info = { inTxt: inText.value }
inFramW.postMessage( JSON.stringify(info), "*")
}
</script>
</body>
</html>
iframe page
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
<p> the iframe </p>
<p id="info-Parent">...</p>
<script>
const infoParent = document.querySelector('#info-Parent')
window.onmessage=e=>
{
let message = JSON.parse ( e.data )
infoParent.textContent = message.inTxt
}
</script>
</body>
</html>
You can pass the value on the parent page as a parameter to the iframe.
Say for example the following
Parent HTML,
<input type="text" id="parenteElem">
<iframe id="frameOnParent">
Parent Script:
<script type="text/javascript">
$("#parentElem").on("change", function(event) {
$('#frameOnParent').attr('src', "test.html?param1=" + $(this).val());
})
</script>
Iframe HTML:
<h1>Hi</h1>
Iframe Script:
<script type="text/javascript">
function getHeader() {
var headerText = window.location.search.substring("param1");
return headerText;
}
var heading = getHeader();
$("h1").html(heading);
</script>

Angular Js hide Div one by one with animation

I am looking to fadeout all Div (with css property display set to inline:block) with same class randomly one-by-one until 1 last random div remains. I am certainly able to do it with jquery but I am unable to make it work with fadeOut inline:block property.
So my div are aligned next to each other like
and I would need to hide them randomly one by one.
After a random div is removed
the removed div space should be retained as in css property visibility:hidden and the last div number which is left will be shown in JavaScript alert.
Here is my staring code
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="lib/style.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-animate.min.js"></script>
<script src="lib/script.js"></script>
</head>
<body class="container" ng-app="animateApp" ng-controller="mainController">
<div class="row">
<div class="col-xs-12">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
</div>
</div>
</body>
</html>
Here is the fiddle https://plnkr.co/edit/OG1EmWjQi1bHj5OC69Z7?p=info
Any help is really appreciated.
You can define how items are hidden through the ng-hide CSS class. You can override the display attribute to keep it as inline-block, and use CSS animations to fade it away.
// Add your code here
angular.module("animateApp", [])
.controller("mainController", function($scope, $timeout) {
$scope.data = [1, 2, 3, 4, 5];
var hidden = [];
$scope.shouldHide = function(index) {
return hidden.indexOf(index) >= 0;
};
function hideRandom() {
if ($scope.data.length - 1 < hidden.length) {
return;
}
var randomTime = Math.floor(Math.random()*1000)
var randomElem = Math.floor(Math.random()*$scope.data.length);
while (hidden.indexOf(randomElem) >= 0) {
randomElem = Math.floor(Math.random()*$scope.data.length);
}
$timeout(function() {
hidden.push(randomElem);
hideRandom();
}, randomTime);
}
hideRandom();
});
/* Add your styles here */
.item{
height:30px;
width:30px;
display:inline-block;
border:1px solid #000000;
}
.item.ng-hide {
transition:0.5s linear opacity;
opacity:0;
display:inline-block !important;
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.19/angular.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.20/angular-animate.min.js"></script>
</head>
<body class="container" ng-app="animateApp" ng-controller="mainController">
<div class="row">
<div class="col-xs-12">
<div class="item" ng-repeat="i in data track by $index" ng-show="!shouldHide(i)">{{i}}</div>
</div>
</div>
</body>
</html>

" Cannot read property 'then' of undefined" in angular drag n drop

I am trying to use angular drag and drop http://codef0rmer.github.io/angular-dragdrop, but when I am trying a basic example, i am getting the error. My code -
<apex:page standardStylesheets="false" sidebar="false" showHeader="false">
<style>
table, th , td {
border: 1px solid grey;
border-collapse: collapse;
padding: 5px;
}
</style>
<html ng-app="myApp">
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.1.1/css/bootstrap-responsive.min.css" rel="stylesheet" />
<div ng-controller="dragDropController">
<div class="row-fluid">
<div class="span6">
<div class="btn btn-primary" data-drag="true" ng-model="list" jqyoui-draggable="{animate: true}">{{list.title}}</div>
</div>
<div class="span6">
<div class="thumbnail" data-drop="true" ng-model="droppedList" jqyoui-droppable="{beforeDrop: 'beforeDrop'}"></div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1/jquery-ui.min.js"></script>
<script src="https://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.2/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script>
<script src="{!$Resource.AngularDragDrop}" />
<script>
angular.module('myApp', ['ngDragDrop']).controller('dragDropController', function($scope, $http) {
$scope.list = {title : 'Drag me..!!'}
$scope.droppedList = {title: 'Drop place'};
$scope.beforeDrop = function() {
console.log('Before dropping..!!');
};
});
</script>
</html>
</apex:page>
Can someone help me with same.??
I have tried using same different versions of angular and also tried copying angular version from the actual site example but still facing same error
Thanks,
Ray
The beforeDrop function should return a promise (documentation).
The plugin executes your beforeDrop, where you would typically ask the user for confirmation, and then it "drops" (or not).
As you are not waiting for user input, to get rid of the error you could inject $q and return the dummiest promise, so to speak:
$scope.beforeDrop = function () {
console.log('Before dropping..!!');
return $q.when();
}
But the final look of beforeDrop will be more like:
$scope.beforeDrop = function () {
// open modal
// ...
return modalPromise;
}

Angular ng-bind not updated when value changes

I want to bind the content of a span element (that is the current position of the element).
Problem: when I change the element position, angular doesn't update the value of the ng-bind attribute.
This is my html:
!doctype html>
<html lang="en" ng-app="exempleApp">
<head>
<meta charset="utf-8">
<title>jQuery UI Draggable - Default functionality</title>
<link rel="stylesheet" href="jquery-ui.css">
<script src="jquery2.1.4.js"></script>
<script src="jquery-ui.js"></script>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript" src="exempleApp.js"></script>
<link rel="stylesheet" href="/resources/demos/style.css">
<style>
.movable { width: 150px; height: 150px; padding: 0.5em; background- color: green;}
</style>
<script>
$(function() {
$( ".movable" ).draggable(
{
drag: function(){
var offset = $(this).offset();
var xPos = offset.left;
var yPos = offset.top;
var thisId = $(this).attr('id');
$('#' + thisId + ' .posX').text(xPos);
$('#' + thisId + ' .posY').text(yPos);
}
}
);
});
</script>
</head>
<body ng-controller="imgController as ctrl">
<div id="1" class="ui-widget-content, movable" >
<p>Drag me around</p>
<span class="posX" ng-bind="ctrl.presentation.images[0].posX"></span>
<span class="posY" ng-bind="ctrl.presentation.images[0].posY"></span>
</div>
<div id="2" class="ui-widget-content, movable" >
<p>Drag me around</p>
<span class="posX" ng-bind="ctrl.presentation.images[1].posX"></span>
<span class="posY" ng-bind="ctrl.presentation.images[1].posY"></span>
</div>
<div >
<span ng-bind="ctrl.presentation.images[0].posX"></span>
<span ng-bind="ctrl.presentation.images[0].posY"></span>
</div>
</body>
</html>
And this is my exempleApp.js:
(function() {
var app = angular.module("exempleApp", []);
app.controller('imgController', function(){
this.presentation = pres;
});
var pres = {
images: [
{
posX: "0",
posY: "0"
},
{
posX: "0",
posY: "0"
}
]
};
})();
Thanks for the help
https://docs.angularjs.org/api/ng/directive/ngBind
Typically, you don't use ngBind directly, but instead you use the
double curly markup like {{ expression }} which is similar but less
verbose.
Try this:
<span class="posX">{{ctrl.presentation.images[1].posX}}</span>
Full explanations Databinding in AngularJS
I may have misunderstood your question. It's my understanding that ng- bind binds the value of the html to the value of the object. That is, it's going to read the value from the object, not set it. So when the object changes, the html gets updated. Not the other way around.
#Veo
<p>drag.html</p>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Dragger</title>
<script src="js/jquery.js" type="text/javascript"></script>
<script src="js/jquery-ui.js" type="text/javascript"></script>
<script src="js/angular.js" type="text/javascript"></script>
<script src="js/drag.js" type="text/javascript"></script>
<link rel="stylesheet" href="css/bootstrap.min.css">
<style>
.movable { width: 150px; height: 150px; padding: 0.5em; background- color: green;}
</style>
<body ng-app="exempleApp">
<div ng-controller="imgController">
<div id="1" class="ui-widget-content movable" drag>
<p>Drag me around</p>
<span class="posX">{{presentation.images[0].posX}}</span>
<span class="posY">{{presentation.images[0].posY}}</span>
</div>
<div id="2" class="ui-widget-content movable" drag>
<p>Drag me around</p>
<span class="posX">{{presentation.images[1].posX}}</span>
<span class="posY">{{presentation.images[1].posY}}</span>
</div>
<div>
<span>#1 .movable = </span>
<span ng-bind="presentation.images[0].posX"></span>
<span ng-bind="presentation.images[0].posY"></span>
</div>
<div>
<span>#2 .movable = </span>
<span ng-bind="presentation.images[1].posX"></span>
<span ng-bind="presentation.images[1].posY"></span>
</div>
</div>
<script>
$(function() {
$( ".movable" ).draggable();
});
</script>
</body>
</html>
<p>drag.js</p>
var app = angular.module("exempleApp", []);
app.controller('imgController', function($scope){
$scope.presentation = pres;
});
app.directive('drag', function(){
return {
link: function(scope, element, attrs){
//initial position
scope.presentation.images[attrs.id-1].posX = element.position().left;
scope.presentation.images[attrs.id-1].posY = element.position().top;
//position after drag
element.on('drag', function(){
scope.presentation.images[attrs.id-1].posX = element.position().left;
scope.presentation.images[attrs.id-1].posY = element.position().top;
console.log(scope.presentation.images[attrs.id-1]);
scope.$apply();
})
}
}
})
var pres = {
images: [
{
posX: "0",
posY: "0"
},
{
posX: "0",
posY: "0"
}
]
};
<p>Note changes: - 1)created a drag directive.then apply it to div.movable.
2)initial position will give you position of draggable div on page load.
3)scope.$apply(); plays important role here without this values will not be apply changes. for more information about $apply visit $apply
<p>if you have any problems just ask me</p>

Categories

Resources