I have a problem: my website is searching for checked checkboxes with a javascript.
$(function () {
var $allELements = $('.input-box');
var $selectedElementsListing = $('#selectedElements');
var $selectedElementsLabel = $('#selectedElementsLabel');
var $elementInfo = $('.elementInfo ');
$allELements.on('click', function () {
$selectedElementsListing .html(
$allELements.filter(':checked').map(function (index, checkbox) {
return '<div>' + checkbox.title + '</div>';
}).get().join('')
);
if ($selectedElementsListing .text().trim().length)
{
$selectedElementsListing .show();
$selectedElementsLabel.show();
$elementInfo.show();
}
});
});
So it is searching for checked checkboxes on my main page and is listing the name of the checkboxes on the lower left hand side (as information for the user).
My HTML looks like this:
<div class="elementInfo" >
<p>
<strong id="selectedElementsLabel" ><u>Ausgewählte
Magazine:</u></strong><br />
<span id="selectedElements"></span>
</p>
</div>
And it takes the checkbox names from this input field:
<input class="input-box" title="[[ElementName]]" type="checkbox" id="A[[ID]]" name="ID[]"
value="[[ID]]" checked="[[checked_element]]" />
When I press reload, the information bar for the selected checkboxes isn't appearing. It is showing the checked checkboxes only if I press again any of them (then it shows all which were also selected)
Every time the page is refreshed the DOM is re-rendered and no state is being stored anywhere. To preserve the state of checked boxes you can use localStorage to store the checked state and then upon page load you can read the localStorage and execute a function that checks them by checking local storage data.
// call this every time someone checks a box
window.localStorage.setItem('some key name of data', 'some data structure with checkbox state')
//Do this every time page is loaded
window.localStorage.getItem('previously used key name')
P.S. I assumed you don't have a backend api calling every time someone checks a box where you are preserving state
for further info do visit
A good read to understand state management
Related
The following gif should show the problem in action.
Typeahead seems to trigger the onChange function before actually setting the value from a click, for who knows what reason.
As you can see whatever is typed into the box is grabbed correctly, but if a user selects an option from the dropdown only what had been typed in up to that point is grabbed, rather than the appropriate behavior which is the value in the text-box.
The TypeAhead JS code looks like
$('#typeahead_id').typeahead({
name: 'typeahead',
remote: 'search.php?key=%QUERY,
limit: 10
});
And the html for the input
<label>Team Name:</label>
<input type='text' id='typeahead_id' onChange='update_params("team",typeahead_id)' class='typeahead tt-query' autocomplete='on' spellcheck='false' placeholder='Select Team'><br>`;
The update Param method
function update_params(val, id) {
let temp = nodes[id]
temp.params[val] = $("#" + val + id).val()
console.log(temp)
}
The oddness of this can be explained in that each of the blue boxes is referred to as a node, and can have their own unique typeahead.
I need a way in that users can type the name of the team into the input or select one from the dropdown and my code should be able to retrieve that value and set it in the appropriate spot.
I am quite new to programming but, eager to learn. I am trying to create an app which keeps tracks of goals (I didn't like the ones I found, so I want to make my own). Anyways, there are checkboxes to be checked and when I open a new tab at a later point, I want the checked boxes to be checked. Here is a little snippet from my code:
<label class="container">Drink 2 liters of water
<input type="checkbox" checked="checked">
<span class="checkmark"></span>
</label>
How can I use the chrome.storage function to remember that I clicked this box?. Thank you for your help!.
At a high level, you'll want to use chrome.storage to save your changes any time a checkbox is clicked - or when a button is clicked.
If you're wanting to save every time the checkbox is clicked, you'll bind a listener to the change event of the checkboxes. Then, call chrome.storage to save.
document.querySelectorAll('input[type="checkbox"]').forEach(elem=>{ //Get all input checkboxes
elem.addEventListener('change',(event)=>{ //Add a change listener
const key = event.target.name; //get the name value from the input element
const value = event.target.checked; // has it been checked?
chrome.storage.local.set({[key]: value}, ()=> { //save it
console.log('Value is set to ' + value);
});
})
})
Saving on button press will be similar. You'll bind a click listener to the button then in the callback, select all of the checkboxes and loop over them to save.
When the page is loaded, you'll need to fetch all of the saved values, and set the check state.
chrome.storage.local.get(['goal1','goal2'],(results)=>{ //Fetch goal1, goal2, goalN... from chrome.storage
//.get returns a keyed object you can loop over.
Object.keys(results).forEach((goal)=>{
//Set the check state of each goal.
document.querySelector(`input[name="${goal}"]`).checked = results[goal];
})
})
I am trying to keep count of how many times the check boxes have been clicked on my site, the check boxes are used for filters (for men, women, age, etc).
At the moment I have this code
jQuery('[id^="checkbox"] input').each(
function (index, element) {
jQuery(this).click(
function () {
console.debug("Hello");
}
);
}
);
Which will count (in console) how many times a check box has been click (with an id starting with checkbox), but because the page refreshes the information (and url) with each click, it will only count the first click, and the rest will not be counted.
Is there anyway to carry on counting after the page has been refreshed?
Thanks
To have a persistent count of all checkboxes being checked across all users, you need to have a central total which all counts update. This will be quite tricky for even large sites like YouTube still struggle with this (although to a lesser extent).
I am unaware that this can be accomplished purely in JS (if anyone knows, please edit this answer) and you will likely need some sort of back-end code.
One approach you could take would be:
update a local total of checked checkboxes on click
set a timer of 1/2 seconds on click
once the timer ends, send an ajax request to a back-end page
back-end page receives the update, update the central total
There are many other approaches you could take. You're likely to run into issues like, the central total might not be very accurate (if ajax requests are interrupted) and your bandwidth usage increasing due to the ajax requests.
Gennady Dogaev shared some really good code which posts the id of the checkbox and it's value to another page. This page would likely have the logic to update a database or something similar to track which checkboxes are being used.
<body>
<input type="checkbox" id="check_1" /> 1
<input type="checkbox" id="check_2" /> 2
<input type="checkbox" id="check_3" /> 3
</body>
$(function(){
$("input[type=checkbox]").click(function(){
var box = $(this);
var data = {
id: box.prop('id'),
checked: box.is(':checked')
};
$.get('https://stackoverflow.com/', data).always(function(response){
console.log('server responded', response);
/*Click registered, do what you want here*/
});
});
});
https://jsfiddle.net/nrLpxLuf/
The below answer was to help count all checked checkboxes on the page and update the total locally. I've left it here for reference.
You don't need to loop over all elements to attach a single click event to all of them.
Instead attach a click event to a collection of checkboxes and then update a total variable from within the click function.
var $inputs = $('[id^="checkbox"] input');
var total = $inputs.filter(':checked').length; //this will be 0 if none are found
$inputs.on('click', function(event) {
if($(this).is(':checked')) {
total++;
} else {
total--;
}
console.log(total);
});
If you only want to see if it has been clicked, just add to the total.
You need to set value on load if you want to count the checked after refresh.
var total = 0;
$(document).ready(function (event) {
//onload count for the checked checkboxes and set total value
total = $('[id^="checkbox"] input:checked').length;
$('[id^="checkbox"] input').on('click', function (event) {
$(this).prop('checked') ? total++ :total--;
});
});
So basically what I'm trying to do as a measure of security (and a learning process) is to my own "Capthca" system. What happens is I have twenty "label's" (only one shown below for brevity), each with an ID between 1 and 20. My javascript randomly picks one of these ID's and makes that picture show up as the security code. Each label has its own value which corresponds to the text of the captcha image.
Also, I have the submit button initially disabled.
What I need help with is figuring out how to enable the submit button once someone types in the proper value that matches the value listed in the HTML label element.
I've posted the user input value and the ID's value and even when they match the javascript won't enable the submit button.
I feel like this is a really really simple addition/fix. Help would be much much appreciated!!!
HTML code
<div class="security">
<label class="captcha enabled" id="1" value="324n48nv"><img src="images/security/1.png"></label>
</div>
<div id="contact-div-captcha-input" class="contact-div" >
<input class="field" name="human" placeholder="Decrypt the image text here">
</div>
<input id="submit" type="submit" name="submit" value="Send the form" disabled>
Javascript code
//Picks random image
function pictureSelector() {
var number = (Math.round(Math.random() * 20));
//Prevents zero from being randomly selected which would return an error
if (number === 0) {
number = 1;
};
console.log(number);
//Set the ID variable to select which image gets enabled
pictureID = ("#" + number);
//If the siblings have a class of enabled, remove it
$(pictureID).siblings().removeClass("enabled");
//Add the disabled class to all of the sibling elements so that just the selected ID image is showing
$(pictureID).siblings().addClass("disabled");
//Remove the disabled class from the selected ID
$(pictureID).removeClass("disabled");
//Add the enabled class to the selected ID
$(pictureID).addClass("enabled");
};
//Calls the pictureSelector function
pictureSelector();
//Gets the value of the picture value
var pictureValue = $(pictureID).attr("value");
console.log(pictureValue);
//Gets the value of the security input box as the user presses the keys and stores it as the variable inputValue
$("#contact-div-captcha-input input").keyup(function(){
var inputValue = $("#contact-div-captcha-input input").val();
console.log(inputValue);
});
console.log($("#contact-div-captcha-input input").val());
//Checks to see if the two values match
function equalCheck() {
//If they match, remove the disabled attribute from the submit button
if ($(pictureValue) == $("#contact-div-captcha-input input").val()) {
$("#submit").removeAttr("disabled");
}
};
equalCheck();
UPDATE
Fiddle here
UPDATE #2
$("#contact-div-captcha-input input").keyup(function(){
var inputValue = $("#contact-div-captcha-input input").val();
console.log(inputValue);
if (pictureValue === inputValue) {
$("#inputsubmit").removeAttr("disabled");
}
});
So I got it working 99.9%, now the only problem is that if someone were to backspace or delete the correct value they have inputted, the submit button does not then change back to disabled. Any pointers?
Known issue.
Give your button a name OTHER THAN submit. That name interferes with the form's submit.
EDIT
A link was requested for this -- I don't have a link for pure JavaScript, but the jQuery docs do mention this issue:
http://api.jquery.com/submit/
Forms and their child elements should not use input names or ids that
conflict with properties of a form, such as submit, length, or method.
Name conflicts can cause confusing failures. For a complete list of
rules and to check your markup for these problems, see DOMLint.
EDIT 2
http://jsfiddle.net/m55asd0v/
You had the CSS and JavaScript sections reversed. That code never ran in JSFiddle.
You never re-called equalCheck. I added a call to your keyUp handler.
For some reason you wrapped pictureValue inside a jQuery object as $(pictureValue) which couldn't have possibly done what you wanted.
Basic debugging 101:
A console.log inside of your equalCheck would have shown you that function was only called once.
A console log checking the values you were comparing would have shown
that you had the wrong value.
Basic attention to the weird highlighting inside of JSFiddle would have shown you had the code sections in the wrong categories.
Tried to solve this multiple ways. 1. by simply adding the normal html "checked" default option to radio buttons in my form and 2. having js functions do it, being the gist of the ideas tried.
The issue: I'm finding that no matter how I do it, if the radio is designated as checked by default (before the user makes his/her choice), anything done after that will not be saved correctly (if at all) in localStorage. localStorage WILL save the initial default selections, however but, nothing can be changed from then on (even after "physically" selecting another option).
I know localStorage is working because if I leave off the default designation (and for the rest of the inputs) it functions perfectly.
The form code:
<label>Who is the contact person for this event?<span class="requiredtext">*</span></label>
<input type="radio" name="Contact_Person" id="Contact_Person1" value="Submitter is the contact person" onclick="contacthide()" checked required> I am<br />
<input type="radio" name="Contact_Person" id="Contact_Person2" value="Submitter is not the contact person" onclick="contactshow()" required>
The localStorage save code:
function localStoragefunctions() {
localStorage.clear();
if (Modernizr.localstorage) {
//Set variable to show that data is saved
localStorage.setItem("flag", "set");
//Save radio and checkbox data
$(window).bind('unload', function() {
$('input[type=radio]').each(function() {
localStorage.setItem('radio_' + $(this).attr('id'), JSON.stringify({
checked: this.checked
}));
});
});
The code that spits it back out if the user goes back to make changes before final submission:
$(document).ready(function() {
if (Modernizr.localstorage) {
//Browser supports it
if (localStorage.getItem("flag") == "set") {
$('input[type=radio]').each(function() {
var state = JSON.parse(localStorage.getItem('radio_' + $(this).attr('id')));
if (state) this.checked = state.checked;
});
Other than this, I have a confirmation page that grabs all of the variables stored in localStorage and presents them to the user for final inspection before they hit submit for good.
That consists of: var ContactPerson = localStorage.getItem('Contact_Person'); and then a document.write that spits out html and the variable's value. Again, this works fine if I don't try to set default radio choices (and works great for all other input types).
The ideal outcome would be choosing the most likely radio button choices by default so that it could possibly save the user time. I'd like to not have to present them with a form where they have to physically click each radio button if I can "make that decision for them" before hand.
Hope this all makes sense!
I know this an old question, but I've been troubleshooting a similar issue and thought I'd share my solution.
When you set your localStorage item, you are saving both radio inputs and their values, b/c your using the ID attribute as your key.
localStorage.setItem('radio_' + $(this).attr('id'), JSON.stringify({ checked: this.checked }));
This could be ok, but I've taken a different approach. And, I maybe missing something, so comments are welcome.
Instead, I use $(this).attr('name') to set the key. As a result, when either radio button in selected, you are saving the value to the same localStorage key.
In my scenario, I'm storing many inputs to localStorage, so my solution is a bit abstract. I'm calling saveToLocalStorage() using jQuery's .change() method on each input. Also, I'm saving the input's value directly to localStorage.
function saveToLocalStorage(input) {
if ( $(input).attr('type')=='radio' ) {
localStorage[$(input).attr('name')] = $(input).val();
} else {
localStorage[$(input).attr('id')] = $(input).val();
}
}
When retrieving from localStorage, I had to check if the localStorage key:value pair matched the radio input before selecting it. Otherwise, I was selecting both radio inputs. Note, in my scenario, I'm working with jQuery 1.4.4, hence the attr('checked', 'checked').
$('input[type=radio]').each(function() {
var key = $(this).attr('name');
var val = localStorage[key];
if ( $(this).attr('name') == key && $(this).attr('value') == val ) {
$(this).attr('checked', 'checked');
}
});