adding ngAnimate to controller makes app to not displaying content - javascript

I'm trying to add animation when changing the content inside a my html using ng-inculde, but when ever i add ['ngAnimate'] in the declaration of the controller all of the content inside the main tag simply dissapear.
HTML:
<div ng-app="myApp">
<div ng-controller="firstCtrl">
<div id="wrapper">
<main ng-init="nav('data/table.html')">
<div ng-include="filePath">
</div>
</main>
</div>
</div>
</div>
JS:
var myApp = angular.module("myApp",['ngAnimate']);
myApp.controller ('firstCtrl', function($scope, PersonService){
$scope.users = PersonService.list();
$scope.saveUser = function () {
PersonService.save($scope.newuser);
$scope.newuser = {};
}
$scope.nav = function(path){
$scope.filePath = path;
}
})
this code wont work since im adding ['ngAnimate'] but if i'll delete it and keep the brackets empty the content will display. can someone tell me why and if its the correct way to get the animation when the content changes (table.html changes to a different file)
this is the header part incase needed:
<head lang="en">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular-sanitize.js"></script>
<script src="https://code.angularjs.org/1.2.6/angular-animate.js"></script>
<script src="js/angular.min.js"></script>
</head>

Give reference of angular-animate.min.js file in order to use 'ngAnimate' module. You have to give reference of this file after angular.min.js.

Related

How to add code cells to HTML page with Javascript and Ace.JS?

Is it possible to create several text editor cells within a single page? My desired outcome is to have a button that when clicked allows the user to add new cells of code, where the user can write and later run. Similar to Jupyter notebook. The editor itself is imported from the ace.js library.
For that, I think I need some function add_editor(parent_div) that adds a new text editor to a div that is given as a parameter. ( Which I have failed to implement )
My initial thoughts are perhaps to create a shared class for all of the editors and append it to the father div with jQuery, but when I tried using a class instead of an id for the design,the editor won't load.
I'm not so good with handling with the DOM (especially without React), so even if the solution seems obvious to you, it might not to me.
This is last working version of the code that I have so far
<html lang="en">
<head>
<title>ACE in Action</title>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!-- Define the editor's CSS !-->
<style type="text/css" media="screen">
#editor {
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div class="row">
<!-- a row of two columns: the first will contain the text editors, the second is irrelevant !-->
<div class="col-9" style="height:200px;">
<div class="container" style="">
<div id="editor">
<!-- the div containing the code, has the id "editor" !-->
def print_something():
print(a)
</div>
</div>
</div>
<div class="col-3">
empty column
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.5/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
function configure_editor(){
var editor = ace.edit("editor");
editor.setTheme("ace/theme/monokai");
editor.session.setMode("ace/mode/python");
editor.getSession().setUseWrapMode(true);
editor.setShowPrintMargin(false);
}
configure_editor()
</script>
</body>
</html>
Help will be much appreciated!
Edit: I need to solve this in Javascript or Jquery, without React.
A cleaner method is to assign an editor to each instance using your own structure. With jquery:
<div id="instance0"></div><div id="instance1"></div>
<script>
var instances[];
var $rootElement = $('#instance0');
newInstance($rootElement);
var $rootElement = $('#instance1');
newInstance($rootElememt);
function newInstance($rootElement){
var instance = {};
instance.id = $rootElement.attr('id');
instance.$root = $rootElement;
instance.editor = ace.edit($rootElement[0]);
instance.editor.instance = instance;
instances.push(instance);
}
</script>
This gives you a 1 to 1 instance to editor relationship with backpointers. It will save you much angst in the future. You can just flip in sessions and keep the editors static.
I think I have found somewhat of a solution on my own with jQuery, even though it seems messy.
Each time a new editor will be added with increasing ids, i.e : "editor0", "editor1", "editor2", and so on.
Here is the full code
<html lang="en">
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<title>ACE in Action</title>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<!-- Define the editor's CSS !-->
</head>
<body>
<div class="row">
<!-- a row of two columns: the first will contain the text editors, the second is irrelevant !-->
<div class="col-9" style="height:200px;">
<div id="editors_container">
</div>
</div>
<div class="col-3">
<button id="add_editor">Add a new editor</button>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.5/ace.js" type="text/javascript" charset="utf-8"></script>
<script>
existing_editors = [];
$(document).ready(function(){
$("#add_editor").click(function(){
console.log("reached here!")
let editor_id = "editor"+existing_editors.length;
$newDiv = $("<div id="+editor_id+" style=width:100%;height:100%>"+"</div>");
$("#editors_container").append($newDiv);
let editor = ace.edit(editor_id);
editor.setTheme("ace/theme/monokai");
editor.session.setMode("ace/mode/python");
editor.getSession().setUseWrapMode(true);
editor.setShowPrintMargin(false);
existing_editors.push(editor);
});
});
</script>
</body>
</html>

Angularjs two-way binding in index.html

I am new to Angularjs. I am trying to build a simple system with a login page and it will redirect to another page after successfully logged in.
I am trying to show all the pages in index.html with ng-view (including login page). I try to use ng-if to decide when to show the navigation bar on top of the page.
The value of vm.page will not change after logged in
index.html
<html ng-app="myApp">
<head>
<title></title>
<link href="css/bootstrap.min.css" rel="stylesheet"/>
<link href="css/custom.css" rel="stylesheet"/>
<script src="jquery/jquery-3.3.1.min.js"></script>
<script src="node_module/angular/angular.js"></script>
<script src="node_module/angular-route/angular-route.js"></script>
<script src="app.js"></script>
<script src="controllers/login-controller.js"></script>
</head>
<body>
<div ng-controller="LoginController as lg" >
<div ng-if="lg.page != 'Login'" ng-include="'view/navigation-top.html'"></div>
</div>
<div ng-view></div>
</body>
login-controller.js
angular.module('myApp').controller("LoginController", LoginController);
function LoginController($http, $location, $scope) {
var vm = this;
vm.page = "Login";
vm.login = function(){
vm.page = "Main";
$location.path('/')
}
}
It is working when the vm.page is initiate and set to "Login", but the page does not change when i set it to "Main".
Appretiate if anyone can help me, thank you :D
The problem is the $location.path('/') call in your Login-Function. This will navigate to /index.html and re-initialize the LoginController. Therefore the vm.page variable is reset to 'Login'.
Remove the location.path() or create a service which reatains the Page/Login-State.

Adding Config/RouteProvider breaks ng-repeat

This issue is most likely due to my naivity as I am just beginning to teach myself JS and AngularJS in parallel. I have put together a simple example of what I am seeing in this plunker. Basically, my app handles an ng-repeat correctly, but as soon as I add the config method it does not replace {{menuItem.itemName}} with the value of the variable. Now, my config method is currently empty, so that may be the problem. But, I assumed I could just have a no-op method and add routes as I went, testing each one.
Here is my HTML:
<html ng-app="site">
<head>
<script src = https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.5/angular.min.js></script>
<script src ="script.js"></script>
<link href="http://fonts.googleapis.com/css?family=Great+Vibes" rel="stylesheet" type="text/css">
<title>Site</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body ng-controller='mainCtrl'>
<div id="main-container">
<div id="header">Site
</div>
<div id="side-bar">
<ul id="side-bar-menu">
<li ng-repeat="menuItem in menuItems"><span class="underline"><a ng-href={{menuItem.itemLink}}>{{menuItem.itemName}}</a></span></li>
</ul>
</div>
</div>
</body>
</html>
JS:
'use strict';
angular.module('site',[]).
controller('mainCtrl', ['$scope', function($scope) {
$scope.menuItems = [{
itemName: "Home",
itemLink: "#Home"
}];
}]);
//enabling the config breaks the output (and of course ;
//above needs to be replaced with . when config enabled)
/*config(['$routeProvider', function($routeProvider) {}]);*/

Javascript: DOM elements updated via jquery.get() aren't responding to extant page listeners

I'm trying to update the content of a div (#slide-content) on clicking certain navigation elements (h2.pagenav). The content structure is uniform, and each requested HTML document contains two such nav elements ('Previous','Next'). However, my listener only fires onceā€”for click events on the initial nav button present at page load, and I don't understand why.
My understanding is that when using jQuery's append() function instead of html(), the appended content should be registered with the DOM and thus available for event listening. Lil' help?
The page structure is pretty simple:
The HTML
<?php require('common.php'); ?>
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Ethogram Lab</title>
<link rel="stylesheet" href="css/foundation.css"/>
<link rel="stylesheet" href="css/foundation-icons.css"/>
<link rel="stylesheet" href="css/app.css"/>
<script src="js/vendor/modernizr.js"></script>
</head>
<body>
<div id="slide-content">
<div class="slide">
<div class="row">
<div class="row">
<!---- content ---->
</div>
<div class="row">
<div class="small-4 small-centered columns">
<h2 data-link="slide_0" class="medium button expand text-center pagenav">Start <i class="fi-play"></i></h2>
</div>
</div>
</div>
</div>
</div>
</div>
<script src='js/vendor/jquery.js'></script>
<script src='js/foundation.min.js'></script>
<script>
$(document).foundation();
</script>
<script src='js/app.js'></script>
</body>
</html>
The Javascript
And here is the relevant it of app.js
/**
* PAGE VARS
*/
var DS = '/';
var WEBROOT = "127.0.0.1"+DS+"ethogram"+DS;
var PHP = ".php";
/**
* DOM LISTENERS
*/
$(".pagenav").click(function() {
console.log("*** pagenav listener has fired");
var loc = $(this).attr('data-link');
var pageNum = loc.substr(-2) == "_" ? loc.substr(-1) : loc.substr(-2);
var URL = WEBROOT+"slides"+DS+loc+PHP;
$.get(URL, function(data) {
$("#slide-content").html('').append(data).fadeIn();
});
});
The ".on()" function should be used. ".live()" is deprecated.
.on() function
$("body").on("click", ".pagenav", function() {
// do something
});
You should use
$("body").on ("click",".pagenav",function(){
// Your code go here
})
This function will detect the items created programatically
See Documentation

Apply in progress in Angular.JS

I have angularjs application and <span> in it. I try to hide it with ng-hide directive, but:
<span ng-hide="hideSpan">
And
// controller code here
....
$scope.hideSpan = true;
....
Doesn't work, it's ignoring. And if i make:
// controller code here
....
$scope.$apply(function(){$scope.hideSpan = true});
....
I get error: $apply already in progress.
How can i correctly use ng-hide/ng-show in this way?
Thank you.
You should be able to directly control the hide/show functions from your controller just as you show. The following is working example using a button to trigger toggling of hide show.
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="myapp" ng-controller="mycontroller">
<span ng-hide="hideSpan">Some Content to hide</span>
<button ng-click="toggleHide()"/>Toggle Hide</button>
</body>
</html>
And the script.
angular.module('myapp', []).controller('mycontroller', function($scope){
$scope.hideSpan = true;
$scope.toggleHide = function(){
if($scope.hideSpan === true){
$scope.hideSpan = false;
}
else{
$scope.hideSpan = true;
}
}
});
I've created a simple plunker to show this in action at http://plnkr.co/edit/50SYs0Nys7TWmJS2hUBt?p=preview.
As far as why the $apply is causing an error, this is to be expected as direct scope (provided by the $scopeProvider) variable operations are already watching for change and wrapped into a default apply of sorts in core angular so any change will be automatically applied to the other bindings of that variable.
you can just change the hideSpan value in ng-click, save few lines. cheers
<!DOCTYPE html>
<html>
<head>
<script data-require="angular.js#1.1.5" data-semver="1.1.5" src="http://code.angularjs.org/1.1.5/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="myapp" ng-controller="mycontroller">
<span ng-hide="hideSpan">Some Content to hide</span>
<button ng-click="hideSpan=!hideSpan"/>Toggle Hide</button>
</body>

Categories