I'm trying to use jQuery to filter through some product search results.
There are various types of filters one could use to dig through the results (color, type, size, etc) and I would like to make it impossible to end up with "no results" through the filters by hiding the ones that do not have any content as filters are engaged.
I suppose another way of phrasing my question would be that I'm trying to verify what filters should exist before allowing the user to activate them.
For example in the sample code, if #brnd_B was selected and no products contained .prdbx.brnd_B.ptype_C, then #ptype_C should be disabled so the user cannot select it.
The #col_Red option should be disabled once any of the filters are engaged since it doesn't exist within the products list. #cat_C sould be disabled for the same reason.
Then the appropriate .prdbx boxes should display after filtering, obviously.
Sample Code:
<h1>Brands</h1>
<input type="radio" class="bFilter filterSwitch" name="bFilter" id="brnd_A">
<input type="radio" class="bFilter filterSwitch" name="bFilter" id="brnd_B">
<input type="radio" class="bFilter filterSwitch" name="bFilter" id="brnd_C">
<h1>Types</h1>
<input type="radio" class="pTypeFilter filterSwitch" name="pTypeFilter" id="ptype_A">
<input type="radio" class="pTypeFilter filterSwitch" name="pTypeFilter" id="ptype_B">
<input type="radio" class="pTypeFilter filterSwitch" name="pTypeFilter" id="ptype_C">
<h1>Options</h1>
<input type="radio" class="bTypeFilter filterSwitch" name="bTypeFilter" id="cat_A">
<input type="radio" class="bTypeFilter filterSwitch" name="bTypeFilter" id="cat_B">
<input type="radio" class="bTypeFilter filterSwitch" name="bTypeFilter" id="cat_C">
<h1>Colors</h1>
<input type="radio" class="cTypeFilter filterSwitch" name="cTypeFilter" id="col_Black">
<input type="radio" class="cTypeFilter filterSwitch" name="cTypeFilter" id="col_Blue">
<input type="radio" class="cTypeFilter filterSwitch" name="cTypeFilter" id="col_Red">
<h1>Products</h1>
<div class="prdbx show brnd_A cat_B ptype_C col_Black yld_Standard mod_PIXMAiP4820 mod_PIXMAiX6520 mod_PIXMAiX6550">Data 1</div>
<div class="prdbx show brnd_B cat_A ptype_A col_Blue yld_Standard mod_PIXMAiX6520">Data 2</div>
<div class="prdbx show brnd_A cat_A ptype_B col_Black yld_Standard mod_PIXMAiP4820">Data 3</div>
This is the jQuery I have so far; it's displaying the appropriate .prdbx's for the most part, but it never "verifies the radio button should be allowed" before displaying them, which is what I'm struggling with.
If I make the sep variable a comma, I get mixed results, as well.
Any help would be greatly appreciated.
$('.filterSwitch').click(function(e) {
$('.brandbx').hide();
$('.prdbx').hide(); // hide all products
// set up variables
thisFilter1 = "";
var sep = ""
// hide inapplicable filters
// figure out what we're displaying
$('input[name=bFilter]:checked').each(function(e) {
thisFilter1 = thisFilter1 + sep + '.'+this.id;
});
$('input[name=bTypeFilter]:checked').each(function(e) {
thisFilter1 = thisFilter1 + sep + '.'+this.id;
});
$('input[name=pTypeFilter]:checked').each(function(e) {
thisFilter1 = thisFilter1 + sep + '.'+this.id;
});
$('.cTypeFilter').each(function(e) {
thisFilter1 = thisFilter1 + sep + '.'+this.id;
});
$(thisFilter1).show();
verifyEmpty();
});
function verifyEmpty(){
var totalFilter = 0;
$('input[name=bFilter]:checked').each(function(e) {
totalFilter++;
});
$('.cTypeFilter:checked').each(function(e) {
totalFilter++;
});
$('.pTypeFilter:checked').each(function(e) {
totalFilter++;
});
$('.bTypeFilter:checked').each(function(e) {
totalFilter++;
});
if(totalFilter == 0){
$('.prdbx').show(); // show all products
$('.brandbx').show(); // show models
}
}
You can try following code
$('.filterSwitch').each(function(){
if($("."+this.id).length<=0)
this.disabled=true;
});
This is considering that even if one radio button is selected and others are blank it should filter the values(as your code works now).
If its not the case & you want all the radio buttons to be selected before filtering then the code will be different.
Related
I am trying to check if a radio button is selected or not. If the "morn_before" radiobutton is selected, the data will be stored as "2", but if the "morn_after" radiobutton is selected instead, the data will be stored as "1".
Currently my code show below is not working. For example when i select the "morn_before" radiobutton, it doesnt print "morn_before checked true" in the console, despite me putting console.log("morn_before checked true") in that if statement.
HTML:
<div class="radiobutton">
<input type="radio" id="morn_before" name="morn_time" value="morn_before">
<label for="morn_before">Before Food</label><br>
<input type="radio" id="morn_after" name="morn_time" value="morn_after">
<label for="morn_after">After Food</label><br><br>
</div>
Javascript:
function check() {
let user=firebase.
auth().currentUser;
let uid;
if(user!=null){
uid=user.uid;
}
var firebaseRef = firebase.database().ref();
if(document.getElementById("morn_before").checked){
console.log("morn_before checked true");
firebase.database().ref(uid).child('/radiobutton/').child('/morn_time/').set("2");
}
else if(document.getElementById("morn_after").checked){
firebase.database().ref(uid).child('/radiobutton/').child('/morn_time/').set("1");
}
}
check();
You don't need any JavaScript for this. You can have a completely different display than the stored value.
<div class="radiobutton">
<input type="radio" id="morn_before" name="morn_time" value="2">
<label for="morn_before">Before Food</label><br>
<input type="radio" id="morn_after" name="morn_time" value="1">
<label for="morn_after">After Food</label><br><br>
</div>
Should produce the same result. The only improvement would be to set one of these to default true, in case the user chose neither. But that'd be up to you.
ADDITIONAL INFO: You are not supposed to read a radio button group that way.
You should go over some basics of HTML INPUT tag such as
https://www.geeksforgeeks.org/how-to-get-value-of-selected-radio-button-using-javascript/
Is this a good solution to check multiple radio buttons with 1 label? I have a form with multiple steps. The last step shows a summary about the previous steps and I need to get all data from there. Is there a better option? How can I get the text from the input fields and insert it to the summary? JavaScript?
$('label').click(function() {
id = this.id.split('-');
if (id[0] === '1') {
id[0] = '2';
} else {
id[0] = '1';
}
$('#' + id[0] + '-' + id[1]).prop('checked', true);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="one">
<input type="radio" id="1-1" name="1-level">
<label for="1-1" id="1-1">1</label>
<input type="radio" id="1-2" name="1-level">
<label for="1-2" id="1-2">2</label>
</div>
<div class="two">
<input type="radio" id="2-1" name="2-level">
<label for="2-1" id="2-1">1</label>
<input type="radio" id="2-2" name="2-level">
<label for="2-2" id="2-2">2</label>
</div>
Add a form element to wrap your input elements in. Forms can access all the inputs that are inside of it and see their names and their values. So in this case it is important that you use the value attribute on your input elements. Start by doing the above and make your code look like the example below.
Also, be careful with id's. They need to be unique, so they can only appear once in every document. Right now the label and their input elements have the same id.
<form id="step-form">
<div class="one">
...
</div>
</form>
Like #Shilly suggested, use the FormData API. This API is designed to get all the values from a form, think input, textarea and select elements and puts all of that data into a single object. This way you can create as many form-elements as you want, add them to the form and store their values in a single object.
The data in that object will be read as key-value pairs, which in this case are the name and value attribute values. For example: ['1-level', '2'], here we see the input with the name '1-level' and the value '2'.
I would not recommend using other input elements to show your results or summary. This could be confusing for the user as it suggests input. Instead print your results in plain text or create a list.
I do not know the jQuery equivalent of many of these API's or methods, so I've used Vanilla JavaScript to create a demo which, hopefully, demonstrates what you try to accomplish.
If you have any question, I've been unclear, or have not helped you in any way. Please let me know.
const form = document.getElementById('step-form');
const summary = document.getElementById('step-summary');
const clear = document.getElementById('step-clear');
// Remove all children of the summary list.
function clearSummary() {
while(summary.firstElementChild) {
summary.firstElementChild.remove();
}
}
// Clear list on click.
clear.addEventListener('click', event => {
clearSummary();
});
form.addEventListener('submit', event => {
// Clear list first.
clearSummary();
// Create a fragment to store the list items in.
// Get the data from the form.
const fragment = new DocumentFragment();
const formData = new FormData(event.target);
// Turn each entry into a list item which display
// the name of the input and its value.
// Add each list item to the fragment.
for (const [ name, value ] of formData) {
const listItem = document.createElement('li');
listItem.textContent = `${name}: ${value}`;
fragment.appendChild(listItem);
}
// Add all list items to the summary.
summary.appendChild(fragment);
event.preventDefault();
});
<form id="step-form">
<div class="one">
<input type="radio" id="1-1" name="1-level" value="1">
<label for="1-1">1</label>
<input type="radio" id="1-2" name="1-level" value="2">
<label for="1-2">2</label>
</div>
<div class="two">
<input type="radio" id="2-1" name="2-level" value="1">
<label for="2-1">1</label>
<input type="radio" id="2-2" name="2-level" value="2">
<label for="2-2">2</label>
</div>
<div class="three">
<input type="radio" id="3-1" name="3-level" value="1">
<label for="3-1">1</label>
<input type="radio" id="3-2" name="3-level" value="2">
<label for="3-2">2</label>
</div>
<ul id="step-summary"></ul>
<button type="submit">Review form</button>
<button type="button" id="step-clear">Clear summary</button>
</form>
I admit, still a noobie at jquery and I have a page with a total of 12 buttons / toggles (only 3 is shown as example) , which when clicked each one will pull up a php page with it set of checkboxes listed with products within a div on the advance search page. Since there are alot of information between each checkbox list, it slows the system down so I had to create an event when clicked it pulls that checkbox information when needed from another php page. Problem is... the checkboxes won't stay check when I toggle between the buttons. I have tried to a fuction where it sets the localstorage item when checked but doesn't seem to work. In so, need you help on how to make the checkboxes stay checked when going back to through each button / toggle.
So is there a way that will keep my checkboxes checked when toggleing? And How (please use code examples)
Is there a better way I could do to make this work more efficiently, so it will load the page faster? If so, How? (please use code examples)
KITE_PAGE.PHP (works the same for ball, hula hoop and other products)
<div>
<input type="checkbox" class="product_chkKite101" name="product_chk" value=" Like Kite 101 " /><label >Like USA Kite</label>
<input type="checkbox" class="product_chkKite102" name="product_chk" value=" Like Kite 102 " /><label >Like Mexico Kite</label>
<input type="checkbox" class="product_chkKite103" name="product_chk" value=" Like Kite 103 " /><label >Like Canada Kite</label>
</div>
NOTLIKE_KITE_PAGE.PHP (works the same for ball, hula hoop and other products)
<div>
<input type="checkbox" class="product_chkKite101" name="product_chk" value=" Not Like Kite 101 " /><label >Not Like USA Kite</label>
<input type="checkbox" class="product_chkKite102" name="product_chk" value=" Not Like Kite 102 " /><label >Not Like Mexico Kite</label>
<input type="checkbox" class="product_chkKite103" name="product_chk" value=" Not Like Kite 103 " /><label >Not Like Canada Kite</label>
</div>
Advance Search Page:
Html from Advance Search page
Buttons (again only three is shown):
<ul class="category">
<li>KITES</li>
<li>BALLS</li>
<li>HULA HOOPS</li>
</ul>
The Div where the pages will load into:
<div id="product_container" >
<div class="kite box" >
<div class="tx-row" id='kite-in' >
</div>
<div class="tx-row" id='kite-x' >
</div>
</div>
<div class="ball box" >
<div class="tx-row" id='ball-in' >
</div>
<div class="tx-row" id='ball-x' >
</div>
</div>
<div class="document box" >
<div class="tx-row" id='hoop-in' >
</div>
<div class="tx-row" id='hoop-x' >
</div>
</div>
</div>
JQuery that retrieves the information when button is clicked
$(document).ready(function(){
var $content = $('.box');
function showContent(type) {
$content.hide().filter('.' + type).show();
}
$('.category').on('click', '.kite-btn', function(e) {
if ($('#kite-in').is(':empty')){
showContent(e.currentTarget.hash.slice(1));
e.preventDefault();
}else {
$("#kite-in").load("/wp-content/themes/child/kite_page.php");
$("#kite-x").load("/wp-content/themes/child/notlike_kite_page.php");
showContent(e.currentTarget.hash.slice(1));
e.preventDefault();
}
});
$('.category').on('click', '.ball-btn', function(e) {
if ($('#ball-in').is(':empty')){
showContent(e.currentTarget.hash.slice(1));
e.preventDefault();
}else {
$("#ball-in").load("/wp-content/themes/child/ball_page.php");
$("#ball-x").load("/wp-content/themes/child/notlike_ball_page.php");
showContent(e.currentTarget.hash.slice(1));
e.preventDefault();
}
});
$('.category').on('click', '.hoop-btn', function(e) {
if ($('#hoop-in').is(':empty')){
showContent(e.currentTarget.hash.slice(1));
e.preventDefault();
}else {
$("#hoop-in").load("/wp-content/themes/child/hoop_page.php");
$("#hoop-x").load("/wp-content/themes/child/notlike_hoop_page.php");
showContent(e.currentTarget.hash.slice(1));
e.preventDefault();
}
});
$(".box").hide();
});
An Additional Question to this as well:
Is there a way to disable a checkbox with same class (example: class="product_chkKite101" ) when one is checked between pages?
first what you can do is use on click attribute for all checkbox and pass the current element and better use id also because it will be unique and only one for a one checkbox
<input id="product_chkKite101" type="checkbox" onclick="checkChecked(this)" class="product_chkKite101" name="product_chk" value=" Not Like Kite 101 " /><label >Not Like USA Kite</label>
now in checkChecked function first make an empty array
var checkedCheckbox = [];
function checkChecked(ele){
var id = ele.id;
if ($.inArray(id, checkedCheckbox) !== -1)
{
var index = checkedCheckbox.indexOf(id);
if (index > -1) {
checkedCheckbox.splice(index, 1);
}
}else{
checkedCheckbox.push(id);
}
localStorage.setItem("selected", JSON.stringify(selected));
}
now to make checkbox checked when page is reload or when button is toogled you can run this code
var checkCheckedStorage = [];
$(function() {
if (localStorage.getItem("selected") != null) {
checkCheckedStorage = JSON.parse(localStorage.getItem("selected"));
checkChecked = checkCheckedStorage;
checkCheckedStorage.forEach(function(ele) {
console.log(ele);
$('#' + ele).prop('checked', true);
});
}
});
if this code doesnot get executed when toggling the buttons then what you can do is write the code inside a function again and call it from the toggle event of a button
I figured out why it wasn't staying checked. Every time I click on a button / toggle again, it reloads the information. I had my if statement with in my jquery in correct.
Updated jQuery
Had to add an id inside a div to each page. Then checked to see if the id is there or not. If it is not there, then upload the page. If it is there, just use the current page contents.
$('.category').on('click', '.kite-btn', function(e) {
if ($('#kitechk').length){
showContent(e.currentTarget.hash.slice(1));
e.preventDefault();
}else {
$("#kite-in").load("/wp-content/themes/child/kite_page.php");
$("#kite-x").load("/wp-content/themes/child/notelike_kite_page.php");
showContent(e.currentTarget.hash.slice(1));
e.preventDefault();
alert('finish')
}
});
Below is my code, I am trying to hide and show dynamic elements. The problem I am having is, I only want my hidden div to only show one at a time if only I check "Other". However, the code below will show the hidden div for all number of #dynamicRows I have. so it works for initial 1st #dynamicRow added, the problem is when I have two or more #dynamicRows
$('#dynamicRow').on('click', 'input[id^=race]', function () {
if ($(this).is(":checked")) {
if ($(this).val() == "Other") {
$(".cssclass").each(function (index) {
$(this).closest("div").show();
});
}
else {
$(".cssclass").each(function () {
$(this).closest("div").hide();
});
}
}
});
Below are dynamic rows, for help purposes i am showing the html code, however, it doesn't exist on the screen, a user will click "ADD" to generate the code below. I have no problem in generating dynamic row and it is not why I am posting. note the name in my radio button is generated by c# and everything works. Again the problem is not how to create a dynamic row, it is nicely taken care of in C#.
Dynamic row one works with the above jQuery:
<div id="dynamicRow">
<input type="radio" value="No" id="race[]" name="Person[hhhhhh].race"> No:
<input type="radio" value="Other" id="race[]" name="Person[hhhhhh].race"> Other:
<div id="iamhidden" class="cssclass">
I appear one at a time, when other radio button is checked
</div>
</div>
Dynamic row two doesn't work with the above jquery and it takes the above form events as its own, so if i check the radio button in row 2, the 1st dynamic row responds to that event and vice versa:
<div id="dynamicRow">
<input type="radio" value="No" id="race[]" name="Person[hhhhh].race"> No:
<input type="radio" value="Other" id="race[]" name="Person[hhhhh].race"> Other:
<div id="iamhidden" class="cssclass">
I appear one at a time, when other radio button is checked
</div>
</div>
Working Example
id should be unique in same document, replace the duplicate ones by a class :
<input type="radio" value="No" class="race" name="Person[hhhhhh].race"> No:
<input type="radio" value="Other" class="race" name="Person[hhhhhh].race"> Other:
Also add class and not id to the dynamic rows generated by your C# code :
<div class="dynamicRow">
Then in your js use this class :
$(".cssclass").hide();
$('.dynamicRow').on('click', '.race', function () {
if ($(this).val() == "Other") {
$(this).next(".cssclass").show();
} else {
$(this).nextAll(".cssclass").hide();
}
});
Hope this helps.
Try this:
$('body').on('click', '#dynamicRow', function () {
if ($(this).find('[value=Other]').is(":checked")) {
$(".cssclass").each(function (index) {
$(this).closest("div").show();
});
} else {
$(".cssclass").each(function () {
$(this).closest("div").hide();
});
}
});
He is a working example of what you wanted. I am generating the required with js only.
Few Points to mention
you add the event listener to the parent of the dynamic generated content.
Avoid use of IDs if they are not going to be unique and prefer classes and pseudo selectors if required
var counter = 0;
function addNewEntry(){
++counter;
var str = '<div class="dynamicRow"><input type="radio" value="No" id="race[]" name="Person[hh'+counter+'].race"> No:<input type="radio" value="Other" id="race[]" name="Person[hh'+counter+'].race"> Other:<div id="iamhidden" class="cssclass"> I appear one at a time, when other radio button is checked</div> </div>';
$('#dynamicRowContainer').append(str);
$("#dynamicRowContainer .dynamicRow:last-child .cssclass").hide()
}
$('#dynamicRowContainer').on('change', '.dynamicRow > input', function () {
if(this.value=="Other"){
$(this).siblings('.cssclass').show();
}else{
$(this).siblings('.cssclass').hide();
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button onclick="addNewEntry()">Add New Entry</button>
<div id="dynamicRowContainer">
</div>
I have an app I am creating, I've been able to get through it so far relatively hassle free. Until now. At the moment I need to find a way to keep the information produced by if statements for a check box. I have been able to get this working for a radio button by just storing the data in a global variable but I am not sure how to with a check box.
Code:
if ($('#Chk_0').is(':checked')) {
check = "Check1" + ", ";
countCheck++;
}
if ($('#Chk_1').is(':checked')) {
check = "Check2" + ", ";
countCheck++;
}
if (countCheck == 0) {
Check = "Nothing is checked";
}
Checkbox:
<div data-role="collapsible" id="cCheck" class="hCheck">
<h3>CheckBox</h3>
<div data-role="fieldcontain">
<fieldset data-role="controlgroup">
<legend>Option</legend>
<input type="checkbox" name="Check" id="Check_0" class="custom" value="" />
<label for="Check_0">Check1</label>
<input type="checkbox" name="Check" id="Check_1" class="custom" value="" />
<label for="Check_1">Check2</label>
</fieldset>
</div>
</div>
You can use an array and a string.
var checkedOptions=[]
var checkedGroup="";
if ($('#Check_0').is(':checked')) {
if(checkGroup=="Check"){
checkedGroup.push("Check_0");
}
else
{
checkGroup="Check"
checkedGroup=["Check0"];
}
countCheck++;
}
BTW: You have an error in your code. The IDs of the input tags and the jQuery are not the same.
As i understand your question ,you need to know is any check box is checked and if any checked you need the ids so this may be help
var ids = '';
$(':checked').each(function (i, element) {
ids += $(element).prop('id')+",";
})
then you can chekc if ids has length
if (ids.length>0) {
//use ids variable here
}