I have some familiarity with the ... operatorspread syntax
and recently I saw a developer use the spread syntax (as attached in snippet as ) [...document.querySelectorAll('#wrapper button')].map((button)=> button.addEventListener('click',Add));
the above ... spread syntax with the map function looks tough for me to understand, can someone help me understand it in simple terms conceptually..thanks for your time
document.addEventListener('DOMContentLoaded', () => {
var temp = [];
var arrayOfStrings = [];
console.log(document.querySelectorAll('#wrapper button')) //choose button only in the wrapper div and not the others like CLR
//listen to only button events(other than the CLR)
document.querySelectorAll('#wrapper button').forEach(button => button.addEventListener('click', Calculat));
//listen to CLR button events
document.getElementById('clear1').addEventListener('click', () => {
temp = [];
arrayOfStrings = [];
document.querySelector('.my_flex').textContent = ('');
});
function Calculat(e) {
z = e.target.innerText;
// console.log(z);
document.querySelector('.my_flex').append(z); //append to the flex object
if (z == '=') {
document.querySelector('.my_flex').append(eval(arrayOfStrings));
return false;
}
temp.push(z);
arrayOfStrings = temp.join("");
}
});
div {
width: 7cm;
}
button {
border: 0;
line-height: 3.5;
padding: 0 20px;
font-size: 1rem;
text-align: center;
/*align the text f the button to the center*/
color: #fff;
text-shadow: 1px 1px 1px #000;
border-radius: 10px;
background-color: rgba(220, 0, 0, 1);
background-image: linear-gradient(to top left, rgba(0, 0, 0, .2), rgba(0, 0, 0, .2) 30%, rgba(0, 0, 0, 0));
box-shadow: inset 2px 2px 3px rgba(255, 255, 255, .6), inset -2px -2px 3px rgba(0, 0, 0, .6);
}
button:hover {
background-color: green;
}
button {
border: 0;
line-height: 3.5;
padding: 0 20px;
font-size: 1rem;
text-align: center;
color: #fff;
text-shadow: 1px 1px 1px #000;
border-radius: 10px;
background-color: rgba(220, 0, 0, 1);
background-image: linear-gradient(to top left, rgba(0, 0, 0, .2), rgba(0, 0, 0, .2) 30%, rgba(0, 0, 0, 0));
box-shadow: inset 2px 2px 3px rgba(255, 255, 255, .6), inset -2px -2px 3px rgba(0, 0, 0, .6);
}
button:hover {
background-color: green;
}
.my_flex {
display: flex;
background-color: tomato;
margin: 8px;
padding: 20px;
font-size: 30px;
}
<a>Calculations(Simple Mathematics only, example: 1+7,2*8 etc):--</a>
<div id="wrapper">
<button>1</button>
<button>2</button>
<button>3</button>
<button>4</button>
<br>
<button>5</button>
<button>6</button>
<button>7</button>
<button>8</button>
<button>9</button>
<button>+</button>
<button>-</button>
<button>*</button>
<button>0</button>
<button>(</button>
<button>)</button>
<button>/</button>
<button>=</button>
<button>.</button>
</div>
<div><button id="clear1">CLEAR</button></div>
<div class="my_flex">
<!--just to get nice output on flex canvas -->
</div>
It's not just pointless to use the array spread syntax here, it's also pointless (and indeed confusing) to use map. This should rather use the forEach method:
document.querySelectorAll('#wrapper button').forEach(button => {
button.addEventListener('click', calculate);
});
or even better just a simple for loop:
for (const button of document.querySelectorAll('#wrapper button')) {
button.addEventListener('click', calculate);
}
It's because that the result returned by querySelector is not an instance of Array.In other words the result has no map method and destructuring it inside of array will let you to use Array.prototype.map method on newly created array.
Related
I'm trying to create an hover event in an element with a nested a icon.
The problem is when the cursor touch the <i class="material-icons fav icons lov-icon lov-icon-color"> favorite</i> element because that tigger the event mouseout
How to keep the same event in a nested element ?
$(".fav-btn").mouseout((event) => {
let favButton = $(event.currentTarget);
let favIcon = $(event.currentTarget.children[0]);
console.log(favButton);
if (favButton.hasClass('fav-btn-selected') && favIcon.hasClass('lov-icon-color-selected')) {
favButton.removeClass('fav-btn-selected');
favIcon.removeClass('lov-icon-color-selected');
favButton.addClass('fav-btn');
favIcon.addClass('lov-icon-color');
}
});
$(".fav-btn").mouseenter((event) => {
let favButton = $(event.currentTarget);
let favIcon = $(event.currentTarget.children[0]);
console.log(favIcon);
if (favButton.hasClass('fav-btn') && favIcon.hasClass('lov-icon-color')) {
favButton.removeClass('fav-btn');
favIcon.removeClass('lov-icon-color');
favButton.addClass('fav-btn-selected');
favIcon.addClass('lov-icon-color-selected');
}
});
https://jsfiddle.net/4mLnckaw/3/
Since you're using jQuery, you can also use hover and toggleClass to do so.
Here's a demo:
$(".fav-btn").hover((event => {
let favButton = $(event.currentTarget);
let favIcon = $(event.currentTarget.children[0]);
favButton.toggleClass('fav-btn fav-btn-selected');
favIcon.toggleClass('lov-icon-color lov-icon-color-selected');
}));
.circle {
display: inline-block;
text-align: center;
width: 70px;
height: 70px;
-moz-border-radius: 50% !important;
-webkit-border-radius: 50% !important;
border-radius: 50%;
-webkit-box-shadow: -2px 3px 10px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: -2px 3px 10px 0px rgba(0, 0, 0, 0.75);
box-shadow: -2px 3px 10px 0px rgba(0, 0, 0, 0.75);
}
.circle>.icons {
position: relative;
top: calc(50% - 10px);
/* 50% - 3/4 of icon height */
}
.fav-btn {
background-color: #FFFFFF;
}
.msg-btn {
background-color: #FFFFFF;
}
.lov-icon {
font-size: 25px;
}
.msg-icon {
font-size: 25px;
}
.lov-icon-color {
color: red;
}
.msg-icon-color {
color: green;
}
.fav-btn-selected {
background-color: #b61825;
}
.msg-btn-selected {
background-color: green;
}
.lov-icon-color-selected {
color: #FFFFFF;
}
.msg-icon-color-selected {
color: #FFFFFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<a href="">
<div class="circle fav fav-btn m-2">
<i class="material-icons fav icons lov-icon lov-icon-color">favorite</i>
</div>
</a>
Use mouseenter and mouseleave events instead.
mouseleave and mouseout are similar but differ in that mouseleave does
not bubble and mouseout does. This means that mouseleave is fired when
the pointer has exited the element and all of its descendants, whereas
mouseout is fired when the pointer leaves the element or leaves one of
the element's descendants (even if the pointer is still within the
element).
const applyMouseEnterStlye = (button, icon) => {
button.removeClass('fav-btn');
button.addClass('fav-btn-selected');
icon.removeClass('lov-icon-color');
icon.addClass('lov-icon-color-selected');
};
const applyMouseLeaveStlye = (button, icon) => {
button.removeClass('fav-btn-selected');
button.addClass('fav-btn');
icon.removeClass('lov-icon-color-selected');
icon.addClass('lov-icon-color');
};
const toggleStyles = event => {
const button = $(event.target);
const icon = $(button.find('i'));
switch (event.type) {
case 'mouseenter':
applyMouseEnterStlye(button, icon);
break;
case 'mouseleave':
applyMouseLeaveStlye(button, icon);
break;
}
}
const circleEl = document.querySelector('.circle');
circleEl.addEventListener('mouseenter', toggleStyles);
circleEl.addEventListener('mouseleave', toggleStyles);
.circle {
display: inline-block;
text-align: center;
width: 70px;
height: 70px;
-moz-border-radius: 50% !important;
-webkit-border-radius: 50% !important;
border-radius: 50%;
-webkit-box-shadow: -2px 3px 10px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: -2px 3px 10px 0px rgba(0, 0, 0, 0.75);
box-shadow: -2px 3px 10px 0px rgba(0, 0, 0, 0.75);
}
.circle>.icons {
position: relative;
top: calc(50% - 10px);
/* 50% - 3/4 of icon height */
}
.fav-btn {
background-color: #FFFFFF;
}
.msg-btn {
background-color: #FFFFFF;
}
.lov-icon {
font-size: 25px;
}
.msg-icon {
font-size: 25px;
}
.lov-icon-color {
color: red;
}
.msg-icon-color {
color: green;
}
.fav-btn-selected {
background-color: #b61825;
}
.msg-btn-selected {
background-color: green;
}
.lov-icon-color-selected {
color: #FFFFFF;
}
.msg-icon-color-selected {
color: #FFFFFF;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<a href="">
<div class="circle fav fav-btn m-2">
<i class="material-icons fav icons lov-icon lov-icon-color">favorite</i>
</div>
</a>
I am making the transition over from Desktop .NET development to Web Development and I have just run into something that I don't understand. I was under the impression that when defining global variables if you opened a new webpage in the sane session the variable would still be accessible in memory to prevent the need to reload it. Can someone please clarify this matter?
I am loading a JSON database into memory as an array of objects var PlayerDatabase. I created an intelligent search bar to select a player and open a page with information about them. When opening the new page the PlayerDatabase is undefined.
Initial Search Bar page:
/*
window.fn = {};
var playerDatabase = [];
var count = 0;
window.fn.open = function() {
var menu = document.getElementById('menu');
menu.open();
};
window.fn.load = function(page) {
var menu = document.getElementById('menu');
var navi = document.getElementById('navi');
menu.close();
navi.resetToPage(page, { animation: 'fade' });
};
// Data Load Event
function showModal() {
var modal = document.querySelector('ons-modal');
modal.show();
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
playerDatabase = JSON.parse(this.responseText);
count = $(playerDatabase).toArray().length;
modal.hide();
console.log(count);
}
};
var requestURL = 'dataURL';
xmlhttp.open("GET", requestURL, true);
xmlhttp.send();
}
*/
// Search Bar Filter Logic
function searchPlayers() {
var input, filter, ul, li, a, i;
input = document.getElementById("searchBarInput");
filter = input.value.toUpperCase();
div = document.getElementById("dropdownItems");
li = div.getElementsByTagName("li");
// remove all current items
for (i = li.length - 1; i > -1; i--) {
div.removeChild(li[i]);
}
// check for min length
if (filter.length < 3) {
$('#dropdownItems').append("<li><a>Please input at least 3 characters.</a></li>");
} else {
// Here I add filtered items to the drop dwon
$('#dropdownItems').append("<li><a href='playerPage.html?playerID=" + "playerID" + "'>" + "Player Name" + " - " + "Player Position" + "</a></li>");
}
}
// Search Bar focus lost
$(document).on("focusout", "#searchBarInput input", function() {
var div = document.getElementById("dropdownItems");
var li = div.getElementsByTagName("li");
// remove all current items
for (i = li.length - 1; i > -1; i--) {
div.removeChild(li[i]);
}
});
/* * Copyright (c) 2012 Thibaut Courouble
* Licensed under the MIT License
================================================== */
a {
color: #1e7ad3;
text-decoration: none;
font-size: 12px;
}
a:hover {
text-decoration: underline
}
input {
font-size: 13px;
color: #555860;
}
.search {
position: relative;
margin: 0 auto;
}
.search input {
height: 26px;
width: 100%;
padding: 0 12px 0 25px;
background: white url("https://cssdeck.com/uploads/media/items/5/5JuDgOa.png") 8px 6px no-repeat;
border-width: 1px;
border-style: solid;
border-color: #a8acbc #babdcc #c0c3d2;
border-radius: 13px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-box-shadow: inset 0 1px #e5e7ed, 0 1px 0 #fcfcfc;
-moz-box-shadow: inset 0 1px #e5e7ed, 0 1px 0 #fcfcfc;
-ms-box-shadow: inset 0 1px #e5e7ed, 0 1px 0 #fcfcfc;
-o-box-shadow: inset 0 1px #e5e7ed, 0 1px 0 #fcfcfc;
box-shadow: inset 0 1px #e5e7ed, 0 1px 0 #fcfcfc;
}
.search input:focus {
outline: none;
border-color: #66b1ee;
-webkit-box-shadow: 0 0 2px rgba(85, 168, 236, 0.9);
-moz-box-shadow: 0 0 2px rgba(85, 168, 236, 0.9);
-ms-box-shadow: 0 0 2px rgba(85, 168, 236, 0.9);
-o-box-shadow: 0 0 2px rgba(85, 168, 236, 0.9);
box-shadow: 0 0 2px rgba(85, 168, 236, 0.9);
}
.search input:focus+.results,
.search .results:hover {
display: block
}
.search .results {
display: none;
position: absolute;
top: 35px;
left: 0;
right: 0;
z-index: 10;
padding: 0;
margin: 0;
border-width: 1px;
border-style: solid;
border-color: #cbcfe2 #c8cee7 #c4c7d7;
border-radius: 3px;
background-color: #fdfdfd;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fdfdfd), color-stop(100%, #eceef4));
background-image: -webkit-linear-gradient(top, #fdfdfd, #eceef4);
background-image: -moz-linear-gradient(top, #fdfdfd, #eceef4);
background-image: -ms-linear-gradient(top, #fdfdfd, #eceef4);
background-image: -o-linear-gradient(top, #fdfdfd, #eceef4);
background-image: linear-gradient(top, #fdfdfd, #eceef4);
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-ms-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-o-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
}
.search .results li {
display: block;
}
.search .results li:first-child {
margin-top: -1px
}
.search .results li:first-child:before,
.search .results li:first-child:after {
display: block;
content: '';
width: 0;
height: 0;
position: absolute;
left: 50%;
margin-left: -5px;
border: 5px outset transparent;
}
.search .results li:first-child:before {
border-bottom: 5px solid #c4c7d7;
top: -11px;
}
.search .results li:first-child:after {
border-bottom: 5px solid #fdfdfd;
top: -10px;
}
.search .results li:first-child:hover:before,
.search .results li:first-child:hover:after {
display: none
}
.search .results li:last-child {
margin-bottom: -1px
}
.search .results a {
display: block;
position: relative;
margin: 0 -1px;
padding: 6px 40px 6px 10px;
color: #808394;
text-color: #808394;
font-weight: 500;
text-shadow: 0 1px #fff;
border: 1px solid transparent;
border-radius: 3px;
}
.search .results a span {
font-weight: 200
}
.search .results a:before {
content: '';
width: 18px;
height: 18px;
position: absolute;
top: 50%;
right: 10px;
margin-top: -9px;
background: url("https://cssdeck.com/uploads/media/items/7/7BNkBjd.png") 0 0 no-repeat;
}
.search .results a:hover {
text-decoration: none;
color: #fff;
text-shadow: 0 -1px rgba(0, 0, 0, 0.3);
border-color: #2380dd #2179d5 #1a60aa;
background-color: #338cdf;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #59aaf4), color-stop(100%, #338cdf));
background-image: -webkit-linear-gradient(top, #59aaf4, #338cdf);
background-image: -moz-linear-gradient(top, #59aaf4, #338cdf);
background-image: -ms-linear-gradient(top, #59aaf4, #338cdf);
background-image: -o-linear-gradient(top, #59aaf4, #338cdf);
background-image: linear-gradient(top, #59aaf4, #338cdf);
-webkit-box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px rgba(0, 0, 0, 0.08);
-moz-box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px rgba(0, 0, 0, 0.08);
-ms-box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px rgba(0, 0, 0, 0.08);
-o-box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px rgba(0, 0, 0, 0.08);
box-shadow: inset 0 1px rgba(255, 255, 255, 0.2), 0 1px rgba(0, 0, 0, 0.08);
}
:-moz-placeholder {
color: #a7aabc;
font-weight: 200;
}
::-webkit-input-placeholder {
color: #a7aabc;
font-weight: 200;
}
.lt-ie9 .search input {
line-height: 26px
}
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<!-- Page Content -->
<header class="w3-display-container w3-content w3-wide" style="max-width:1500px;" id="home">
<img class="w3-image w3-black" src="http://www.sportssabermetrics.net/html/images/header_image.jpg" alt="Header Image" width="100%">
<div class="w3-display-middle w3-center" style="width:60%;">
<!-- Search Bar -->
<section class="main">
<div id="myDropdown" style="margin: auto; font-size: 14px;">
<form class="search" method="post"><input type="text" id="searchBarInput" placeholder="Search for NFL Player" onkeyup="searchPlayers()" />
<ul id="dropdownItems" class="results">
</ul>
</div>
</section>
</div>
</header>
</body>
Seperate Javascript file to handle New Page
// Load full HTML page prior to making calls
$(function() {
// check to see if data has loaded
if (count > 0) {
// query URL parameters
var url_string = window.location.href;
var url = new URL(url_string);
var c = url.searchParams.get("playerID");
var player;
for (i=0; i < count; i++) {
if (playerDatabase[i].playerID = c) {
player = playerDatabase[i];
{ break; }
}
}
} else {
// Load Data
showModal();
console.log(count);
}
});
Here I'll do it since he originally beat me by a couple seconds (I upvoted) and expand. Variables do not persist in the browser from session to session. you need cookies or localStorage for that.
HOWEVER, note there are differences between the two. If you are planning to support a wide variety of browsers and users, you'll need to check that local storage is available or else your user will be toast. If you are planning on sending this data ever back to the server, then cookies is still the preferred method if you really need it to persist.
I, like you, moved from ASP .Net into the web, and something to consider is, do you really need the front end to remember and store this data? For some things that is a security issue as well. Many times it can actually be preferable to pass the data you need back and forth, and when you are done it's disposed rather than physically caching it. I would argue in full web you should be polling for data every page load from the server even if it's redundant. That way you control what the user has, the front end is dumb, and you are sure the data is not tampered with which becomes very important...
I would say, tread lightly with storage outside of session tokens etc on the front end, it can get to be a mess very quickly and is very un-webby. How are you going to insure that the data is not stale, what if modifications are made? How long are you going to have the data persist without a refresh, when you get a large number of users, if they don't wipe their cache and you let them store something for x-length of time, you're going to run into this and it's a fundamental design flaw. Even if you refresh the data every few minutes, when you get to scale that is an eternity and you will get data conflicts. Decide if you really, really, really need this stored on the (and each) user's machine.
It's now clear to me that mixins and inheritance are generally considered bad and composition is the way to go, this from:
https://medium.com/#dan_abramov/mixins-are-dead-long-live-higher-order-components-94a0d2f9e750
https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html
Now, what to do when you find two components that specialize in different things and you want a component that is the result of both behaviors mixed? For instance, I want a textarea that both grows automatically when text goes beyond initial rows, and allow mentions inside (aka. mix react-mentions with react-textarea-autosize)
How am I supposed to compose both in a way that works?
Am I supposed to code a brand new component copying/merging the inner code from both components?
What's the ReactJs way to compose in such scenarios?
I came across the same issue. With react-mention you don't have to use the react-text-autosize as you can achieve the same behavior with css which can auto grow the textarea generated. Consider following example
<MentionsInput
value={content}
placeholder="Add a comment"
onChange={this.onChange}
className="mentionWrapper">
<Mention
trigger="#"
data={users}
className="mentionedFriend"
displayTransform={(id, display) => `#${display}`}
/>
</MentionsInput>
For this i've used the following styles
.mentionWrapper {
width: 100%;
background: transparent;
font-size: 0.9rem;
color: #a9b5c4;
}
.mentionWrapper .mentionWrapper__control {
border-radius: 25px;
border: 1px solid #3a546f;
min-height: 45px;
}
.mentionWrapper .mentionWrapper__control .mentionWrapper__highlighter {
padding: 0.7rem 1rem;
}
.mentionWrapper .mentionWrapper__control .mentionWrapper__input {
padding: 0.7rem 1rem;
outline: 0;
border: 0;
resize: none;
outline: none;
font-size: 0.9rem;
color: #7288a3;
border-color: #3a546f;
overflow: hidden;
}
.mentionWrapper .mentionWrapper__control .mentionWrapper__input::placeholder {
color: #7288a3;
}
.mentionWrapper__suggestions {
background-color: rgba(0, 0, 0, 0.6) !important;
padding: 10px;
-webkit-box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
box-shadow: 0px 0px 11px 0px rgba(0, 0, 0, 0.75);
border-radius: 0.8rem;
}
.mentionWrapper__suggestions .mentionWrapper__suggestions__list {
font-size: 14px;
}
.mentionWrapper
.mentionWrapper__suggestions
.mentionWrapper__suggestions__item--focused {
color: #ffffff;
border-bottom: 1px solid #3a546f;
font-weight: 600;
}
.mentionedFriend {
color: #7288a3;
text-decoration: underline;
}
Key point here is that i've applied a min-height of 45px to "control" div which is append by react-mention package. By doing so you will get the attached result.
I'm trying to get data from import io in php format, however that doesn't work with pagination, so have had to do it in javascript (code below) however i need to put it into a database so I guess php would be the best (or at least easiest for me). My question is how can i convert a javascript array into a php array.
thanks,
MsKazza
<!DOCTYPE html>
<html>
<head>
<title>Import•io Example</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<!-- 1. Include the client library -->
<script src="https://cdn.import.io/js/2.0.0/importio.js"></script>
<!-- 2. Configure the library -->
<script type="text/javascript">
importio.init({
"auth": {
"userGuid": "4e3524b0-5ff7-4102-9710-f96246a8303c",
"apiKey": "oX9ksC/OQXxeO6dXYlNTgl8Juuh2SkCpdih2f0xH9d+3tzoBT0CsFuLr+ZlWPxVLbylL9XHQ8dLxNJvrKc2AUg=="
},
"host": "import.io"
});
// Data and done callbacks
var dataCallback = function(data) {
console.log("Data received", data);
for (var i = 0; i < data.length; i++) {
var d = data[i];
for (var k in d.data) {
document.write("<i>" + k + "</i>: " + d.data[k] + "<br />");
}
document.write("<hr>");
}
}
var doneCallback = function(data) {
console.log("Done, all data:", data);
document.write("<b>Done</b><hr>");
}
// 3. Do the query (when the function is called)
var doQuery = function() {
// Query for tile goldenwherewhen
importio.query({
"connectorGuids": [
"83c211ab-91a1-4e54-9838-dc086bc1b527"
],
"input": {
"what": "hotels",
"where": "ireland"
}
}, { "data": dataCallback, "done": doneCallback });
}
</script>
<style>body { text-align: center; } button { line-height: 20px; color: #333; text-align: center; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); vertical-align: middle; cursor: pointer; border: 1px solid #CCC; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff',endColorstr='#ffe6e6e6',GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,0.2),0 1px 2px rgba(0,0,0,0.05); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),0 1px 2px rgba(0, 0, 0, 0.05); outline: 0; padding: 11px 19px; font-size: 17.5px; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; color: #FFF; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); background-color: #EC3C87; background-image: -moz-linear-gradient(top,#EE4E93,#E92076); background-image: -webkit-gradient(linear,0 0,0 100%,from(#EE4E93),to(#E92076)); background-image: -webkit-linear-gradient(top,#EE4E93,#E92076); background-image: -o-linear-gradient(top,#EE4E93,#E92076); background-image: linear-gradient(to bottom,#EE4E93,#E92076); background-repeat: repeat-x; border-color: #E92076 #E92076 #AC1153; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee4e93',endColorstr='#ffe92076',GradientType=0); filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); }</style>
<body>
<button onClick="doQuery()">Query</button>
<p style="margin-top: 0"><img alt="" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABaCAMAAADtqqpJAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAvFQTFRFUVJST1BQUFFR/////f39TE1N/v7+TU5OUlNTTk9PSElJSUpK/Pz8WltbU1RU+Pj4SktLRkdHS0xM+/v7R0hI9/f3YmNjV1hYiouL5ubm7e3tVVZW9PT0VFVVXF1dQUJCRUZGWFlZ3t7e39/f9vb22dnZ8/PzzMzM0NDQ5OTk8fHx6urqyMjI+vr6X2Bg+fn5YGFhYWJif4CA8PDwjY6O6enp7Ozsc3R0cXJyi4uL7u7uZ2hoz8/PhoeHtre3kJGRmJmZQEFBqqqq2tvbkpOTnJ2d7+/vg4ODeXp6o6Oj9/j4goOD6+vrr7Cw1dXV1NTUbG1tysrKwcHB1dbWh4iIlJSUxMTEi4yMZmdnxsfHcnJyVldXd3h4vr6+TE5Orq+vZGVlY2RkQ0RE4eHhuLi44uLi3d3dzs/P09PT5+jofn9/x8fH29zcl5mZl5eXlpeXRkhIamtrra2tp6ioWVpabW5uXV5ePT4+cHFxw8PDQUNDx8jI19fX6OjobG5uPD09yMnJpqampaWlampqpqiok5WVvb29REZGnZ6era6u/v//1tfXvr+/kJCQdnd3gICA9PX1g4SE4ODgrK2tS01Nk5SUdHV1wMDAv8DAwMHBaWpq6unpREVFhIWFt7e38vLyv7+/fX19fX9/W1xccXFxioqKpqenaGhoTU1NXmBg4+Tke3x8QkNDZGRk0dHRWVtbZmVlh4eHf39/z9DQj4+Ps7Ozb3Bwc3Nz5eXljo+PSkxMUFBQ8vPz3Nzc9fX13NvbVVVVVFRU3t3deHl5oKCgU1NTdXZ25+fnuLm5ubm5a2xspKWlenp6wcLC9vf38fLyuru71NXVqKiow8TEm5ycsbKysbGx7e7uaGpqhoaGUlJSfn5+zc7O1tbWvLy8zc3N0tLS6uvrysvLoaKinp6edXV1/f7+zM3NiImJaGlp2tra8/T0TU9P29vb/Pv7bm9veHp69fb2XF5emZmZ6+rq+vv7s7S0u7y8lJWVZWZm////lMTowQAAAPt0Uk5T/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wDjnwPIAAAD80lEQVR42uzYU9AmRxQG4NMYf7bx27bXtm1nrZgbZze2bdu2bdtWX2X+3eAitZsvmz4Xqdq5mpqaear7nHd6ahqEnEPNE/zvV0GKzU49/9W9vsXS/RFrv6U/R5H00gsogPP0ShzdnTKAeK8r5ih6STsBMOC0WziGvsgLADpNN1QUydcd81123Slo2X2jfum6+wPTHnuc6iQdebtctp4YZJedVk1vPoMkV5dzyfrLTlsnzp79Q0SzBh/CperqGz67MGD1sJ92X6WcMPW9ei5RZ/11e+gQmD7ckX810FWXTqmWp7OCTxWAaQA1S0T0ydY+hjn5QAeTpp+TtF+lyTq5coodnz0ujit05llRafp5BtDQeJNsmMiFKgqPpob3mgmSdHZ3nILyzWKdZk7p7ebweRGT3h7Pk6PzTjuOesmyEAkcti1CTZvDG2sq5OijXgPwDIr1S4FrQMG21f64tc19mRS97IlLgGj5Yt5sJdPD/phPXkxK3Z8aYqcRnuOisMXQhiUkr+/56yiYS4uY+GGa4ZvUJldXb9wI5kFN9lnT/Yo5PiZZX/jKF6P79Z41thikJSj7y7dbx5Kta1b+Y8TTUC9bZ7/nZMFgRfswJlv/cw41oLUOxNIH3qRYnQksfWQKlE4VS485Dc9yN5ZenKLmLwJJ54UeoEOqkXT10TBc8aIDSXe/NRec8zmWPgAgcxWWXrkyQGZ3YHX1mMsJCSew9K9Ga8ZJUSy9MER8dUj/TUK9z0fJiUGssc8Kw6FdfiSdr81AdiJH0j+vA/pguYqkt63XjNUxrK6WbADl1kos/RkLbjuAIenB7z30nlFHIOl8DoV738Xa4yiZQzyRs7H0WRr4HnAg6Wp/H7iWMSS9tJYatdUCSe/IgN6ApQ/tBvAWq0j6HVkCqYcFjq7OmAnKykos/SEA63mBo7MFOqFT90HS/QfbPb1IIOlPhynNPoukOw5XQOn2I+mNVaD7PhY4OtvkAe31IhydXfYdAWuMQNIjik63FCDpi5KU6osZjl7+tQFm63bx/6aX3WAB1HwpcPQuF4DyCEfRebFLA++xqsDQ+d4hosP6UoGhs+vbNVBc7zgw9B9nOBWA+FE7vmvn9OCdy10GaJ4RQyXpfzWPqbzizKQBNNv1kZCiBxMFbrG1xMGytrHnWl5KzHBFmZCis7xrb358zbhxR0ZH9F3xa58AULJu2Mh/fi433T0praedAWcoUKvP7d3edNV2v+mXpYsXiELsb5BGNdA0XYe6MTk9lqNeemHSqVlkTz0dqGqvmrAwxyjkqKvBz8a+9H5kRfMna44/+a6ck5tzIu0cFolGB6v/N++FtH2xXfou/X+g/ybAAPqmhSv3+0oDAAAAAElFTkSuQmCC" /></p>
</body>
</html>
You can do this in many ways, two of the "best" would be
1, sending variables in the format variable[key] = value php will reconise this and do the the conversion so $_GET['variable']['key'] would contain value. http://php.net/manual/en/language.variables.external.php
2, send it as a JSON string use JSON.stringify(yourArray); (NOTE: IE8 and above support this, older versions need a libary like json2), then in php call json_decode() on the variable. http://php.net/manual/en/function.json-decode.php
I am not a programmer, just know a good amount of css and html, but almost no javascript. I am trying to implement a free menu I found (thanks to stu nichols), but I am running into an issue I think is the the jquery script. I contacted the designer but he was not able to help.
I input the menu into jsfiddle.
http://jsfiddle.net/3vAaN/
HTML:
<ul class="leftnav1">
<li>tier1
<ul>
<li>t1 s1</li>
<li>t1 s2</li>
<li>t1 s3</li>
</ul>
</li>
<li>tier2
<ul>
<li>t2 s1</li>
<li>t2 s2</li>
<li>t2 s3</li>
<li>t2 s4</li>
<li>t2 s5</li>
</ul>
</li>
</ul>
CSS:
.leftnav1 { font: bold 15px/15px arial, sans-serif; text-align: center; border: 5px solid #400; }
.leftnav1 {background:#600; width:180px;
background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.5)), to(rgba(255, 255, 255, 0)));
background-image: -moz-linear-gradient(-90deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
}
.leftnav1 ul {background:#700; width:170px;
background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.5)), to(rgba(255, 255, 255, 0)));
background-image: -moz-linear-gradient(-90deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
}
.leftnav1 ul ul {background:#800; width:160px;
background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.5)), to(rgba(255, 255, 255, 0)));
background-image: -moz-linear-gradient(-90deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
}
.leftnav1 ul ul ul {background:#900; width:150px;
background-image: -webkit-gradient(linear, 0% 0%, 0% 95%, from(rgba(255, 255, 255, 0.5)), to(rgba(255, 255, 255, 0)));
background-image: -moz-linear-gradient(-90deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
}
.leftnav1 ul { display: none; }
.leftnav1, .leftnav1 ul { padding: 10px 5px; margin: 0; list-style: none; -o-border-radius: 10px; -ms-border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px; -o-box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.5); -ms-box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.5); -moz-box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.5); -webkit-box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.5); box-shadow: 0px 5px 5px rgba(0, 0, 0, 0.5); }
.leftnav1 li a { color: #ddd; text-indent: 0; text-decoration: none; display:block; }
.leftnav1 li { cursor: pointer; width: 100%; padding: 5px 0; }
.leftnav1 li a:hover { color: #fff; }
.leftnav1 li.has_ul { color: #fc0; }
.leftnav1 li.has_ul:hover { color: #0cf; }
.leftnav1 li.clicked { color: #0cf; }
JavaScript:
$(document).ready(function () {
timer=0;
/* time in milliseconds */
collapse = 10000;
$(".leftnav1 li:has(ul)").click(function (event) {
if (this == event.target) {
$(this).toggleClass('clicked').children('ul').slideToggle();
$(this).find('li:has(ul)').removeClass('clicked').find("ul").slideUp();
$(this).siblings().removeClass('clicked').find("ul").slideUp();
}
}).addClass('has_ul');
$(".leftnav1").mouseover(function() {
clearTimeout(timer);
});
$(".leftnav1").mouseleave(function() {
timer = window.setTimeout(function(){
$('.leftnav1 li > a').siblings().children().removeClass('clicked').find('ul').slideUp();
$('.leftnav1 li > a').parent().siblings().removeClass('clicked').find('ul').slideUp();
}, collapse);
});
});
If you look at the menu, the sliding works correctly on the first tier because it does not contain a link within the li.
On tier 2, I add a link within the li which also has a sub ul. The sliding only works if you click on the very tip top of the li area. Not on the whole li area. My guess is that the link fires if you click anywhere on the word, not allowing the slide function in the script to fire, and vice versa when you click the tip top of the li area.
I have tried display:block in every possible class that might solve it, and it hasn't. Is it possible that jquery cannot fire a function and follow a link at the same time? The implementation of the menu will be in a static left hand column of an ecommerce site, and the links will be to categories within the site that load in the inner page area.
Rewrite the function to fire when clicking on the link (<a>). At the end of the event handler, make sure you include return false or use preventDefault()
See http://api.jquery.com/event.preventDefault/