hide popover when clicked outside of it - javascript

here is my code for popover html:
<a data-placement="bottom" style="float:right;margin-right:20px;" id="new-quote-popover" popover><img src="img/user.png"/> <b>{{UserName}}</b>
<div id="popover-head" class="hide">USER DETAILS</div>
<div id="popover-content" class="hide">
<div class="row smallMargin">
<div class="col-sm-4">
varun
</div>
<div class="col-sm-8">
<select name="selectopt" style="width:80%">
<option value="001">001</option>
<option value="002">002</option>
</select>
</div>
</div>
</div>
</a>
and the directive for popover is
js:
app.directive('popover', function($compile){
return {
restrict : 'A',
link : function(scope, elem){
var content = $("#popover-content").html();
var compileContent =function() {
return $compile(content)(scope);
};
var title = $("#popover-head").html();
var options = {
content: compileContent,
html: true,
title: title
};
$(elem).popover(options);
}
}
});
It is working well..I am trying to hide the pop-over whenever cliked outside of it.But as it is in tag i am unable to do so.please help me in this.I tried with classname,id but not succeeded .
I checked this question it is not working for me

You need to inject $document service and to create new event listener mousedown on document root.
$document.on('mousedown', addClickOutsideListener);
function addClickOutsideListener(event) {
var target = event.target;
while(target != document.body) {
if(target == elem[0]) {
//user clicked on Popover, nothing to do
return;
}
if(!target.parentNode)
return;
target = target.parentNode;
}
hidePopover();
});
Don't forget add listener of scope destroying:
scope.$on('$destroy', function() {
$document.off('mousedown', addClickOutsideListener);
});

Related

dropdown menu OracleJet / Javascript

Im trying to implement dropdown menu in oracle JET but if I click on the menu link it doesn't work :( What am I doing wrong?
html:
<div id='menubutton-container'>
<oj-menu id="myMenu" slot="menu" style="display:none" on-oj-action="[[menuItemAction]]">
<oj-option id="ac" value="Additional Compensation" >
<span class="demo-icon-font demo-fire-icon-24" slot="startIcon"></span>
<a id="1ds" href="#2"
data-bind="click: menuItemAction">MyLink</a>
</oj-menu>
</oj-menu-button>
</div>
vieModel js:
self.selectedMenuItem = ko.observable("(None selected yet)");
self.menuItemAction = function( data, event )
{
this.selectedMenuItem(event.currentTarget.id);
return true;
};
Bootstrap.whenDocumentReady().then(
function()
{
ko.applyBindings(new EmployeesViewModel, document.getElementById('menubutton-container'));
}
);
First there is no closing tag for oj-option and starting tag for oj-menu-button.
The currentTarget.id it will refer to oj-menu.
below html and js works fine
<div id='menubutton-container'>
<oj-menu-button>
<oj-menu id="myMenu" slot="menu" style="display:none" on-oj-action="[[menuItemAction]]">
<oj-option id="ac" value="Additional Compensation" >
<span class="demo-icon-font demo-fire-icon-24" slot="startIcon">MyLink</span>
</oj-option>
</oj-menu>
</oj-menu-button>
self.selectedMenuItem = ko.observable("(None selected yet)");
self.menuItemAction = function (event)
{
console.log(event.currentTarget);
console.log(event.currentTarget.id);
console.log(event.target.value);
self.selectedMenuItem(event.target.value);
return true;
};

on check checkbox hide/show div in view

I'm trying to show MeetingDiv when IsAnonymous is checked and when IsMeeting is checked, MeetingTextBox should be shown.
Tried .click, .change and live and nothing worked. I don't know where I'm wrong.
<div class="col-md-4 sidePad" >
#Html.Label("Is Anonymous")
#Html.CheckBoxFor(p => p.IsAnonymous, new { id = "CBAnonymous"})
</div>
<div class="col-md-6" id="MeetingDiv" style="display:none">
#Html.Label("Is Meeting")
#Html.CheckBoxFor(p => p.IsMeeting, new { id = "CBMeeting"})
</div>
<div class="col-md-6" id="MeetingTextBox" style="display:none">
#Html.Label("Meeting Name")
#Html.TextBoxFor(p => p.MeetingName, new { id = "TBMeetingName"})
</div>
<script>
$(function () {
$("#CBAnonymous").click(function () {
if ($(this).prop("checked")) {
$("#MeetingDiv").show();
} else {
$("#MeetingDiv").hide();
}
});
});
</script>
Try this
$('#CBAnonymous').change(function(){
if(this.checked)
$("#MeetingDiv").show();
else
$("#MeetingDiv").hide();

jquery: read inside each div, span and input

I'm creating a project in ASP.NET MVC and jQuery. When a user click on addSentence button, I want to duplicate a div called copythis with all events and insert it in another div called myform.
in copythis I have two div: in the first there is a span called sentence where I insert the text in the input in the second the user can add more then one field with different text.
When the user clicks the button called save I want to read all copythis in myform and create a structure to send to a webapi.
I have a problem is the javascript because I can read properly each div.
$("#addSentence").on("click", function (event) {
if ($("#inputSentence").val() == "")
alert("Sentence must have a value");
else {
event.preventDefault();
var theContainer = $("#copythis");
if (theContainer != null) {
var clonedSection = $(theContainer).clone(true);
if (clonedSection != null) {
$(clonedSection).find("#sentence")
.text($("#inputSentence").val());
$(clonedSection).appendTo("#myform");
}
}
}
});
$("#save").on("click", function (event) {
$("#myform #copythis").children().each(function (index, element) {
var elm = $(this);
var sentence = elm.find('.row span#sentence').val();
if (sentence != '') {
console.log('Sentence: ' + sentence);
$("input").children().each(function (m, l) {
var txt = $(this).val();
if (txt != '') {
console.log('Example: ' + txt);
}
});
}
});
});
function makeRepeater(sectionsSelector, addClass, removeClass, AYSMsg) {
$(sectionsSelector + " " + addClass + "," + sectionsSelector +
" " + removeClass).on("click", function (event) {
// Avoiding the link to do the default behavior.
event.preventDefault();
// Get the container to be removed/cloned
var theContainer = $(this).parents(sectionsSelector);
if ($(this).is(addClass)) {
// Cloning the container with events
var clonedSection = $(theContainer).clone(true);
// And appending it just after the current container
$(clonedSection).insertAfter(theContainer);
} else {
// If the user confirm the "Are You Sure" message
// we can remove the current container
if (confirm(AYSMsg)) {
// Making fade out, hide and remove element a sequence
// to provide a nice UX when removing element.
$(theContainer).fadeOut('normal',
function () {
$(this).hide('fast',
function () { $(this).remove(); }
);
}
);
}
}
});
}
makeRepeater(
'.my-repeated-section-form', /* The container selector */
'.addform', /* The add action selector */
'.removeform', /* The remove action selector */
'Are you sure you want to remove this section?' /* The AYS message. */
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
<div class="row">
<div class="row">
<div class="col-lg-10">
<div class="input-group">
<input id="inputSentence" type="text"
class="form-control" placeholder="Sentence...">
<span class="input-group-btn">
<button class="btn btn-secondary"
type="button" id="addSentence">Add</button>
</span>
</div>
</div>
</div>
<div class="col-lg-12">
<div style="display: inline;">
<div class="group-of-repeated-sections" style="display: none;">
<div class="my-repeated-section">
<div id="copythis">
<div class="row">
<div class="col-lg-10">
<span id="sentence"></span>
</div>
<div class="col-lg-2">
<span>
+
-
</span>
</div>
</div>
<div class="my-repeated-section-form">
<div class="row">
<div class="col-lg-12">
<input type="text" />
<span>
+
-
</span>
</div>
</div>
</div>
<div style="height:25px;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id="myform"></div>
<button id="save">Save</button>

Collapsable panel with bootstrap and knockout

I can't make an accordion with KnockoutJS, and Bootstrap to work properly. I have defined it like so:
<div class="panel-group" id="accordion" data-bind="foreach: Advertisers()">
<div class="panel panel-default">
<div class="panel-heading">
<h4 class="panel-title">
<span data-toggle="collapse" data-bind="html: $data, attr: { 'data-target': '#' + $data }"></span>
</h4>
</div>
</div>
<div class="panel-collapse collapse" data-parent="#accordion" data-bind="attr: { id: $data }">
<div class="panel-body">
...content...
"Advertisers" is an observable array of strings, and hence $data is a string. I get one "row" for each advertiser.
All rows are initially collapsed, and clicking a row expands the content below. So far so good.
The problem is that when I click another row I would expect the previous expanded to collapse, but that's not happening. (I couldn't make a fiddle to work either, with Bootstrap and KnockoutJS...)
Edited the code.
What about a simple custom binding, which also allows you to unclutter your view a bit:
ko.bindingHandlers.bootstrapAccordion = {
init: function(elem, value, allBindings) {
var options = ko.utils.unwrapObservable(value()),
handleClass = '[data-toggle]',
contentClass = '.collapse',
openItem = ko.utils.unwrapObservable(options.openItem) || false,
itemClass = '.' + ko.utils.unwrapObservable(options.item) || '.accordion-group',
items = $(elem).find(contentClass);
// toggle: false required to hide items on load
items.collapse({ parent: elem, toggle: false });
if (openItem > -1) items.eq(openItem).collapse('show');
// if the array is dynamic, the collapse should be re-initiated to work properly
var list = allBindings.get('foreach');
if (ko.isObservable(list)) {
list.subscribe(function() {
$(elem).find(contentClass).collapse({ parent: elem, toggle: false });
});
}
$(elem).on('click', handleClass, function() {
$(elem).find(contentClass).collapse('hide');
$(this).closest(itemClass).find(contentClass).collapse('show');
});
}
};
This binding takes 2 parameters (className for container, and optionally, an item to open on load), eg: bootstrapAccordion: {item: 'panel-group', openItem: 0}, and should be set on the same element which has a foreach binding. It assumes that collapsible sections have a collapse class, and the handles to toggle them have a data-toggle attribute.
See it in action here:
http://jsfiddle.net/pkvn79h8/22/
I extended Tyblitz's example above to include support for changing an icon (eg, +/-, up/down arrow) and support for moving to the next panel by applying data-open-next attribute to whatever should move to next panel on click.
ko.bindingHandlers.bootstrapAccordion = {
init: function (elem, value, allBindings) {
var options = ko.utils.unwrapObservable(value()),
handleClass = '[data-toggle]',
contentClass = '.collapse',
openedClass = ko.utils.unwrapObservable(options.openedClass) || 'fa-minus',
closedClass = ko.utils.unwrapObservable(options.closedClass) || 'fa-plus',
openCloseToggleClasses = openedClass + ' ' + closedClass,
openItem = ko.utils.unwrapObservable(options.openItem) || false,
itemClass = '.' + (ko.utils.unwrapObservable(options.item) || 'accordion-group'),
items = $(elem).find(contentClass);
var initializeItems = function(items) {
// toggle: false required to hide items on load
items.collapse({ parent: elem, toggle: false });
if (openItem > -1) {
items.eq(openItem).collapse('show');
items.eq(openItem).closest(itemClass).find('.panel-heading').find('i').toggleClass(openCloseToggleClasses);
items.eq(openItem).closest(itemClass).find('.panel-heading').addClass('active');
}
}
initializeItems(items);
// if the array is dynamic, the collapse should be re-initiated to work properly
var list = allBindings.get('foreach');
if (ko.isObservable(list)) {
list.subscribe(function () {
initializeItems($(elem).find(contentClass));
});
}
$(elem).on('click', handleClass, function () {
$(elem).find(contentClass).collapse('hide');
$(this).closest(itemClass).find(contentClass).collapse('show');
$(this).closest(itemClass).parent().find('.panel-heading i').removeClass(openCloseToggleClasses);
$(this).closest(itemClass).parent().find('.panel-heading i').addClass(closedClass);
$(this).closest(itemClass).parent().find('.panel-heading').removeClass('active');
if ($(this).closest(itemClass).find('.panel-collapse').attr('aria-expanded') === "true") {
$(this).closest(itemClass).find('.panel-heading i').toggleClass(openCloseToggleClasses);
$(this).closest(itemClass).find('.panel-heading').addClass('active');
}
});
$(elem).on('click', '[data-open-next]', function () {
$next = $(this).closest(itemClass).next(itemClass).find(handleClass);
if ($next.length) {
$next.click();
} else {
$same = $(this).closest(itemClass).find(contentClass);
$same.collapse('hide');
$same.parent().find('.panel-heading i').removeClass(openCloseToggleClasses);
$same.parent().find('.panel-heading i').addClass(closedClass);
$same.parent().find('.panel-heading').removeClass('active');
}
});
}
};
Sample markup to use with this binding:
<div data-bind="foreach: listOfThings, bootstrapAccordion: { openItem: 0 }">
<div class="accordion-group">
<div class="panel panel-default" style="cursor: pointer;" data-toggle>
<div class="panel-heading">
<i class="fa fa-plus fa-pull-left fa-2x"></i>
<h3 data-bind="text: name">Title of expander</h3>
</div>
</div>
<div class="panel-collapse collapse">
<div class="panel-body">
<div class="clearfix" data-accordion-content>
<!-- content goes here -->
<!-- ko if: $index() < $parent.listOfThings().length -1 -->
<button data-open-next>Next Thing</button>
<!-- /ko -->
</div>
</div>
</div>
</div>
</div>
I would feel bad not contributing back :)

Need help with jQuery click function

Hey guys, I have a simple question (hope is simple). I have created sort of an accordion but I need to something like if button is clicked, slide down the content and else if button is clicked again slide up the content, please find below what I have done so far. Thanks for your help in advance.
$('#experiences').click(function () {
var cb = function () {
$('#experiences').addClass('active');
$('#hiddenExperiences').slideDown();
$('#addExperiences').fadeIn();
return false;
}
closeFilters(cb);
return false;
});
$('.btn-close').click(function () {
var cb = function () {
return false;
};
closeFilters(cb);
return false;
});
function closeFilters(callbackFunc) {
$(".active").removeClass("active");
$(".add-filters").fadeOut(250);
$(".hidden-filters").slideUp("slow", callbackFunc);
}
<div class="heading" id="experiences">
<p>Experiences</p>
</div><!--heading-->
<div class="filter">
<div class="hidden-filters" id="hiddenExperiences">
<p>Filtering by:</p>
<ul class="curr-filter"></ul>
</div><!-- hidden-filters -->
<div class="add-filters extra-width" id="addExperiences">
<div class="inner">
<h4 class="title-filtery">Filtery By:</h4>
<div class="btn-holder clearfix">
<input type="button" class="btn-update" value="" />
</div>
</div>
</div><!-- filters -->
</div><!-- filter -->
See this method
http://api.jquery.com/slideToggle/
and this event
http://api.jquery.com/toggle-event/
You can perform this in Javascript onClick of the button something like this:
function toggle_visibility(id) {
var e = document.getElementById(id);
if(e.style.display == "inline") {
e.style.display = 'none';
}
else if(e.style.display == "none") {
e.style.display = "inline";
}
}
Looks like you're adding the .active class to all elements with id=experiences
$('#experiences').addClass('active');
You need to find the element that got clicked and pass that through.
var tgt;
$('#experiences').click(function (event) {
tgt = $(event.target);
var cb = function () {
$(tgt).addClass('active');
$('#hiddenExperiences').slideDown();
$('#addExperiences').fadeIn();
return false;
}
closeFilters(cb);
return false;
});
I'm not sure how your expand works, but that's where you're going to need to look.
I used this is another project I was doing, it may be of some assistance
JS:
$('.container .ui-widget-header').click(function(){$(this).parent().children('.ui-widget-content').slideToggle()});
HTML:
<div class="container">
<div class="ui-widget-header">Title</div>
<div class="ui-widget-content">Content</div>
</div>
<div class="container">
<div class="ui-widget-header">Title2</div>
<div class="ui-widget-content">Content2</div>
</div>

Categories