$anchorScroll is not working in AngularJs - angularjs

I am working on an app that submits the form and get the result from the server which followed by HTML table view. My input form is a bit big which covers whole the screen. When the table comes then I want automatically scroll down at the table view. I used $anchorScroll from angularJs. But I am not able to achieve the result what I want. I also used $timeout to make sure the table is already exist or not and then perform $anchorScroll, but still no success. (based on this solution : Using $location and $anchorScroll to scroll a table row into view
Hear is my code.
HTML
<div data-ng-controller="searchController as searchCtrl" id="scrollArea">
<form>
//HTML input elements
<div class="buttons">
<md-button class="md-primary md-raised" ng-click="searchCtrl.gotoTable('resultTable')">Start</md-button>
</div>
</form>
</div>
<!-- Smart Table for displaying result -->
<div class="rtable" ng-show = "searchCtrl.tableViewData.length > 0" id="resultTable">
//table content
</div>
Controller
angular.module('myApp')
.controller("searchController", function($log, searchService, $scope, $location, $anchorScroll, $timeout){
var self = this;
self.gotoTable = function(resultTable)
{
$timeout(function() {
$location.hash(resultTable);
$anchorScroll();
});
};
});
I dont know why its not working?
Do i need to define the id scrollArea and resultTable in my CSS?
Any help would be appreciated.
Thanks in advance.
UPDATE
Based on Okazari's solution, I tried to put a another div with many br tag above at the very bottom of my HTML. Now When I refresh the page then it automatically scroll to that div tag without clicking Start. this is a bit weird. I also tried to cover the
<div class="rtable" ng-show = "searchCtrl.tableViewData.length > 0" id="resultTable">
tag with another div tag with id = "resultTable".
But still it did not work.

You actually are invoking your function without any parameters
ng-click="searchCtrl.gotoTable()"
whereas in your controller you expect to have one :
self.gotoTable = function(resultTable)
Try something like this
ng-click="searchCtrl.gotoTable('resultTable')"
or this :
self.gotoTable = function()
{
$timeout(function() {
$location.hash("resultTable");
$anchorScroll();
});
};
(just one, not both)
Hope it helped.
EDIT : Pretty sure that you can't go to a hidden div. As i said in comment your ng-show may be evaluated to true when you try to anchorscroll().
Here is a working plunker without ng-show. I'll build a tiny solution to avoid the ng-show issue.
To avoid this side effect, i wrapped the div with ng-show with another div.
<div id="resultTable">
<div class="rtable" ng-show = "searchCtrl.tableViewData.length > 0">
</div>

Related

ng-click is not working in kendo editor

I'm trying to insert an html tag with ng-click event in the kendo editor. When I get the inserted data and show in a div, ng-click is not working. The normal onclick in javascript is working fine, but ng-click is not.
The below given is the <a> tag inserted on the editor text area.
<a ng-click="testMsg()"><span>' + nodeId + '</span></a>
Any idea on how to resolve this ?
onclick is DOM native event handler but ng-click isn't. Only those functions that are registered in the scope will be available. Any built-in functions will NOT be available to ng-click without an explicit assignment to the scope as my example shows.
var app = angular.module('app1', []);
app.controller('ctrl1', ['$scope', function($scope) {
function testMsg() {
alert('Hello world');
}
$scope.goodTestMsg = testMsg;
}]);
<div ng-app="app1" ng-controller="ctrl1">
<p ng-click="goodTestMsg()">Click me will show a message</p>
<p ng-click="testMsg()">Click me should happen nothing</p>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
TL;DR: The method testMsg is not exposed to the controller scope. Try adding something like $scope.testMsg = testMsg; will solve your problem.
Instead of textarea, try using div. I am facing similar problem which was partially solved with div. However it will be inline editing as the toolbar will get hidden and it will be displayed only when you focus cursor on the div.

AngularJS - looking to add and remove an iframe based on dom events

I would like to add an iframe to a page when certain links are clicked and remove it when other mouse events happen on the page. From what I can see, it seems that using an AngularJS directive would be the best way to do this. What I'm not sure about is what is the best way to format the directive. I'm thinking of making the directive at the attribute level...something like this:
<div myIframeDirective></div>
What I'm not sure of is the best way of removing/adding the directive contents (an iframe and a header above it) when various click events happen on the main page. Not looking for anyone to write the code for me...just looking for examples of how this can be best accomplished.
You should be using ng-if.
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
Here's a working example:
var app = angular.module('app', []);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<iframe src="http://www.example.com/" ng-if="showIframe"></iframe>
<button ng-click="showIframe = !showIframe">Click me to show/hide the iframe</button>
</div>
In Angular, ng-if will remove the iframe from the DOM if it is false.
This means the URL will NOT be requested until ng-if is true.
<iframe ng-if="frameDisplayed" ng-src="{{src}}"></iframe>
And use the link
Toggle
Then in your controller, you can control what your iframe display:
$scope.src = 'https://angularjs.org';

angular directives comment section

I am working on a website that displays numerous articles. Each article has a comment section. I have effectively been able to recursively write the comments to the DOM with recursion inside an ng-repeat. However, I need to be able to click on a respond button on any of the comments (they display in a nested fashion) and for a div to be inserted beneath the clicked button. This div would contain a text area for the comment they want to submit and a button. When this second button is clicked, the controller will save the comment to the database. I initially wanted to do this by directly manipulating the DOM from the controller. However, after further research, that would be in direct violation of the MVC/MVW pattern. I believe the correct answer is to create a custom directive. Please give me some insight on how to correctly do this. Any and all information would be very helpful. Thanks in advance.
If you want to add response div dinamically:
<div ng-repeat="article in articles" id="article-{{$index}}">
<p>{{article.content}}</p>
<button ng-click="addAnswer($index)">Add Answer</button>
</div>
js:
myApp.controller("articlesController", function($compile){
$scope.addAnswer = function (index) {
var div = $("<div></div>");
var input = $("<input type='text' ng-model='article.response'></input>");
div.append(input);
var button = $("<button>Send</button>");
button.attr("ng-click", "sendResponse(article)");
$compile(div)($scope);
$("#article-" + index).append(div);
};
});
You don't really need to make a directive to achieve this.
html:
<div ng-repeat="article in articles">
<p>{{article.content}}</p>
<input type="text" ng-model="article.response"></input>
<button ng-click="sendResponse(article)">Send</button>
</div>
js:
myApp.controller("articlesController", function($http){
$scope.sendResponse = function (article) {
console.log(article.response);
$http.post(url, article);
};
});
Of course, you can do it better by hidding input and send button, and show it after user clicks over an answer button.

AngularJS's ng-model icm textarea

I'm trying to add some text to the last cursor place after clicking a button.
In the controller:
$scope.addEmoji = function(name){
var element = $("#chat-msg-input-field");
element.focus(); //ie
var selection = element.getSelection();
var textBefore = $scope.chatMsg.substr(0, selection.start);
var textAfter = $scope.chatMsg.substr(selection.end);
$scope.chatMsg = textBefore + name + textAfter;
}
$scope.updateChatMsg = function(chatMsg){
$scope.chatMsg = chatMsg;
}
$scope.sendChatMsg = function(){
var backend = $scope.convs[$scope.active.conv].backend.name;
$scope.view.addChatMsg($scope.active.conv, $scope.active.user, $scope.chatMsg,new Date().getTime() / 1000, backend);
Chat[backend].on.sendChatMsg($scope.active.conv, $scope.chatMsg);
$scope.chatMsg = '';
};
And then some HTML:
<div class="chat-msg-button" >
<button ng-click="view.toggle('emojiContainer')" ><img src="/apps/chat/img/emoji/smile.png"></button>
</div>
<form id="chat-msg-form" ng-submit="sendChatMsg()">
<div class="chat-msg-button" >
<button type="submit"><div class="icon-play"> </div></button>
</div>
<div id="chat-msg-input">
<textarea id="chat-msg-input-field" autocomplete="off" type="text" ng-model="chatMsg" ng-change="updateChatMsg(chatMsg)" placeholder="Chat message"></textarea>
<div>{{ chatMsg }}</div>
</div>
</form>
What I'm trying to achieve: a user types some text in the textarea => $scope.chatMsg gets the value of the textarea. Now the user press one of the button's => the name of the button is added to the latest cursor position. (it's no problem to find the latest cursor position)
The problem
There is a difference between the value of $scope.chatMsg, {{ chatMsg }} inside the div and the text in the textarea.
The contents of the textarea and the div stays always the same. But when pressing the button the name is added to $scope.chatMsg but the contents of the textarea isn't changed...
How can I solve this?
TIA
First of all, you're mixing jQuery with AngularJS, it doesn't look like you need jQuery here that much.
Also, your chat message is updated in 3 different functions, so you need some debugging to see which are fired.
In general:
To solve your issue, try some more debugging, do a
$scope.$watch($scope.chatMsg, function(){
console.log($scope.chatMsg);
});
this will watch all changes to chatMsg. Add console.log() to each of your functions and you can watch which is fired.
Also, rather than using {{ }} inside your div just use ng-bind since that text is the only item in your div, it's cleaner if your app crashes somewhere.
// change from
<div>{{ chatMsg }}</div>
// to
<div ng-bind="chatMsg "></div>
Update: after seeing your plunker, I modified it and came up with this: http://plnkr.co/edit/oNKGxRrcweiJafKCm9A5?p=preview
Your ng-repeat needs to be tracked by $index so that duplicates are displayed rather than crashing when someone creates the same message
I solved all problems. The plunkr form above works. So after investigating all scopes with the Angular chrome extension I saw that chatMsg was defined in another scope. Thus not in the scope I was trying to acces it from.
Via this question angularJS ng-model input type number to rootScope not updating I found a solution.
I added chatMsg to the fields object.

How to create set of div blocks using AngularJs

I am newbie to AngularJs. I need to create set of div blocks (given as code) on button click.
<div>
<div>Div A</div>
<div>Div B</div>
<div>Div C</div>
</div>
I have done this using hard coded divs Demo. But I just need to use ng-repeat and directives. Any help will be appreciated.
Using ng-click is the way to go for binding the click event to your button. You should not be trying to handle button clicks with a directive. The demo you have is very close to what you need. There is a working Plunk HERE, but the general guts of it follow:
<button ng-click="myFunction()">Add</button>
<div ng-repeat="item in myList">
<div>{{item.A}}</div>
<div>{{item.B}}</div>
<div>{{item.C}}</div>
</div>
$scope.myList = [];
$scope.myFunction = function(){
var myItem = {A:someValue, B:someOther, C:someThing};
$scope.myList.push(myItem);
};
The divs that hold the items could also make use of directives to change them somehow, but that is quite a bit more code. There are plenty of SO answers and Angular documentation that show you how to write directives, so I won't repeat them here.

Resources