everyone. I am a jquery beginner and want to ask a few questions.
I am coding a simple math captcha for form submission test, I wanna generate a set of new random number each time when I press the "reset button".
But I when I google for the solution, most are trying to reload the page or reload the whole function, So I wanna ask if there is a way to do this.
And I would be very pleased if you guys can help me improving the codes as I think I am writing quite dummy. Thanks so much!!!
Please have a look at my code in fiddle :)
https://jsfiddle.net/v7bcjj1q/#&togetherjs=2nOVnkI34j
my code:
$(document).ready(function(){
$('button[type=submit]').attr('disabled','disabled');
var randomNum1;
var randomNum2;
//set the largeest number to display
var maxNum = 20;
var total;
randomNum1 = Math.ceil(Math.random()*maxNum);
randomNum2 = Math.ceil(Math.random()*maxNum);
total =randomNum1 + randomNum2;
$( "#question" ).prepend( randomNum1 + " + " + randomNum2 + "=" );
// When users input the value
$( "#ans" ).keyup(function() {
var input = $(this).val();
var slideSpeed = 200;
$('#message').hide();
if (input == total) {
$('button[type=submit]').removeAttr('disabled');
$('#success').slideDown(slideSpeed);
$('#fail').slideUp(slideSpeed);
}
else {
$('button[type=submit]').attr('disabled','disabled');
$('#fail').slideDown(slideSpeed);
$('#success').slideUp(slideSpeed);
}
});
// Wheen "reset button" click, generating new randomNum1 & randomNum2
});
For re-usability, a separate function can be used to generate the question
var total;
function getRandom(){return Math.ceil(Math.random()* 20);}
function createSum(){
var randomNum1 = getRandom(),
randomNum2 = getRandom();
total =randomNum1 + randomNum2;
$( "#question" ).text( randomNum1 + " + " + randomNum2 + "=" );
//in case of reset
$('#success, #fail').hide();
$('#message').show();
}
Inside the document load, the function can be called to initialize and subsequently attached to the click event
$(document).ready(function(){
$('button[type=submit]').attr('disabled','disabled');
//create initial sum
createSum();
// On "reset button" click, generate new random sum
$('button[type=reset]').click(createSum);
//....
One step further would be to set the visibility in a function that (re)checks the input on both keyup and reset.
Example fiddle
Just add an onClick event on the reset button
Inside you have to generate new numbers, total, clear question and clear input
$('button[type=submit]').attr('disabled', 'disabled');
var randomNum1;
var randomNum2;
//set the largeest number to display
var maxNum = 20;
var total;
randomNum1 = Math.ceil(Math.random() * maxNum);
randomNum2 = Math.ceil(Math.random() * maxNum);
total = randomNum1 + randomNum2;
$("#question").prepend(randomNum1 + " + " + randomNum2 + "=");
// When users input the value
$("#ans").keyup(function() {
var input = $(this).val();
var slideSpeed = 200;
$('#message').hide();
if (input == total) {
$('button[type=submit]').removeAttr('disabled');
$('#success').slideDown(slideSpeed);
$('#fail').slideUp(slideSpeed);
} else {
$('button[type=submit]').attr('disabled', 'disabled');
$('#fail').slideDown(slideSpeed);
$('#success').slideUp(slideSpeed);
}
});
// Wheen "reset button" click, generating new randomNum1 & randomNum2
$("#reset").on("click", function() {
randomNum1 = Math.ceil(Math.random() * maxNum);
randomNum2 = Math.ceil(Math.random() * maxNum);
total = randomNum1 + randomNum2;
$("#question").empty();
$("#ans").val('');
$("#question").prepend(randomNum1 + " + " + randomNum2 + "=");
});
* {
padding: 0;
margin: 0;
}
html,
body {
font-family: 'Open Sans';
font-weight: lighter;
font-size: 12px;
width: 100%;
height: 100%;
}
#success,
#fail {
display: none;
}
#message,
#success,
#fail {
margin-top: 10px;
margin-bottom: 10px;
}
.container {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
p {
display: inline;
margin-right: 5px;
}
input,
button {
font-family: 'Open Sans';
font-weight: lighter;
font-size: 12px;
}
input {
border: 1px solid #FFBBD7;
width: 30px;
height: 20px;
text-align: center;
}
button {
border: none;
border-radius: 1.5em;
color: #FFF;
background: #FFBBD7;
padding: 2.5px 10px;
width: 75px;
height: 30px;
cursor: pointer;
transition: background .5s ease-in-out;
}
button:hover:enabled {
background: #303030;
}
button:disabled {
opacity: .5;
cursor: default;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p id="question"></p>
<input id="ans" type="text">
<div id="message">Please verify.</div>
<div id="success">Validation complete :)</div>
<div id="fail">Validation failed :(</div>
<button type="submit" value="submit">Submit</button>
<button type="reset" id="reset" value="reset">Reset</button>
You can do it like this, add this piece of code:
$('#reset').click(function(e){
randomNum1 = Math.ceil(Math.random()*maxNum);
randomNum2 = Math.ceil(Math.random()*maxNum);
total =randomNum1 + randomNum2;
$( "#question" ).html( randomNum1 + " + " + randomNum2 + "=" );
});
#reset is in this case your reset button. You should just give it that ID, or change the selection depending on what you like most.
On click, you'll reset the variables, and change the HTML from the question.
I did it by just duplicating the code, but you might want to create a single function for it, as you are using it multiple times.
Related
I cannot get it to just display one at a time. It has to do a full cycle before it displays just one paragraph. Pulling my hair out.
$(function(){
setInterval(function(){$('.forumFeed > :first-child').fadeOut(3000).next('p').delay(3000).fadeIn(1000).end().appendTo('.forumFeed');}, 5000);
});
https://codepen.io/capseaslug/pen/yqyBXB
Hide all but the first paragraph tag by default. Inside the setInterval hide the one that is showing and display the next one (controlled by an index variable).
To make the items fade in/out nicely you can fade in the next element after the visible one is finished hiding.
Added some variables at the top to play with the aesthetics / number of items looped through.
SO didn't have moment.js so I hard coded some string. Codepen for a working version.
var numberOfItems = 10;
var flipSpeed = 2000;
var fadeOutSpeed = 500;
var fadeInSpeed = 200;
(function(c){
var uniquename = 'rssfeed' // id of target div
var query = 'select * from rss(0,' + numberOfItems + ') where url = "https://forums.mankindreborn.com/f/-/index.rss"'; // RSS Target, 0,5 signifies number of entries to show
var numretries = 1; // increase this number (number of retries) if you're still having problems
//////// No Need To Edit Beyond Here Unless You Want To /////////
var counter = typeof c === 'number'? c : numretries;
var thisf = arguments.callee;
var head = document.getElementsByTagName('head')[0];
var s = document.createElement('script');
window["callback_" + uniquename + (--counter)] = function(r){
head.removeChild(s);
if(r && r.query && r.query.count === 0 && counter > 0){
return thisf(counter);
}
//r now contains the result of the YQL Query as a JSON
var feedmarkup = '';
var feed = r.query.results.item // get feed as array of entries
for (var i=0; i<feed.length; i++) {
feedmarkup += '<p><span class="firstrowwrap"><a href="' + feed[i].link + '">';
feedmarkup += feed[i].title + '</a> <span class="comments"> Replies: ';
feedmarkup += feed[i].comments + ' </span></span><span class="secondRow"> <i class="fas fa-feather-alt"></i> ' ;
feedmarkup += feed[i].creator + ' <span class="posttime"> Last Post: ';
//pubishdate since
publishDate = feed[i].pubDate;
var inDate = publishDate;
var publisheddate = new Date(inDate);
feedmarkup += 'moment.js is missing ' + '</span></span></p>';
//endpublishdate since
}
document.getElementById(uniquename).innerHTML = feedmarkup;
};
var baseurl = "https://query.yahooapis.com/v1/public/yql?q=";
s.src = baseurl + encodeURIComponent(query) + "&format=json&callback=callback_" + uniquename + counter;
head.append(s);
})();
$(function(){
var index = 0;
setInterval(function() {
$('#rssfeed>p:visible').fadeOut(fadeOutSpeed, ()=> {
$('#rssfeed>p').eq(index).fadeIn(fadeInSpeed);
});
index++;
if(index === $('#rssfeed>p').length){
index = 0;
}
}, flipSpeed);
});
#main-container {
padding:4em;
background: #333;
font-family: 'exo'
}
#rssfeed p:not(:first-child) {
display: none;
}
a{
font-weight:
500;
color: #68ddda;
}
a:hover{
color: #4ca7a4;
}
.firstrowwrap{
display: flex;
justify-content: space-between;
}
.secondRow{
display: block;
padding-top: 4px;
margin-bottom: -5px;
}
#rssfeed p{
background-color: #212121;
padding: 10px;
width: 400px;
margin-bottom: 2px;
color: #464646;
}
.comments{
height: 18px;
position: relative;
z-index: 1;
padding-left: 8px;
margin-left: 4px;
font-size: 12px;
}
.comments:after{
content: "";
position: absolute;
width: 100%;
height: 100%;
left: 0px;
top: 0px;
background-color: #969696;
border-radius: 2px;
z-index: -1;
margin-left: 4px;
}
.posttime{
float: right;
font-size: 13px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid" id="main-container">
<div class="row">
<div class="col-md-12">
<div class="forumFeed" id="rssfeed"></div>
</div>
</div>
</div>
I create the checkout page of an eshop and I have a loop in which I display the products that the user has added to the cart. Inside the loop, I display the info for the products I have a text area so the user can choose the quantity of each product. The problem is that the id of each text area must be unique. How can I create many textareas in a loop with different ids?
textarea:
<form name='txtAreaForm' method='GET'>
<textarea disabled name='textArea' id='counter'></textarea>
</form>
Also, I have two buttons (+-) to change the value of the textarea, this is the .js file:
var counter = 1;
// Display total
$("#counter").text(counter);
// When button is clicked
$("#plusButton").click(function(){
counter = counter + 1;
$("#counter").text(counter);
});
//Subtract
$("#minusButton").click(function(){
if (counter>1) {
counter = counter - 1;
$("#counter").text(counter);
}
});
Though the question is not quite clear to me, you can do something like the following:
var counter = 1;
// Display total
$("#counter").text(counter);
var counter = counter + 1;
for(var i=0; i<5; i++){
$("form").append('<textarea name=textArea"+counter+" id=counter"+counter+">1</textarea><input class="plus" type="button" value="+" /><input class="minus" type="button" value="-" /><br>');
}
// When button is clicked
$(".plus").click(function(){
var txtArea = $(this).prev('textarea').text();
$(this).prev('textarea').text(parseInt(txtArea)+1);
});
//Subtract
$(".minus").click(function(){
var txtArea = $(this).prev().prev('textarea').text();
if(txtArea >=2){
$(this).prev().prev('textarea').text(parseInt(txtArea)-1);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name='txtAreaForm' method='GET'>
</form>
You can use just JavaScript to render a form with as many textareas with its id as necessary and set the actions to each button related to each of them.
See this demo:
(function() {
// Set the plus action on every button with the class name «plus».
function setPlusAction() {
function plus(e) {
var textarea = e.target.previousSibling; // Find the textarea element related to the button clicked.
textarea.value = textarea.value * 1; // Convert the value into number.
textarea.value++; // Increment its value.
}
var elems = document.getElementsByClassName("plus"), i, len = elems.length, button;
for (i = 0; i < len; i++) {
button = elems[i]; // Find the current button.
button.onclick = plus; //Set the «plus» function on every button which has been found.
}
}
// Set the minus action on every button with the class name «minus».
function setMinusAction() {
function minus(e) {
var textarea = e.target.previousSibling.previousSibling; // Find the textarea element related to the button clicked.
textarea.value = textarea.value * 1; // Convert the value into number.
if (textarea.value > 1) {
textarea.value--; // Decrement its value.
}
}
var elems = document.getElementsByClassName("minus"), i, len = elems.length, button;
for (i = 0; i < len; i++) {
button = elems[i]; // Find the current button.
button.onclick = minus; //Set the minus function on every button which has been found.
}
}
// Render a form with the quantity of textareas required.
function buildForm(textareas) {
var html = "<form name=\"txtAreaForm\" method=\"GET\">", i;
for (i = 0; i < textareas; i++) {
html += "<div><textarea disabled name=\"textArea\" id=\"textarea";
html += i;
html += "\">1</textarea><button class=\"plus\" type=\"button\">+</button><button class=\"minus\" type=\"button\">-</button></div>";
}
html += "</form>";
return html; // Return the html content with the form.
}
/*
1. Render the form with document.getElementById("div").innerHTML = buildForm(50);
2. Once the form is renderd call setPlusAction() function;
3. And call setMinusAction() function;
*/
document.getElementById("div").innerHTML = buildForm(50); // Set 50 textareas.
setPlusAction();
setMinusAction();
})();
#div div {
border: solid 1px #ccc;
margin: 2px;
padding: 2px;
}
button.plus,
button.minus {
cursor: pointer;
}
<div id="div"></div>
Update:
jQuery version:
$(function() {
// Render a form with the quantity of textareas required.
function buildForm(textareas) {
var html = "<form name=\"txtAreaForm\" method=\"GET\">", i;
for (i = 0; i < textareas; i++) {
html += "<div><textarea disabled name=\"textArea\" id=\"textarea";
html += i;
html += "\">1</textarea><button class=\"plus\" type=\"button\">+</button><button class=\"minus\" type=\"button\">-</button></div>";
}
html += "</form>";
return html; // Return the html content with the form.
}
$("#div").html(buildForm(50)); // Render the form with 50 textareas.
$(".plus").on("click", function() {
var texarea = $(this).prev(), value = texarea.val() * 1;
value++;
texarea.val(value);
});
$(".minus").on("click", function() {
var texarea = $(this).prev().prev(), value = texarea.val() * 1;
if (value > 1) {
value--;
texarea.val(value);
}
});
});
#div div {
border: solid 1px #ccc;
margin: 2px;
padding: 2px;
}
button.plus,
button.minus {
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="div"></div>
Remember: IDs must be unique.
I prefer using a class, because I think it is more clear for the code.
Example: my_set_Of_Text_area.add ('<div><span> Ananas : </span>','</div>');
I prefer using data to made the link with the counting area and the + / - buttons.
$(function() {
class TxtAreaFab {
constructor(Form_ID, TextAreaPrefix, BtPlusClass, BtMinusClass) {
this._ref = 0;
this._TaP = TextAreaPrefix;
this._BtPlus = BtPlusClass;
this._BtMinus = BtMinusClass;
this._$ID = $('#' + Form_ID);
}
add(before, after) {
var elements = before;
this._ref++;
elements += "<textarea disabled id='TxtArea_" + this._ref + "'>1</textarea>";
elements += "<button class=" + this._BtPlus + " data-ref=\"TxtArea_" + this._ref + "\">+</button>";
elements += "<button class=" + this._BtMinus + " data-ref=\"TxtArea_" + this._ref + "\">-</button>";
elements += after;
$(elements).appendTo(this._$ID);
}
/* ----- not used , just here for sample
clear () {
this._$ID.html('');
this._ref = 0;
}
*/
};
var my_set_Of_Text_area = new TxtAreaFab('txtAreaForm', 'zoneTA_', 'ClassBtPlus', 'ClassBtMinus');
my_set_Of_Text_area.add('<div><span> Apples : </span>', '</div>');
my_set_Of_Text_area.add('<div><span> Oranges : </span>', '</div>');
my_set_Of_Text_area.add('<div><span> Pears : </span>', '</div>');
my_set_Of_Text_area.add('<div><span> Bananas : </span>', '</div>');
$('#txtAreaForm').on('click', "button", function(e) {
e.stopPropagation();
var $txtArea = $("#" + $(this).data("ref")),
v = parseInt($txtArea.val());
if ($(this).hasClass('ClassBtPlus')) $txtArea.val(++v);
if ((v > 1) && ($(this).hasClass('ClassBtMinus'))) $txtArea.val(--v);
return false;
});
my_set_Of_Text_area.add('<div><span> Ananas : </span>', '</div>');
});
#txtAreaForm div {
clear: both;
height: 30px;
}
#txtAreaForm div span {
display: block;
float: left;
width: 120px;
font-weight: bold;
text-align: right;
padding-right: 10px;
}
#txtAreaForm textarea {
display: block;
float: left;
width: 40px;
height: 16px;
font-weight: bold;
text-align: center;
resize: none;
}
<form name='txtAreaForm' id='txtAreaForm' method='GET'></form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
Special Fun solution! (but real).
I did it with only 9 lines of JavaScript / jQuery, and a little more in CSS.
And no need for textarea id. (Ok, my 2 "if" statements have only 1 line).
For the HTML part, each text box is placed in a "p" (paragraph), and that's it:
<p><textarea disabled > 1 </textarea></p>
<p><textarea disabled > 2 </textarea></p>
<p><textarea disabled > 3 </textarea></p>
The trick is in the CSS where I use :after and :before like the "+" or "-" buttons.
placed to the right of each box "p".
form p:after {
right: -22px;
content:'+';
...
form p:before {
right: -43px;
content:'-';
In the jQuery part.
I use the relative position of the mouse click to determine whether the operation should be a plus or minus. For the little story: -- $ (this) .outerWidth (); -- Is usefull.
Of course, it would still be better to add an ID on each textarea; but after reflection, it appeared to me that these input fields could be generated at the PHP server (?).
So, strange as it may seem, this solution is very serious. ;)
Everything is in the snippet.
$(function() {
$('form p').click(function(e) {
var
posX = (e.pageX - $(this).offset().left) - $(this).outerWidth();
Sign = (posX > 22) ? "moins" : (posX > 0) ? "plus" : "none",
Valn = parseInt($(this).children('textarea').text());
if (Sign === 'plus') $(this).children('textarea').text(++Valn);
if ((Sign === 'moins') && (Valn > 1)) $(this).children('textarea').text(--Valn);
});
});
textarea,
form,
p,
textarea {
font-family: Tahoma, sans-serif;
font-size: 16px;
}
textarea {
float: left;
width: 40px;
height: 22px;
font-weight: bold;
text-align: center;
resize: none;
line-height: 20px;
}
form p {
box-sizing: border-box;
display: block;
float: left;
clear: both;
position: relative;
border: 0;
margin: 5px 0 0 20px;
padding: 0;
}
form p:before,
form p:after {
position: absolute;
top: 2px;
width: 20px;
height: 20px;
display: block;
color: white;
background-color: darkslategray;
text-align: center;
font-size: 18px;
}
form p:after {
right: -22px;
content: '+';
line-height: 18px;
}
form p:before {
right: -43px;
content: '-';
line-height: 16px;
}
<form name="txtAreaForm" method='GET'>
<p><textarea disabled> 1 </textarea></p>
<p><textarea disabled> 2 </textarea></p>
<p><textarea disabled> 3 </textarea></p>
</form>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
I'm working on the freeCodeCamp "Show the local weather" project. I have almost everything working except I cannot seem to get the switch to toggle between Fahrenheit and Celsius to work properly. It's a very basic page for showing the weather and I want the user to be able to switch between Fahrenheit and Celsius by clicking on the tags and then the page will update with the new temperature. Currently, when I click on the 'C' tag it will display the correct temperature for a brief moment, but then quickly switch back to Fahrenheit. Any help would be greatly appreciated. Here is the link to the page: https://codepen.io/spencerj171/full/yzmmvR/
Thanks to everyone in advance!
HTML
<body>
<div class="container weather">
<div id="location"></div>
<div class="row">
<div class="col-lg-6">
<br><br>
<span class="ftemp" id="currentTemp"></span>
<span id="forc"> F | C</span>
<div>
<span id="icon"></span>
<span id="description"></span>
</div>
<span class="ftemp" id="lowTemp"></span>
<span class="ftemp" id="highTemp"></span>
<div id="humidity"></div>
</div>
<div class="col-lg-6">
<div id="map"></div>
</div>
</div>
</body>
CSS
body{
background-color: rgb(152, 157, 165);
color: black;
}
.switch{
border: none;
background-color: rgb(255, 255, 255);
text-decoration: none;
}
.weather{
text-align: center;
margin-top: 100px;
background-color: rgb(255, 255, 255);
border-radius: 5px;
padding: 50px 50px 50px 50px;
width: 50%;
height: auto;
position: relative;
}
#location{
font-size: 2em;
padding-bottom: .5em;
}
#currentTemp{
font-size: 1.5em;
display: inline-block;
}
#forc{
color: black;
display: inline-block;
font-size: 1em;
}
#icon{
width: 100%;
height: auto;
}
#description{
display: inline-block;
}
#lowTemp{
display: inline-block;
padding-right: 10px;
}
#highTemp{
display: inline-block;
}
#humidity{
}
#map{
width: 100%;;
height: 300px;
margin: auto;
}
a.switch{
text-decoration: none;
color: black;
}
a:hover{
color: rgb(0, 182, 255);
}
JavaScript
var url = "https://api.openweathermap.org/data/2.5/weather?q=cleveland&appid=d32fada3b37530ca403693700ae6c134";
var gurl = "https://maps.googleapis.com/maps/api/js?key=AIzaSyCrBes2R9nOEvbMHMoJ4oCTzSNGaOD6eQc&callback=initMap";
var degree = '<span id="forc"> F | C</span>';
var apiOpen = "d32fada3b37530ca403693700ae6c134";
var map;
var tempSwitch = false;
$(document).ready(function(){
getLocation();
});
//Get location of user
function getLocation(){
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
latitude = position.coords.latitude;
longitude = position.coords.longitude;
getWeather();
initMap();
});
} else{
alert("Please allow location services.")
}
}
//Retrieve weather
function getWeather(){
data = $.ajax({
type: "GET",
url: url,
dataType: 'jsonp',
success: function(json){
current = fahrenheit(json.main.temp);
low = fahrenheit(json.main.temp_min);
high = fahrenheit(json.main.temp_max);
$("#location").html("<div id='location'>" + json.name + " Weather</div>");
$("#currentTemp").html("<span class='ftemp' id='currentTemp'>" + current + "°" + "</span>");
$("#icon").html("<span id='icon'><img src='https://openweathermap.org/img/w/" + json.weather[0].icon + ".png'></span>");
$("#description").html("<span id='description'>" + json.weather[0].description.toUpperCase()) +"</span>";
$("#lowTemp").html("<span class='ftemp' id='lowTemp'>↓ " + low + "° " + "</span>");
$("#highTemp").html("<span class='ftemp' id='highTemp'>↑ " + high + "° " + "</span>");
$("#humidity").html("<div id='humidity'>Humidity: " + json.main.humidity + "%</div>");
}
});
switchTemp();
}
//Create Map
function initMap() {
map = new google.maps.Map(document.getElementById('map'), {
center: {lat: 41.505493, lng: -81.681290},
zoom: 10
});
}
//Convert temperature
function fahrenheit(kel){
var f = Math.floor(9/5 * (kel - 273) + 32);
return f;
}
function fahr(c){
var fahr = Math.floor( c * 1.8 + 32);
return fahr;
}
function celsius(f){
var c = Math.floor((f - 32) * 5/9);
return c;
}
//Switch temperature
function switchTemp(){
$("#c").on("click", function(){
if(tempSwitch === false){
$("#currentTemp").html("<span id='currentTemp'>" + celsius(current) + "°" + "</span>");
$("#lowTemp").html("<span id='lowTemp'>↓ " + celsius(low) + "° " + "</span>");
$("#highTemp").html("<spanid='highTemp'>↑ " + celsius(high) + "° " + "</span>");
tempSwitch === true;
}
});
$("#f").on("click", function(){
if(tempSwitch === true){
$("#currentTemp").html("<span id='currentTemp'>" + fahr(current) + "°" + "</span>");
$("#lowTemp").html("<span id='lowTemp'>↓ " + fahr(low) + "° " + "</span>");
$("#highTemp").html("<spanid='highTemp'>↑ " + fahr(high) + "° " + "</span>");
tempSwitch === false;
}
});
}
There was 2 problems in your code:
You C and F is a link, so when you click it makes a page refress since you have nothing in href="". either use href="#" or e.preventDefault(); as in the example just below:
$("#f").on("click", function(e){
e.preventDefault();
});
You use === to set tempSwitch as in tempSwitch === false but you need to use only one = as in tempSwitch = false
DEMO
I've got an array of cars and i'm looping through each car. I take input from the user using window.prompt() method. I take that value and filter it through my array of cars. I just want to know how I can restrict the car name the user selects to only those in the array
Fiddle : https://jsfiddle.net/qomu1fny/
var CarsWorld = {
cars : ['Honda','toyota','mercedes','jaguar'],
init: function(){
var getData = prompt('Which Car You Wanna Drive','');
for(var i = 0 ; i < this.cars.length ; i++){
$('.wrap').append(' ' + this.cars[i] + ' <br/> ');
}
},
};
CarsWorld.init();
var getData = prompt('Which Car You Wanna Drive','');
var foundCar = "";
for(var i = 0 ; i < this.cars.length ; i++){
$('.wrap').append(' ' + this.cars[i] + ' <br/> ');
//check if this car in the array is the picked car
if(this.cars[i] == getData){
foundCar = getData;
}
}
$('.wrap').append('you picked ' + foundCar);
Note that if the car isn't on the list then it won't output anything. Fiddle here: http://jsfiddle.net/e5qh3pvw/
I've tried to rephrase your question to something more understandable (currently under peer review). I understand you want to have a prompt that will restrict the choices of the user to the car models in your array.
Unfortunately, window.prompt() cannot achieve this, neither is there any synchronous (blocking) way to achieve it. You will need to use a modal dialog, and insert a regular html select element with your choices, or use a group of radio buttons.
I have created a fiddle that started getting bloated as I progressed. I used a few advanced techniques, just to engage your curiousity, since I suspect you are new to javascript.
Javascript:
var CarsWorld = {
cars : ['Honda','toyota','mercedes','jaguar'],
init: function(){
var getData = 'none';
for(var i = 0 ; i < this.cars.length ; i++){
$('.wrap').append(' ' + this.cars[i] + ' <br/> ');
}
var prompter = new CarsWorld.PromptSelect('Which Car You Wanna Drive', function(selected){
getData = selected;
alert('You chose '+ getData +'! ');
//other logic you want to apply on getData
});
prompter.show();
}
};
CarsWorld.PromptSelect = function(message, callback) {
self = this;
this.init = function(){
self.dropdown = '<select id="selectedCar">';
$.each(CarsWorld.cars, function(index, car){
self.dropdown += '<option>' + car + '</option>';
});
self.dropdown += '</select>';
self.markup = [
'<div class="prompt">',
'<div class="title">CarsWorld Prompt</div>',
'<div class="body">',
'<label for="selectedCar">'+ message +':</label>' + this.dropdown + '</div>',
'<div class="footer">',
'<button class="btn-ok">Ok</button>',
'<button class="btn-cancel">Cancel</button>',
'</div>',
'</div>'
].join('');
};
this.show = function(){
$('.overlay').show();
$('body').css('overflow', 'hidden');
self.init();
$('body').append(self.markup);
$('.prompt .btn-ok').on('click', function(){
self.hide();
callback($('#selectedCar').val());
self.destroy();
});
$('.prompt .btn-cancel').on('click', function(){
self.destroy();
});
return self;
};
this.hide = function(){
$('.prompt').hide();
$('.overlay').hide();
$('body').css('overflow', 'auto');
return self;
};
this.destroy = function(){
self.hide();
return self;
};
};
CarsWorld.init();
HTML:
<div class="wrapper">
<h1> Please choose the car of your type </h1>
<div class="wrap"></div>
<div class="overlay"></div>
</div>
CSS:
.overlay {
display: none;
position: absolute;
width: 100%;
height: 100%;
z-index: 990;
background: #444;
opacity: 0.5;
top: 0;
left: 0;
}
.prompt {
display: block;
position: absolute;
z-index: 999;
width: 300px;
height: 200px;
top: 50%;
left: 50%;
margin-left: -200px;
margin-top: -100px;
}
.prompt .title {
background: black;
color: white;
height: 10%;
padding: 10px;
border-radius: 3px 3px 0 0;
text-align: center;
font-weight: bold;
}
.prompt .body {
background: white;
height: 60%;
padding: 20px;
}
.prompt .footer {
background: grey;
text-align: right;
padding: 10px;
height: 10%;
border-radius: 0 0 3px 3px;
}
I have implemented 2 types of Accordians for my application- 1 Column and 2 Column
Im having a problem with the Static Height for the 1 Column Accordian. And I've been trying to modify the JavaScript all day but cant seem to get it to work.
The Heights should be dynamic in Height depending upon the amount data, however as you can see the Height is fixed, and some of the data is getting cut off:
http://www.davincispainting.com/whydavincis.aspx
The other 2 Column Accordian has almost the same JavaScript as the 1 Column Accordian, however the Height is dynanmic depending on how much data there is:
http://www.davincispainting.com/glossary.aspx
I would provide a Fiddle however the Data is now dynamic:
Here is the JavaScript for the problem Accordian:
<script type="text/javascript">
$.fn.accordion = function () {
return this.each(function () {
$container = $('#mid-featureleft-client');
$container.find("dt").each(function () {
var $header = $(this);
var $selected = $header.next();
$header.click(function () {
$('.active').removeClass('active');
$(this).addClass('active');
if ($selected.is(":visible")) {
$selected.animate({
height: 0
}, {
duration: 300,
complete: function () {
$(this).hide();
}
});
} else {
$unselected = $container.find("dd:visible");
$selected.show();
var newHeight = heights[$selected.attr("id")];
var oldHeight = heights[$unselected.attr("id")];
$('<div>').animate({
height: 1
}, {
duration: 300,
step: function (now) {
var stepSelectedHeight = Math.round(newHeight * now);
$selected.height(stepSelectedHeight);
$unselected.height(oldHeight + Math.round((newHeight - oldHeight) * now) - Math.round(newHeight * now));
},
complete: function () {
$unselected.hide().css({
height: 0
});
}
});
}
return false;
});
});
// Iterate over panels, save heights, hide all.
var heights = new Object();
$container.find("dd").each(function () {
$this = $(this);
$this.css("overflow", "hidden");
heights[$this.attr("id")] = $this.height();
$this.hide().css({
height: 0
});
});
});
};
$(document).ready(function () {
$.getJSON('FaqsJson.ashx?factType=2', function (datas) {
var str_one = "";
str_one = "<dl>"
$.each(datas, function () {
str_one += "<dt class=\"glossquestion\">" + this['Question'] + "</dt>";
str_one += "<dd class=\"glossanswer\" style=\"-webkit-margin-start:0px\"><div class=\"answerbox\">" + this['Answer'] + "</div></dd>";
});
str_one += "</dl>";
$("#glossary_first").html(str_one);
$("#mid-featureleft-client").accordion();
});
});
</script>
Here is the relevent HTML:
<div id="mid-feature-client">
<div id="mid-featureleft-client">
<div id="glossary_first" class="controlbox">
<br /><br />
</div>
<div style="clear: both;">
</div>
</div>
</div>
Here is the relevent css:
#mid-featureleft-client .controlbox {
width:546px;
padding:3px 0 0 6px;
position:relative;
/*background-color:green;*/
}
#mid-featureleft-client .glossarycontrolbox {
width:260px;
padding:3px 0 0 6px;
position:relative;
float:left;
/*background-color:blue;*/
}
.question-clicked {
background-color: #CCCCCC;
color: #0C2A55;
/*margin-top: 10px;*/
/*padding: 2px 5px 0;*/
}
.questionLink-clicked {
color: #0C2A55;
font-size: 1.2em;
font-weight: bold;
}
.answerbox {
padding: 3px 5px 3px 5px;
}
.questionLink {
color: #0C2A55;
font-size: 1.2em;
font-weight: bold;
}
.glossquestion {
padding: 0 5px 4px 0;
}
.glossanswer {
background-color: #F9FBFC;
display: none;
}
#accordion .handle {
width: 260px;
height: 30px;
background-color: orange;
}
#accordion .section {
width: 260px;
height: 445px;
background-color: #a9a9a9;
overflow: hidden;
position: relative;
}
dt {
/*background-color: #ccc;*/
}
dd {
/*height: 30px;*/
}
.active {
background: #a9a9a9;
}
The problem is with the way you're storing the heights, a bit after this comment:
// Iterate over panels, save heights, hide all.
Specifically, this line:
heights[$this.attr("id")] = $this.height();
Your dd elements don't have an id, so on each iteration of the loop, heights[''] is being set to the height of the current dd.
You should be able to fix it by changing this:
$.each(datas, function () {
str_one += "<dt class=\"glossquestion\">" + this['Question'] + "</dt>";
str_one += "<dd class=\"glossanswer\" style=\"-webkit-margin-start:0px\"><div class=\"answerbox\">" + this['Answer'] + "</div></dd>";
});
to this:
var i = 0;
$.each(datas, function () {
str_one += "<dt class=\"glossquestion\">" + this['Question'] + "</dt>";
str_one += "<dd id=\"rand_" + i + "\" class=\"glossanswer\" style=\"-webkit-margin-start:0px\"><div class=\"answerbox\">" + this['Answer'] + "</div></dd>";
i++;
});
I'm just going to point out that my fix doesn't seem very jQuery-esque, and your entire code seems complicated for what it's doing.
If you changed your JSON to something like this:
[{"Question1":"..","Answer1":".."},{"Question2":"..","Answer2":".."}, .. ]
You could do this:
$.each(datas, function (i, v) {
str_one += "<dt class=\"glossquestion\">" + this['Question'] + "</dt>";
str_one += "<dd id=\"Dd" + i + "\" class=\"glossanswer\" style=\"-webkit-margin-start:0px\"><div class=\"answerbox\">" + this['Answer'] + "</div></dd>";
});
which is cleaner code than incrementing our own variable i inside $.each.