Trying to write a cypress test for drag and drop to a specific destination - drag-and-drop

I am able to drag the content but its dropping in the same location instead of intended location.
My goal is to drop at specific location,which isn't happening.Need some help or suggestion on this!!
My test
it('moves the piece when dragged to valid place', function () {
cy.get('[data-cy="dataExplorer" ]').find('ux-accordion-panel').first().click();
cy.get('[data-cy="metricContainer"]').first()
.trigger('mousedown', { button: 0 })
.wait(1000)
.trigger('mousemove', {force: true, x: -370, y: 180, bubbles: false})
.trigger('mouseup', {force: true})
});
My html
<table class="table table-hover">
<tbody uxTabbableList>
<tr *ngFor="let field of fields; let i=index" uxTabbableListItem>
<td class="metric-group" (mouseenter)="activeRowId = field.id"
(mouseleave)="activeRowId = null" [attr.aria-expanded]="activeRowId === field.id"
[cdkDropListConnectedTo]="['mashup-dashboard']" cdkDropList>
<div cdkDrag (cdkDragDropped)="dragDropped($event, field)" data-cy="metricContainer" class="metric-container">
<div data-cy="metricName" class="metric-name">
<div>{{field.name}}</div>
<div *cdkDragPlaceholder class="drop-preview-placeholder"></div>
<div *cdkDragPreview>{{field.name}}</div>
</div>
<div class="add-button-container" [class.flt-show]="activeRowId === field.id">
<button type="button" aria-label="Edit" class="btn button-primary"
[tabindex]="activeRowId === field.id ? 0 : -1" (click)="addMetricPanel(field);">
</button>
</div>
</div>
</td>
</tr>
</tbody>
</table>

Related

Passing user id to delete method using bootstrap modals

I'm new to angular and this is what I'm trying to achieve:
I have a component that shows a list of users. When the delete action is clicked, a modal dialog appears to ask for confirmation.
I'm not really sure how to pass the id of the user to delete to the delete method.
users.component.html:
<div class="container">
<div style="margin-top:10px;">
<mat-form-field appearance="standard">
<mat-label>Filter</mat-label>
<input matInput (keyup)="applyFilter($event)" placeholder="Ex: mia" #input>
</mat-form-field>
<div class="mat-elevation-z8">
<table mat-table [dataSource]="dataSource" matSort>
<!-- ID Column -->
<ng-container matColumnDef="id">
<th mat-header-cell *matHeaderCellDef mat-sort-header> ID </th>
<td mat-cell *matCellDef="let row" id="userid"> {{row.id}} </td>
</ng-container>
<!-- Name Column -->
<ng-container matColumnDef="email">
<th mat-header-cell *matHeaderCellDef mat-sort-header> Email </th>
<td mat-cell *matCellDef="let row"> {{row.email}} </td>
</ng-container>
<!-- Fruit Column -->
<ng-container matColumnDef="username">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Username </th>
<td mat-cell *matCellDef="let row"> {{row.username}} </td>
</ng-container>
<!-- Fruit Column -->
<ng-container matColumnDef="action">
<th mat-header-cell *matHeaderCellDef mat-sort-header>Action</th>
<td mat-cell *matCellDef="let row" >
<!--
<button mat-icon-button color="warn" (click)="deleteUser(row.id)"> -->
<!---->
<button mat-icon-button color="warn" class="open-exampleModal" data-bs-toggle="modal" data-bs-target="#exampleModal" >
<!--
<button mat-icon-button color="warn" (click)="opendialog()" > -->
<mat-icon>delete</mat-icon>
</button>
</td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
<!-- Row shown when there is no matching data. -->
<tr class="mat-row" *matNoDataRow>
<td class="mat-cell" colspan="4">No data matching the filter "{{input.value}}"</td>
</tr>
</table>
<mat-paginator [pageSizeOptions]="[5, 10, 25, 100]" aria-label="Select page of users"></mat-paginator>
</div>
</div>
</div>
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true" *ngFor="let user of users" >
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Confirmation de la suppression</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
Êtes-vous sûr de vouloir supprimer l'utilisateur?
</div>
<div class="modal-footer">
<button mat-raised-button color="primary" (click)="deleteUser(user.id)" data-bs-dismiss="modal">Supprimer</button>
<button mat-raised-button color="warn" data-bs-dismiss="modal">Annuler</button>
</div>
</div>
</div>
</div>
users.component.ts:
import { Component, OnInit, ViewChild} from '#angular/core';
import { MatDialog, MatTableDataSource, } from '#angular/material';
import { AddUserComponent } from '../add-user/add-user.component';
import { UserServiceService } from '../services/user-service.service';
import {MatPaginator} from '#angular/material/paginator';
import {MatSort} from '#angular/material/sort';
import { User } from '../models/user';
import { FormGroup, FormBuilder, Validators } from '#angular/forms';
#Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit{
displayedColumns: string[] = ['id', 'email', 'username','action'];
users:User[]=[];
dataSource: MatTableDataSource<User>;
userDetail:FormGroup;
#ViewChild(MatPaginator,{static:true}) paginator: MatPaginator;
#ViewChild(MatSort,{static:true}) sort: MatSort;
constructor(private dialog:MatDialog, private userService: UserServiceService, private formBuilder:FormBuilder, ) {
userService.getAllUsers().subscribe((users) => {
for (const user of users) {
const newUser = new User(user.id, user.email, user.username);
this.users.push(newUser);
}
//console.log(this.users);
this.dataSource = new MatTableDataSource<User>(this.users);
this.dataSource.paginator=this.paginator;
this.dataSource.sort=this.sort;
});
}
ngOnInit() {
this.getAllUsers();
this.userDetail=this.formBuilder.group({
username:['',Validators.required],
email:['',Validators.required],
password:['',Validators.required]
})
}
openDialog(){
this.dialog.open(AddUserComponent,{
width:'30%'
});
}
getAllUsers(){
this.userService.getAllUsers()
.subscribe({
next:(res)=>{
this.users=res;
//console.log(res);
console.log(this.users);
this.dataSource=new MatTableDataSource(res);
// this.dataSource = res;
this.dataSource.paginator = this.paginator;
}, error:(err)=>{
alert("error while fetching records");
}
})
}
refresh() {
this.getAllUsers();
this.dataSource.data = [...this.dataSource.data];
this.dataSource.paginator = this.paginator;
}
deleteUser( id:number){
this.userService.deleteUser(id)
.subscribe({
next:(res)=>{
//alert("utilisateur supprimé avec succée!");
this.refresh();
},
error:()=>{
alert("erreur lors de la suppression");
}
});
}
applyFilter(event: Event) {
const filterValue = (event.target as HTMLInputElement).value;
this.dataSource.filter = filterValue.trim().toLowerCase();
if (this.dataSource.paginator) {
this.dataSource.paginator.firstPage();
}
}
}
This way it is always deleting the first record, I'm not sure how to pass the right user id.

Check only one checkbox and uncheck previous checked checkbox

I wanted that when I change my selection in my checkbox the only selected checkbox will be selected and the previous selected checkbox will be uncheck.
My code is working but i really wanted to select only one checkbox.
In my view.
<center><table></center>
<tr>
<th><center>
List of Names</center></th>
<th colspan="3">
Actions
</th></tr>
<tr ng-repeat="role in roles">
<td>
<label>
<ion-checkbox ng-model="isChecked" ng-
change="format(isChecked,role,$index)"
ng-init="isChecked=false"><div class="wew">
{{role}}
</div></ion-checkbox>
</label>
</td>
<td>
<button ng-hide="!isChecked" ng-click="present()">P </button> </td>
<td>
<button ng-hide="!isChecked" ng-click="late()">L</button></td>
<td><button ng-hide="!isChecked" ng-click="absentss()">A</button></td>
<td><button ng-hide="!isChecked" ng-click="delete()">D</button></td>
</tr> </table>
And I think in my controller is the part where i need to change my codes to achieved the correct result.
$scope.isChecked = false;
$scope.selected = [];
$scope.format = function (isChecked, role, index) {
if (isChecked==true) {
$scope.selected.push(role);
}
else {
var _index = $scope.selected.indexOf(role);
$scope.selected.splice(_index, 1);
}
var students = $scope.selected;
console.log(students);
for( var s=0; s<students.length; s++) {
$scope.stud = [
students[s]
]
};
Thank you in advanced! I hope that someone can help in this matter.
Checkboxes are for multiple selections within a group.
Use radio buttons instead.
Example With AngularJs
This is way you can also implement.
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script>
angular.module('app', []).controller('appc', ['$scope',
function($scope) {
$scope.selected = 'other'; //default selection
}
]);
</script>
</head>
<body ng-app="app" ng-controller="appc">
<label>SELECTED: {{selected}}</label>
<div>
<input type="checkbox" ng-checked="selected=='male'" ng-true-value="'male'" ng-model="selected">Male
<br>
<input type="checkbox" ng-checked="selected=='female'" ng-true-value="'female'" ng-model="selected">Female
<br>
<input type="checkbox" ng-checked="selected=='other'" ng-true-value="'other'" ng-model="selected">Other
</div>
</body>
</html>

kendo sortable widget mvvm UI glitch

I am using kendo's mvvm and sortable widget to allow a user to sort multiple tables with data binded to it. I have implemented the following code. It works, but the data seems to be logging correctly to the console. However, the data in the UI jumps around.
$(".sortable-handlers").kendoSortable({
handler: ".move",
hint:function(element) {
return element.clone().addClass("sortable-hint");
},
change: function(e) {
var services = viewModel.get("services");
console.log(e.oldIndex);
var oldIndex = e.oldIndex;
var newIndex = e.newIndex;
services.splice(newIndex, 0, services.splice(oldIndex, 1)[0]);
//Set it back to the original list
viewModel.set("services", services);
console.log(JSON.stringify(viewModel.get("services")));
}
});
It's been a long time but adding .trigger("change") works for me (I'm using jquery ui sortable instead of kendo ui sortable).
// Define model with dependent method
var MyModel = kendo.data.Model.define({
fields: {
left: "number",
right: "number"
},
total: function() {
return this.get("left") + this.get("right");
}
});
// Create view model
var viewModel = kendo.observable({
items: []
});
// bindings
kendo.bind($("#myView"), viewModel);
// using $.ui.sortable when list changes
var timeout = null;
viewModel.items.bind("change", function(e) {
clearTimeout(timeout);
timeout = setTimeout(function() {
$("#sortable").sortable({
update: function(e, ui) {
// get UID of sorting target
var targetUid = ui.item.attr("uid");
// list before
var beforeIndexes = _.map(viewModel.items, _.iteratee("uid"));
// target's original index
var fromIdx = _.indexOf(beforeIndexes, targetUid);
// list after
var afterIndexes = $("#sortable").sortable("toArray", {
attribute: "uid"
});
// target's new index
var toIdx = _.indexOf(afterIndexes, targetUid);
var changeItem = viewModel.items[fromIdx];
viewModel.items.splice(fromIdx, 1);
if (toIdx >= viewModel.items.length) {
viewModel.items.push(changeItem);
} else {
viewModel.items.splice(toIdx, 0, changeItem);
}
// refresh
viewModel.items.trigger("change");
}
});
}, 500);
});
// add some items to list
viewModel.items.push(new MyModel({
left: 1,
right: 2
}));
viewModel.items.push(new MyModel({
left: 6,
right: 3
}));
viewModel.items.push(new MyModel({
left: 5,
right: 7
}));
<link href="https://code.jquery.com/ui/1.12.0-beta.1/themes/smoothness/jquery-ui.css" rel="stylesheet" />
<link href="https://kendo.cdn.telerik.com/2016.1.112/styles/kendo.common.min.css" rel="stylesheet" />
<link href="https://kendo.cdn.telerik.com/2016.1.112/styles/kendo.default.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.0-beta.1/jquery-ui.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2016.1.112/js/kendo.all.min.js"></script>
<script src="http://underscorejs.org/underscore-min.js"></script>
<div id="myView">
<div class="k-grid k-widget">
<div class="k-grid-header">
<div class="k-grid-header-wrap">
<table>
<thead>
<tr>
<th class="k-header">SORTABLE</th>
</tr>
</thead>
</table>
</div>
</div>
<div class="k-grid-content">
<table>
<tbody id="sortable" data-bind="source: items" data-template="template-item">
</tbody>
</table>
</div>
</div>
<div class="k-grid k-widget">
<div class="k-grid-header">
<div class="k-grid-header-wrap">
<table>
<thead>
<tr>
<th class="k-header">NOT-SORTABLE</th>
</tr>
</thead>
</table>
</div>
</div>
<div class="k-grid-content">
<table>
<tbody id="sortable" data-bind="source: items" data-template="template-item">
</tbody>
</table>
</div>
</div>
</div>
<script type="text/x-kendo-template" id="template-item">
<tr data-bind="attr: {uid: uid}">
<td>
<span data-bind="text: left" />+
<span data-bind="text: right" />=
<span data-bind="text: total" />
</td>
</tr>
</script>

Dynamic HTML ID with Bootstrap, Play framework and Scala templates

I'm working on an application with Bootstrap and Play 2 using Scala templates. I want to enumerate the ID of every row of jobs so that each row will map to a corresponding collapsed row that show more information. Below is my initial attempt, but so far it doesn't work yet. Any comments or hints on how to achieve this is greatly appreciated.
<tbody>
#lists.zipWithIndex.map { case(elem, index) =>
<tr data-toggle="collapse" data-target="res#index" class="accordion-toggle">
<td><!--Display elem--></td>
</tr>
<tr>
<td colspan="3"><div class="accordion-body collapse" id="res#index"></div></td>
</tr>
}
</tbody>
Example from one of my projects, just do it in the same way:
#countries.byRegion.zipWithIndex.map { p =>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion2" href=#("#collapse" + p._2)>
#p._1._1 <span class="pull-right">#p._1._2</span>
</a>
</div>
<div id=#("collapse" + p._2) class="accordion-body collapse">
<div class="accordion-inner">
#data.programs.map { prog =>
#if(prog.region == p._1._1) {
<p>#prog.level</p>
}
}
</div>
</div>
</div>
}
to make it work you have to make "dynamic" href's and id's: href=#("#collapse" + p._2) id=#("collapse" + p._2) in your case change p._2 to index

jQuery Datepicker only firing if I first click on another input field

I'm having some strange behaviour when using the datepicker. When I load the page, and directly click on the datepicker input, nothing happens. When I click again, nothing happens. But when I click on another input field and then try again the datepicker field, it'll show up.
The issue showed up, after I put the datepicker trigger into a live function, because I have input which will be dynamically generated.
This is my code:
$(".date").on('click', function() {
$(this).datepicker({
dateFormat: "dd.mm.yy",
altField: $(this).closest("td").find(".dateFormated"),
altFormat: "yy-mm-dd"
})
})
Edit: I have seen that live() is deprecated as of 1.7. I therefore switched live() for on(). Didn't solve the issue though.
Whole Html
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="content-type" content="text/html" />
<meta name="author" content="gencyolcu" />
<title>Untitled 1</title>
<link rel="stylesheet" href="http://localhost:8082/ivy/page/designer/ZWM$1/css/cupertino/jquery-ui-1.9.2.custom.css" />
<script type="text/javascript" src="http://localhost:8082/ivy/page/designer/ZWM$1/jquery.min.js"></script>
<script type="text/javascript" src="http://localhost:8082/ivy/page/designer/ZWM$1/js/jquery-ui-1.9.2.custom.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
counter = 0;
$("#addRow").click(function() {
counter++;
rowHtml = '\
<tr class="datarow" id="row' + counter + '">\
<td><input type="text" class="date" /><input type="text" class="dateFormated" /></td>\
<td><input type="text" class="from" /></td>\
<td><input type="text" class="to" /></td>\
<td>\
<select class="type">\
<option value="1">Typ 1</option>\
<option value="2">Typ 2</option>\
</select>\
</td>\
<td class="removeRow" id=' + counter + '>X</td>\
</tr>';
$('#submitButton').before(rowHtml);
})
$(".removeRow").live("click", function() {
id = $(this).attr("id");
$("#row" + id).remove();
})
$("[name=formZeitdaten]").submit(function(i) {
values = "";
$(".datarow").each(function(j) {
tr = $(this);
date = tr.find('td').find('.date').val();
from = tr.find('td').find('.from').val();
to = tr.find('td').find('.to').val();
type = tr.find('td').find('.type').val();
values = values + date + ',' + from + ',' + to + ',' + type + ';';
})
console.log(values);
$("[name=dataset]").val(values);
})
$("#slider").slider({
range: true,
min: 0,
max: 1440,
step: 15,
values: [30, 210],
slide: function(event, ui) {
$(".date").val(ui.values[0] + ":" + ui.values[1]);
}
});
$(".date").on('click', function() {
$(this).datepicker({
dateFormat: "dd.mm.yy",
altField: $(this).closest("td").find(".dateFormated"),
altFormat: "yy-mm-dd"
})
})
});
</script>
</head>
<body>
<span id="test"></span>
<form name="formZeitdaten" method="post">
<table id="zeitdaten">
<tr>
<td>Datum</td>
<td>Von</td>
<td>Bis</td>
<td>Typ</td>
<td id="addRow"><input type="button" value="Hinzufügen" /></td>
</tr>
<tr class="datarow">
<td><input type="text" class="date" /><input type="text" class="dateFormated" /></td>
<td><input type="text" class="from" /></td>
<td><input type="text" class="to" /></td>
<td>
<select class="type">
<option value="1">Typ 1</option>
<option value="2">Typ 2</option>
</select>
</td>
<td></td>
</tr>
<tr id="submitButton">
<td><input type="submit" /></td>
</tr>
</table>
</form>
<div id="slider"></div>
</body>
</html>
In your addRow function, add:
$("#row"+counter+" .date").datepicker({
dateFormat: 'dd-mm-yy',
minDate: 0,
showButtonPanel: true,
showAnim: 'show'
});
after you add the element to the DOM. You can then get rid of the $(".date").on('click',...) statement later.
This should work for you
$('.date').datepicker({
dateFormat: 'dd-mm-yy',
minDate: 0,
showButtonPanel: true,
showAnim: 'show'
});