trying to reenable link after preventDefault has been used - javascript

I have a link with the text "No New Notifications". The following code is used to make the link not clickable:
if ($.trim($('a#full_notifications_link').text()) == "No New Notifications"){
$('a#full_notifications_link').click(function(){
event.preventDefault();
return false;
});
}
I am using Ajax to poll the server and update the text. When the text is updated to say "See All Notifications", I want the link to become clickable. I am using the following code, but it is not working.
$(document).ajaxComplete(function(){
if ($.trim($('a#full_notifications_link').text()) == "See All Notifications"){
$('a#full_notifications_link').click(function(){
return true;
});
}
});
I know the problem has something to do with returning true, because if i put an alert in right before returning true, the alert works. Unfortunately, the link is still unclickable.
I also CANNOT change any of my html because it is generated differently every time by the backend.

Adding a new event handler does not remove the event handlers you already have, so the default action is still prevented.
Use on() and off() instead
if ($.trim($('a#full_notifications_link').text()) == "No New Notifications"){
$('a#full_notifications_link').on(function(event){
event.preventDefault();
});
}
$(document).ajaxComplete(function(){
if ($.trim($('a#full_notifications_link').text()) == "See All Notifications"){
$('a#full_notifications_link').off('click');
}
});
It does seem easier to just check the text inside the event handler
$('a#full_notifications_link').on('click', function(e) {
if ( $.trim($(this).text()) == "No New Notifications"){
e.preventDefault();
}
});

Could you just move your logic into the click handler?
$('a#full_notifications_link').click(function(evt){
if($(this).text() == "No New Notifications") {
evt.preventDefault();
}
});

Related

jquery selector for future element if visible

One of my ajax popup is loading too late.so my condition of jquery to check visibility is not working.
$(document).ready(function() {
if($('#emailCart').is(':visible')){
alert('yes');
let shouldFire = true;
$("input, select").click(function(){
if(shouldFire) {
alert('sent');
sendGAEvent('Email', 'click','Email Cart');
shouldFire = false;
}
});
};
});
seems "is(':visible')" only checks for dom loaded elements.How can i apply this conditions to future elements also.
Email cart image
When clicking on this Email cart button many textboxes appear on clicking any one of those my code should work. I am using a tool tempormonkey by which i inject my code to websites.But my code is not working when i inject using tempormonkey but instead works with console.
Do it the other way around: check the visibility in the handler function.
$(document).ready(function() {
$("input, select").click(function() {
if ($('#emailCart').is(':visible')) {
alert('sent');
sendGAEvent('Email', 'click', 'Email Cart');
}
});
});
If the input and select elements are loaded dynamically, use event delegation as described in Event binding on dynamically created elements?. But that doesn't change the logic of how to check for visibility of the cart.
Its not possible to write such code which will execute in future but we can monitor that on click of document because you are saying that on click of Email Cart button you want to execute it.
I hope it will resolve your issue, try it:-
$(document).on('click', function (e) {
if (!$('#emailCart').is(':visible')) return;
alert('yes');
let shouldFire = true;
$("input, select").click(() => {
if (!shouldFire) return;
alert('sent');
sendGAEvent('Email', 'click', 'Email Cart');
shouldFire = false;
});
});

How to make a tag description required

I'm pretty new to WordPress, but basically what I'm trying to achieve is to make a tag's description a required field on my custom theme for WordPress 4.5.2
I've tried three approaches, but all of them failed so if anyone WordPress expert out there could guide me would be nice.
Approach #1
functions.php
I've tried to 'edit' the hook when the edit_tag_form_fields and add_tag_form hook is called, then modify via Javascript
function require_category_description(){
require_once('includes/require_category_description.php');
}
add_action('edit_tag_form_fields', 'require_category_description');
add_action('add_tag_form', 'require_category_description');
require_category_description.php
<script>
jQuery(document).ready(function(){
var description = jQuery('#tag-description');
if(!description) description = jQuery('#description');
if(description){
description.parents('form').submit(function(){
if(description.val().trim().length < 1){
console.log('Please enter a description...');
return false;
}
});
}
});
</script>
It was not working, the form was submitting even though the description field was empty, and above all, the console.log inside the event listener never happened. I've tried to log the description variable to make sure it's going inside the if case. Therefore, I assumed the form was never submitting, and the whole 'submission' is done via Ajax, on the button click.
Approach #2
The functions.php remains the same as approach #1, but I've made some changes Javascript wise to target the button click event instead of the form submit event.
require_category_description.php
<script>
jQuery(document).ready(function(){
var description = jQuery('#tag-description');
if(!description) description = jQuery('#description');
if(description){
var button = description.parents('form').find('#submit');
button.on('click', function(e){
if(description.val().trim().length < 1)
console.log('Please enter a description...');
e.preventDefault();
return false;
});
}
});
</script>
The form is however still submitting, but this time, I see the console log message.
Please enter a description...
My theory is that WordPress is binding an event to the button's click before my event, so it's processing the built-in event with Ajax before going to my custom click event.
Approach #3
require_category_description.php
I've tried to unbind the click events from my button before adding my own click event.
<script>
jQuery(document).ready(function(){
var description = jQuery('#tag-description');
if(!description) description = jQuery('#description');
if(description){
var button = description.parents('form').find('#submit');
button.unbind('click');
button.on('click', function(e){
if(description.val().trim().length < 1)
console.log('Please enter a description...');
e.preventDefault();
return false;
});
}
});
</script>
The result is the same as approach #2. The form is still submitting, but I see the console log message.
Edit tag:
When editing tag, WordPress call wp_update_term. But there're no filters or AJAX call, so we must use get_term() which is called by wp_update_term():
add_filter('get_post_tag', function($term, $tax)
{
if ( isset($_POST['description']) && empty($_POST['description']) ) {
return new \WP_Error('empty_term_name', __('Tag description cannot be empty!', 'text-domain'));
} else {
return $term;
}
}, -1, 2);
We also need to update term_updated_message to make the error clear:
add_filter('term_updated_messages', function($messages)
{
$messages['post_tag'][5] = sprintf('<span style="color:#dc3232">%s</span>', __('Tag description cannot be empty!', 'text-domain'));
return $messages;
});
Because WordPress hardcoded the notice message div, I used inline css to make the error look like a waring. Change it to your preference.
Add new tag:
The AJAX request calls wp_insert_term so we can use pre_insert_term filter. Try this in your functions.php
add_filter('pre_insert_term', function($term, $tax)
{
if ( ('post_tag' === $tax) && isset($_POST['description']) && empty($_POST['description']) ) {
return new \WP_Error('empty_term_name', __('Tag description cannot be empty!', 'text-domain'));
} else {
return $term;
}
}, -1, 2);
Here I used the built-in empty_term_name error to show notice message but you should register your own one.
Also, take a look at wp_ajax_add_tag to fully understand what we're doing.
Demo:
It's Ajax so you cannot rely on submit event, here is a solution, how you can do.
All you want to do is include form-required class to the parent tag of the particular element, but there is kick on it. their validateForm check only on input tags not on textarea so I have implemented an idea, it works.
Try this
function put_admin_script() { ?>
<script>
jQuery(document).ready(function(){
var description = jQuery('#tag-description');
if( !description ) {
description = jQuery('#description');
}
if( description ) {
description.after( $('<p style="visibility:hidden;" class="form-field form-required term-description-wrap"><input type="text" id="hidden-tag-desc" aria-required="true" value="" /></p>') );
}
description.keyup(function(){
$("#hidden-tag-desc").val( $(this).val() );
});
jQuery("#addtag #submit").click(function(){
console.log("Not empty"+description.val().trim().length);
if( description.val().trim().length < 1 ) {
description.css( "border", "solid 1px #dc3232" );
} else {
description.css( "border", "solid 1px #dddddd" );
}
});
});
</script>
<?php
}
add_action('admin_footer','put_admin_script');

Need click event to trigger alert during else

So, this code is working:
<script>
$(document).ready(function(){
  var btn = $('#submit_send_order');
  btn.attr({disabled: 'disabled'});
  var chk = $('.end-box');
  chk.click(function(){
    if ($(this).attr('checked'))
      btn.removeAttr('disabled');
    else
      btn.attr({disabled:'disabled'});
  });
});
</script>
but I can't get any working version of a click, onclick, or event handler to cause a popup message during the else condition. Unless users checks a box, they cannot send their order on my site. Right now they click the button and nothing happens until they check the box. But I'd like an alert to show as well, e.g.:
$(document).ready(function(){
$('#submit_send_order').click(function(){
alert("You cannot proceed until you check the end box");
});
});
As Verhaeren said above, if the button is disabled, then it can't fire the click event. Rather than disabling the button, I would just put an if/else check in the click event.
So...
$(document).on('click', '#submit_send_order', function(event) {
event.preventDefault();
if ($('.end-box').prop('checked')) {
//Handle form submission
} else {
alert('You cannot proceed until you check the end box');
}
});
The onclick event doesn't fire when the element is disabled. Also, notice which is the right method to see if the checkbox is checked:
$(document).ready(function(){
var btn = $('#submit_send_order');
btn.attr({disabled: 'disabled'});
var chk = $('.end-box');
chk.on('click', function(){
if ($(this).is(':checked'))
btn.removeAttr('disabled');
else
btn.attr({disabled:'disabled'});
});
btn.on('click', function(){
alert("You cannot proceed until you check the end box");
});
});
I build a "solution" for this if you REALLY whant to do that. You can check it at this fiddle:
http://jsfiddle.net/2f1wsb8c/3/
It's placing an element with the same size of the button over it to catch the click when the button is disabled.

X-Editable: stop propagation on "click to edit"

I have an editable element inside a div which itself is clickable. Whenever I click the x-editable anchor element, the click bubbles up the DOM and triggers a click on the parent div. How can I prevent that? I know it's possible to stop this with jQuery's stopPropagation() but where would I call this method?
Here's the JSFiddle with the problem: http://jsfiddle.net/4RZvV/ . To replicate click on the editable values and you'll see that the containing div will catch a click event. This also happens when I click anywhere on the x-editable popup and I'd like to prevent that as well.
EDIT after lightswitch05 answer
I have multiple dynamic DIVs which should be selectable so I couldn't use a global variable. I added an attribute to the .editable-click anchors which get's changed instead.
editable-active is used to know if the popup is open or not
editable-activateable is used instead to know if that .editable-click anchor should be treated like it is
$(document).on('shown', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).attr("editable-active", true);
});
$(document).on('hidden', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).removeAttr("editable-active");
});
The check is pretty much like you've described it
$(document).on("click", ".version", function() {
$this = $(this)
// Check that the xeditable popup is not open
if($this.find("a[editable-active]").length === 0) { // means that editable popup is not open so we can do the stuff
// ... do stuff ...
}
})
For the click on the links, simply catch the click event and stop it:
$("a.editable-click").click(function(e){
e.stopPropagation();
});
The clicks within X-editable are a bit trickier. One way is to save a flag on weather the X-editable window is open or not, and only take action if X-editable is closed
var editableActive = false;
$("a.editable-click").on('shown', function(e, reason) {
editableActive = true;
});
$("a.editable-click").on('hidden', function(e, reason) {
editableActive = false;
});
$("div.version").click(function(e) {
var $this;
$this = $(this);
if(editableActive === false){
if ($this.hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
}
});
Fixed Fiddle
It's not pretty, but we solved this problem with something like:
$('.some-class').click(function(event) {
if(event.target.tagName === "A" || event.target.tagName === "INPUT" || event.target.tagName === "BUTTON"){
return;
}
We're still looking for a solution that doesn't require a specific list of tagNames that are okay to click on.

What is the opposite of evt.preventDefault();

Once I've fired an evt.preventDefault(), how can I resume default actions again?
As per commented by #Prescott, the opposite of:
evt.preventDefault();
Could be:
Essentially equating to 'do default', since we're no longer preventing it.
Otherwise I'm inclined to point you to the answers provided by another comments and answers:
How to unbind a listener that is calling event.preventDefault() (using jQuery)?
How to reenable event.preventDefault?
Note that the second one has been accepted with an example solution, given by redsquare (posted here for a direct solution in case this isn't closed as duplicate):
$('form').submit( function(ev) {
ev.preventDefault();
//later you decide you want to submit
$(this).unbind('submit').submit()
});
function(evt) {evt.preventDefault();}
and its opposite
function(evt) {return true;}
cheers!
To process a command before continue a link from a click event in jQuery:
Eg: Click me
Prevent and follow through with jQuery:
$('a.myevent').click(function(event) {
event.preventDefault();
// Do my commands
if( myEventThingFirst() )
{
// then redirect to original location
window.location = this.href;
}
else
{
alert("Couldn't do my thing first");
}
});
Or simply run window.location = this.href; after the preventDefault();
OK ! it works for the click event :
$("#submit").click(function(event){
event.preventDefault();
// -> block the click of the sumbit ... do what you want
// the html click submit work now !
$("#submit").unbind('click').click();
});
event.preventDefault(); //or event.returnValue = false;
and its opposite(standard) :
event.returnValue = true;
source:
https://developer.mozilla.org/en-US/docs/Web/API/Event/returnValue
I had to delay a form submission in jQuery in order to execute an asynchronous call. Here's the simplified code...
$("$theform").submit(function(e) {
e.preventDefault();
var $this = $(this);
$.ajax('/path/to/script.php',
{
type: "POST",
data: { value: $("#input_control").val() }
}).done(function(response) {
$this.unbind('submit').submit();
});
});
I would suggest the following pattern:
document.getElementById("foo").onsubmit = function(e) {
if (document.getElementById("test").value == "test") {
return true;
} else {
e.preventDefault();
}
}
<form id="foo">
<input id="test"/>
<input type="submit"/>
</form>
...unless I'm missing something.
http://jsfiddle.net/DdvcX/
This is what I used to set it:
$("body").on('touchmove', function(e){
e.preventDefault();
});
And to undo it:
$("body").unbind("touchmove");
There is no opposite method of event.preventDefault() to understand why you first have to look into what event.preventDefault() does when you call it.
Underneath the hood, the functionality for preventDefault is essentially calling a return false which halts any further execution. If you’re familiar with the old ways of Javascript, it was once in fashion to use return false for canceling events on things like form submits and buttons using return true (before jQuery was even around).
As you probably might have already worked out based on the simple explanation above: the opposite of event.preventDefault() is nothing. You just don’t prevent the event, by default the browser will allow the event if you are not preventing it.
See below for an explanation:
;(function($, window, document, undefined)) {
$(function() {
// By default deny the submit
var allowSubmit = false;
$("#someform").on("submit", function(event) {
if (!allowSubmit) {
event.preventDefault();
// Your code logic in here (maybe form validation or something)
// Then you set allowSubmit to true so this code is bypassed
allowSubmit = true;
}
});
});
})(jQuery, window, document);
In the code above you will notice we are checking if allowSubmit is false. This means we will prevent our form from submitting using event.preventDefault and then we will do some validation logic and if we are happy, set allowSubmit to true.
This is really the only effective method of doing the opposite of event.preventDefault() – you can also try removing events as well which essentially would achieve the same thing.
Here's something useful...
First of all we'll click on the link , run some code, and than we'll perform default action. This will be possible using event.currentTarget Take a look. Here we'll gonna try to access Google on a new tab, but before we need to run some code.
Google
<script type="text/javascript">
$(document).ready(function() {
$("#link").click(function(e) {
// Prevent default action
e.preventDefault();
// Here you'll put your code, what you want to execute before default action
alert(123);
// Prevent infinite loop
$(this).unbind('click');
// Execute default action
e.currentTarget.click();
});
});
</script>
None of the solutions helped me here and I did this to solve my situation.
<a onclick="return clickEvent(event);" href="/contact-us">
And the function clickEvent(),
function clickEvent(event) {
event.preventDefault();
// do your thing here
// remove the onclick event trigger and continue with the event
event.target.parentElement.onclick = null;
event.target.parentElement.click();
}
I supose the "opposite" would be to simulate an event. You could use .createEvent()
Following Mozilla's example:
function simulateClick() {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var cb = document.getElementById("checkbox");
var cancelled = !cb.dispatchEvent(evt);
if(cancelled) {
// A handler called preventDefault
alert("cancelled");
} else {
// None of the handlers called preventDefault
alert("not cancelled");
}
}
Ref: document.createEvent
jQuery has .trigger() so you can trigger events on elements -- sometimes useful.
$('#foo').bind('click', function() {
alert($(this).text());
});
$('#foo').trigger('click');
This is not a direct answer for the question but it may help someone. My point is you only call preventDefault() based on some conditions as there is no point of having an event if you call preventDefault() for all the cases. So having if conditions and calling preventDefault() only when the condition/s satisfied will work the function in usual way for the other cases.
$('.btnEdit').click(function(e) {
var status = $(this).closest('tr').find('td').eq(3).html().trim();
var tripId = $(this).attr('tripId');
if (status == 'Completed') {
e.preventDefault();
alert("You can't edit completed reservations");
} else if (tripId != '') {
e.preventDefault();
alert("You can't edit a reservation which is already attached to a trip");
}
//else it will continue as usual
});
jquery on() could be another solution to this. escpacially when it comes to the use of namespaces.
jquery on() is just the current way of binding events ( instead of bind() ). off() is to unbind these. and when you use a namespace, you can add and remove multiple different events.
$( selector ).on("submit.my-namespace", function( event ) {
//prevent the event
event.preventDefault();
//cache the selector
var $this = $(this);
if ( my_condition_is_true ) {
//when 'my_condition_is_true' is met, the binding is removed and the event is triggered again.
$this.off("submit.my-namespace").trigger("submit");
}
});
now with the use of namespace, you could add multiple of these events and are able to remove those, depending on your needs.. while submit might not be the best example, this might come in handy on a click or keypress or whatever..
you can use this after "preventDefault" method
//Here evt.target return default event (eg : defult url etc)
var defaultEvent=evt.target;
//Here we save default event ..
if("true")
{
//activate default event..
location.href(defaultEvent);
}
You can always use this attached to some click event in your script:
location.href = this.href;
example of usage is:
jQuery('a').click(function(e) {
location.href = this.href;
});
In a Synchronous flow, you call e.preventDefault() only when you need to:
a_link.addEventListener('click', (e) => {
if( conditionFailed ) {
e.preventDefault();
// return;
}
// continue with default behaviour i.e redirect to href
});
In an Asynchronous flow, you have many ways but one that is quite common is using window.location:
a_link.addEventListener('click', (e) => {
e.preventDefault(); // prevent default any way
const self = this;
call_returning_promise()
.then(res => {
if(res) {
window.location.replace( self.href );
}
});
});
You can for sure make the above flow synchronous by using async-await
this code worked for me to re-instantiate the event after i had used :
event.preventDefault(); to disable the event.
event.preventDefault = false;
I have used the following code. It works fine for me.
$('a').bind('click', function(e) {
e.stopPropagation();
});

Categories

Resources