Making a JQuery button act as a dropdown - javascript

Take this JQuery UI Button sample as a reference:
http://jqueryui.com/demos/button/#splitbutton
Now, how would you implement that dropdown when click the small button?
My caution is mainly with the transformation .button() does to the actual button that messes the offset coordenates.
To sum it, I need opinions on how to correctly implement a dropdown on the click of a JQuery button that integrates with the current theme.
Thanks!
Alex

I finally made it and looks like the picture above.
I blogged about it here and I'm also posting all the code bellow.
Please refer to the blog post for deeper explanation.
CSS
<style type="text/css">
.ItemActionButtons{}
.ItemActionButtons .SaveExtraOptions
{
display: none; list-style-type: none; padding: 5px; margin: 0; border: 1px solid #DCDCDC; background-color: #fff; z-index: 999; position: absolute;
}
.ItemActionButtons .SaveExtraOptions li
{
padding: 5px 3px 5px 3px; margin: 0; width: 150px; border: 1px solid #fff;
}
.ItemActionButtons .SaveExtraOptions li:hover
{
cursor: pointer;
background-color: #DCDCDC;
}
.ItemActionButtons .SaveExtraOptions li a
{
text-transform: none;
}
</style>
HTML
<div class="ItemActionButtons">
<div class="buttonset" style="float: right;">
<input id="btnDelete" type="button" value="Delete" class="button" onclick="ItemActionButtons.onDeleteClick.apply(this)" />
<input id="btnCancel" type="button" value="Cancel" class="button"onclick="ItemActionButtons.onCancelClick.apply(this)" />
</div>
<div id="divSaveButton" class="buttonset" style="float: right;">
<input id="btnSave" type="button" value="Save" class="button" onclick="ItemActionButtons.onSaveClick.apply(this)" />
<input id="btnSaveExtra" type="button" class="button" value="+" onclick="ItemActionButtons.onSaveExtraClick.apply(this)" />
<ul class="SaveExtraOptions ui-corner-bottom" id="btnSaveExtraOptions">
<li onclick="$('#btnSaveExtraOptions').toggle(); ItemActionButtons.SaveAndNewClick.apply(this)">Save and New</li>
<li onclick="$('#btnSaveExtraOptions').toggle(); ItemActionButtons.SaveAndCopyClick.apply(this)">Save and Copy</li>
</ul>
</div>
</div>
JavaScript
<script type="text/javascript">
$(document).delegate('#btnSaveExtra', 'mouseleave', function () { setTimeout(function(){ if (!ItemActionButtons.isHoverMenu) { $('#btnSaveExtraOptions').hide(); }}, 100, 1) });
$(document).delegate('#btnSaveExtraOptions', 'mouseenter', function () { ItemActionButtons.isHoverMenu = true; });
$(document).delegate('#btnSaveExtraOptions', 'mouseleave', function () { $('#btnSaveExtraOptions').hide(); ItemActionButtons.isHoverMenu = false; });
var $IsHoverExtraOptionsFlag = 0;
$(document).ready(function () {
$(".button").button();
$(".buttonset").buttonset();
$('#btnSaveExtra').button({ icons: { primary: "ui-icon-plusthick" } });
$('#btnSaveExtraOptions li').addClass('ui-corner-all ui-widget');
$('#btnSaveExtraOptions li').hover(
function () { $(this).addClass('ui-state-default'); },
function () { $(this).removeClass('ui-state-default'); }
);
$('#btnSaveExtraOptions li').mousedown(function () { $(this).addClass('ui-state-active'); });
$('#btnSaveExtraOptions li').mouseup(function () { $(this).removeClass('ui-state-active'); });
});
var ItemActionButtons = {
isHoverMenu: false,
AllowDelete: function (value) { value ? $("#btnDelete").show() : $("#btnDelete").hide() },
AllowCancel: function (value) { value ? $("#btnCancel").show() : $("#btnCancel").hide(); },
AllowSave: function (value) { value ? $("#btnSave").show() : $("#btnSave").hide() },
AllowSaveExtra: function (value) { value ? $("#btnSaveExtra").show() : $("#btnSaveExtra").hide() },
onDeleteClick: function () { },
onCancelClick: function () { },
onSaveClick: function () { },
onSaveExtraClick: function () {
$('#btnSaveExtraOptions').toggle();
var btnLeft = $('#divSaveButton').offset().left;
var btnTop = $('#divSaveButton').offset().top + $('#divSaveButton').outerHeight(); // +$('#divSaveButton').css('padding');
var btnWidth = $('#divSaveButton').outerWidth();
$('#btnSaveExtraOptions').css('left', btnLeft).css('top', btnTop);
},
SaveAndNewClick: function () { },
SaveAndCopyClick: function () { }
}
</script>

A pluggin is also available to do this.
jQuery DropDown Button

IMHO, drowdowns should always appear 'over' other content, not push it down, so absolute positioning is perfect for that. Basically add a wrapper div with position: relative around the button and the dropdown menu (which will have position:absolute; display:none), and toggle the dropdown visibility on click. The absolute positioning of the dropdown shouldn't be affected by other children of the wrapper div, such as the button, so it will appear exactly where you tell it to in the CSS.

HTML:
<div id="container">
<span class="arrow">∨</span> <span class="default">Choose your option...</span>
<input type="hidden" value="" class="mehidden"/>
<ul class="selectBox">
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
</div>
CSS:
.arrow
{
background: none repeat scroll 0 0 #FFFFFF;
border: 1px solid #CCCCCC;
font-size: 0.8em;
font-weight: bold;
height: 26px;
left: 208px;
line-height: 26px;
position: absolute;
text-align: center;
vertical-align: middle;
width: 26px;
z-index: 100;
}
.selectBox
{
border: 1px solid #1F1F1F;
list-style-type: none;
margin: 0;
padding: 3px;
position: absolute;
width: 200px;
display:none;
top: 25px;
}
#container
{
position:relative
}
.toggler
{
overflow:visible;
}
.default
{
border: 1px solid #1f1f1f;
width:200px;
height:20px;
padding:3px;
position:absolute
}
.selectBox li:hover
{
background:#ddd
}
JQUERY:
$('.arrow').click(function() {
$('.selectBox').slideToggle(200).css('borderTop', 'none');
$('.selectBox li').click(function() {
$('.mehidden').val($(this).text());
$('.default').text($(this).text());
$('.selectBox').slideUp(200);
});
});

Related

When to Call JavaScript Toggle Function?

I have a drop down menu I need to make appear and disappear using pure JavaScript (no libraries/jQuery). Thus I am developing a toggle function. However despite trying several approaches, nothing seems to work. My current idea is to create a variable to hold the state of the menu (open or closed). Once the display of the menu changes from "none" to "block", the variable should change from "closed" to "open". Then an event listener would be added to the body element so when anything is clicked, the menu closes (i.e. the display property is changed back to "none").
Unfortunately the above doesn't seem work. When I put the If/else block outside of an event listener it fires when the page loads, but not when the menuToggle variable changes. If I put it or a function inside the menuPlaceholder event listener the menu won't open, probably due to the open and close code being called basically at the same time.
Clearly I am missing something, probably related to program control or function calling. Does anyone have any insights?
The code I am working with is below. Note the alert functions peppered throughout the code are for testing purposes only.
//Puts IDs for search preference selection box into variables
var menuPlaceholder = document.getElementById('searchSelection');
var menuDisplay = document.getElementById('searchOptions');
var boxLabel = document.getElementById('searchLabel');
//Puts IDs for text input box and submission into variables
var searchBoxPlaceholder = document.getElementById('searchInput');
var searchInput = document.getElementById('searchBox');
var submitButton = document.getElementById('submit');
//Adds class to each search option and puts ID of hidde field into variable
var searchPrefSubmission = document.getElementsByClassName('buttonSearch');
var hiddenInput = document.getElementById('searchChoice');
//Global variable to indicate whether searchOptions menu is opened or closed
var menuToggle = "closed";
//Closes element when one clicks outside of it.
function hideOnClickOutside(element) {
const outsideClickListener = event => {
if (!element.contains(event.target) && isVisible(element)) { // or use: event.target.closest(selector) === null
element.style.display = 'none'
removeClickListener()
}
}
const removeClickListener = () => {
document.removeEventListener('click', outsideClickListener)
}
document.addEventListener('click', outsideClickListener)
}
const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length )
//When the placeholder box is clicked, the option menu appears
menuPlaceholder.addEventListener('click', function (event){
menuDisplay.style.display = "block";
menuToggle = "open";
//Add click event to searchPref buttons
for (i = 0; i < searchPrefSubmission.length; i++) {
//Assigns value of the button to both the hidden input field and the placeholder box
searchPrefSubmission[i].addEventListener('click', function(event) {
hiddenInput.value=this.value;
boxLabel.innerHTML = this.value;
menuDisplay.style.display = "none";
menuPlaceholder.style.display = "inline-block";
});
}
});
//This code causes the text input box of the search form to appear when the background box is clicked
searchBoxPlaceholder.addEventListener('click', function(event){
searchInput.style.display = "inline";
submitButton.style.display = "inline";
//hideOnClickOutside(menuDisplay);
});
if (menuToggle == "open"){
document.body.addEventListener('click', function(event){
alert('Foo!');
})
}else{
alert('Boo!');
}
/*function toggleMenu () {
//menuDisplay.style.display = "none";
alert('Boo!');
menuToggle = "closed";
}*/
body {
font-family:Montserrat, sans-serif;
}
#searchOptionPlaceholder {
display: inline-block;
}
#searchSelection {
padding: 10px 20px;
margin-right: 10px;
background-color: #F0F3F5;
display: inline-block;
color: #000000;
width: 140px;
max-width: 200px;
max-height: 35px;
border: 2px solid black;
vertical-align: middle;
}
#searchSelection img {
float: right;
}
#searchLabel {
display: inline-block;
padding-top: 10px;
vertical-align: top;
}
#searchOptions {
display: none;
background-color: #F0F3F5;
position: absolute;
z-index: 2;
}
#searchOptions ul {
background-color: #F0F3F5;
padding: 5px;
}
#searchOptions li {
list-style-type: none;
border-bottom: 2px solid black;
}
#searchOptions li:hover {
background-color: #706868;
color: #ffffff;
}
.buttonSearch {
background-color: transparent;
border: none;
padding: 10px;
font-size: 14px;
}
.searchSubHeading {
font-size: 12px;
}
#searchInput {
display: inline-block;
background-color: #F0F3F5;
padding: 10px 100px;
position: relative;
top: 0px;
max-width: 350px;
border: 2px solid black;
vertical-align: middle;
}
#searchInput img {
position: relative;
left: 80px;
}
#searchBox {
display: none;
width: 80%;
background-color: #F0F3F5;
border: none;
font-size: 1.5em;
position: relative;
right: 50px;
vertical-align: middle;
}
#submit {
border: none;
background-image: url('https://library.domains.skidmore.edu/search/magnifyingGlass.png');
background-repeat: no-repeat;
background-size: contain;
width: 50px;
height: 30px;
position: relative;
right: -80px;
vertical-align: middle;
}
#otherLinks {
margin-top: 10px;
}
#otherLinks a{
color: #000000;
}
#otherLinks a:hover{
color: #006a52;
}
<h1>Library Search</h1>
<form method="post" action="https://library.domains.skidmore.edu/search/searchBox.php" id="librarySearch">
<div id="searchSelection"><span id="searchLabel">Catalog</span><img src="down.png" height="30px" width="30px" /></div>
<div id="searchOptions">
<ul>
<li><button type="button" name="searchPref" value="Catalog" class="buttonSearch">Catalog<br /><br /><span class="searchSubHeading">Search books and DVDs</span></button></li>
<li><button type="button" name="searchPref" value="SearchMore" class="buttonSearch">SearchMore<br /><br /><span class="searchSubHeading">Search everything</span></button></li>
<li><button type="button" name="searchPref" value="Journals" class="buttonSearch">Journals<br /><br /><span class="searchSubHeading">Search journals</span></button></li>
</ul>
</div>
<div id="searchInput">
<input type="hidden" id="searchChoice" name="searchPref" value="catalog" />
<input type="search" id="searchBox" size="60" name="searchText" placeholder="Search our holdings"/><button type="submit" id="submit"></button></div>
<div id="otherLinks">Advanced Catalog Search | WorldCat | eBooks</div>
</form>
Some issues:
Adding event listeners within an event listener is in most cases a code smell: this will add those inner listeners each time the outer event is triggered. Those listeners remain attached, and so they accumulate. So, attach all event handlers in the top-level script, i.e. on page load, and then never again.
The if ... else at the end will execute on page load, and then never again. So the value of menuToggle is guaranteed to be "closed". You need to put that if...else switch inside the handler, so that it executes every time the event triggers, at which time the menuToggle variable will possibly have a modified value.
The body element does not stretch (by default) over the whole window. If you want to detect a click anywhere on the page, you should attach the listener on the document element itself, not on document.body.
When the click on the menu placeholder is handled, you should avoid that this event "bubbles" up the DOM tree up to the document, because there you have the other handler that wants to hide the menu again. You can do this with event.stopPropagation().
The global variable is not absolutely necessary, but if you use it, then I would call it menuVisible and give it a boolean value: false at first, and possibly true later.
For actually toggling the menu, I would create a function, which takes the desired visibility (false or true) as argument, and then performs the toggle.
Do not use undeclared variables, like the for loop variable i. Define it with let.
Here is your code with those changes implemented. Of course, there is still a lot that could be improved, but I believe that goes beyond the scope of this question:
var menuPlaceholder = document.getElementById('searchSelection');
var menuDisplay = document.getElementById('searchOptions');
var boxLabel = document.getElementById('searchLabel');
var searchBoxPlaceholder = document.getElementById('searchInput');
var searchInput = document.getElementById('searchBox');
var submitButton = document.getElementById('submit');
var searchPrefSubmission = document.getElementsByClassName('buttonSearch');
var hiddenInput = document.getElementById('searchChoice');
// Changed name and type of global variable:
var menuVisible = false;
// Removed some functions ...
menuPlaceholder.addEventListener('click', function (event){
// Use new function for actually setting the visibility
toggleMenu(!menuVisible);
// Avoid that click event bubbles up to the document level
event.stopPropagation();
});
// Add these event handlers on page load, not within another handler
// Define loop variable with let
for (let i = 0; i < searchPrefSubmission.length; i++) {
//Assigns value of the button to both the hidden input field and the placeholder box
searchPrefSubmission[i].addEventListener('click', function(event) {
hiddenInput.value = this.value;
boxLabel.innerHTML = this.value;
// Use the new function for setting the visibility
toggleMenu(false);
menuPlaceholder.style.display = "inline-block";
});
}
searchBoxPlaceholder.addEventListener('click', function(event){
searchInput.style.display = "inline";
submitButton.style.display = "inline";
});
// Bind handler on document itself, and call new function
document.addEventListener('click', function(event) {
toggleMenu(false);
});
// new function to perform the toggle
function toggleMenu(show) {
menuDisplay.style.display = show ? "block" : "none";
menuVisible = show;
}
body {
font-family:Montserrat, sans-serif;
}
#searchOptionPlaceholder {
display: inline-block;
}
#searchSelection {
padding: 10px 20px;
margin-right: 10px;
background-color: #F0F3F5;
display: inline-block;
color: #000000;
width: 140px;
max-width: 200px;
max-height: 35px;
border: 2px solid black;
vertical-align: middle;
}
#searchSelection img {
float: right;
}
#searchLabel {
display: inline-block;
padding-top: 10px;
vertical-align: top;
}
#searchOptions {
display: none;
background-color: #F0F3F5;
position: absolute;
z-index: 2;
}
#searchOptions ul {
background-color: #F0F3F5;
padding: 5px;
}
#searchOptions li {
list-style-type: none;
border-bottom: 2px solid black;
}
#searchOptions li:hover {
background-color: #706868;
color: #ffffff;
}
.buttonSearch {
background-color: transparent;
border: none;
padding: 10px;
font-size: 14px;
}
.searchSubHeading {
font-size: 12px;
}
#searchInput {
display: inline-block;
background-color: #F0F3F5;
padding: 10px 100px;
position: relative;
top: 0px;
max-width: 350px;
border: 2px solid black;
vertical-align: middle;
}
#searchInput img {
position: relative;
left: 80px;
}
#searchBox {
display: none;
width: 80%;
background-color: #F0F3F5;
border: none;
font-size: 1.5em;
position: relative;
right: 50px;
vertical-align: middle;
}
#submit {
border: none;
background-image: url('https://library.domains.skidmore.edu/search/magnifyingGlass.png');
background-repeat: no-repeat;
background-size: contain;
width: 50px;
height: 30px;
position: relative;
right: -80px;
vertical-align: middle;
}
#otherLinks {
margin-top: 10px;
}
#otherLinks a{
color: #000000;
}
#otherLinks a:hover{
color: #006a52;
}
<h1>Library Search</h1>
<form method="post" action="https://library.domains.skidmore.edu/search/searchBox.php" id="librarySearch">
<div id="searchSelection">
<span id="searchLabel">Catalog</span>
<img src="down.png" height="30px" width="30px" />
</div>
<div id="searchOptions">
<ul>
<li>
<button type="button" name="searchPref" value="Catalog" class="buttonSearch">
Catalog<br /><br /><span class="searchSubHeading">Search books and DVDs</span>
</button>
</li>
<li>
<button type="button" name="searchPref" value="SearchMore" class="buttonSearch">
SearchMore<br /><br /><span class="searchSubHeading">Search everything</span>
</button>
</li>
<li>
<button type="button" name="searchPref" value="Journals" class="buttonSearch">
Journals<br /><br /><span class="searchSubHeading">Search journals</span>
</button>
</li>
</ul>
</div>
<div id="searchInput">
<input type="hidden" id="searchChoice" name="searchPref" value="catalog" />
<input type="search" id="searchBox" size="60" name="searchText" placeholder="Search our holdings"/>
<button type="submit" id="submit"></button>
</div>
<div id="otherLinks">
Advanced Catalog Search |
WorldCat |
eBooks
</div>
</form>

with javascript onclick add classname to a div

I want to achieve with javascript something like when i clink on any of thumbnail (btn-1, btn-2 and btn-3) the specific class should be add to box div dynamically.
my code: JSFiddle
document.getElementById('btn-1').onclick = function() {
document.getElementById('box').className = 'bg-1';
}
#box {
background-color: darkgray;
width: 200px;
height: 200px;
}
.thumbnail {
width: 30px;
height: 30px;
border: 1px solid;
margin: 5px;
position: relative;
float: left;
}
#btn-1 {
background-color: red;
}
#btn-2 {
background-color: green;
}
#btn-3 {
background-color: blue;
}
.bg-1 {
background-color: red;
}
.bg-2 {
background-color: blue;
}
.bg-3 {
background-color: blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="box"></div>
<div class="thumbnail" id="btn-1"></div>
<div class="thumbnail" id="btn-2"></div>
<div class="thumbnail" id="btn-3"></div>
You javascript is working, but your CSS isn't.
You need to add !important as follows to .bg-1, .bg-2 and .bg-3
.bg-1 {
background-color: red !important;
}
Otherwise the id styling is taking preference over the class styling
You can see the classname is being added if you right click on the grey div and choose inspect element in Chrome.
Instead of bothering with classes, use simply a data- attribute like: data-bg="#f00"
$('[data-bg]').css('background', function () {
$(this).on('click', () => $('#box').css('background', this.dataset.bg));
return this.dataset.bg;
});
#box {
background: darkgray;
width: 120px; height: 120px;
}
[data-bg] {
width: 30px; height: 30px;
margin: 5px;
float: left;
}
<div id="box"></div>
<div data-bg="red"></div>
<div data-bg="#00f"></div>
<div data-bg="rgb(255,0,180)"></div>
<div data-bg="linear-gradient(to right, #E100FF, #7F00FF)"></div>
<script src="//code.jquery.com/jquery-3.1.0.js"></script>
You want to use jquery .addClass() function:
$('.myButton').addClass('myNewClass');
The function would probably look something like this:
$(function () {
$('.thumbnail').click(function() {
$('#box').addClass($(this).attr('id'));
});
})
You can get all the thumbnails as an array, and then iterate through the array and dynamically add an event listener to each, which will add the desired className to box when clicked:
var thumbnails = document.getElementsByClassName('thumbnail');
Array.from(thumbnails).forEach(function(thumbnail) {
var id = thumbnail.id;
thumbnail.addEventListener('click', function() {
document.getElementById('box').className = id.replace('btn', 'bg')
});
});

Disappearing drop down menu

I am trying to create a disappearing drop down menu that disappears into the top of the page, and you can only see the word 'open'. This opens the the menu, the word open changes to the word close which when clicked makes the menu disappear again. Help would be much appricated.
<html>
<head>
<title>dropdown</title>
<link rel="stylesheet" type="text/css" href="dropdown_css.css">
<script type = "text/javascript">
function navagate(menu) {
var panel = document.getElementById(menu),maxh = "-362px", navg = document.getElementById('navag');
if (panel.style.marginTop == maxh){
panel.style.marginTop = "0px";
navag.innerHTML = "Close";
}
else {
panel.style.marginTop = maxh;
navag.innerHTML = "Open";
}
}
window.onload = function(){panel.style.marginTop = "-362px";}
</script>
<body>
<div id = "panel">
<ul>
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
<div id ="sections_button">
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
</html>
#panel {
width : 160px;
height: 130px;
background-color: gray;
margin-left: 30px;
margin-top:20px;
}
#panel li {
list-style-type: none;
}
Here, I've made a JS fiddle that may help you out: http://jsfiddle.net/942z0nhh/ I did not play around with the styling at all.
A few things I noticed:
You're making some mistakes that I think you wouldn't make if you indented properly. Take a look here, where you closed your body twice:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
</div>
</div>
</body>
</body>
Second, you have some spelling mistakes:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
vs
function navagate(menu) {
You can see there that your function would never be called because of it.
Lastly, your 'open' and 'close' a here:
<a onclick = "navigate ('panel')" id = "navag">Open</a>
Was within the div your function was overwriting. The function would change it to 'close'- but then it wouldn't be visible to the user anyway! I moved it above, which I hope makes sense.
Please let me know if you have any other questions, or if I misunderstood.
You could also do it only with CSS. It's the "css checkbox hack". I'm having it not like you want it but it is pretty close. Changing the text from open to close should be also possible.
At the moment, I don't know how to move the open/close label below the ul list.
*, html {
padding: 0px;
font-family: sans-serif;
}
/* Checkbox Hack */
input[type=checkbox] {
position: absolute;
display: none;
}
label {
display: block;
cursor: pointer;
content: "close";
}
/* Default State */
#wrapper {
display: block;
background: gray;
color: white;
text-align: center;
}
/* Toggled State */
input[type=checkbox]:checked ~ #menu {
display: block;
background: lightgray;
color: black;
top:0px;
}
.menuToggle ul{
display: none;
width: 100%;
}
#menu {
padding-top: 5px;
margin: 0px;
list-style: none;
}
<div id="wrapper">
<div class="menuToggle">
<label for="toggle-1">open</label>
<input type="checkbox" id="toggle-1"/>
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
</ul>
</div>
</div>
With jQuery you could do it like the example below.
I think it is now almost like you wanted it. Maybe some styling improvements are required.
With the css hack I couldn't manage the text change. With js you have more possibilities. You could also improve/modify the animations.
$(function() {
var $menuButton = $('#openButton');
var $menu = $('#menu');
var btnToggleAnim = function() {
$menuButton.animate({opacity: 'toggle'}, "fast");
};
var menuToggleAnim = function() {
$('#menu').animate({
height:'toggle',
//opacity: 'toggle'
}, { duration: "slow" });
};
$('#closeButton,#openButton').on('click', function() {
menuToggleAnim();
btnToggleAnim();
});
});
*, html {
padding: 0px;
font-family: sans-serif;
}
a {
text-decoration:none;
}
#openButton {
display:block;
background: gray;
color: #fff;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
#closeButton{
display: block;
background: gray;
color: #fff;
text-align: center;
border: 2px solid lightgray;
border-bottom-left-radius: 13px;
border-bottom-right-radius: 13px;
}
#wrapper {
display: block;
text-align: center;
}
#menu {
display: none;
background: lightgray;
color: black;
padding-top: 5px;
margin: 0px;
list-style: none;
}
#menu {
color: #000;
text-decoration: none;
border: 2px solid lightgray;
border-radius: 15px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="wrapper">
open
<ul id="menu">
<li>CIT</li>
<li>Blackboard</li>
<li>Mcomms</li>
<li>Tables</li>
<li>Exams</li>
<li>close</li>
</ul>
</div>

Issue with set focus on conformation box in jquery/javascript?

On click of button i need to see a custom conformation dialogue box. I am able to see it but once the dialogue box has opened then I don't want to perform any action in HTML page until user select any option in dialogue box. I mean just similar to alert box functionality, until we say "Ok" in alert box the control does not go to HTML page. I need the same , My code is as follows,
Css
<style>
#confirmBox {
z-index:9999;
display: none;
background-color: #eee;
border-radius: 5px;
border: 1px solid #aaa;
position: relative;
width: 300px;
left: 50%;
margin-left: -150px;
padding: 6px 8px 8px;
box-sizing: border-box;
text-align: center;
}
#confirmBox .button {
background-color: #ccc;
display: inline-block;
border-radius: 3px;
border: 1px solid #aaa;
padding: 2px;
text-align: center;
width: 80px;
cursor: pointer;
}
#confirmBox .button:hover {
background-color: #ddd;
}
#confirmBox .message {
text-align: left;
margin-bottom: 8px;
}
</style>
Script:
$( "#locationList" ).on( "click", "li", function( event ) {
var form = $(this).closest('form');
doConfirm("The Coordinates for Selected location are "+ coodinatesDetails, function yes() {
alert("mail");
}, function no() {
//alert("Ok"); -- Do Nothing
} , function sms()
{
alert("sms");
});
});
function doConfirm(msg, yesFn, noFn, smsFn) {
var confirmBox = $("#confirmBox");
confirmBox.find(".message").text(msg);
confirmBox.find(".yes,.no,.sms").unbind().click(function () {
confirmBox.hide();
});
confirmBox.find(".yes").click(yesFn);
confirmBox.find(".no").click(noFn);
confirmBox.find(".sms").click(smsFn);
confirmBox.show();
}
HTML:
<div id="confirmBox">
<div class="message"></div>
<span class="button yes">Mail</span>
<span class="button sms">SMS</span>
<span class="button no">Cancle</span>
</div>
You will only need an overlay to accomplish this. Try something like this: http://jsfiddle.net/7MJBR/1/
Html Changes:
<div id="confirmOverlay"></div>
<div id="confirmBox">
<div class="message"></div> <span class="button yes">Mail</span>
<span class="button sms">SMS</span>
<span class="button no">Cancle</span>
</div>
CSS Changes:
#confirmOverlay {
position:fixed;
background: rgba(0,0,0,.5);
z-index: 9998;
width:100%;
top:0px;
left:0px;
}
Javscript Change:
function doConfirm(msg, yesFn, noFn, smsFn) {
var confirmBox = $("#confirmBox");
$("#confirmOverlay").height( $(window).height() );
confirmBox.find(".message").text(msg);
confirmBox.find(".yes,.no,.sms").unbind().click(function () {
confirmBox.hide();
$("#confirmOverlay").hide();
});
confirmBox.find(".yes").click(yesFn);
confirmBox.find(".no").click(noFn);
confirmBox.find(".sms").click(smsFn);
confirmBox.show();
}
The Overlay having a Z-index of 1 below your popup, and the fact that it covers the screen will prevent people from accessing the content below. I provided filler content in my JSFIDDLE to show this.
Once the dialog and overlay are no longer needed; $('#confirmOverlay').hide() or $('#confirmOverlay').fadeOut(200) will make it go bye bye. :)
I hope this helps! Let me know if you have questions.

jquery on handler not working for inserted element

I've got a simple to-do list app. To-do items are inserted by jQuery as <li> items. When they're checked off, they're removed from #todolist and prepended to #donelist. I want to let the user replace to-do items they've accidentally checked off, hence the .on handler for #donelist .checkbox elements, but it's not working. I've been puzzling over this for an embarrassingly long amount of time. How can I get the click handler working for #donelist .checkboxes?
HTML:
<div id="topform">
<input type="text" id="task" placeholder=" New task...">
</div>
<ul id="todolist">
</ul>
<ul id="donelist">
</ul>
JS:
$('#todolist').on('click', '.checkbox', checkTask);
$('#donelist').on('click', '.checkbox', replaceTask);
$('input').keypress(function (e) {
if (e.which == 13) {
addTask(e);
}
});
function addTask(e) {
taskToAdd = $('#task').val();
var listItem = "<li><span class='todotask'>" + taskToAdd + "</span><div class='checkbox'></div></li>";
$('#todolist').prepend(listItem);
}
function checkTask() {
var listItem = $(this).parent();
listItem.remove();
$('#donelist').prepend(listItem);
}
function replaceTask() {
alert('hey buddy');
}
Full CSS:
html,
body {
margin: 0;
padding: 0;
background-color: #313131;
font-family: 'Helvetica', sans-serif;
}
#task {
width: 98%;
margin: 5px auto 7px auto;
padding: 0;
display: block;
height: 45px;
border: none;
border-radius: 2px;
font-size: 25px;
background-color: #F7F7F7;
}
ul {
margin: 0 auto 0 auto;
padding: 0;
width: 98%;
}
li {
list-style-type: none;
padding: 0;
margin: 5px auto 0 auto;
width: 100%;
height: 45px;
line-height: 45px;
position: relative;
font-size: 25px;
border-radius: 2px;
background-color: #F7F7F7;
}
#donelist li {
opacity: .5;
text-decoration: line-through;
}
.todotask {
margin-left: 7px;
}
.checkbox {
height: 31px;
width: 31px;
border-radius: 2px;
background-color: #C1C1C1;
position: absolute;
right: 7px;
top: 7px;
}
checkTask() works just fine, which is what really confuses me. checkTask() is called when the user clicks on a dynamically inserted element (a div in a li that's inserted by addTask(). Why doesn't replaceTask() fire as well?
Having the corresponding HTML in the OP would have helped, so I've had to guess a bit about how the structure, but here's a working example of what I think you're looking for:
HTML
<h1>ADD</h1>
<input id="task"></input>
<button id="add">Add</button>
<h1>TODO</h1>
<ul id="todolist">
<li><span class='todotask'>" Take out the garbage "</span><div class='checkbox'></div></li>
<li><span class='todotask'>" Do the dishes "</span><div class='checkbox'></div></li>
</ul>
<h1>DONE</h1>
<ul id="donelist">
</ul>
CSS
.checkbox{
width: 15px;
height: 15px;
background-color: black;
display: inline-block;
cursor: pointer;
}
JavaScript inside document.ready()
$('#todolist').on('click', '.checkbox', checkTask);
$('#donelist').on('click', '.checkbox', replaceTask);
$("#add").click(addTask);
function addTask(e) {
taskToAdd = $('#task').val();
var listItem = "<li><span class='todotask'>" + taskToAdd + "</span><div class='checkbox'></div></li>";
$('#todolist').prepend(listItem);
}
function checkTask() {
var listItem = $(this).parent();
listItem.remove();
$('#donelist').prepend(listItem);
}
function replaceTask() {
var listItem = $(this).parent();
listItem.remove();
$('#todolist').prepend(listItem)
}

Categories

Resources