How to destroy bootstrap colorpicker? - javascript

I am using bootstrap colorpicker in my logic as given below : -
for (var i = 0; i < abc.length; i++) {
if (selectedValue == abc[i].name) {
var color = getColor(selectedValue);
$('.colorPicker').colorpicker('setValue', color).on(
'changeColor', function(ev) {
var colorCode = ev.color.toHex();
changeColor(colorCode);
}).on('hidePicker', function(ev) {
alert("Hiding colorpicker");
});
}
}
The above code gets called from a method everytime a user select some value in dropdown.
Problem :
Now when I open the colorpicker and close it by defocusing it. I get the alert "Hiding colorpicker" once in first go.
If I select another value from dropdown that fires the above given code again and then I open and close the color picker again. The I get the alert twice and so on in increasing numbers.
My Understanding:
My understanding is that I am initializing color picker with different values everytime the above code is fired ,So code is creating different instances of colorpicker on same ".colorPicker" class element. So I need to remove the previously created instance of colorPicker before initializing a new one.
What I tried:
I used the below given line as the first line in my method to destroy this first. But it's not working.
$('.colorPicker').colorpicker('destroy');
Any help that how can I destroy the colorpicker everytime and then use the new instance on every method call so that I can avoid multiple alerts of "Hiding colorpicker".

Related

How to extend Leaflet Icon Class to add data-open attribute to marker HTML?

I'm trying to trigger some functionality based on the click of a marker on a GeoJSON layer in Leaflet. The eventual functionality I'm trying to implement is a flyout, or scroll out type modal populated from the individual feature's JSON attributes. Essentially, I'm trying to implement the functionality in this Tutsplus Tutorial with dynamic feature content based on the marker click.
I THINK I've figured out most of the pieces I need, but I'm struggling with how to add a data attribute, specifically data-open, to the individual marker. Building on an earlier question of mine I've realized it's not enough to just update a DOM element's CSS, but rather my app should be implementing changes based on data attributes to fully get the functionality I want.
From this question I know that this should be done by extending the L.Icon class that Leaflet provides, but the answer is a bit too terse for my current JS skills. I apologize for this effectively being a "ELI5" of a previously asked question, but I'm not sure where the options and slug come into function. I think they're implied by the question, rather than the answer I'm citing and being set on the marker itself.
Here's a simplified version of the the click handler on my markers, which grabs and zooms to location, gets feature info, and populates that info to a div. The zoom functionality works, as does extracting and placing the feature info, but I'm struggling with how to connect the functionality to trigger the modal and place the div with the feature info over the map.
function zoomToFeature(e) {
var latLngs = [e.target.getLatLng()];
var markerBounds = L.latLngBounds(latLngs);
var street = e.target.feature.properties.str_addr;
document.getElementById('street').textContent = street;
mymap.fitBounds(markerBounds);
//where the modal trigger should be
document.getElementById('infoBox').classList.add('is-visible');
}
Here are the event listeners taken from the linked tutorial, which are currently not firing, but I have them working in a standalone implementation:
const openEls = document.querySelectorAll("[data-open]");
const closeEls = document.querySelectorAll("[data-close]");
const isVisible = "is-visible";
//this is the event I want to trigger on marker click
for (const el of openEls) {
el.addEventListener("click", function() {
const modalId = this.dataset.open;
console.log(this);
document.getElementById(modalId).classList.add(isVisible);
});
}
for (const el of closeEls) {
el.addEventListener("click", function() {
this.parentElement.parentElement.parentElement.classList.remove(isVisible);
});
}
document.addEventListener("click", e => {
if (e.target == document.querySelector(".modal.is-visible")) {
document.querySelector(".modal.is-visible").classList.remove(isVisible);
}
});
So, where I'm trying to get is that when my markers are clicked, the trigger the modal to appear over the map. So, I think I'm missing connecting the marker click event with the event that triggers the modal. I think what's missing is adding the data attribute to the markers, or some way chain the events without the data attributes. As there's no direct way to add an attribute to the markers, I try to add slug option on my circle markers:
var circleMarkerOptions = {
radius: 2,
weight: 1,
opacity: 1,
fillOpacity: 0.8,
slug: 'open',
}
and If I read the previously asked question's answer correctly, than extending the Icon Class this way should add a data-open attribute.
L.Icon.DataMarkup = L.Icon.extend({
_setIconStyles: function(img, name) {
L.Icon.prototype._setIconStyles.call(this, img, name);
if (options.slug) {
img.dataset.slug = options.slug;
}
}
});
A stripped down version of my code is here (thanks #ghybs). My full implementation pulls the markers from a PostGIS table. It's a bit hard to see in the Plunker, but this code adds my class to my modal, but doesn't trigger the functionality. It does trigger the visibility if the class is manually updated to modal.is-visible, but the current implementation which renders modal is-visbile doesn't, which I think is because the CSS is interpreted on page load(?) and not in response to the update via the dev tools, while the concatenated css class matches extactly(?). When I do trigger the modal via the dev tools, the close modal listeners don't seem to work, so I'm also missing that piece of the puzzle.
So, it's a work-around to setting the data attribute, but I realized I was shoe-horning a solution where it wasn't needed. Assuming someone ends up with the same mental block. Appropriate listeners on the modal close button and another function passed to the existing marker click listener produce the desired functionality.
const closeM = document.querySelector(".close-modal");
closeM.addEventListener("click", closeMe);
var modal = document.getElementById('infoBox');
and
function modalAction(){
modal.style.display = 'block';
}
function closeMe(){
modal.style.display = 'none';
}

ESRI customizing the home button gis javascript

Overall Question First then please read: How can I remove the SelectedBusStops and SelectedBusRoutes and Zoom to map:map when user clicks home button?
Here is what I am trying to do. I have a JavaScript Application that utilizes that ArcGIS API for JavaScript along with some Ajax and JQuery in there. I'm trying to customize the Home Button or create my own, that can do more than simply zoom to the initial extent. I tried doing this on my own by creating a button that called a function goHome(). Then within that function I did things like remove the highlighted Selected route from the list and then scrolled to the top of the route list and removed any bus arrival times that may have been populate when a user clicked on a bus stop to show times. I've got it to do everything I want so far except remove the current highlighted (Selected Route) along with the Current Bus Stops that are associated with the selected Route and then Zoom to my initial map extent.
I was trying to do something like setting the setDefinitionExpression of the feature layer I wanted to modify, but due to where this function is in my code it cannot see them. When I put this function inside of the main function it gives me the ReferenceError: goHome is not defined. So I put it outside of the main function and everything works so far but can't figure out how to get the featureLayers to go away. It will give me an error saying:
ReferenceError: selectedBusStops is not defined
selectedBusStops.setDefinitionExpression("Route is null");
When a user clicks on a route in the list it will then go in and set a definitionExpression to show only that Selected Route. Like this:
selectedBusStops.setDefinitionExpression("Route like '%" + routeSlice + "%'");
Here are my FeatureLayers: ** Here was my issues with not being able to use these in another function. I declared these with the 'var' and that made them local to the function they were in. Removed the 'var' and problem solved, I can now at least clear the features. **
var selectedBusRoute = new FeatureLayer("http://PROD_RTC_SystemMap/MapServer/4", {
mode: FeatureLayer.MODE_SELECTION,
outFields: ["*"],
infoTemplate: selectedBusRouteTemplate
});
var selectedBusStops = new FeatureLayer("http://PROD_RTC_SystemMap/MapServer/0", {
mode: FeatureLayer.MODE_ONDEMAND,
outFields: ["*"],
infoTemplate: selectedBusStopsTemplate
});
I was thinking if there was a way to manipulate the esri/dijit/HomeButton somehow to do all of this or am I on the right track? Esri/github/homebutton
Thanks for taking the time to read this and I appreciate all input (even those that say my code looks like a*#).
Here is the code I have for the function that is getting called:
function goHome() {
// Reset the Accordian Content Panes and fix naming
var newTitle = "Bus Arrival Times";
dijit.byId("pane3").set("title", newTitle);
var container = dijit.byId("container");
container.selectChild("RTCBusroutes", true);
// This will remove old values in Bus Arrival Time pane so Bus Arrival Times will clear
var results = document.getElementById("results");
var rowCount = results.rows.length;
for (var x = rowCount - 1; x > 0; x--) {
results.deleteRow(x);
}
// Removes the Highlight from the currently selected Item in the RTC Bus Routes List pane
$('.highlight').removeClass('highlight');
// Scrolls to the top of the List in the RTC Bus Routes Content Pane List
$('#RTCBusroutes').scrollTop(0);
// Remove Currently Selected Bus Routes
// Remove Currently Selectes Bus Stops
// Zoom to Map Extent
}
Here is the Button I added:
<button id="homeImg" onclick="goHome()">
<img id="myImg" src="img/home.png" />
</button>
CSS for the Home Button #homeImg
/* for the Home Button CSS */
#homeImg {
position: absolute;
top: 138px;
left: 28px;
z-index: 8;
background-color: #888888;
opacity: 0.8;
filter: alpha(opacity=80);
cursor: pointer;
}
You can clear a featureLayer by calling the .clear() method on it, then smwill clear all graphics in the layer.
If you only want to clear the selections call the .clearSelections() method.
There is more documenta ion here on other featurelayer methods:
https://developers.arcgis.com/javascript/jsapi/featurelayer-amd.html#methods

jQuery UI MultiSelect Widget-Cant able to apply in one item

I'm using this jQuery UI Multiselect Widget script: http://runnable.com/UgMdJqspu4chAAAP/how-to-create-jquery-ui-multiselect-widget in asp.net.I have one child page with master page.While i am applying this control by default its applying to all dropdownlist.I want to apply for a single Dropdownlist. Can anybody help me out?
<script type="text/javascript">
$(function () {
/*
define global variable,
and store message container element.
*/
var warning = $(".message");
$('select').multiselect(
{
/*
The name of the effect to use when the menu opens.
To control the speed as well, pass in an array
*/
show: ["slide", 1000],
/*
The name of the effect to use when the menu closes.
To control the speed as well, pass in an array
*/
hide: ["slide", 1000],
/*
Either a boolean value denoting whether or not to display the header,
or a string value.
If you pass a string,
the default "check all", "uncheck all", and "close"
links will be replaced with the specified text.
*/
header: "Choose only TEN items!",
/*
Fires when a checkbox is checked or unchecked,
we are using this option to restrict,
user to select no more than 3 option
*/
click: function (e) {
if ($(this).multiselect("widget").find("input:checked").length > 10) {
warning.addClass("error").removeClass("success").html("You can only check three checkboxes!");
return false;
}
else {
warning.addClass("success").removeClass("error").html("Check a few boxes.");
}
}
/*
.multiselectfilter()
Initialize filtering on any of your multiselects
by calling multiselectfilter() on the widget.
*/
}).multiselectfilter();
});
</script>
In $('select').multiselect() while i am passing my dropdown-list Id then this control is not working.Only its working while giving 'select'and simultaneously its applying to all dropdown-list. but i want to apply in one dropdown-list.Can anyone suggest me?
With ID it should work
$(document).ready(function(){
$("#example").multiselect();
});
Reference link below is using the same plugin, Can you check your browser console for any javascript errors ?
http://www.erichynds.com/blog/jquery-ui-multiselect-widget

How to check whether a twitter bootstrap popover is visible or not?

I have an element $('#anElement') with a potential popover attached, like
<div id="anElement" data-original-title="my title" data-trigger="manual" data-content="my content" rel="popover"></div>
I just would like to know how to check whether the popover is visible or not: how this can be accomplished with jQuery?
If this functionality is not built into the framework you are using (it's no longer twitter bootstrap, just bootstrap), then you'll have to inspect the HTML that is generated/modified to create this feature of bootstrap.
Take a look at the popupver documentation. There is a button there that you can use to see it in action. This is a great place to inspect the HTML elements that are at work behind the scene.
Crack open your chrome developers tools or firebug (of firefox) and take a look at what it happening. It looks like there is simply a <div> being inserted after the button -
<div class="popover fade right in" style="... />
All you would have to do is check for the existence of that element. Depending on how your markup is written, you could use something like this -
if ($("#popoverTrigger").next('div.popover:visible').length){
// popover is visible
}
#popoverTrigger is the element that triggered that popover to appear in the first place and as we noticed above, bootstrap simply appends the popover div after the element.
There is no method implemented explicitly in the boostrap popover plugin so you need to find a way around that. Here's a hack that will return true or false wheter the plugin is visible or not.
var isVisible = $('#anElement').data('bs.popover').tip().hasClass('in');
console.log(isVisible); // true or false
It accesses the data stored by the popover plugin which is in fact a Popover object, calls the object's tip() method which is responsible for fetching the tip element, and then checks if the element returned has the class in, which is indicative that the popover attached to that element is visible.
You should also check if there is a popover attached to make sure you can call the tip() method:
if ($('#anElement').data('bs.popover') instanceof Popover) {
// do your popover visibility check here
}
In the current version of Bootstrap, you can check whether your element has aria-describedby set. The value of the attribute is the id of the actual popover.
So for instance, if you want to change the content of the visible popover, you can do:
var popoverId = $('#myElement').attr('aria-describedby');
$('#myElement').next(popoverid, '.popover-content').html('my new content');
This checks if the given div is visible.
if ($('#div:visible').length > 0)
or
if ($('#div').is(':visible'))
Perhaps the most reliable option would be listening to shown/hidden events, as demonstrated below. This would eliminate the necessity of digging deep into the DOM that could be error prone.
var isMyPopoverVisible = false;//assuming popovers are hidden by default
$("#myPopoverElement").on('shown.bs.popover',function(){
isMyPopoverVisible = true;
});
$("#myPopoverElement").on('hidden.bs.popover',function(){
isMyPopoverVisible = false;
});
These events seem to be triggered even if you hide/show/toggle the popover programmatically, without user interaction.
P. S. tested with BS3.
Here is simple jQuery plugin to manage this. I've added few commented options to present different approaches of accessing objects and left uncommented that of my favor.
For current Bootstrap 4.0.0 you can take bundle with Popover.js: https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.bundle.min.js
// jQuery plugins
(function($)
{
// Fired immiedately
$.fn.isPopover = function (options)
{
// Is popover?
// jQuery
//var result = $(this).hasAttr("data-toggle");
// Popover API
var result = !!$(this).data('bs.popover');
if (!options) return result;
var $tip = this.popoverTip();
if (result) switch (options)
{
case 'shown' :
result = $tip.is(':visible');
break;
default:
result = false;
}
return result;
};
$.fn.popoverTip = function ()
{
// jQuery
var tipId = '#' + this.attr('aria-describedby');
return $(tipId);
// Popover API by id
//var tipId = this.data('bs.popover').tip.id;
//return $(tipId);
// Popover API by object
//var tip = this.data('bs.popover').tip; // DOM element
//return $(tip);
};
// Load indicator
$.fn.loadIndicator = function (action)
{
var indicatorClass = 'loading';
// Take parent if no container has been defined
var $container = this.closest('.loading-container') || this.parent();
switch (action)
{
case 'show' :
$container.append($('<div>').addClass(indicatorClass));
break;
case 'hide' :
$container.find('.' + indicatorClass).remove();
break;
}
};
})(jQuery);
// Usage
// Assuming 'this' points to popover object (e.g. an anchor or a button)
// Check if popover tip is visible
var isVisible = $(this).isPopover('shown');
// Hide all popovers except this
if (!isVisible) $('[data-toggle="popover"]').not(this).popover('hide');
// Show load indicator inside tip on 'shown' event while loading an iframe content
$(this).on('shown.bs.popover', function ()
{
$(this).popoverTip().find('iframe').loadIndicator('show');
});
Here a way to check the state with Vanilla JS.
document.getElementById("popover-dashboard").nextElementSibling.classList.contains('popover');
This works with BS4:
$(document).on('show.bs.tooltip','#anElement', function() {
$('#anElement').data('isvisible', true);
});
$(document).on('hidden.bs.tooltip','#anElement', function() {
$('#anElement').data('isvisible', false);
});
if ($('#anElement').data('isvisible'))
{
// popover is visible
$('#tipUTAbiertas').tooltip('hide');
$('#tipUTAbiertas').tooltip('show');
}
Bootstrap 5:
const toggler = document.getElementById(togglerId);
const popover = bootstrap.Popover.getInstance(toggler);
const isShowing = popover && popover.tip && popover.tip.classList.contains('show');
Using a popover with boostrap 4, tip() doesn't seem to be a function anymore. This is one way to check if a popover is enabled, basically if it has been clicked and is active:
if ($('#element').data('bs.popover')._activeTrigger.click == true){
...do something
}

Show and hide dynamic jQuery UI Dialogs

I know this should be simple, but it doesn't appear to be working the way I hoped it would.
I'm trying to dynamically generate jQuery UI dialogs for element "help."
I want to toggle the visibility of the dialog on close (x button in dialog), and clicking of the help icon. This way, a user should be able to bring up the dialog and get rid of it, as needed, multiple times during a page view.
// On creation of page, run the following to create dialogs for help
// (inside a function called from document.ready())
$("div.tooltip").each(function (index, Element) {
$(Element).dialog({
autoOpen: false,
title: $(Element).attr("title"),
dialogClass: 'tooltip-dialog'
});
});
$("a.help").live("click", function (event) {
var helpDiv = "div#" + $(this).closest("span.help").attr("id");
var dialogState = $(helpDiv).dialog("isOpen");
// If open, close. If closed, open.
dialogState ? $(helpDiv).dialog('close') : $(helpDiv).dialog('open');
});
Edit: Updated code to current version. Still having an issue with value of dialogState and dialog('open')/dialog('close').
I can get a true/false value from $(Element).dialog("isOpen") within the each. When I try to find the element later (using a slightly different selector), I appear to be unable to successfully call $(helpDiv).dialog("isOpen"). This returns [] instead of true/false. Any thoughts as to what I'm doing wrong? I've been at this for about a day and a half at this point...
Maybe replace the line declaring dialogState with var dialogState = ! $(helpDiv).dialog( "isOpen" );.
Explanation: $(helpDiv).dialog( "option", "hide" ) does not test if the dialog is open. It gets the type of effect that will be used when the dialog is closed. To test if the dialog is open, you should use $(helpDiv).dialog( "isOpen" ). For more details, see http://jqueryui.com/demos/dialog/#options and http://jqueryui.com/demos/dialog/#methods.
I was able to get it working using the following code:
$("div.tooltip").each(function (index, Element) {
var helpDivId = '#d' + $(Element).attr('id').substr(1);
var helpDiv = $(helpDivId).first();
$(Element).dialog({
autoOpen: true,
title: $(Element).attr("title"),
dialogClass: 'tooltip-dialog'
});
});
// Show or hide the help tooltip when the user clicks on the balloon
$("a.help").live("click", function (event) {
var helpDivId = '#d' + $(this).closest('span.help').attr('id').substr(1);
var helpDiv = $(helpDivId).first();
var dialogState = helpDiv.dialog('isOpen');
dialogState ? helpDiv.dialog('close') : helpDiv.dialog('open');
});
I changed the selectors so that they're identical, instead of just selecting the same element. I also broke out the Id, div and state into separate variables.

Categories

Resources