Modifying a list in AngularJS - javascript

Attempting to make list items clickable without a checkbox. I want those items to to get a strike through when clicked and still have the delete option at the end. This functions properly, but I can't seem to maintain that when I try to make the items clickable. How do I need to modify this code to make it work?
<p class="lead" ng-bind="vm.list.content"></p>
<div class="list-group">
<span data-ng-repeat="item in vm.list.items|orderBy:'name'"
class="list-group-item" ng-class="{strike: item.check}">
<input type="checkbox" ng-model="item.check" ng-click="vm.cross(item)">
<a class="btn btn-default pull-right" ng-click="vm.remove(item)">
<i class="glyphicon glyphicon-trash"></i></a>
<h4 class="list-group-item-heading" ng-bind="item.name + ' - ' + item.priority"></h4>
</span>
</div>
Controllers:
function remove(item){
var removedItem = $scope.vm.list.items.indexOf(item);
$scope.vm.list.items.splice(removedItem, 1);
if (vm.list._id) {
vm.list.$update(successCallback, errorCallback);
} else {
vm.list.$save(successCallback, errorCallback);
}
function successCallback(res) {
$state.go('lists.view', {
listId: res._id
});
}
function errorCallback(res) {
vm.error = res.data.message;}
}
function cross(item){
if (vm.list._id) {
vm.list.$update(successCallback, errorCallback);
} else {
vm.list.$save(successCallback, errorCallback);
}
function successCallback(res) {
$state.go('lists.view', {
listId: res._id
});
}
function errorCallback(res) {
vm.error = res.data.message;}
}

Why not to move the checkbox behavior to the item wrapper? In this case, if click on the trash, the outer click handler will not be triggered because we stop event from further propagation.
<div class="list-group">
<span data-ng-repeat="item in vm.list.items|orderBy:'name'" class="list-group-item" ng-class="{strike: item.check}" ng-click="item.check = true; vm.cross(item)">
<a class="btn btn-default pull-right" ng-click="vm.remove(item);$event.stopPropagation();">
<i class="glyphicon glyphicon-trash"></i>
</a>
<h4 class="list-group-item-heading" ng-bind="item.name + ' - ' + item.priority"></h4>
</span>
</div>
If you want to cross/uncross item by click, you can implement a method like toggleCross and use it instead of "item.check = true" statement:
item.toggleCheck = function() {
this.check = !this.check;
}

Related

Sweet Alert 2, custom buttons

I have added 2 custom buttons in my sweet alert, but the functions for them aren't working, can u advise me a fix for that?
//Custom buttons
html: '<button id="prev-btn" class="btn btn-warning"><i class="fas fa-angle-left fa-3x"></i></button>' +
'<button id="next-btn" class="btn btn-primary"><i class="fas fa-angle-right fa-3x"></i></button>',
//Functions for them
$("#next-btn").on("click", function() {
if(currentMarineKnotIndex+1 == receivedArray.length){
currentMarineKnotIndex = 0;
}
else{
currentMarineKnotIndex++;
}
$(".nautical-knot-title").html(receivedArray[currentMarineKnotIndex].nameLV+"<br>");
$(".nautical-knot-desc").html(receivedArray[currentMarineKnotIndex].descriptionLV);
$("#modal-header-div").css("background", "url('../Images/uploads/"+receivedArray[currentMarineKnotIndex].Image+"')");
});
$("#prev-btn").on("click", function() {
if(currentMarineKnotIndex == 0){
currentMarineKnotIndex = receivedArray.length - 1;
}else{
currentMarineKnotIndex--;
}
$(".nautical-knot-title").html(receivedArray[currentMarineKnotIndex].nameLV+"<br>");
$(".nautical-knot-desc").html(receivedArray[currentMarineKnotIndex].descriptionLV);
$("#modal-header-div").css("background", "url('../Images/uploads/"+receivedArray[currentMarineKnotIndex].Image+"')");
This link (official site) might be useful -> https://sweetalert.js.org/guides/

How to add a class to the body of the page, when the menu is open?

I created a "more" button at the bottom left of my site to display a menu.
When you click on the button, the + becomes x
https://www.s1biose.com/groupe/recettes-et-astuces
<div class="dropup">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdown-menu-action" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<div class="fa-4x">
<span class="fa-layers fa-fw">
<i class="fas fa-circle"></i>
<i class="fa-inverse fas fa-plus" data-fa-transform="shrink-6"></i>
</span>
</div>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdown-menu-action">
<li><i class="fas fa-id-card fa-lg"></i> Créer mon profil</li>
</ul>
</div>
How to add a class .overlay-is-navbar-collapse to the body of the page, when the menu is open and delete the class when the menu is closed ?
The following code does not work. If I click outside, the menu closes but the class remains on body.
$('#dropdown-menu-action').on('click', () => {
$('body').toggleClass('overlay-is-navbar-collapse');
});
I have tried the following code, but it does not work :
$('#dropdown-menu-action').on('shown.bs.dropdown', function () {
$('body').addClass('overlay-is-navbar-collapse');
});
$('#dropdown-menu-action').on('hidden.bs.dropdown', function () {
$('body').removeClass('overlay-is-navbar-collapse');
});
Use .one to attach a listener to the body right when the body's class gets added:
$('#dropdown-menu-action').on('click', () => {
$('body').addClass('overlay-is-navbar-collapse');
$('body').one('click', () => {
$('body').removeClass('overlay-is-navbar-collapse');
});
});
why don't you try this,
$('#dropdown-menu-action').on('click', () => {
$('body').toggleClass('overlay-is-navbar-collapse');
});
$('.dialog-off-canvas-main-canvas').on('click', () => {
$('body').removeClass('overlay-is-navbar-collapse');
});
Try this,
$('dropdown-menu-action').click(function(){
if($(body).hasClass('overlay-is-navbar-collapse')){
$('body').removeClass('overlay-is-navbar-collapse');
}
else{
$('body').addClass('overlay-is-navbar-collapse');
}
});

Angular2 + Cordova + Barcode scanner Plugin: Android behavior

I am trying to use the barcode scanner on my Angular2 app with Cordova and relative plugin.
I can just test on Android now, and I am getting strange behaviors. I am not able to find the problem, whether the plugin or my code.
The scan works right, but after switching from the camera activity to the app webview it's like events and data binding aren't well handled.
When scan returns a result, I set a property on my view to tell app the scan state is success and so my angular view shows some buttons to open a link for example.
Sometime works, others not. Also if I rescan a code, and I cancel it, leaving camera activity it shows me the previous not showed result.. Or sometime just doesn't work at all :(
JAVASCRIPT:
export class ScanQRView extends View {
private scanState: string = 'ready';
[....]
public scan(): void {
if (this.utility.inApp('barcodeScanner')) {
cordova.plugins.barcodeScanner.scan(
(result) => {
setTimeout(() => {
if (!result.cancelled) {
this.onResult(result.text);
console.log(this.scanState);
} else {
this.onResult(false);
}
}, 500);
},
(error) => this.onResult(false), {
preferFrontCamera : true,
showFlipCameraButton : true,
showTorchButton : true,
torchOn: true,
//prompt : "Place a barcode inside the scan area",
resultDisplayDuration: 500,
formats : "QR_CODE",
disableAnimations : true,
disableSuccessBeep: false
}
);
}
}
public onResult(result: string|boolean): void {
if (result === false) {
this.scanState = 'error';
} else {
this.link = result.toString();
this.scanState = 'success';
}
}
}
TEMPLATE:
<div class="row scan" *ngIf="scanState == 'ready'">
<div class="col-xs-3"></div>
<div class="col-xs-6">
<button type="button" class="btn btn-info btn-lg btn-block fade-in-out-button" (click)="scan()">
<i class="fa fa-camera" aria-hidden="true"></i>
</button>
</div>
<div class="col-xs-3"></div>
</div>
<div class="row scan" *ngIf="scanState == 'success'">
<div class="col-xs-12">
<div class="btn-group">
<div class="btn-group">
<button type="button" class="btn btn-info btn-lg" (click)="cancel()">
<i class="fa fa-refresh" aria-hidden="true"></i>
</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-info btn-lg fade-in-out-button" (click)="openLink()">
<i class="fa fa-link" aria-hidden="true"></i> Apri
</button>
</div>
</div>
</div>
</div>
I tried with and without the timer, nothing changes..
Anyone had similar problems?
You can use a Promise :
public scan(): void {
this.promiseScan().then(result => {
this.resultQrcode = result;
}).catch((ex) => {
console.log(ex);
});
}
public promiseScan(): any {
return new Promise((resolve, reject) => {
cordova.plugins.barcodeScanner.scan(
(result) => {
return resolve(result.text);
},
(error) => {
return reject('ERROR');
}
);
});
}

JAVA: Deleting a div generated by a for loop

How do you delete a div that is generated by a for loop? I have this code that generates divs:
EDIT: I have tried the changes of #Andrew Liberio but what happened is that my applicant divs have scattered all over the place. This is the new code and the script as well. Notice how I had put the ending semicolon of the for loop in order to get put the the index in the ajax. (Not seen in the code block for some reason but it goes like this >/script> <%}%>
<% ApplicantDAO applicantDAO = new ApplicantDAO();%>
<% for (int i = 0; i < applicantDAO.viewApplicant().size(); i++) {%>
<div class="column">
<div class="col-sm-3 col-xs-4">
<div class="list-group">
<a class="list-group-item active">
<img src = "th_1x1.jpg" class = "img-responsive" alt = "Responsive Image" width = "100%" height ="100">
<h4 class="list-group-item-heading" id="guardName<%=+i%>" id="guardName<%=+i%>"><%=applicantDAO.viewApplicant().get(i).getApplicantFirstName() + " "%>
<%=applicantDAO.viewApplicant().get(i).getApplicantLastName()%></h4>
</a>
<a class="list-group-item">
<p class="list-group-item-text" id="applyingFor<%=+i%>" id="applyingFor<%=+i%>"><%=applicantDAO.viewApplicant().get(i).getApplyingFor()%></p>
</a>
<a class="list-group-item" data-toggle="modal" href="#moreDetails<%=+i%>">
<button class="btn btn-primary btn-lg btn-block" id="moreDetails">More Details</button>
</a>
<a class="list-group-item">
<button type="button" class="btn btn-default" aria-label="Left Align">
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>
</button>
<button type="button" class="btn btn-default" aria-label="Left Align">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</a>
<script>
$(".delete").on("click", function () {
var id = $(this).attr("delete<%=applicantDAO.viewApplicant().get(i).getApplicantID()%>"); //get the id of the row
$.post("url_to_servlet_responsible_to_exclude_item", {
tId: id,
someOtherData: "anyData"
}).done(function () {
//if everything went ok,
//delete the div
$("div#" + id).remove();
});
})
</script>
But I dont know how to delete it at the same time delete it at the database. I use a jsp and servlet. This is my code for delete:
public boolean rejectApplicant(Applicant RejectedApplicant) {
try {
DBConnectionFactory myFactory = DBConnectionFactory.getInstance();
Connection conn = myFactory.getConnection();
String query = "delete from applicant where applicantID = ?";
PreparedStatement pstmt = conn.prepareStatement(query);
int rows = pstmt.executeUpdate();
conn.close();
pstmt.close();
return true;
} catch (SQLException ex) {
Logger.getLogger(ApplicantDAO.class.getName()).log(Level.SEVERE, null, ex);
}
return false;
}
I think that the same logic applies when transferring the values of the div to the database. The page is an applicant page where applicants are screened then if they do not pass, they will be removed and when they are accepted, the values will be passed to the database. Please suggest on what should I do. I already searched javascript and jquery but I just dont understand the terms like nodes etc. Any help or leads would be appreciated. Thank you!
You could pass an id to each div or/and to each button as #LAROmega suggested.
<div class="column" id="<%=applicantDAO.viewApplicant().get(i).getApplicantId()">
<div class="col-sm-3 col-xs-4">
...
<button type="button" class="btn btn-default delete" aria-label="Left Align" id="<%=applicantDAO.viewApplicant().get(i).getApplicantId()">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
Then, you could use this script to delete the row using AJAX.
$(".delete").on("click", function(){
var id = $(this).attr("id"); //get the id of the row
$.post("url_to_servlet_responsible_to_exclude_item", {
tId: id,
someOthetData: "anyData"
}).done(function(){
//if everything went ok,
//delete the div
$("div#" + id).remove();
});
})
First, I think you should not use the function on("click" in a loop.
You should use class delete for each button that you want to delete.
<button type="button" class="btn btn-default delete" data-id="<%=applicantDAO.viewApplicant().get(i).getApplicantID()%>" aria-label="Left Align">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
Outside of the loop, you call function on click
$(".delete").on("click", function () {
var id = $(this).attr("data-id"); //get the id of the row
$.post("url_to_servlet_responsible_to_exclude_item", {
tId: id,
someOtherData: "anyData"
}).done(function () {
//if everything went ok,
//delete the div
$("div#" + id).remove();
});
})

Update parent scope through child scopes in Angular

<div class="full-row" ng-repeat="row in pendingRequests | orderBy: '-modificationDate' | partition:3">
<div class="one-third" ng-repeat="request in row track by request.id">
<div class="incoming_request" ng-class="actionClass(request)">
<div class="request_comments">
<hr>
<p><span>Recipients:</span></p>
<div class="comments">
<p ng-repeat="comment in request.comments track by comment.id" class="dont-break-out">
<span class="author" ng-bind="comment.userName | employeeName">:</span>
{{comment.text}}
<span ng-if="comment.status == State.APPROVED" class="approval success" ng-click="changestatus(comment, request)"><i class="fa fa-check"></i></span>
<span ng-if="comment.status == State.REJECTED" class="approval error" ng-click="changestatus(comment, request)"><i class="fa fa-times"></i></span>
<span ng-if="comment.status == State.PENDING" class="approval" ng-click="changestatus(comment, request)" title="{{showApproveTooltip(comment)?'Click to approve the request on behalf of this user':''}}"><i class="fa fa-clock-o"></i></span>
</p>
</div>
</div>
<div class="request_resolve">
<hr>
<div class="textarea-holder">
<textarea placeholder="Your comment..." ng-model="request.newComment" ng-model-options="{ updateOn: 'default blur'}"></textarea>
</div>
<div class="button-container">
<button ng-click="approve(request);" ng-disabled="request.isProcessing" class="btn btn-primary" am-hide-request-resolve-div>Confirm<i ng-hide="request.isProcessing" class="fa fa-check"></i><span ng-show="request.isProcessing" class="spinner no-hover"><a><i class="fa-li fa fa-spinner fa-spin"></i></a></span></button>
<button ng-click="reject(request);" ng-disabled="request.isProcessing" class="btn btn-default pull-right" am-hide-request-resolve-div>Reject <i class="fa fa-times"></i></button>
</div>
</div>
Here is peace of code. As You may see there are many ng-repeats. My pendingRequests collection very often is updated from server. After 3 or more updates when I click on some button nothing is happend on UI.
Details :
On approve click I change status of one comment.
$scope.approve = function (request) {
var currentUserComment = request.comments.filter(function(comm) {
return comm.userId == user.id && comm.status == "Pending";
})[0];
currentUserComment.status = State.APPROVED; // change comments Status
currentUserComment.text = request.newComment;
delete request.newComment;
if (!currentUserComment) {
request.isProcessing = false;
return;
}
Comments.update(currentUserComment, function() {
// $rootScope.$broadcast('daysUpdated');
});
request.isProcessing = false;
};
This must show this span <span ng-if="comment.status == State.APPROVED" class="approval success" ng-click="changestatus(comment, request)"><i class="fa fa-check"></i></span> , cause now status is equal to State.APPROVED. But nothing happens.
After some research I think it all because ng-repeat and collection updates.
ng-repeat creates a child scope for each item, and so the scopes in play might look like this:
bookCtrl scope = { tags: [ 'foo', 'bar', 'baz' ] }
ng-repeat child scopes: { tag: 'foo' }, { tag: 'bar' }, { tag: 'baz' }
So when I update comment.status for some request Angular don't know in what scope it exists.
Am I right? And how can I solve my problem (after changing comment status show correct span)?
More Simple code :
<div ng-repeat="request in requests">
<div ng-repeat="comment in request.comments">
<span ng-if="comment.status == State.APPROVED" class="approval success"><i class="fa fa-check"></i></span>
<span ng-if="comment.status == State.REJECTED" class="approval error"><i class="fa fa-times"></i></span>
<span ng-if="comment.status == State.PENDING" class="approval"><i class="fa fa-clock-o"></i></span>
</div>
<div>
<button ng-click="approve(request)">
Approve
</button>
</div>
</div>
And approve function :
var user = LoggeInUser(); // some user who is loggedIn now
$scope.approve = function(request){
var currentUserComment = request.comments.filter(function(comm) {
return comm.userId == user.id && comm.status == "Pending";
})[0];
currentUserComment.status = State.APPROVED; // change comments Status
Comments.update(currentUserComment, function() { // send PUT request to API
// $rootScope.$broadcast('daysUpdated');
});
}
You may find your solution in moving the functions to $scope.functions.functionName. I believe from reviewing this that you are running into scoping issues, as you alluded to in your statement.
JS
$scope.functions.approve = function () { ... }
HTML
functions.approve(request)
You also might have a look at using controller as, sometimes that can help:
https://docs.angularjs.org/api/ng/directive/ngController

Categories