I make a simple demo on which I just add rows dynamically. When I press add button and fill the name in input field then press ok it generate a row. So there is a Star icon in that I need to show pop over on click. I am able to show pop over. Now I need to hide that pop over when user click outside. I googled it and find one solution which works fine also but it is not like angular can you please tell how I can hide using angular way ..or another way ..?
Second problem is: when I generate a second row and click on the star icon it is not hiding the previous open popovers - why?
http://plnkr.co/edit/46RWSLtxxJgvw5MF1PmM?p=preview
I am able to hide pop over when click outside like this but this jQuery way do you suggest other way ?
$('html').on('click', function(e) {
if (typeof $(e.target).data('original-title') == 'undefined' &&
!$(e.target).parents().is('.popover.in')) {
$('[data-original-title]').popover('hide');
}
});
I'm not sure why you're not using one of the AngularJS libs that provide a Bootstrap popover, like this one to which I've contributed, but the general "angular" solution is to track the state of the popover in the directive and react on click when necessary. E.g.:
// in the link method
isOpen = false
function openPopover () {
// ... open the popover ...
// track the state
isOpen = true;
}
function closePopover () {
// ... close the popover ...
// track the state
isOpen = false;
}
function handleClick ( event ) {
if ( isOpen ) {
event.preventDefault();
event.stopPropagation();
closePopover();
}
};
$rootElement.on( 'click', handleClick );
scope.on( 'destroy', function () {
$rootElement.off( 'click', handleClick );
});
Related
I have been doing research on this for days and finally have decided to ask this on here. I am using react and material-ui's ClickAwayListener component. The idea is that I have a button, which toggles the this.state.showGridPopup to the opposite of whatever it is currently is. So if the user was to click it once, the grid popup should show, click it again, the popup should disappear. There is an handleShowGrid handler attached to the button that does this:
handleShowGrid = (event) => {
const { widgetButtonEl } = this.state;
const element = widgetButtonEl === null ? event.currentTarget : null;
console.log('In handleShowGrid!!!!!');
this.setState({
showWidget: !this.state.showWidget,
widgetButtonEl: element
});
}
All this works well. And toggles the popup to show when we click on the button attached to the handler.
<ButtonBase onClick={this.handleShowGrid}>Open Swap</ButtonBase>
The issue is when I add Material-UI's ClickAwayListener. The reason for adding this is to close the grid when a user clicks outside the grid. Here is the ClickAwayListener below:
<ClickAwayListener onClickAway={this.handleCloseWidget}>
<SurveyGrid />
</ClickAwayListener>
And the handleCloseWidget handler:
handleCloseGrid = (e) => {
console.log('In handleCloseWidget!!!!!');
this.setState({
showWidget: !this.state.showWidget,
widgetButtonEl: null
});
}
So now clicking outside grid is fine and closes the Grid. However, now, clicking on the button that should toggle the Grid being show (this.state.showWidget), causes the handleCloseGrid to fire. And then afterwards the handleShowGrid would fire. Is there anyway to not have the handleCloseGrid handler to fire? It seems like an issue with propagation and event bubbling. Have tried different things like e.stopPropagation() but to no avail.
Not to sure how to attack the following scenario.
I have a form with a row which is drag and drop-able and this is working perfectly. The issue I have is that I want to disable some buttons when the rows do not match page load and re-enable when they do.
I have the below jQuery code so far:
var $form = $('form'),
origForm = $form.serialize();
// Drag & drop for existing rules
$(function () {
$("#sortableRows").sortable();
$("#sortableRows").disableSelection();
});
// Check to see if form defaults have changed
$('form :input').change(function () {
if ($form.serialize() !== origForm) {
addDisable();
} else {
removeDisable();
}
});
// Added the disabled attribute when form changes
var addDisable = function () {
$("button[name='addButton'], button[name='modifyButton'], button[name='deleteButton'], button[name='activeButton'], button[name='inactiveButton'], input[name='searchDialPlanBox']").attr('disabled', true);
}
// Removes the disabled attribute
var removeDisable = function () {
$("button[name='addButton'], button[name='modifyButton'], button[name='deleteButton'], button[name='activeButton'], button[name='inactiveButton'], input[name='searchDialPlanBox']").removeAttr('disabled');
}
As I said the drag and drop and the disable/enable functions are working fine of everything else e.g. I disable the listed buttons when an input is changed but no sure on on how to do this when the div row is moved.
Got part of it working but stuck on when moving other divs as the first on works fine but other always fall into the Else
Drag & Drop Does Not Disable Buttons As Doesn't Fall Into Correct IF Statement
You can also give callback function like below for sortable
$( ".selector" ).sortable({
change: function( event, ui ) {}
});
Where is the code responsible for drag and drop handling?
For now Ill assume that is done by .sortable(). Then you would have to look into the docs of this function and search for events which are triggered on drag/drop and attach an listener which then calls disable/enable button.
Something like:
/*...*/.sortable({
dragStart: addDisable,
dragEnd: removeDisable
})
If you want to enable/disable depending on certain conditions then of course you have to implement that in the event handler too.
I'm trying to put a link on a selectize dropdown in order to allow the user make an operation other than select an item while still allowing that the user selects the item as main option.
Here is an example of what I want to achieve (but is not working as expected):
What I did is plainly insert links on the HTML. But it's not working, I suppose that for some kind of event propagation stop, is it possible to achieve with selectize?
Nobody did answer yet and I think there's more to say about, so, here is an example of what I did:
render: {
option: function(item) {
return '<div><span>'+item.label+'</span>'
+ '<div class="pull-right">'
+ 'Link'
+ '</div></div>';
}
}
As you can see, I did change the "option" renderization, and inserted a link in plain HTML. The problem is that -as shown on image- when I do click the link, the browser does not follow the link, but executes the default action for selectize, which is selecting the clicked element.
What I want to achieve is to make it follow the link when clicked.
Here is a fiddle of what I did: http://jsfiddle.net/uetpjpa9
The root problem is that Selectize has mousedown and blur handlers that are dismissing the dropdown before the mouseup event that would complete the click that your link is waiting for from ever occurring. Avoiding this without direct support from Selectize is not easy, but it is possible thanks to its plugin system and the amount of access it gives you to Selectize internals.
Here's a plugin that allows a dropdown element with the class clickable to be clicked on. (demo)
Selectize.define('option_click', function(options) {
var self = this;
var setup = self.setup;
this.setup = function() {
setup.apply(self, arguments);
var clicking = false;
// Detect click on a .clickable
self.$dropdown_content.on('mousedown click', function(e) {
if ($(e.target).hasClass('clickable')) {
if (e.type === 'mousedown') {
clicking = true;
self.isFocused = false; // awful hack to defuse the document mousedown listener
} else {
self.isFocused = true;
setTimeout(function() {
clicking = false; // wait until blur has been preempted
});
}
} else { // cleanup in case user right-clicked or dragged off the element
clicking = false;
self.isFocused = true;
}
});
// Intercept default handlers
self.$dropdown.off('mousedown click', '[data-selectable]').on('mousedown click', '[data-selectable]', function() {
if (!clicking) {
return self.onOptionSelect.apply(self, arguments);
}
});
self.$control_input.off('blur').on('blur', function() {
if (!clicking) {
return self.onBlur.apply(self, arguments);
}
});
}
});
To use it, you need to pass the plugin option to the selectize call (.selectize({plugins:['option_click']})) and add the clickable class to links in your dropdown template. (This is fairly specific. If there are nested elements, make sure clickable is on the one that will first see the mousedown event.)
Note that this is a fairly hackish approach that may have edge cases and could break at any time if something about how Selectize dispatches events changes. It would be better if Selectize itself would make this exception, but until the project catches up to its backlog and becomes more receptive to requests and PRs this may be the most practical approach.
I have a modal window that allows users to submit a form as one of the call-to-actions. However, clicking 'Submit' closes the modal window but I do not want it to. Here is the page: infowest.com/residential-internet.
To activate the modal window, the user clicks the yellow-orange "Get started" button on any of the "cards" of Internet options. Then to fill out and submit a form, the user clicks the "Request a callback" button. Actually, come to find, clicking ANYWHERE accept the "Request a callback" button closes the modal window, not just clicking the 'Submit' button.
I tried using this code:
if ( $(event.target).is('.modal-window-content') ) {
return false;
}
if ( $(event.target).is('input') ) {
return false;
}
to keep the modal from closing, which worked but didn't allow the form to submit or even try to submit. The form uses Ajax. It is the WP Contact Form 7 plugin.
I am using jQuery that I'm just making up as I go but I've never really been taught jQuery so I'm assuming I'm making errors in the js code. Here is my code:
var pagePosition;
$('.js--activate-cta-modal').click(function() {
if ( (!$(this).hasClass('.active')) && (!$('body').hasClass('modal-active')) ) {
pagePosition = $(window).scrollTop();
$('.cta-modal-window').css( "margin-top", pagePosition );
$(this).addClass("active");
$('body').addClass("modal-active");
$('body').css( "top", -pagePosition );
return false;
}
if($(this).hasClass('active')) {
$(this).removeClass('active');
$('body').removeClass('modal-active')
$('body').css( "top", "0" );
$('body').scrollTop(pagePosition);
}
});
$('.js--activate-cta-modal').click(function (e) {
e.stopPropagation();
});
$('.modal-overlay').click(function() {
$('body').removeClass('modal-active');
$('.js--activate-cta-modal').removeClass('active');
$('body').css( "top", "0" );
$('body').scrollTop(pagePosition);
});
$('.cta-modal-window').click(function() {
// if ( $(event.target).is('.modal-window-content') ) {
// return false;
// }
// if ( $(event.target).is('input') ) {
// return false;
// }
$('body').removeClass('modal-active');
$('.js--activate-cta-modal').removeClass('active');
$('body').css( "top", "0" );
$('body').scrollTop(pagePosition);
});
$('.close-modal-window').click(function() {
$('body').removeClass('modal-active');
$('.js--activate-cta-modal').removeClass('active');
$('body').css( "top", "0" );
$('body').scrollTop(pagePosition);
});
I greatly appreciate any and all help! Thank you!
It's important not to confuse Event.stopPropagation() and Event.preventDefault(), and to understand exactly what they do.
Event.stopPropagation() will prevent events from bubbling up through the DOM. Normally if you click on an element its event will attempt to fire, and then the parent element will attempt to fire its version of the event, and so on up the tree. This is used to contain events to a certain level on the DOM.
Event.preventDefault() stops the default action that elements might have from triggering. The most common one is using this on a form to stop it from submitting. This is used to cancel out the default behavior of elements with certain events.
Here is an example of a common modal staging technique. http://codepen.io/Oka/pen/xGKJVJ
(If you're new to CodePen, click the eyeballs to view any compiled code. I've used Jade and SCSS here. The page is also running Normalize.css)
With this technique we only need one Event.stopPropagation() to stop similar events from bubbling up from the modal to its container. Clicking anywhere on the modal's container will close the modal, and so will the small close button. You can expand this to suit your needs, the key is the modal should never bubble to its container.
JS
var open = $('.modal-open'),
close = $('.modal-close'),
modal = $('.modal'),
container = $('.modal-container');
function openModal (e) {
container.addClass('active');
}
function closeModal (e) {
container.removeClass('active');
}
open.on('mouseup', openModal);
close.on('mouseup', closeModal);
container.on('mouseup', closeModal);
modal.on('mouseup', function (e) {
e.stopPropagation();
});
(Keep in mind some of this stuff is IE9+. Make sure to check browser compatibility if you have legacy needs.)
I now understand a little more of what
$('element').click(function (e) {
e.stopPropagation();
});
is for. This is used to not perform the click function of the targeted element. I'll need to do some more reading on this but I solved the issue by using this code to target the div.modal-window-content.
I'm struggling with this javascript at the moment.
$(document).ready(function () {
var visible = false;
var body = false;
$("body").mouseup(function () {
if (visible) {
$(this).parent().find("ul.subnav").slideUp('slow');
visible = false;
$(this).removeClass("clicked-background");
body = true;
}
});
$("ul.topnav li a").click(function () { //When trigger is clicked...
var menu = $(this).parent().find('ul.subnav');
if (!visible && !body) {
$(this).parent().find("ul.subnav").slideDown('fast').show();
visible = true;
$(this).addClass("clicked-background");
}
// else if (visible)
//{
// $(this).parent().find("ul.subnav").slideUp('slow');
// visible = false;
// $(this).removeClass("clicked-background");
// }
body = false;
});
});
I wanted to add the feature, so if you clicked outside the menu/navigation the dropdown would hide.
The current problem with this code is, that if you click the menu and then click outside the menu - you have to double click the menu again to get it showen. This is caused by the body variable is set too 'True' ofc.
I made the body variable trying to fix the problem if you clicked the menu - and then clicked the same link again. The menu would first open correctly, and then close and open again.
Soo main problem is. My navigation open -> closes -> open
Don't use global variables. Check if the actual element is visible by checking
.is(':visible');
You can use that on the various selectors you have now.
I would be tempted to use onmouseout of the 'now visible' menu as the event of choice..
I dont think that running events off of the body tag is the good way to go.
the flow should be..
click (menu button or link)
show menu
set onmouseout for button and menu on click
onmouseout, remove onmouseout events