How can I scroll down to bottom of a specific div on page load in a chat conversation using Nuxt.js? - adonis.js

I want scroll down to the last div
<div v-for="(message, message_index) in messageArray" :key="message_index">
<div class="chatList">
</div>
</div>

I'm assuming you have a chat component where you want to scroll down to the last message on page load.
Although there are many ways to achieve this, I found this is the simplest one.
scrollIntoView() inside this.$nextTick(function () {}) gets the job done.
Bind your every div inside the loop with unique id. :id="`m-(some_unique_id)`">
<div v-for="(message, message_index) in messageArray" :key="message_index">
<div :id="`m-${message.id}`">
</div>
</div>
and get the element of the last index of messageArray. And tell the scrollIntoView to scroll down to that div.
script
<script>
mounted: {
this.getChatBoxUsersChats();
},
methods: {
getChatBoxUsersChats() {
this.$nextTick(function () {
let length = this.messageArray.length;
if (length > 0) {
let id = this.messageArray0[length - 1].id;
let element = document.getElementById("m-" + id);
element.scrollIntoView({ behavior: "smooth", block: "end" });
});
},
},
}
</script>

Related

Angular Function that is always loading (automatically)

I have a function that loads referring data and images and another that loads the image itself from a folder.
Is there a way to always have the function that loads images, always working? That is, if you upload an image, this function will be automatically executed and will upload that image.
At the moment I am executing the function using (click), but what I want is that it is always being executed automatically.
HTML
<div class="container-fluid first">
<div class="row tab-pane Galeria">
<div *ngFor="let product of products" (click)="ImageInfo($event,product.id)" class="col-xl-2 col-lg-3 col-md-4 col-sm-6">
<div class="image-item">
<a class="d-block image-block h-100" >
<img [src]="Imagenss" class="Images img-fluid" alt="">
<div class="ImageText"> {{product.name}}</div>
</a>
</div>
</div>
</div>
</div>
Component.ts
ImageInfo(e, id) {
if (e != null) {
this.ID = id;
}
var self = this;
self.homeService.getImage(self.ID).then(function (resultado) {
if (resultado) {
self.Imagenss = resultado;
}
}).catch();
}
Your question is very unclear so I am not sure that this is exactly what you want to do, but you can use the function setInterval to run your function that uploads the images automatically every X milliseconds.
Two side notes regarding your code:
You should use let instead of var, the scope isn't the same and you can get unwanted results if you use var: What's the difference between using "let" and "var"?
You don't need to use self = this, if you use an anonymous function as callback then you can use this directly:
ImageInfo(e, id) {
if (e != null) {
this.ID = id;
}
this.homeService.getImage(this.ID).then(resultado => {
if (resultado) {
this.Imagenss = resultado;
}
}).catch();
}

How to trigger component event in angular dart tests?

I'm using angular_test.dart to test my components. I want to test that clicking on a particular <li> will mark it as selected.
multiple_choice_quiz_component.html
<div>
<div class="contain-center">
<h1>{{quiz.getDescription}}</h1>
</div>
<div class="contain-center">
<ul>
<li *ngFor="let answer of quiz.getChoiceList"
(click)="onSelect(answer)"
[class.selected]="answer == selectedAnswer"
[class.correct]="correctAnswer && answer == selectedAnswer"
[class.incorrect]="!correctAnswer && answer == selectedAnswer"
>
{{answer}}
</li>
</ul>
</div>
</div>
multiple_choice_quiz_component.dart
class MultipleChoiceQuizComponent
{
String selectedAnswer;
String description;
bool correctAnswer = false;
Quiz quiz;
MultipleChoiceQuizComponent(QuizService quizService)
{
this.quiz = quizService.getQuiz();
}
void onSelect(String answer)
{
selectedAnswer = answer;
this.correctAnswer = this.quiz.isAnswer(answer);
}
}
test.dart
...
import 'package:angular_test/angular_test.dart';
....
group('My Tests', () {
test('should change li element to selected', () async {
var bed = new NgTestBed<MultipleChoiceQuizComponent>();
var fixture = await bed.create();
await fixture.update((MultipleChoiceQuizComponent Component) {
});
});});
In my test, how can I trigger a click on let's say the second <li> and evaluate that it has the selected property? And how do I mock the quiz service and inject it to the constructor?
I thought I wasn't going to figure it out, but I did.
Using a debug html test file helped a lot. On the console I could set breakpoints. Using the console I could navigate through the methods of these objects to find out what I needed to call.
NgTestBed bed = new NgTestBed<MultipleChoiceQuizComponent>();
NgTestFixture fixture = await bed.create();
Element incorrectAnswer = fixture.rootElement.querySelector('.quiz-choice:nth-child(2)');
incorrectAnswer.dispatchEvent(new MouseEvent('click'));
bool hasClass = incorrectAnswer.classes.contains('incorrect');
expect(true, hasClass);
You can use PageObjects to interact with the page:
https://github.com/google/pageloader

Angular modal template not displaying

I'm somewhat new to Angular. I am trying to display a Bootstap 3 modal dialog when an invalid user role is detected. I cannot get my modal template to display. The behavior seems to work i.e. I can dismiss the faded overlay..I just don't see the actual modal template.
Bootstrap 3
AngularJS 1.0.7
AngularJS UI Bootstrap 0.6.0
Controller
gsApp.controller('MainController', ['$rootScope', '$scope', '$q', '$window', '$location', '$modal', 'ApplicationCache', 'UserService',
function MainController($rootScope, $scope, $q, $window, $location, $modal, ApplicationCache, UserService) {
$scope.userRole = "BadRole";
$scope.showBadRoleModel = function () {
var showBadRoleModelInstance = $modal.open({
templateUrl: "badRoleModal.html",
backdrop: true,
windowClass: 'modal',
controller: badRoleModalInstance,
resolve: {
items: function () {
return $scope.userRole;
}
}
});
}
var badRoleModalInstance = function($scope, $modalInstance, items){
$scope.ok = function () {
$modalInstance.close();
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
}]);
HTML
<div class="row" ng-controller="MainController">
<script type="text/ng-template" id="badRoleModal.html">
<div class="modal-header">
<h3>I'm a modal!</h3>
</div>
<div class="modal-body">
<h2>body</h2>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()">OK</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
<button class="btn" ng-click="showBadRoleModel()">Show bad role modal</button>
</div>
AngularJs UI Bootstrap doesn't work with Bootstrap 3 yet.
See more details here: https://github.com/angular-ui/bootstrap/issues/331
Here's a reusable Angular directive that will hide and show a Bootstrap 3 (or 2.x) modal.
app.directive("modalShow", function () {
return {
restrict: "A",
scope: {
modalVisible: "="
},
link: function (scope, element, attrs) {
//Hide or show the modal
scope.showModal = function (visible) {
if (visible)
{
element.modal("show");
}
else
{
element.modal("hide");
}
}
//Check to see if the modal-visible attribute exists
if (!attrs.modalVisible)
{
//The attribute isn't defined, show the modal by default
scope.showModal(true);
}
else
{
//Watch for changes to the modal-visible attribute
scope.$watch("modalVisible", function (newValue, oldValue) {
scope.showModal(newValue);
});
//Update the visible value when the dialog is closed through UI actions (Ok, cancel, etc.)
element.bind("hide.bs.modal", function () {
scope.modalVisible = false;
if (!scope.$$phase && !scope.$root.$$phase)
scope.$apply();
});
}
}
};
});
Usage Example #1 - this assumes you want to show the modal - you could add ng-if as a condition
<div modal-show class="modal fade"> ...bootstrap modal... </div>
Usage Example #2 - this uses an Angular expression in the modal-visible attribute
<div modal-show modal-visible="showDialog" class="modal fade"> ...bootstrap modal... </div>
Another Example - to demo the controller interaction, you could add something like this to your controller and it will show the modal after 2 seconds and then hide it after 5 seconds.
$scope.showDialog = false;
$timeout(function () { $scope.showDialog = true; }, 2000)
$timeout(function () { $scope.showDialog = false; }, 5000)
I'm late to contribute to this question - created this directive for another question. Here are some related links: Simple Angular Directive for Bootstrap Modal and https://stackoverflow.com/a/19668616/1009125
Hope this helps.

if statement inside knockout array

Im trying to load a knockout observable array 25 items at a time using a count variable. The idea is that when you click a button you get another 25 items in the list. Sounds simple but Im useless with knockout.
I tried calling $root.getCount and $parent.getCount and put getCount in my list-view div as a value but none work. I might be over thinking it. All i want to do is put a named variable into the if statement where $getCount is. help would be awesome.
<div class="list-view" >
<ul data-bind="foreach: myBigList" class="shop_list">
<!-- ko if: $index() < $getCount -->
<li class="list_row">
</li>
<!-- /ko -->
</ul>
</div>
here's my view model
$(function () {
var viewModel = {
count: ko.observable(25),
getCount: function () {
return count;
},
updateCount: function () {
count+=count;
},
};
ko.applyBindings(viewModel);
})
I'm not sure I understand what you are really trying to achieve, but I'm going to assume you already have a big list of items that you want to display in groups of 25. You can achieve that using the visible binding:
<div class="list-view" >
<ul data-bind="foreach: myBigList" class="shop_list">
<li class="list_row" data-bind="visible: $index() < $parent.count()">
</li>
</ul>
</div>
Since count is an observable, to upate it's value you need to do this:
$(function () {
function ViewModel() {
this.count = ko.observable(25);
this.updateCount = function () {
var newCount = this.count() + 25;
this.count(newCount);
};
}
ko.applyBindings(new ViewModel());
})
Since count is an observable, you must use the function syntax to return it: return count();. If you want to add 25 to the count variable each time the updateCount method is called, you will need to hardcode the value.
$(function () {
var viewModel = {
count: ko.observable(25),
getCount: function () {
return count();
},
updateCount: function () {
count()+=25;
},
};
ko.applyBindings(viewModel);
})

jQueryUI Slider is not scrolling div

I am new to jquery, so apologies if this is a lengthy question. The following is what I have come up with for a horizontal slider to scroll a div containing lists of images.
The result is the slider not scrolling the div. Any help would be great.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var slideDrag,
slideWidth = 330,
slideSpeed = 200;
animated = false;
$(".scroll-slider").slider({
animate: slideSpeed,
start: checkType,
slide: doSlide,
max: slideWidth
});
// Set each slider to a value
$(".scroll-slider").each(function(index){
$(this).slider("value", 330 / 5 * index);
});
// You can also change a slider at any time like so:
// $(".scroll-slider:eq(0)").slider("value", value);
//
// That would move the first slider to a value, along with its content
function checkType(e){
slideDrag = $(e.originalEvent.target).hasClass("ui-slider-handle");
}
function doSlide(e, ui){
var target = $(e.target).prev(".scroll-content"),
// If sliders were above the content instead of below, we'd use:
// target = $(e.target).next(".scroll-content")
maxScroll = target.attr("scrollWidth") - target.width();
// Need to check type now to prevent the new change handler from firing twice when user clicks on slider,
// because both 'slide' and 'change' events are fired on a click, but only a 'change' when setting slider
// value manually via code.
if (e.type == 'slide'){
// Was it a click or drag?
if (slideDrag === true){
// User dragged slider head, match position
target.attr({scrollLeft: ui.value * (maxScroll / slideWidth) });
}
else{
// User clicked on slider itself, animate to position
target.stop().animate({scrollLeft: ui.value * (maxScroll / slideWidth) }, slideSpeed);
}
animated = true;
}
else{
if (animated === false){
target.stop().animate({scrollLeft: ui.value * (maxScroll / slideWidth) }, slideSpeed);
}
animated = false;
}
}
});
</script>
</script>
<style>
/* Styling the scroll elements */
.scroll-container{padding-bottom:30px}
.scroll-content{width:330px;height:110px;overflow:hidden;margin-bottom:10px}
.scroll-content ul{
width:880px;
height:110px;
margin-bottom:5px
}
.scroll-content li{
float:left;
}
.ui-slider .ui-slider-handle{width:16px;height:12px;position:absolute;top:-3px;background:#234786;border:none}
</style>
<body>
<div id="wrapper">
<h2>Multiple Slider Control Demo</h2>
<div id="left">
<div class="scroll-container">
<div class="scroll-content">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
</ul>
</div>
</div>
<div class="scroll-slider"></div>
</div>
</div>
Are you trying to work from this demo?
http://cnanney.com/journal/demo/div-slide/
I had the same error, and replaced the version of jQuery I was using with the one used in the demo and it worked.