I am making a webpage that has a baseball strikezone with 25 buttons that will be clickable in 25 locations. I need to know if there is a easier way to do this then what I am doing. Maybe something that will take up far less lines. The button is clicked and then the counter is added by one to another table.
$('#one').click(function(){
counter++;
$('#ones').text(counter);
});
var countertwo = 0;
$('#two').click(function(){
countertwo ++;
$('#twos').text(countertwo);
});
A bit of a guess here, but:
You can store the counter on the button itself.
If you do, and you give the buttons a common class (or some other way to group them), you can have one click handler handle all of them.
You can probably find the other element that you're updating using a structural CSS query rather than id values.
But relying on those ID values:
$(".the-common-class").click(function() {
// Get a jQuery wrapper for this element.
var $this = $(this);
// Get its counter, if it has one, or 0 if it doesn't, and add one to it
var counter = ($this.data("counter") || 0) + 1;
// Store the result
$this.data("counter", counter);
// Show that in the other element, basing the ID of what we look for
// on this element's ID plus "s"
$("#" + this.id + "s").text(counter);
});
That last bit, relating the elements by ID naming convention, is the weakest bit and could almost certainly be made much better with more information about your structure.
You can use something like this:
<button class="button" data-location="ones">One</button>
...
<button class="button" data-location="twenties">Twenty</button>
<div id="ones" class="location">0</div>
...
<div id="twenties" class="location">0</div>
$('.button').on('click', function() {
var locationId = $(this).data('location')
, $location = $('#' + locationId);
$location.text(parseInt($location.text()) + 1);
});
Also see this code on JsFiddle
More clean solution with automatic counter
/* JS */
$(function() {
var $buttons = $('.withCounter'),
counters = [];
function increaseCounter() {
var whichCounter = $buttons.index(this)+1;
counters[whichCounter] = counters[whichCounter] ? counters[whichCounter] += 1 : 1;
$("#counter"+whichCounter).text(counters[whichCounter]);
}
$buttons.click(increaseCounter);
});
<!-- HTML -->
<button class="withCounter">One</button>
<button class="withCounter">Two</button>
<button class="withCounter">Three</button>
<button class="withCounter">Four</button>
<p id="counter1">0</p>
<p id="counter2">0</p>
<p id="counter3">0</p>
<p id="counter4">0</p>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Related
I have very delicate problem, I'll make an example. What am i doing is that I'm basically prepending elements and differentiating them by incrementing (i need to do it this way for certain reasons), then there is an option to click on any element and delete it.
This is only stupid example of what it looks like:
$(function () {
var i = 0;
$("#new").click(function(){
i++;
$("#container").prepend("<div class='prepended "+i+"'>blah blah blah</div>")
$(".prepended").click(function(){
$(this).remove();
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="new">click here</button>
<div id="container"></div>
When I delete any element, I need to somehow manage to make the incrementing "i" variable fill the missing element. I don't know how to explain in words so I'll explain in "code":
Let's say I prepended 6 elements so the "i" variable is now 6:
if(deleted_divs_class == 1)
{
i = 1; // fill the missing "1"
next_click_i = 6; // variable i on next click should be 6 in order to continue in right order
}
else if (deleted_divs_class !== 1 || 6) // deleted element is somewhere from middle so it's not 1 or 6
{
i = fill_missing_number; // fill the removed number
next_click_i = 6; // continue in right order
}
else
{
i--;
// deleted element is the last element of line so continue normally by incrementing
}
i know how to get deleted_divs_class variable and apply the next_click_i variable but i don't know how make the whole thing work dynamically
I know that this question might seems very weird but this is just an example, it's part of much much much bigger code and i just need to make logic of this "incrementation" in order to make the whole thing work properly as i need.
So i just can not figure out the logic.
I suppose I created the code you are looking for, but I’m not sure if I understood your question correctly. Look at this code. Is this what you wanted or not?
$(function () {
var missed=[]; //Here will be stored missed numbers
var i = 0;
$("#new").click(function(){
var n=0;
if(missed.length>0) {
n=missed.shift(); //get next missed number from the array
} else
n=++i;
$("#container").prepend("<div data-i='"+n+"' class='prepended "+n+"'>"+n+"blah blah blah</div>")
});
$('#container').on('click',".prepended",[], function(){
missed.push($(this).data('i')); //save removed number into missed numbers array
$(this).remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="new">click here</button>
<div id="container"></div>
To backfill the deleted i values, you'll need to store them. In this example, deleted_i holds all deleted values, and attempts to retrieve the new value from there first when creating a new element. If it's empty, it defaults to incrementing the value of i.
Note also that the click event is now bound to the container so that it only fires once - in your example, it was getting re-bound to all .prepended elements, so that when you clicked on one, it was firing that function as many times as the loop had run so far.
$(function () {
var i = 0,
deleted_i = []
$("#new").click(function(){
var idx;
console.log(deleted_i)
if(deleted_i.length) idx = deleted_i.shift() //grab the first deleted index, if one exists
else idx = ++i;
$("#container").prepend("<div data-index='"+idx+"' class='prepended "+idx+"'>blah blah blah this is "+idx+"</div>")
});
$("#container").click(function(e){
var $target = $(e.target)
if($target.hasClass('prepended')){
$target.remove();
deleted_i.push($target.attr('data-index'))
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="new">click here</button>
<div id="container"></div>
I am using bootstrap time-picker, I want to use that for any number of text-field, from 1 to any number, as its depend on members. I am pasting my code below, currently i have added "1" so its working for just one text-field, but If Members needed more than one text-field to show time ..how i can do that ?
var counterAvailabilityN = 1;
$('#es_availability_time_from' + counterAvailabilityN).timepicker();
setTimeout(function() {
$('#timeDisplay').text($('#es_availability_time_from' + counterAvailabilityN).val());
}, 100);
$('#es_availability_time_from' + counterAvailabilityN).on('changeTime.timepicker', function(e) {
$('#timeDisplay').text(e.time.value);
});
$('#es_availability_time_untill' + counterAvailabilityN).timepicker();
setTimeout(function() {
$('#timeDisplay').text($('#es_availability_time_untill' + counterAvailabilityN).val());
}, 100);
$('#es_availability_time_untill' + counterAvailabilityN).on('changeTime.timepicker', function(e) {
$('#timeDisplay').text(e.time.value);
});
Basically I am retrieving data "from to until" from database, so its some times coming with 3 text-fields and some time its coming with 5 text-fields, so i am unsure how many text-field will come from which member, If it is 3, i need to add 3 times time-picker in each text-field, If it is 5, I want to add 5 times time-picker, and as you see, i fixed it for 1, I just want on page load, it should read how many there and based on that add time-picker in each text-field, each text-field has different ID's, from 1 to any number.
Here is an example of using Event delegation, it's not obviously using boostrap timepicker, but it will work for that too.
The example is very basic to make easy to follow. Whatever you type into the from INPUT just gets copied into the to INPUT.
I've used three classes, for targeting the correct elements.
I've also used jQuery clone method to make multiple copies of elements, rather than hand coding it all in HTML.
$(function () {
var clone = $('#clone'), body = $('body');
for (var l = 1; l < 10; l ++) {
var cloned = clone.clone();
cloned.removeClass('hidden');
cloned.appendTo(body);
}
body.on('input propertychange', '.from', function () {
var copyTo = $(this).parents('.fromto').find('.to');
copyTo.val($(this).val());
});
});
.hidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- create a clone, make it's easy to create multiple ones -->
<div id="clone" class="fromto hidden">
from <input class="from" />
to <input class="to" />
</div>
I am trying to toggle a div when its name is clicked.
I have multiple coupls like that in my page, and I want it to work as
"when <p id= "d2"> is clicked => <div id="d2"> is toggled".
I tried those functions:
$(document).ready(function(){
$("p").click(function(){
$("div#" + $(this).attr('id')).toggle();
});
});
function rgt() {
//document.body.innerHTML = "";
var id = "d" + this.id;
var situation = document.getElementById(id).style.display;
if (situation == "none") {
situation = "block";
}
else {
situation = "none";
}
}
function showHide(theId) {
if (document.getElementById("d" + theId).style.display == "none") {
document.getElementById("d" + theId).style.display = "block";
}
else {
document.getElementById("d" + theId).style.display = "none";
}
}
I can't make it Work!!! Why is it?
the browser says:"no 'display' property for null"...
I will be more than happy to solve it with simple jquery
Ensure Your id Attributes Are Unique
Assuming that your id attributes are unique, which they are required to be per the specification:
The id attribute specifies its element's unique identifier (ID). The
value must be unique amongst all the IDs in the element's home subtree
and must contain at least one character. The value must not contain
any space characters.
You should consider renaming your id attributes to d{n} and your paragraphs to p{n} respectively as seen below :
<button id='p1'>p1</button> <button id='p2'>p2</button> <button id='p3'>p3</button>
<div id='d1'><pre>d1</pre></div>
<div id='d2'><pre>d2</pre></div>
<div id='d3'><pre>d3</pre></div>
which would allow you to use the following function to handle your toggle operations :
$(function(){
// When an ID that starts with P is clicked
$('[id^="p"]').click(function(){
// Get the proper number for it
var id = parseInt($(this).attr('id').replace(/\D/g,''));
// Now that you have the ID, use it to toggle the appropriate <div>
$('#d' + id).toggle();
})
});
Example Using Unique IDs
You can see an interactive example of this approach here and demonstrated below :
Consider Using data-* Attributes
HTML supports the use of data attributes that can be useful for targeting specific elements through jQuery and associating them to other actions. For instance, if you create an attribute on each of your "p" elements as follows :
<button data-toggles='d1'>p1</button>
<button data-toggles='d2'>p2</button>
<button data-toggles='d3'>p3</button>
and then simply change your jQuery to use those as selectors :
$(function(){
// When an element with a "toggles" attribute is clicked
$('[data-toggles]').click(function(){
// Then toggle its target
$('#' + $(this).data('toggles')).toggle();
});
});
Is this you are looking?
$("#p1").on("click", function() {
$("#d1").toggle();
});
js fiddle: https://jsfiddle.net/Jomet/09yehw9y/
jQuery(function($){
var $toggles = $('.divToggle');
var $togglables = $('.togglableDiv');
$toggles.on('click', function(){
//get the div at the same index as the p, and toggle it
$togglables.eq($toggles.index(this)).toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p class="divToggle">Show Me 1</p>
<p class="divToggle">Show Me 2</p>
<p class="divToggle">Show Me 3</p>
<div class="togglableDiv">Weeee 1</div>
<div class="togglableDiv">Weeee 2</div>
<div class="togglableDiv">Weeee 3</div>
Minimal approach using classes. This solution assumes the order of the p elements in the dom are in the same order as the divs are in the order. They do not have to be contiguous, but the order does matter with this solution.
ids are not the droids you are looking for.
An id needs to be unique. If you want to classify something one would suggest to use classes. You can actually use serveral of them for some fancy stuff. How about something like this:
<p class="toggle one">one</p>
<div class="toggle one" style="display:none">content one</div>
Straight forward. Every element that is a switch or switchable gets the class toggle. Each pair of switch and switchable(s) gets an additional identifier (like one, two, ...).
Simple JScript Implementation:
Now how about not using JQuery to work with that? Sure it i$ handy, but it hides all that neat stuff one would eventually like to learn her/himself!
var myToggle = {};
(function(module) {
"use strict";
(function init() {
var elements = document.getElementsByClassName("toggle");
var element;
var i = elements.length;
while (i) {
i -= 1;
element = elements[i].className;
elements[i].setAttribute("onclick", "myToggle.swap(\"" + element + "\")");
}
}());
module.swap = function(element) {
var couple = document.getElementsByClassName(element);
var i = couple.length;
while (i) {
i -= 1;
if (couple[i].style.display === "none" && couple[i].tagName === "DIV") {
couple[i].style.display = "block";
} else if (couple[i].tagName === "DIV") {
couple[i].style.display = "none";
}
}
};
}(myToggle));
<p class="toggle one">one</p>
<div class="toggle one" style="display:none">content one</div>
<p class="toggle two">two</p>
<div class="toggle two" style="display:none">content two 1</div>
<div class="toggle two" style="display:none">content two 2</div>
var myToggle = {} is the object we use to keep our little program contained. It prevents that our code conflicts with other declarations. Because what if some plugin on our site already declared a function called swap()? One would overwrite the other!
Using an object like this ensures that our version is now known as myToggle.swap()!
It may be hard to follow how it got to that name. Important hint: something looking like this... (function() { CODE } ()) ...is called an immediately-invoked function expression. iffy! It's a function that is immediatly executed and keeps its variables to itself. Or can give them to whatever you feed it in the last ()-pair.
Everything else is as verbose as can be... no fancy regular expressions, hacks or libraries. Get into it!
I am making a website that displays profiles of people. Each person is designated a svg button and when that button is clicked, a pop up displays that persons information.
I have this jquery function:
$('.button1').click(function() {
$('.person1-profile').fadeIn();
});
$('.button1-exit').click(function() {
$('.person1-profile').fadeOut();
});
$('.button2').click(function() {
$('.person2-profile').fadeIn();
});
$('.button2-exit').click(function() {
$('.person2-profile').fadeOut();
});
$('.button3').click(function() {
$('.person3-profile').fadeIn();
});
$('.button3-exit').click(function() {
$('.person3-profile').fadeOut();
});
I'm wondering if it is possible to do this with Javascript so that it significantly shortens the coding, and rather than copy & pasting that code every time for each person, if variables can be made for people/profile and so it would be something like:
$('var person + button').click(function() {
$('var person + profile').fadeIn();
});
$('var button + exit').click(function() {
$('var person + profile').fadeOut();
});
Thank you I really appreciate it! Sorry if it is unclear.
You could use data-attributes for this one:
Define your buttons like that:
<button class="openButton" data-person="3">Open</button>
<button class="closeButton" data-person="3">Close</button>
And your open/close-code like that:
$('.openButton').click(function() {
var personNumber = $(this).attr("data-person");
$('.person'+personNumber+"-profile").fadeIn();
});
$('.closeButton').click(function() {
var personNumber = $(this).attr("data-person");
$('.person'+personNumber+"-profile").fadeOut();
});
In action: http://jsfiddle.net/ndx4fn9n/
I can think of few ways of doing it.
You could read only 7th character of the class name. This limits you to having only 10 fields. Or you could put id on very end like this person-profile1 and read 16th and up character.
You could also set up additional tag to your container. But this will cause your web page to not HTML validate.
<div class="person" personid="1">// content</div>
You can do this in your selector:
var buttons = document.getElementsByTagName(svgButtonSelector);
for (i = 0; i > buttons.length; i++) {
$(".button" + index).click(function() {
$(".person" + index + "-profile").fadeIn();
});
}
This will attach the event to every svg button you've got on your page. You just gotta make sure the scope of selection for the buttons is declared right (I'm using document as an example).
I have this script (one of my first) which I have had a bit of help developing:
http://jsfiddle.net/spadez/AYUmk/2/
var addButton =$("#add"),
newResp = $("#resp_input"),
respTextArea = $("#responsibilities"),
respList = $("#resp");
//
function Responsibility(text){
this.text=text;
}
var responsibilities = [];
function render(){
respList.html("");
$.each(responsibilities,function(i,responsibility){
var el = renderResponsibility(responsibilities[i],function(){
responsibilities.splice(i,1);//remove the element
render();//re-render
});
respList.append(el);
});
respTextArea.text(responsibilities.map(function(elem){
return elem.text;//get the text.
}).join("\n"));
}
addButton.click(function(e){
var resp = new Responsibility(newResp.val());
responsibilities.push(resp);
render();
newResp.val("");
});
function renderResponsibility(rep,deleteClick){
var el = $("<li>");
var rem = $("<a>Remove</a>").click(deleteClick);
var cont = $("<span>").text(rep.text+" ");
return el.append(cont).append(rem);
}
Using the top box you can add responsibilities into the text area by typing them into the input box and clicking add. This works perfectly for my first box, but I need this to work for three different boxes and now I'm getting a bit stuck on how to apply this function to all three instances "responsibility, test, test2" without simply duplicating the code three times and changing the variables.
I'm sure this type of thing must come up a lot but I'm not sure if it can be avoid. Hopefully someone with more javascript experience can shed some light on this.
You can e.g. use the scoping of javascript for this:
function Responsibility(text){
/* .... */
}
function setUp(addButton, newResp, respTextArea, respList) {
var responsibilities = [];
function render(){
/* ..... */
}
addButton.click(function(e){
/* ..... */
});
function renderResponsibility(rep,deleteClick){
/* ..... */
}
}
And then for each group you can call:
setUp($("#add"), $("#resp_input"), $("#responsibilities"), $("#resp") );
You need for sure have either different id for each of this fields like #add1, #add2 ...
or you could also group each of this into e.g. a div with a class like .group1 and use class instead of id like .add , .resp_input then you even could reduce the number of parameters you need to pass to the setup to one paramter (only passing the container)
I modified your code to do exactly what you want.
Live Demo http://jsfiddle.net/AYUmk/5/
The trick is to make your responsibilities array a multidimensional array that holds an array for each item (in this case, 3 items).
var responsibilities = [new Array(),new Array(),new Array()];
Then, I updated the add buttons to have a CLASS of add instead of an ID of add. You should never have more than one element with the same ID anyway. Additionally, I added several data items to the buttons. These data items tell the jQuery which array item to use, which textbox to look for, which list to add to, and which text box to add to.
<input type="button" value="Add" class="add" data-destination='responsibilities' data-source='resp_input' data-list='resp' data-index="0">
...
<input type="button" value="Add" class="add" data-destination='test' data-source='tst_input' data-list='tst' data-index="1">
...
<input type="button" value="Add" class="add" data-destination='test2' data-source='tst2_input' data-list='tst2' data-index="2">
Then it was just a matter of changing your click() and render() functions to handle the data and multidimensional array
function render(list, textarea, index){
list.html("");
$.each(responsibilities[index],function(i,responsibility){
var el = renderResponsibility(responsibilities[index][i],function(){
responsibilities[index].splice(i,1);//remove the element
render();//re-render
});
list.append(el);
});
textarea.text(responsibilities[index].map(function(elem){
return elem.text;//get the text.
}).join("\n"));
}
$('.add').click(function(e){
var source = $('#' + $(this).data('source') ).val();
var index = parseInt($(this).data('index'));
var list = $('#' + $(this).data('list') );
var dest = $('#' + $(this).data('destination') );
var resp = new Responsibility(source);
responsibilities[index].push(resp);
render(list, dest, index);
newResp.val("");
});
NOTE: I did not get the removal working, let me know if you require assistance with that as well and I will assist once I reach my office
I would try something like this > http://jsfiddle.net/AYUmk/4/
I would access the items by class instead of ids
$(".class").find("...");
you just need to outscource responsibilities = []; and then it works perfect...
but i wont do the whole worke for you :)