.click function ask me twice for confirmation - ajax

I have this issue, maybe you guys can help me fix it.
Botton Delete:
<button type="button" class="del-trade">Delete</button>
Ajax code:
$(function(){
$("#modaledittrade").on("show.bs.modal", function (e) {
$('.del-trade').click(function(){
var id = $(e.relatedTarget).attr( "data-id" );
if( confirm( "Are you sure?") )
{
$.post( "actions.php?a=del-trade", { "id" : id },function(d){
if( d.type!="ok" )
{
alert( d.msg );
return;
}
$( "tr#" + id ).remove();
resetForms( e.currentTarget );
$( "#modaledittrade").modal('hide');
},"json");
}
});
});
});
The code is give me loop twice... I mean ask me for function confirm() twice.
Video demo: http://sc.sny.pt/sJH6

On what I see, I think reason is because you create multiple instance of onclick event:
first time you delete (when modal is shown) create onclick event and the
second time that create a second event.
This should work :
$(function(){
/*$("#modaledittrade").on("show.bs.modal", function (e) {
}); */
$('.del-trade').click(function(){
var id = $(e.relatedTarget).attr( "data-id" );
if( confirm( "Are you sure?") )
{
$.post( "actions.php?a=del-trade", { "id" : id },function(d){
if( d.type!="ok" )
{
alert( d.msg );
return;
}
$( "tr#" + id ).remove();
resetForms( e.currentTarget );
$( "#modaledittrade").modal('hide');
},"json");
}
});
});

You can pull the click event out, and this will still work as expected, using on:
$(document).on("click", '.del-trade', function(e){
var id = $(e.relatedTarget).attr( "data-id" ); // can still get ID same way
if( confirm( "Are you sure?") )
{
$.post( "actions.php?a=del-trade", { "id" : id },function(d){
if( d.type!="ok" )
{
alert( d.msg );
return;
}
$( "tr#" + id ).remove();
resetForms( e.currentTarget );
$( "#modaledittrade").modal('hide');
},"json");
}
});
EDIT: Or, when the modal is hidden, turn off the delete click action:
$("#modaledittrade").on("hide.bs.modal", function (e) {
$('.del-trade').off("click");
});
$("#modaledittrade").on("show.bs.modal", function (e) {
$('.del-trade').on("click", function(e) { .. });
});

Related

Load more posts with AJAX and also add pagination in URL

On load more button, posts load without page load using AJAX, but wanted to implement Wordpress pagination on load more along with URL changing. Suggestions are welcome.
/* Category/tag page Masonry Grid */
var $mgrid = $( '.post-grid' ).masonry();
$mgrid.masonry( {
itemSelector: '.post-outer',
} );
/* ------------------ Load More Posts Category/tag page ------------------ */
$( document ).on( 'click', '#post-button', function(e) {
e.preventDefault();
var offset = $( this ).attr( 'data-value' );
var cat = $( this ).attr( 'data-cat' ); //load more button attribute
var tag = $( this ).attr( 'data-tag' ); //load more button attribute
var page = $( this ).attr( 'data-page' ); //load more button attribute
var $content;
$.ajax( {
type: "post",
async: false,
dataType: "json",
url: localizeObj.ajaxurl, //localize script in functions.php
data: {
action: 'fetch_posts', //ajax load more function in functions.php
offset: offset,
cat: cat,
tag: tag,
page: page,
search_term: localizeObj.search_term,
current_page: localizeObj.current_page
},
beforeSend: function() {
},
success: function(response) {
/* Adding page numbers on ajax load more */
var pathname = window.location.pathname;
if ( response.success == 'yes' ) {
$content = $(response.posts);
$( '.post-masonry-grid' ).append( $content ).masonry( 'appended', $content );
page = parseInt(page) + 1;
offset = parseInt(offset) + 6;
$('.post-grid-outer').each( function() {
$('.post-grid-outer').addClass(offset);
});
$( '#post-grid-button' ).attr( 'data-value', offset );
$( '#post-grid-button' ).attr( 'data-page', page );
var page_num = '';
if(page <= 2) {
var page_num = 'page/'+ page;
} else {
var page_num = page;
}
window.history.pushState("URL", "Title", page_num); // Add page numbers to URL
} else {
$( '#post-button' ).hide();
}
},
complete : function() {
}
} );
} );

Why 'click' doesn't work event on body in this case

I've tried to make event deledation, set "click" event on body. Event works on button. But why it doesn't work on body?
window.onload = function(){
var bodyN = document.body,
bodyS = bodyN.style
bodyS.transition = "all 0s";
bodyS.backgroundColor = localStorage.getItem("bgc")
bodyN.addEventListener("click", function(e){
console.log(e.target); // why doesn't work this when I click on body?
if (e.target.tagName == "BUTTON") {
console.log(e);
bodyS.transition = "";
bodyS.backgroundColor = e.target.id;
localStorage.setItem("bgc", e.target.id);
}
});
};
the same via jQuery:
$(document).ready(function(){
$("body").css("transition", "all 0s" );
$("body").css("backgroundColor", localStorage.getItem("bgc"));
$("body").on("click", "button", function(e){
console.log(e);
$("body").css("transition", "" );
$("body").css("backgroundColor", e.target.id);
localStorage.setItem("bgc", e.target.id);
})
});
With jQuery, I used "click" instead of "on". Here's an example:
$("body").click(function(e){
console.log(e);
if(e.target.id == "button"){
alert('button');
}
else{
alert('body');
}
});
https://jsfiddle.net/aumayk6s/
Hope it helps you!

Swipe and registration not working simultaneously

I am using Zend framework version 1.11.3 and jquery mobile version 1.3.0-beta.1.My swipe and registration are not working simultaneously.Individually they are working fine.I have tried changing their positions but all in vain.Here is my code -
Registration form code :
<script>
$('#1').on('pageshow', function(event) {
$(document).on('click','#submit_button',function(e) {
if (validatefName() & validatelName() & validateEmail()) {
$.ajax({
errorElement : "em",
type : "POST",
url : "index/saveregister",
data : $('#registerForm').serialize(),
success : function(e) {
// e is for detecting if the meail address already exists in the database.
if (e == 1) {
console.log("success");
//location.reload();
$("#message").html('<h2 style="color:green"><center><br>Thank you for registering with us .</center></h2>');
}
if (e == 0) {
// If email address exists in the database already
//alert("e is zero");
$('#message').html('<h2 style="color:red">Please check ur email address</h2>');
return false;
}
},
error : function(data1, st, rr) {
alert("ajax error");
}
});
//ajax requests
return true;
} else {
return false;
}
});
});
</script>
Swipe code :
$( document ).on( "pageinit", "[data-role='page'].swipe-page", function() {
var page = "#" + $( this ).attr( "id" ),
next = $( this ).jqmData( "next" ),
prev = $( this ).jqmData( "prev" );
if ( next ) {
// Prefetch the next page
$.mobile.loadPage( next );
// Navigate to next page on swipe left
$( document ).on( "swipeleft", page, function() {
$.mobile.changePage( next );
});
}
if ( prev ) {
$( document ).on( "swiperight", page, function() {
$.mobile.changePage( prev , { reverse: true } );
});
}
});
Any help will be appreciated

tap event fired after taphold jQuery Mobile 1.1.1

I am developing an app for iOS using Phonegap bundled with jQuery Mobile 1.1.1. I have a div on my page that is listening for both tap and taphold events.
The problem I am facing is that the tap event is fired after the taphold event once I lift my finger. How do I prevent this?
A solution is provided here but is this the only way to do this? Kinda nullifies the whole point of having two different events for tap & taphold if you need to use a boolean flag to differentiate the two.
Following is my code:
$('#pageOne').live('pageshow', function(event) {
$('#divOne').bind('taphold', function (event) {
console.log("TAP HOLD!!");
});
$('#divOne').bind('tap', function () {
console.log("TAPPED!!");
});
});
Would greatly appreciate the help. Thanks!
Simply set this at the top of your document or anywhere before you define your even:
$.event.special.tap.emitTapOnTaphold = false;
Then you can use it like this:
$('#button').on('tap',function(){
console.log('tap!');
}).on('taphold',function(){
console.log('taphold!');
});
[Tried and Tested]
I checked jQuery Mobile's implementation. They are firing the 'tap' event after 'taphold' every time on 'vmouseup'.
Workaround would be not to fire the 'tap' event if the 'taphold' has been fired. Create a custom event or modify the source as per you need as follows:
$.event.special.tap = {
tapholdThreshold: 750,
setup: function() {
var thisObject = this,
$this = $( thisObject );
$this.bind( "vmousedown", function( event ) {
if ( event.which && event.which !== 1 ) {
return false;
}
var origTarget = event.target,
origEvent = event.originalEvent,
/****************Modified Here**************************/
tapfired = false,
timer;
function clearTapTimer() {
clearTimeout( timer );
}
function clearTapHandlers() {
clearTapTimer();
$this.unbind( "vclick", clickHandler )
.unbind( "vmouseup", clearTapTimer );
$( document ).unbind( "vmousecancel", clearTapHandlers );
}
function clickHandler( event ) {
clearTapHandlers();
// ONLY trigger a 'tap' event if the start target is
// the same as the stop target.
/****************Modified Here**************************/
//if ( origTarget === event.target) {
if ( origTarget === event.target && !tapfired) {
triggerCustomEvent( thisObject, "tap", event );
}
}
$this.bind( "vmouseup", clearTapTimer )
.bind( "vclick", clickHandler );
$( document ).bind( "vmousecancel", clearTapHandlers );
timer = setTimeout( function() {
tapfired = true;/****************Modified Here**************************/
triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
}, $.event.special.tap.tapholdThreshold );
});
}
};
You can use stopImmediatePropagation() method of jquery to solve this issue. According to the explanation in jquery api, stopImmediatePropagation() method
"Keeps the rest of the handlers from being executed and prevents the
event from bubbling up the DOM tree."
put this in your taphold event handler... this suggestion assumes o is a jQuery object that fired the taphold
jQuery(o).one('tap click', function(){ return false; });
the binding to the one method will fire the event only once. returning false will stop the execution of that event if it was an < a > tag.
Since swipe, triggers taphold then I was able to keep it simple with:
$(c).bind("taphold",function(e){
if(e.target.wait){
e.target.wait = false;
}else{
alert("fire the taphold");
}//eo if not waiting
});
$(c).bind("swipe",function(e){
e.target.wait = true;//taphold will come next if I don't wave it off
alert(e.target.text+"("+e.target.attributes.dataId.value+") got swiped");
return false;
});
To support tap too then I'd defer the wait clear until the tap event which will also always fire.
I still have problems, with jquery-mobile's taphold, I solved the problem of the click called after taphold, putting a timeout on the element.
JQM 1.4 with emitTapOnTaphold = false;
Example:
$(".element").on("taphold", function () {
        // function her
         setTimeout (function () {
             $(this).blur();
         400);
});
$.event.special.tap = {
tapholdThreshold: 750,
setup: function() {
var thisObject = this,
$this = $( thisObject );
$this.bind( "vmousedown", function( event ) {
if ( event.which && event.which !== 1 ) {
return false;
}
var origTarget = event.target,
origEvent = event.originalEvent,
/****************Modified Here**************************/
tapfired = false,
timer;
function clearTapTimer() {
clearTimeout( timer );
}
function clearTapHandlers() {
clearTapTimer();
$this.unbind( "vclick", clickHandler )
.unbind( "vmouseup", clearTapTimer );
$( document ).unbind( "vmousecancel", clearTapHandlers );
}
function clickHandler( event ) {
clearTapHandlers();
// ONLY trigger a 'tap' event if the start target is
// the same as the stop target.
/****************Modified Here**************************/
//if ( origTarget === event.target) {
if ( origTarget === event.target && !tapfired) {
triggerCustomEvent( thisObject, "tap", event );
}
}
$this.bind( "vmouseup", clearTapTimer )
.bind( "vclick", clickHandler );
$( document ).bind( "vmousecancel", clearTapHandlers );
timer = setTimeout( function() {
tapfired = true;/****************Modified Here**************************/
triggerCustomEvent( thisObject, "taphold", $.Event( "taphold", { target: origTarget } ) );
}, $.event.special.tap.tapholdThreshold );
});
}
};
#Akash Budhia: Thanks for your solutions.
It's great, sounds it work for me!

Cakephp 2.1 and Jquery UI autocomplete

Mission:
Implement autocomplete of departments(saved in departments table) in employee form field called department.
A user enters a few spellings of department name
That brings up list of the names matching departments
The user select one and that's it.
Platforms
CakePhp 2.1
Jquery UI Autocomplete(part of Jquery UI library version 1.8.18)
Database Model
Emplyee (id, first_name,last_name,department_id)
department(id,name)
so in my add.ctp file ajax call is something like
$( "#auto_complete" ).autocomplete({
source: function( request, response ) {
$.ajax({
url: "/employees/showDepartment",
dataType: "json",
data: {
featureClass: "P",
style: "full",
maxRows: 12,
name_startsWith: request.term
},
success: function( data ) {
alert("success--");
response( $.map( data, function( item ) {
//alert(item);
return {
label: item.name,
value: item.id
}
}));
}
});
},
minLength: 2,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.label :
"Nothing selected, input was " + this.value);
},
open: function() {
$( this ).removeClass( "ui-corner-all" ).addClass( "ui-corner-top" );
},
close: function() {
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
i have a action in my EmployeeController called show_depatment()
public function getAddress() {
$this->autoRender = false;// I do not want to make view against this action.
$this->log($this->params->query['name_startsWith'] , 'debug');
$str = $this->params->query['name_startsWith'];
$this->log($str, 'debug');
$this->layout = 'ajax';
$departments = $this->Employee->Department->find('all', array( 'recursive' => -1,
'conditions'=>array('Department.name LIKE'=>$str.'%'),
'fields'=>array('name', 'id')));
//$this->set('departments',$departments);
$this->log($departments, 'debug');
echo json_encode($departments);
}
I dont want show_department action to have any view so i have made $this->autoRender = false;
but it is not working as expected.
when i debug the response using firebug in response and HTLM section it shows
[{"Department":{"name":"Accounting","id":"4"}}] // when i type "acc" in input field
Question
How to make it to display in form field.
echo json_encode($departments); is it right method of sending response in json format?
when i alert in sucess part of ajax call (alert(item);) it gives error as "undefined"
i'm friend of fat Model and skinny Controller so my Controller action looks like this
public function getAddress()
{
if($this->RequestHandler->isAjax()) {
Configure::write('debug', 0);
$this->layout = 'ajax';
$this->autoRender = false;
echo json_encode($this->Employee->Department->getAddress($this->params['url']['term']));
exit;
}
}
and my Department model method:
public function getAddress($str)
{
$rs = array();
$search = $this->find('all', array(
'recursive' => -1,
'conditions'=>array('Department.name LIKE'=>$str.'%'),
'fields'=>array('name', 'id')
));
if (!empty($search))
{
//the jquery ui autocomplete requires object with label/value so we need to traverse the query results and create required array
foreach ($search as $key => $val)
{
$rs[] = array('label' => $val['Department']['name'],
'value' => $val['Department']['id']);
}
}
return $rs;
}
and finaly my view entry is like this:
$( "#auto_complete" ).autocomplete({
minLength: 2,
source: function( request, response ) {
var term = request.term;
if ( term in cache ) {
response( cache[ term ] );
return;
}
lastXhr = $.getJSON( "/employees/showDepartment", request, function( data, status, xhr ) {
cache[ term ] = data;
if ( xhr === lastXhr ) {
response( data );
}
});
}
});
hope this helps.

Resources