How to make an AJAX call with Confirm in lift? - ajax

I'm new to lift, and want to implement following in my project:
There is a "delete" link in the page, when user clicks it, there will be a confirmation with text "are you sure to delete?". If user clicks on "yes", it will make an AJAX call to delete something on the server side, then show a notice "Operation complete", and after 3 seconds, the page will be reloaded.
How to implement this in lift? I have searched a lot, but not found an correct example.
I can only do this for now:
SHtml.a( ()=>Confirm("are you sure to delete", ???), "delete" )

The easiest way is to use the SHtml.ajaxInvoke in conjunction with JsCmds.Confirm. It will create a server side function and return a tuple with the functionId and JsCmd. So, something like this should do what you are looking to do:
SHtml.a( () => {
JsCmds.Confirm("Are you sure you want to delete?", {
SHtml.ajaxInvoke(() => {
//Logic here to delete
S.notice("Operation complete")
JsCmds.After(3 seconds, JsCmds.Reload) //or whatever javascript response you want, e.g. JsCmds.Noop
})._2
})
}, "delete")
In the above - clicking on the link will trigger the confirmation. If you select OK, then it will issue an ajax call to your function and display a notice. You can use that in any of the SHtml items that require a JsCmd.
If you want to have the page redirect after a timeout, you can just write a client-side javascript function to do what you need and use JsCmds.Run to call it.

Using reactive-web:
confirm("Are you sure you want to do that?") {
case true =>
// handle yes, if so desired
case false =>
// handle no, if so desired
}
See the scaladocs: http://reactive-web.tk/reactive-web-api/#reactive.web.package

Related

Test only if element still present

I have a notification message which pops up upon saving a file and wish to close it only if it is still present when I need to press the next button which may be covered by this notification.
So far this is how I have tried to conditionally close the notification
Cypress.Commands.add('notificationClose', () => {
if (cy.get('.notification').should('be.visible')) {
console.log('CLOSE ME');
cy.get('.notification-dismiss').click({mulitple: true});
}else{
console.log('ALREADY GONE');
}
});
I have also tried a jQuery solution I found here too.
Cypress.Commands.add('notificationClose', () => {
if (Cypress.$('.notifications-wrapper') == true) {
cy.get('.notification-dismiss').click({mulitple: true});
}
});
I only use this immediately before needing to click the subsequent button, so the notification may close on its own.
The element in question is only temporarily attached to the DOM after saving the file.
How do I ask if this element is attached to the DOM?
I'm not completely sure that I understand your issue. But this is what I assume you mean:
You have a popup that isn't closed sometimes.
If the popup isn't closed you want to close it.
If the popup is closed you want to continue the test.
If that is correct we only need to fix step 1 and 2 since those are special. Continuing the test is just like you normally do.
To get the behaviour you need to get() the element and assert if it is present. You can do that with this code:
cy.get('body').then($body => {
if ($body.find('.notification').length === 1) {
cy.get('.notification-dismiss').click()
}
})
// continu the test

Detect AJAX Request

On my website I have mouse over and mouse out events set up on an HTML table. These events trigger ajax requests, and perform certain actions etc. However, i want to be able to not trigger a second request if one is already running. So, is there away to detect these requests, and therefore avoid a second. Incidentally Im using the jQuery $.ajax()
if it helps at all.
Thanks in advance
Chris
I'd try something simple like:
var requestMade = false;
function yourAjaxFunction(){
if(!requestMade)
{
requestmade = true;
$.ajax({
url: "page",
success: function(){
requestMade = false;
}
error: function(){
requestMade = false;
}
});
}
}
You can use the success: and error: settings to change the variable back to false.
I have never used the error so you may have to include some other things in it, but this is the general idea.
For this suppose I'd use ajaxStart() and ajaxStop() which would change specific variable ajaxRunning which could be checked before sending the request (maybe in ajaxStart() directly?)
Set global or local static variable to true when first ajax is about to trigger, than add if before triggering the second one ;) Than after one request is finished, set this variable to false

simulating the "add another item" ajax call in drupal 7 using jquery

I am trying to get jQuery to send a mousedown event to the Drupal 7 "add another item" button for a multi-value field, then wait until the ajax call has completed before filling in that new blank row with data from an element in a jQuery object (that has several elements). I need to use a loop to cycle through the elements (ingredients) in this jQuery object, but no matter what I try my page dies...
Currently, I have something like the following:
i = 0;
ingredients = newHtml.find('.recipe_ingredients > li');
ingredientsLength = ingredients.length;
$('#edit-field-ingredients-und-add-more').mousedown();
while(i < ingredientsLength) {
if ( document.readyState !== 'complete' ) {
// code to fill in the new blank row with data from 'ingredients'
$('#edit-field-ingredients-und-add-more').mousedown();
i++;
}
}
Because I don't yet know how to issue the ajax call myself using jQuery (or using Drupal) I've been trying to just check whether the call has completed by using .readyState and other hack-like methods. I'm just not sure what to try next!
Am I going about this the completely wrong way? Is there a straightforward way to make the "add another item" multi-value field ajax call using jQuery? Any help would be greatly appreciated...
I am not sure if there's a nicer way in Drupal 7, but in Drupal 6 you could use jQuery(document).ajaxComplete with the settings.url property to tell when a specific "Add another item" click had finished.
Start with:
(function($) {
$(document).ajaxComplete(function(e, xhr, settings)
{
alert(settings.url);
});
}(jQuery));
Once you've identified the right settings.url for your field, change that to:
(function($) {
$(document).ajaxComplete(function(e, xhr, settings)
{
if (settings.url == "the path from step 1") {
// Code to populate your fields here
}
});
}(jQuery));
And voila!
You might want to read the page by Jay Matwichuk where I originally learned this technique awhile back. All credit to him (and nclavaud for his comment there), really.

AJAX/prototype reset call

I have an AJAX / prototype related question. I have an AJAX call currently placed inline, in the onclick (i promise i'll move it out of there :) event, looking like this:
onclick="var pn = $('yards').value; $('inventory').update('Working...');
new Ajax.Updater('inventory','ajax.php?ac=checkInventory&productID='.$someproductid.'&yards='+pn,{method:'get', evalScripts: true, asynchronous: true, onComplete:function(tr){$('inventory').update(tr.responseText);}});"
File called ajax.php then gets the data from $_GET[], displays a small text input field. When filled in and clicked on a submit button, it calls a function which reads the relevant data from the file, and prints a result on the screen. The purpose of all this code is inventory check.
So, when a user clicks on the "get inventory" button with the onclick defined as above, everything works nice, the user fills the yardage, the right result pops up, everybody happy. But what makes it less usable is the fact that in case a user wants to do another inventory check, the entire page needs to be refreshed. If it's not, then when clicking on "get inventory" button, the user will be getting the same result of the last check again, not the text input field.
So, my question is, how do I make that after one inventory check, the whole thing sort of resets itself so that the next time a user clicks on "get inventory" button, he'll be offered to fill the text input field again, and hence get the new result.
I'm sorry if I didn't make myself clear enough. I'm very new to AJAX and prototype, and this is my colleague's work I need to finish...Thanks!
Ah I see,
I don't think Ajax.Updater works like that; have a look at the doc:
http://www.prototypejs.org/api/ajax/updater
new Ajax.Updater({ success: 'items', failure: 'notice' }, '/items', {
parameters: { text: $F('text') },
insertion: Insertion.Bottom
});
var pn = $('yards').value;
$('inventory').update('Working...');
new Ajax.Updater('inventory','/ajax.php
,{
parameters: { ac: 'checkInventory'
, productId: /*put productId here*/
, yards:/*put yards here too*/
}
, method:'get'
, evalScripts: true
, asynchronous: true
, onSuccess: function(tr){
//try an alert(tr.repsonseText); just to see what you get back
$('inventory').update(tr.responseText);
}
});
Things to try:
Clear the text input field before your repopulate it when the onComplete event fires in your ajax.updater call.
Alert the response to make sure your getting a different response from the server.
*Use Fiddler to make sure your passing in a different productId
Change onComplete to onSuccess
Hope this helps
Since you've promised to move the code out of the onclick handler do:
var inv = $('inventory');
inv.update('Working...');
new Ajax.Request('ajax.php', {
method:'get',
parameters:{
ac:'checkInventory',
yards:$('yards').value
},
onSuccess: function(response)
{
inv.update(response.responseText);
}
});

Cakephp Ajax Button

I have a delete button. which on click it should visit a url like /delete/{id} and once the response from that url is true. i want to delete the comment box like in facebook.
I wont add any extra than Leo's comment, but I will explain with some code. Presume that you are using jQuery...
$(document).ready(function(){
$('tr a.delete').live('click', function(e){
e.preventDefault();
var link = $(this);
$.get($(this).attr('href'), null, function(response){
if(response == 'ok'){ //you should invent how to get 'ok' or other string identifying that the deletion is successful.
link.parents('tr').remove();
} else {
alert('There is a problem while deleting this element');
}
});
})
});
if you put this code on your project it will handle all links which had .delete class and are in a table row.
There are two things which you should do:
You need to pass some string in
order to detect if the operation is
successful or not. In my example I
would print "ok" on success
deletion.
If your table has pagination, it wont
rebuild the table, while it just
will remove the row from the table.
and if you have let's say 5 rows per
page and you delete all of them the
page will remain empty while there
will be other records in the table.
That's why instead of removing the
tr I would reload the whole page.
In that case the code for successful deletion will look like this:
if(response == 'ok'){
$('#content').load(window.location);
}
The script is not optimised, but it will give you the ideas how to achieve your ideas.
HTH
So write an onClick event handler in your view, a php delete method on the appropriate controller called by the event handler and a javascript action to perform when the ajax call returns success.

Resources