Calling Popover trough boolean or programmatic - javascript

I have a popover which I am calling when an event is fire. But I need that popover to be global
here the popover
<div class="popover" tabindex="-1">
<h5 ng-bind-html="title" ng-show="title"></h5>
...
<button type="button" ng-click="refreshAfterBet(); $hide()">
OK
</button>
</div>
</div>
I am calling it like this
<button ng-click="placeStraightBet(slip)"
title="Bet Confirmation"
data-placement="bottom" data-template="views/betConfirmModal.html"
data-auto-close="1"
bs-popover="" ng-disabled="slip.active != '1'"> Place Bet
</button>
and here the Angular part
$scope.refreshAfterBet = function() {
BetSlipFactory.retrieveBetSlip();
};
$scope.placeStraightBet = function(slip) {
var winValue = parseFloat(slip.risk, 10),
riskValue = parseFloat(slip.win, 10),
riskWin;
if (winValue && riskValue && riskValue > 4) {
BetSlipFactory.placeQuickBet({
wagerType: 1
}).then(function(betId) {
// HERE I NEED TO CALL THE POPOVER
$scope.betId = betId;
}, function(err) {
$scope.betPlaceErr = err.message;
console.log('Whoops, your bet was not placed', err.message);
});
}
};
OK, what I need:
1 - eliminate the function refreshAfterBet
the reason why I need to remove it is because that function should be within the promise where I wrote // HERE I NEED TO CALL THE POPOVER like this:
...
}).then(function(betId) {
// HERE I NEED TO CALL THE POPOVER
BetSlipFactory.retrieveBetSlip().then(function(){
$scope.betId = betId;
});
} ...
If I put it there as you see above, the popover just disappear so the user can not see it. I attached the function refreshAfterBet to the button in the popover, but I am wrong, that function should be call when you call placeStraightBet.
here the DOCS for the popover I am using
So how should I call this popover ?

Related

How to pass defined function into jQuery click event?

I have a drawer menu that expands on btn click, what I am trying to achieve is closing the menu when a user clicks on the sidenav-body class which covers the whole body.
Here is the base html and js
<div class="offcanvas-body sidenav-body">
<main id="main-content" role="main">
<div class="container-fluid short-section-row">
<div class="row">
<div class="side-nav-btn navbar-btn js-side-nav-btn" aria-expanded="false" aria-label="Open Side Navigation" aria-controls="SecondaryMenu">Explore This Section <span class="svg-sprite -hamburger"><svg role="img" aria-label="[object Object]"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#hamburger"></use></svg></span></div>
<nav class="side-nav col-sm-2" role="Secondary navigation" aria-label="Side Navigation" aria-hidden="true" id="SecondaryMenu">
<div class="side-nav__control-bar">
<button class="navbar-btn js-side-nav-btn btn btn-primary pull-right" aria-expanded="false" aria-label="Close Side Navigation" aria-controls="SecondaryMenu" tabindex="-1"><span class="svg-sprite -close"><svg role="img" aria-label="close secondary nav"><use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="#close"></use></svg></span> Menu</button>
</div>
// some ul and li items
</nav>
</div>
</div>
</main>
</div>
How I defined classes
this.$body = $(el);
this.$sideNavBody = $('.sidenav-body');
this.$sideNav = $('.side-nav');
this.$controls = $('.side-nav button');
this.$sideNavBtn = $('.js-side-nav-btn');
I have a toggle function on btn click
sideNavBodyToggleEvent(){
// if the nav is open, run close event
if(this.$body.hasClass('side-is-open')) {
this.sideNavBodyCloseEvent();
} else {
this.sideNavBodyOpenEvent();
}
}
And those conditional functions are defined like so
sideNavBodyCloseEvent () {
this.$body.removeClass('side-is-open');
// always clear the 'opened state' of any open menus
this.$sideNavSection.removeClass('side-is-open');
$(this.$controls).attr('tabindex', '-1');
$(this.$sideNav).attr('aria-hidden', 'true');
$(this.$sideNavBtn).attr('aria-expanded', 'false');
$(this.$sideNavSectionToggle).removeClass('side-is-open');
// unbind the pushed body click event
this.$sideNavBody.off();
}
sideNavBodyOpenEvent() {
this.$body.addClass('side-is-open');
$(this.$sideNav).attr('aria-hidden', 'false');
$(this.$controls).removeAttr('tabindex');
$(this.$sideNavBtn).attr('aria-expanded', 'true');
// bind an event on the div containing the pushed body
// original code left by prev dev was this.$sideNavBody.offClick.bind(this) and doesnt work as I think its trying to run both functions at once (the menu doesnt even open);
//below I am just trying to test if the click event even makes it to this.$.sideNavBody which is the .sidenav-body class and the section I want users to be able to click to close
$(this.$sideNavBody).click(function(e){
console.log(e);
});
}
The open function works and the drawer menu slides out but my attempt at closing it was as follows
$(this.$sideNavBody).click(function(e){
$(this.sideNavBodyCloseEvent());
console.log(e);
});
Which returns this error Uncaught TypeError: this.sideNavBodyCloseEvent is not a function everytime the .sidenav-body / $sideNavBody is clicked
How can I pass is this sideNavBodyCloseEvent() function on that element click?
When adding the bit of code to close the menu when click on the .sidenav body the menu closes when it encounters this code from jquery
if ( !( eventHandle = elemData.handle ) ) { eventHandle = elemData.handle = function( e ) { // Discard the second event of a jQuery.event.trigger() and // when an event is called after a page has unloaded return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply( elem, arguments ) : undefined; }; }
I have never seen or had this problem before any suggestions?
Does this work?
$(this.$sideNavBody).click(function(e){
$(this.sideNavBodyCloseEvent());
console.log(e);
}.bind(this));
The inner function has its own this object, which doesn't have the sideNavBodyCloseEvent method. To use the this object of the outer function in the inner function, use bind.
Normally, you have an initialisation function that binds the necessary event handlers:
init () {
this.$sideNavBtn.click(this.sideNavBodyOpenEvent.bind(this));
this.$sideNavBody.click(this.sideNavBodyCloseEvent.bind(this));
}
How about doing this a different way.
I think I've made a mistake somewhere in there with the elements, but passing this element as a parameter is the main change.
$body = $(el);
$sideNavBody = $('.sidenav-body');
$sideNav = $('.side-nav');
$controls = $('.side-nav button');
$sideNavBtn = $('.js-side-nav-btn');
$sideNavBody.click(function(e){
sideNavBodyCloseEvent($(this))
console.log(e);
});
sideNavBodyCloseEvent (element) {
element.$body.removeClass('side-is-open');
// always clear the 'opened state' of any open menus
element.$sideNavSection.removeClass('side-is-open');
$controls.attr('tabindex', '-1');
$sideNav.attr('aria-hidden', 'true');
$sideNavBtn.attr('aria-expanded', 'false');
$sideNavSectionToggle.removeClass('side-is-open');
// unbind the pushed body click event
$sideNavBody.off();
}

Why my plugin fires multipe callback or clicks

I am creating my simple jQuery plugin that can be use to attach for any action's confirmation. But facing very strange issue, It work fine for single element click, But when i am going to click for second element which also bind with my plugin it work fine but it's also fires for previous clicked element as well.
(function ($) {
$.fn.BootConfirm = function (options) {
// Establish our default settings
var settings = $.extend({
message: 'Are you sure about this ?',
complete: null
}, options);
var self = this;
var cointainer = '\
<div class="modal fade" id="confirmBoot" role="dialog" aria-labelledby="confirmDeleteLabel" aria-hidden="true">\
<div class="modal-dialog">\
<div class="modal-content">\
<div class="modal-header">\
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>\
<h4 class="modal-title">Confirm action</h4>\
</div>\
<div class="modal-body">\
<p>Are you sure about this ?</p>\
</div>\
<div class="modal-footer">\
<button type="button" class="btn btn-default" data-dismiss="modal">Cancel</button>\
<button type="button" class="btn btn-success btn-ok" id="confirm">Ok</button>\
</div>\
</div>\
</div>\
</div>';
return this.each(function () {
var self = this;
$(this).click(function () {
if (!$('#confirmBoot').length) {
$('body').append(cointainer);
}
if (settings.message) {
$('#confirmBoot').find('.modal-body').text($(this).attr('data-confirm'));
}
$('#confirmBoot').modal({ show: true });
if ($.isFunction(settings.complete)) {
$('#confirmBoot').find('.btn-ok').click(function () {
$.when(settings.complete.call(this, self)).done(function () {
$('#confirmBoot').modal("hide"); // Alerts "123"
});
});
}
});
});
}
}(jQuery));
This is my callback function :
function kaushik(myObject) {
ManageAcriveProducts(myObject);
};
and i am calling it by following way
$('a[data-confirm]').BootConfirm({
complete: kaushik
});
For more detail check this js fidder Jsfiddle. Can anyone one share possible solution or better way to do this. Or is there any better way to achieve this ?
The problem is that you're assigning a click on your btn-ok on every click event on a bootconfirmed object. And each click is linked to the object that has been clicked, so it ends up in your callback every time you click btn-ok.
One simple fix, though I'm not sure it's the best, is to remove the click on your btn-ok after the action is complete. Like this:
$.when(settings.complete.call(this, self)).done(function () {
$('#confirmBoot').modal("hide");
$('#confirmBoot').find('.btn-ok').off('click');
});
Working fiddle: http://jsfiddle.net/ywunutyw/
EDIT:
A little improvement on previous solution, it might need some adjustments, since I didn't look into details, but it should give you some ideas. To prevent adding click events and removing them every time user clicks on a button, you can define the click on modal window outside click behavior of each active/inactive button. And on click of active/inactive you define target that will be used in modal confirmation. Like this:
Just before calling behaviors with this.each:
$(document).on('click', '#confirmBoot .btn-ok',
function (e) {
if ($.isFunction(settings.complete)) {
console.log(self)
$.when(settings.complete.call(this, click_origin)).done(function () {
$('#confirmBoot').modal("hide");
});
}
});
Then on the click event of you active/inactive:
click_origin = e.target;
See fiddle: http://jsfiddle.net/ywunutyw/1/

jQuery .click() doesn't fire but console.log shows output

I'm having a problem in my code where I click a DOM-element using JavaScript. The click does not work and I am almost sure it is no dumb programming mistake (always dangerous to say).
After deleting some DOM-elements I want my code to click an element and trigger its onclick event. However this doesn't work. According to my code the event triggers but the event doesn't happen and the click event returns the jQuery object.
HTML:
<div class="castor-tabs">
<div class="castor-tab" data-path="../SiteBuilding/alertbox.js" data-saved="saved" data-editor="5475c897f1900editor">
<span class="castor-filename">alertbox.js</span>
<span class="castor-close"><i class="fa fa-fw fa-times"></i></span>
</div>
<div class="castor-tab" data-path="../SiteBuilding/index.php" data-saved="saved" data-editor="5475c89903e70editor">
<span class="castor-filename">index.php</span>
<span class="castor-close"><i class="fa fa-fw fa-times"></i></span>
</div>
<div class="castor-tab active" data-path="../SiteBuilding/makesite.php" data-saved="saved" data-editor="5475c8997ac77editor">
<span class="castor-filename">makesite.php</span>
<span class="castor-close"><i class="fa fa-fw fa-times"></i></span>
</div>
</div>
JavaScript:
$(".castor-tabs").on("click", ".castor-close", function() {
var tab = $(this).parent();
if(tab.attr("data-saved") == "saved") {
// File is saved
if($(".castor-tab").length > 1) {
// 1 element is 'tab' the other is a second tab
if(tab.next().length > 0) {
// If element is to the right
window.newTab = tab.next();
} else if(tab.prev().length > 0) {
// If element is to the left
window.newTab = tab.prev();
}
} else {
window.newTab = false;
}
var editor = tab.attr("data-editor");
$("#" + editor).remove(); // textarea linked to CodeMirror
$("#" + editor + "editor").remove(); // Huge CodeMirror-element
tab.remove();
if(window.newTab) {
console.log("window.newTab.click()");
console.log(window.newTab.click()); // Simulate click()
}
} else {
// File isn't saved
}
});
The onclick event:
$(".castor-tabs").on("click", ".castor-tab", function() {
$(".castor-tab.active").removeClass("active");
$(this).addClass("active");
var editor = $(this).attr("data-editor");
$(".CodeMirror").hide();
$("#" + editor).show();
});
I saved the element in the window object for a reason. After the code runs and it skips the click-part I still have the DOM-element i want to click saved in the window object. This means I can run
console.log(window.newTab.click());
again. Surprisingly this does click the element and this does activate the click-event. It also returns the DOM-element instead of the jQuery-object.
The image shows in the first two lines the failed click. The third line is my manual input and the fourth line is the successful return value of the click().
I hope you can help me to solve this.
UPDATE
.trigger("click") unfortunately gives the same output..
UPDATE 2
To help you i made the website available on a subdomain. I know many of you hate it if you have to go to a different page but I hope you'll forgive me because in my opinion this cant be solved through JSFiddle.
The link is http://castor.marknijboer.nl.
After clicking some pages to open try closing them and you'll see what i mean.
try adding return false; at the end, when binding .castor-close click event
$(".castor-tabs").on("click", ".castor-close", function() {
var tab = $(this).parent();
if(tab.attr("data-saved") == "saved") {
// File is saved
if($(".castor-tab").length > 1) {
// 1 element is 'tab' the other is a second tab
if(tab.next().length > 0) {
// If element is to the right
window.newTab = tab.next();
} else if(tab.prev().length > 0) {
// If element is to the left
window.newTab = tab.prev();
}
} else {
window.newTab = false;
}
var editor = tab.attr("data-editor");
$("#" + editor).remove(); // textarea linked to CodeMirror
$("#" + editor + "editor").remove(); // Huge CodeMirror-element
tab.remove();
if(window.newTab) {
console.log("window.newTab.click()");
console.log(window.newTab.click()); // Simulate click()
}
} else {
// File isn't saved
}
return false;
});
Instead of simulating a click, why not just pull the click logic out of your click function and just call the javascript function using the arguments that you'll need to perform your business logic?
Your code is working but not able to trigger click event binded to castor-close because i tag is empty. Put some text in it and check
<span class="castor-close"><i class="fa fa-fw fa-times">Click me</i></span>
DEMO
Your click handler has the requirement that the click target should have the class castor-close but when you are calling click via JavaScript you are clicking the parent element instead (.castor-tab), and the click handler doesn't react.

Getting the collection in a jQuery plugin

Basically, what I am trying to do is create a bbcode editor with a textbox, some buttons and jQuery. Here is my form:
<div class="form-group">
<div class="btn-group btn-group-sm">
<button type="button" class="btn glyphicon bbcode" rel="bold"><b>B</b></button>
<button type="button" class="btn glyphicon bbcode" rel="italic"><i>I</i></button>
</div>
</div>
<div class="form-group">
<textarea class="bbcode" rel="editor" cols="100" rows="12"></textarea>
</div>
and my plugin is called using:
<script>
$('document').ready(function() {
$('.bbcode').bbcode();
});
</script>
and the plugin itself, I am just trying to get the basics done at the minute to update the textbox data when a button is clicked:
(function($) {
"use strict";
$.fn.bbcode = function() {
this.click(function() {
var rel = $(this).attr('rel');
if (rel == 'editor') {
return this;
} else {
alert($(this).attr('rel')); // I can see this pop up so the click event is firing
$('.bbcode[rel=editor]').val('test');
return this;
}
});
}
} (jQuery));
This seems to be the only way I can pick up the textbox, I don't really want to hardcode the class I want like that. I think what I am looking for is a way to get the collection from the function call in the script tags.
This is more than likely something stupid/obvious I have overlooked.
The value of this in the immediate function refers to the collection. However, it is shadowed by the this inside your click handler (which refers to the element being clicked) so you cannot access it.
Create a variable to store this and that'll be your collection.
(function ($) {
"use strict";
$.fn.bbcode = function () {
var $editors = this;
this.click(function () {
var rel = $(this).attr('rel');
if (rel == 'editor') {
return this;
} else {
alert($(this).attr('rel')); // I can see this pop up so the click event is firing
$editors.val('test');
return this;
}
});
}
}(jQuery));

knockout.js "with" binding and dynamic html

I want to have a modal dialog to appear with some content and buttons inside it. The dialog should be bound to some observable property or not, the dialog also must have close buttons, one inside its body, another on the top right corner. My main aim is to close this modal form with these buttons, but "Cancel" button inside dialog's body doesn't work as expected.
1) First approach:
In this example dialog is created with static dialog, on "Open dialog" button click it shows up, it gets closed if clicked on top right X link, but it doesn't close on "Close" button click, however I set my observable to null. I was pretty much sure about this approach, as it was described in this brilliant explanation.
Excerpt from my code:
HTML:
<button data-bind="click: openDialog">Open dialog</button>
<div data-bind="with: dialogOpener">
<div data-bind="dialog: { data: $data, options: { close: Close } }">
<button data-bind="click: Save">Save</button>
<button data-bind="click: Close">Cancel</button>
</div>
</div>
JS:
self.dialogOpener = ko.observable();
self.openDialog = function () {
var data = {
Save: function() {
alert('Saved');
},
Close: function() {
alert('Closed');
self.dialogOpener(null);
}
}
self.dialogOpener(data);
}
Fully working example:
http://jsfiddle.net/cQLbX/
2) Second approach shows how my dialog html is dynamically created and it has the contents and the same results as in the first example.
Excerpt from my code:
HTML:
<button data-bind="click: openDialog">Open dialog</button>
JS:
self.dialogOpener = ko.observable();
self.openDialog = function () {
var element = "";
element += '<div data-bind="with: $data">';
element += '<div data-bind="dialog: { data: $data, options: { close: Close } }">';
element += '<button data-bind="click: Save">Save</button>';
element += '<button data-bind="click: Close">Cancel</button>';
element += '</div>';
element += '</div>';
var data = {
Save: function() {
alert('Saved');
},
Close: function() {
alert('Closed');
self.dialogOpener(null);
}
}
self.dialogOpener(data);
ko.applyBindings(data, $(element)[0]);
}
Fully working example:
http://jsfiddle.net/6T3Ra/
My question is:
On both examples "Cancel" button inside body doesn't work, the dialog doesn't close, what am I doing wrong and how to solve this?
Thanks a lot!
made a bunch of changes to your fiddle, maybe not how you want to do it, but the cancel and x buttons both do the same thing now
http://jsfiddle.net/cQLbX/3/
<div data-bind="dialog: dialogOpener, dialogOptions: { autoOpen: false, close: Close, buttons: { 'Save': Save, 'Cancel': Close } }">
<div data-bind='with: dialogContent'>
<div data-bind="text: Test"></div>
</div>
</div>
i usually structure my dialogs like this, and i've had success with them.
I don't know if you use any plugins and what not, but looking at your js fiddle example no2 with the help of a great thing called debugger is that you aren't explicitly telling the element to hide. A solution to this could be the following:
//If you look at E, E would be the ViewModel and X would be the jQuery Event Click
Close: function(e, x) {
//from the event we have currentTarget which is the button that was pressed.
//parentElement would be the first element, and the next parentElement was
//the modal in your demo. When we call hide() it hides the modal from
//which the button was pressed.
$(x.currentTarget.parentElement.parentElement).hide();
//left these as is from your example
alert('Closed');
self.dialogOpener(null);
}

Categories

Resources