I have a checkbox and i want the user to choose at maximum 3. I can't figure out how to do this.
artificial intelligence <input type = "checkbox" name = "topic[]" value = "29" >
computer graphics <input type = "checkbox" name = "topic[]" value = "30" >
computer animation <input type = "checkbox" name = "topic[]" value = "31" >
software engineering <input type = "checkbox" name = "topic[]" value = "32" >
Have you thought about how the UI would handle this? Here is one approach using jQuery:
// adjust this to be all checkboxes in the group
var theCheckboxes = $("input[type='checkbox']");
theCheckboxes.click(function()
{
if (theCheckboxes.filter(":checked").length > 3)
$(this).removeAttr("checked");
});
http://jsfiddle.net/jyYu5/
This prevents a check after three are marked, but does not visually disable the fields. So that's something additional to consider.
Also, you still have to check on the server side that only three were marked, because the user can obviously submit whatever data he wants.
You can do this with jQuery really easily. Probably a bit harder with straight javascript, but not to much.
Load jQuery, and write a function to execute on click of a checkbox. In that function is an if statement asking two things, it the button currently unchecked and are there more than x number of buttons checked currently. If both are true, then prevent default.
Here's what it should look like:
<input class="checkbox"></input>
$('.checkbox').click(function(){
if ($(this:not(:checked)) && $(".checkbox:checked").length >= 3) {
event.preventDefault()
}
});
That should prevent checking more then 3 check boxes.
well obviously you want some client side validation.... use javascript....
there are several ways to do it...
like plain javascript you can do something like
<script>
var predefined_limit = 3;
document.getElementByTagName('input').onchange = doSomething
function doSomething(){
var counter=0;
var elem = document.getElementByTagName('input');
for(var i=0; i<elem.length; i++)
if(elem.type=='checkbox' && elem.checked == true)
counter ++;
if(counter > predefined_limit){
this.checked = false;
alert('You can check only '+ predefined_limit + 'checkboxes')
}
}
</script>
then you can also use jQuery or other javascript frameworks like the other answer suggests
With jQuery, you can count checked checkboxes like that :
//Count number of checkboxes
$('input[name="type[]"]').on('click', function() {
var nbcheck = $('input[name="type[]"]:checked').length;
if(nbcheck > 2) {
console.log('FORBIDEN!!!!');
//Do stuffs you want -->
}
});
Related
I have a list of songs. I'm trying to determine whether or not a song on the list has been checked or not. If so I need to know the value of the checkbox.
my html looks like this... the value $song_id is pulled from the list in the database.
<input type='checkbox' name='song[]' value='$song_id' />
There could be 10 songs... there could 100.
I need to know which ones have been checked and how to get the value.
On click save item ID of item to array; (js)
On click search was such ID already checked; (in array)
ADDED
You should use jQuery (or raw javascript) to do logic you want. jQuery is http://jquery.com/ using it you can do you want on front-end. Do this on back-end is bad idea.
Once you submit the form the $_POST['song'] variable will contain an array of all the $song_id's that were selected.
You can do something like this:
<input type='checkbox' name='song[]' class='songItem' value='$song_id' />
<input type='hidden' id='selectSongsHidden' />
In JavaScript,
var selectedSongValues = [];
var selectedSongsString = ""; // for comma-separated values
function GetSelectedSongs()
{
var songs = $('.songItem');
var selectedSongs = [];
for(var i=0; i<songs.length; i++)
{
var checked = $(songs[i]).is(':checked');
if(checked)
{
selectedSongs.push(songs[i]);
}
}
for(var j=0; j<selectedSongs.length; j++)
{
selectedSongValues.push($(selectedSongs[j]).val());
selectedSongsString += $(selectedSongs[j]).val() + ",";
}
$('#selectSongsHidden').val(selectedSongsString);
}
When you press submit, in the onclick event you can call this function and set the value to a hidden field.
You can see this in a working http://jsfiddle.net/A3e3y
foreach ( $_POST['song'] AS $song_id ) {
// do smth with $song_id ...
}
I have a page which is paginated to 100 results per page by php with checkboxes beside each. I have three functions: one to select all, one to save what was checked, and one to restore what was checked.
I don't understand why my toggle function does not work with the other two.
If I click select all (which performs a toggle()) the checked values are not saved;
however, if I click them by hand they do get saved across pagination.
I am assuming that I have to do something along the lines of persistCheckBox(checkboxes[i].checked) to the last line of my toggle function --which I tried and it did not work; Can someone explain why?
function toggle(source) {
checkboxes = document.getElementsByName('multi_mag[]');
for (var i = 0, n = checkboxes.length; i < n; i++) {
checkboxes[i].checked = source.checked;
}
}
function restorePersistedCheckBoxes() {
var aStatus = getPersistedCheckStatus();
for (var i = 0; i < aStatus.length; i++) {
var aPair = aStatus[i].split(':');
var el = document.getElementById(aPair[0]);
if (el) {
el.checked = aPair[1] == '1';
}
}
}
function persistCheckBox(el) {
var found = false;
var currentStateFragment = el.id + ':' + (el.checked ? '1' : '0');
var aStatus = getPersistedCheckStatus();
for (var i = 0; i < aStatus.length; i++) {
var aPair = aStatus[i].split(':');
if (aPair[0] == el.id) {
// State for this checkbox was already present; replace it
aStatus[i] = currentStateFragment;
found = true;
break;
}
}
if (!found) {
// State for this checkbox wasn't present; add it
aStatus.push(currentStateFragment);
}
// Now that the array has our info stored, persist it
setPersistedCheckStatus(aStatus);
}
Neither the click nor the change events are triggered when changing the checked value programmatically.
Since you tagged your question with jQuery, I will demonstrate using some jQuery code.
It is unclear from your code how you do your persistent storage or what is your HTML structure, so the code will show a general approach.
A word of advice, though: I strongly suggest that you remove styling code out of the structure and use CSS and avoid inline event handling. Pretty much everything that you want to accomplished can be done more cleanly from outside the HTML.
I will be suing a form with several checkboxes, the first of which will change the other checkboxes' state.
HTML:
<form id="boxes">
<input type="checkbox" id="all" name="all" />
<input type="checkbox" name="multi_mag[]" class="normal" />
...
<input type="checkbox" name="multi_mag[]" class="normal" />
</form>
Javascript:
In this example, all of the 'normal' checkboxes have some common property (in this case, I decided on a class), that allow event delegation.
$('#boxes').delegate('.normal', 'change', function (e) {
console.log('changed', e.target.checked);
});
This code sets a function to run every time a checkbox changes, corresponding to your persistCheckBox() method.
Next, the equivalent of your toggle() function:
$('#all').change(function (e) {
var checked = e.target.checked;
console.log('changed checkall box: ', checked);
checkboxes = document.getElementsByName('multi_mag[]');
for (var i = 0, n = checkboxes.length; i < n; i++) {
checkboxes[i].checked = checked;
$(checkboxes[i]).change();
}
});
It is executed whenever the "main" checbox changes its state. All of the checkboxes are iterated, their values are changed and the change event is triggered, which causes each to run the aforementioned function.
You can apply this method to your (cleaned) code, and the persistence should be maintained.
Example jsFiddle (check your console for the activity log).
This little piece of code can check / uncheck a checkbox, and will trigger any associated events.
$('input[type=checkbox]').trigger('click');
It could help maybe
I fixed this by adding I fixed this by adding "persistCheckBox(checkboxes[i]);" to the last line of the toggle() function. #MasterAM I appreciate your critiques and will be using them to optimize my code. I also appreciate the JQuery solution you provided.
I have couple of input field and values in them. This is projected to the user.
The user can modify these values and submit them.
When submitted, I need to check which input field is modified.
I can compare the previous fields and current fields and check. But I am trying to find more optimized way to do this.
I can use javascript, php, jquery and html tricks
<input id="input1" value="someValue" type="text">
<input id="input2" value="someValue" type="text">
Script:
$('input').on('change',function(){
var id = $(this).attr('id');
alert("input field is modified : ID = " + id);
});
You can create 2 different input, 1 hidden with a class like originalVal and 1 visible for every input.
Then on submit you do something like that :
$('input').each(function(){
var currentVal = $(this).val();
var originalVal = $(this).closest('.originalVal').val()
if(currentVal != originalVal){
//This input has changed
}
})
Since no code was given, you could compare what was in the input compared to what is now in it.
HTML Input:
<input type="text" id="testInput" value="DB Value"/>
jQuery
var modifiedInputs = [];
var oldVal = "";
$("#testInput").focus(function() {
oldVal = this.value;
}).blur(function() {
console.log("Old value: " + oldVal + ". New value: " + this.value);
//If different value, add to array:
if (this.value != oldVal) {
modifiedInputs.push(this.id);
}
});
Fiddle: http://jsfiddle.net/tymeJV/tfmVk/1/
Edit: Took it a step further, on modification of an input, if the changed value is different from the original, it pushes the elements ID to the array.
I would say your best bet would be to get the initial values from the input fields, and then compare them later on. Then, just do a comparison once the submit button is clicked. For instance, put this somewhere in your $(document).ready() that way it will retrieve the initial value.
var oldValue=[];
$('input').each(function(){
oldValue.push($(this).val());
});
Then you can compare later on when you hit the submit.
you could compare with default value like this
for(var i in formObj)
if('value' in formObj[i] && formObj[i].value!=formObj[i].defaultValue){
//do what ever here ...
}
I have dynamically created an array of checkboxes in PHP for a form, but I don't want the Submit button to appear unless at least one checkbox is checked. Scouring the Internet most people who want the Submit button to only appear after checking a checkbox only have one "I agree" checkbox. Is it the dynamic creation that is preventing my script working?
PHP↴
// Dynamically create checkboxes from database
function print_checkbox($db){
$i = 0;
foreach($db->query('SELECT * FROM hue_flag') as $row) {
if ($i == 0 || $i == 3 || $i== 6 || $i == 9){
echo '<br><br>';
}
$i++;
echo '<span class="'.$row['1'].'"><label for="'.$row['1'].'">'.ucfirst($row['1']).'</label><input type="checkbox" name="hue[]" id="hue" value="'.$row['0'].'"></span> ';
}
}
jQuery↴
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function(){
$('#hue[]').click(function(){
$('#input_gown').toggle();
});
});
</script>
PHP function call↴
<?php print_checkbox($conn_normas_boudoir);?>
Admittedly I know nothing about jQuery or JavaScript and am still learning PHP. So, if there's a better way to implement this, let me know.
You're giving all your checkboxes the same ID. That's not allowed; IDs have to be unique.
An easy solution to both problems is to assign all the checkboxes a common class:
echo '<span class="'.$row['1'].'"><label for="'.$row['1'].'">'.ucfirst($row['1']).'</label><input type="checkbox" name="hue[]" class="hue" value="'.$row['0'].'"></span> ';
Then select the class in jQuery:
$('.hue').change(function(){
$('#input_gown').toggle();
});
But that may give unexpected results; what if two checkboxes are checked? The #input_gown element will toggle on and off again. Perhaps you only want it shown if at least one checkbox is checked:
$('.hue').change(function(){
var val = false;
$('.hue').each(function() {
val = val || $(this).is(':checked'); // any checked box will change val to true
});
$('#input_gown').toggle(val); // true=show, false=hide
});
http://jsfiddle.net/mblase75/AyY3Z/
Your jQuery selector is looking for elements with id hue[]. But your elements have the id of just hue.
Change this:↴
$(document).ready(function(){
$('#hue[]').click(function(){
$('#input_gown').toggle();
});
});
to this (IDs should really always be unique, and the square brackets will need to be escaped to work with the selector engine), (a demo)):↴
$(document).ready(function(){
$('input[name=hue\\[\\]]').click(function(){
$('#input_gown').toggle();
});
});
I'm looking to create a simple jquery game.
It starts like this, the user enters a number in a text field.
<form>
<input type="text" id="MyNumber" value="" />
<button id="getit">Play</button>
</form>
<div id="randomnumber"></div>
After the click the play button, a series of numbers will appear in the div id randomnumber.
The objective is to click on the randomly rotating numbers in the div id randomnumber when they see the number they intered in the my number text field. If they click their number, they win.
The jquery script I have requires a button be pushed to generate the number, (I don't want a button pushed each time a new number should be generated.) The script also doesn't identify the number that was clicked, or send it to my checknumber.php page so I can store the number entered and the number picked in a database.
Any help?
this is the jquery script I have.
function IsNumeric(n){
return !isNaN(n);
}
$(function(){
$("#getit").click(function() {
var numLow = $("#lownumber").val();
var numHigh = $("#highnumber").val();
var adjustedHigh = (parseFloat(numHigh) - parseFloat(numLow)) + 1;
var numRand = Math.floor(Math.random()*adjustedHigh) + parseFloat(numLow);
if (IsNumeric(numLow)
&& IsNumeric(numHigh)
&& (parseFloat(numLow) <= parseFloat(numHigh))
&& (numLow != '')
&& (numHigh != ''))
{
$("#randomnumber").text(numRand);
} else {
$("#randomnumber").text("Careful now...");
}
return false;
});
$("input[type=text]").each(function(){
$(this).data("first-click", true);
});
$("input[type=text]").focus(function(){
if ($(this).data("first-click")) {
$(this).val("");
$(this).data("first-click", false);
$(this).css("color", "black");
}
});
});
The "Play" button is good to start the ball rolling (I'm not certain if you were thinking of removing it entirely). To generate numbers periodically, use setInterval.
$(function(){
var initialPeriod=500; // 0.5s
var generateNumIval;
function generateNum() {
var numLow = $("#lownumber").val();
var numHigh = $("#highnumber").val();
var adjustedHigh = (parseFloat(numHigh) - parseFloat(numLow)) + 1;
var numRand = Math.floor(Math.random()*adjustedHigh) + parseFloat(numLow);
if (IsNumeric(numLow)
&& IsNumeric(numHigh)
&& (parseFloat(numLow) <= parseFloat(numHigh))
&& (numLow != '')
&& (numHigh != ''))
{
$("#randomnumber").text(numRand);
} else {
$("#randomnumber").text("Careful now...");
}
}
function run(period) {
clearInterval(generateNumIval);
generateNumIval = setInterval(generateNum, period);
}
$("#getit").click(function() {
run(initialPeriod);
return false;
});
...
You can change the period (such as to increase the difficulty when the user clicks the correct number, or decreasing the difficulty when the user makes too many sequential mistakes) by calling run with a new period. If you want to change the period after generating each number, use setTimeout rather than setInterval.
To check a click on a number, register a click handler on #randomnumber that compares its val() to #MyNumber's val(). From there, take appropriate action as to whether it's a hit or miss. As Dan says, doing this for every click will create quite a bit of network traffic. Though only a small amount of data may be transmitted each time, the number of connections can cause a significant impact. Instead, have a "Stop" button and send the data if the user clicks it, or use an unload handler (one does not exclude the other).
Your server will crash and burn if you have more than a couple people playing this game. People can identify and click very fast (multiple times per second), but unless they live next to your server, you can't receive and respond to HTTP requests that fast, nor can your server handle hundreds or more per second from the multiple users.
Write the game in JavaScript and when they're done, send the totals (# of wrong clicks and # of right clicks, or whatever) to your server to save. Do your best to obfuscate how they're sent so that it's not trivial to make up scores.
There's a couple of things to look out for here. There's no reason why the random numbers can't be generated from the number the player has entered himself, or even better, a number generated by the game itself.
The way which you've done the placeholder text, using data and two event handlers is also somewhat messy. At a minimum you should be using .one to attach a one-time event handler for this, but it would be much better if you use the HTML5 placeholder attribute with a Javascript fallback.
Other than that, you're still missing significant amount of game logic in there. I won't advice you to work on this game for too long though - it's great as an exercise in working with JavaScript and jQuery, but otherwise not very worthwhile.
Oh, and just for fun, I also built my own version of this.
var hitCount = 0,
missCount = 0;
function IsNumeric(n) {
return !isNaN(n);
}
$("#getit").click(function() {
var li = [],
intervals = 0,
n = parseInt($('#MyNumber').val());
if (IsNumeric(n)) {
setInterval(function() {
li[intervals++ % li.length].text(Math.random() > .1 ? Math.floor(Math.random() * (10 + n) + (n / 2)) : n).attr('class', '');
}, 500);
}
$('#randomnumber').empty();
for (var i = 0; i < 5; i++) {
li.push($('<li />').click(function() {
var $this = $(this);
if (!$this.hasClass('clicked')) {
if (parseInt($this.text(), 10) === n) {
$this.addClass('correct');
$('#hitcount').text(++hitCount);
} else {
$this.addClass('wrong');
$('#misscount').text(++missCount);
}
}
$this.addClass('clicked');
}).appendTo('#randomnumber'));
}
return false;
});
Crude yes, but it sort of works. Have a look at it here: http://jsfiddle.net/DHPQT/
For fun..
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
var mainLoop;
$(function(){
$("#getit").click(function() {
if ($(this).attr('class') == 'start') {
$(this).attr('class','play');
$(this).html('STOP THE MADNESS!');
mainLoop = window.setInterval(function() {
var output = '';
for (var i = 0; i < 10; i++) {
var numLow = $("#lownumber").val();
var numHigh = $("#highnumber").val();
var adjustedHigh = (parseFloat(numHigh) - parseFloat(numLow)) + 1;
var numRand = Math.floor(Math.random()*adjustedHigh) + parseFloat(numLow);
output += '<div>'+numRand+'</div>';
}
$('#randomnumbers').html(output);
},250);
} else {
window.clearInterval(mainLoop);
var sweetWin = false;
$('#randomnumbers').children().each(function() {
var v = $(this).html();
if (v == $('#MyNumber').val()) {
alert('WIN!');
sweetWin = true;
$.post('127.0.0.1',{outcome:'win'});
}
});
if (!sweetWin) {
alert('FAIL!');
$.post('127.0.0.1',{outcome:'loss'});
}
$(this).attr('class','start');
$(this).html('Play');
}
});
});
</script>
</head>
<body>
Low: <input type="text" id="lownumber" value="0" />
High: <input type="text" id="highnumber" value="100" />
<input type="text" id="MyNumber" value="50" />
<button id="getit" class="start">Play</button>
<div id="randomnumbers"></div>
</body>
</html>