jQuery show and hide dynamic classes not working - javascript

I am trying to hide and show div's displayed on my page with a select element however having a bit of trouble as I can't seem to get the jQuery to function.
I am listing results from my SQL table using PHP that currently displays every row onto my page and prints them into a list.
I want to make the jQuery hide the div's that don't have a class that matches the select option that is selected.
Here is an example of the listing template that echo's out all of the MySQL results and displays them into a template and is then looped to display every row on the table:
<?php while($row = $results->fetch(PDO::FETCH_ASSOC))
{
echo '
<div class="listing-container ' . $row["Make"] . '">
<h3 class="model-listing-title clearfix">'.$row["Make"].' '.$row["Model"].' '.$row["Variant"].'</h3>
<h3 class="price-listing">£'.number_format($row['Price']).'</h3>
</div>
<div class="listing-container-spec">
<img src="'.(explode(',', $row["PictureRefs"])[0]).'" class="stock-img-finder"/>
<div class="ul-listing-container">
<ul class="overwrite-btstrp-ul">
<li class="diesel-svg list-svg">'.$row["FuelType"].'</li>
<li class="saloon-svg list-svg">'.$row["Bodytype"].'</li>
<li class="gear-svg list-svg">'.$row["Transmission"].'</li>
<li class="color-svg list-svg">'.$row["Colour"].'</li>
</ul>
</div>
<ul class="overwrite-btstrp-ul other-specs-ul h4-style">
<li>Mileage: '.number_format($row["Mileage"]).'</li>
<li>Engine size: '.$row["EngineSize"].'cc</li>
</ul>
<button href="#" class="btn h4-style checked-btn hover-listing-btn"><span class="glyphicon glyphicon-ok"></span> History checked
</button>
<button href="#" class="btn h4-style more-details-btn hover-listing-btn tst-mre-btn"><span class="glyphicon glyphicon-list"></span> More details
</button>
<button href="#" class="btn h4-style test-drive-btn hover-listing-btn tst-mre-btn"><span class="test-drive-glyph"></span> Test drive
</button>
<h4 class="h4-style listing-photos-count"><span class="glyphicon glyphicon-camera"></span> 5 More photos</h4>
</div>
';
} ?>
The 'Make' is added to the listing-container div to add a class to be able to filter the results with jQuery.
Here is the form with the select element I am using:
<form>
<select class="form-control select-box">
<option value="make-any">Make (Any)</option>
<?php while($make = $filterres->fetch(PDO::FETCH_ASSOC))
{
echo '
<option>'.$make["Make"].'</option>
';
} ?>
</select>
<select class="form-control last-select select-box">
<option value="model-any">Model (Any)</option>
<option value="two">Two</option>
<option value="three">Three</option>
<option value="four">Four</option>
<option value="five">Five</option>
</select>
</form>
As you can see the select option contains the 'Make' and is looped.
So down to the jQuery:
<script>//Wait for DOM to load
(function() {
$(“.select-box”).change( function() {
// get the value of the select element
var make = $(this).val();
//get all of the listing-container divs, remove the ones with the selected make class, then hide the rest
$(“.listing-container”).not(“.” + make).hide();
});
});</script>
So in theory this should work but for some reason it isn't, can anybody notice anything that might be wrong?
I have placed my script below the core jQuery in my footer and it still doesn't work.
Here is a live example: http://www.drivencarsales.co.uk/used-cars.php

Looks like you're using the wrong quotes in the source code of that page try replacing them with "
//Wait for DOM to load
$(function() {
$(".select-box").change( function() {
// get the value of the select element
var make = $(this).val();
//get all of the listing-container divs, remove the ones with the selected make class, then hide the rest
$(".listing-container").not("." + make).hide().next().hide();
});
});
Edit
You also need a $ before the function

If I understand you correctly ↓ working code ↓
$(function() {
$('.select-box').on("change",function() {
var make = this.value;
$('div.listing-container.'+make+",div.listing-container."+make+" + div.listing-container-spec").show();
$('div.listing-container:not(.'+make+'),div.listing-container:not(.'+make+') + div.listing-container-spec').hide();
});
});
And shorter code (but slower):
$(function() {
$('.select-box').on("change",function() {
var make = this.value;
$('.listing-container.'+make+",.listing-container."+make+" + div").show();
$('.listing-container:not(.'+make+'),.listing-container:not(.'+make+') + div').hide();
});
});
P.S.You miss value attribute (but in live example everything ok):
echo '<option value="'.$make["Make"].'">'.$make["Make"].'</option>';

Related

After generating divs using php for loop and also dynamically assigning for them ids how to i target the ids using jquery?

Am using a while loop to out various elements each containing rows from a mysql database. I was able to make each div have different id however, i have no idea how i can target each of the divs usings jquery through the ids so that each div is a clickable link.
Here is a part of my code
<!-- php script -->
<?php
require_once 'controllers/fetchVids.php';
if (mysqli_num_rows($result) > 0) {
// output data of each row
while($row = mysqli_fetch_assoc($result)) {
$fileName = $row[$filePath];
$file = basename($fileName);
$mb = round($row[$size] / (1000000), 2);
echo "
<div class='container search-output' id=''>
<div class='row song-info' id='file-$row[$videoId]'>
<div class= 'col col-sm-6 artist'>
$file
</div>
<div class= 'col col-sm-3 song-title'>
<span>Size:</span>
$mb mb
</div>
<div class= 'col col-sm-3 song-title'>
<span>Downloads:</span>
$row[$downloads]
</div>
</div>
<div class='row-lower'>
<a href='#' class='icon all-links'>
<i class='fa fa-whatsapp'></i> Share
</a>
<i class='fa fa-clock duration'></i> Duration $row[$duration] mins
</div>
</div>
";
} else {
echo "No New Videos";
}
mysqli_close($connection);
?>
Someone please show me the right jquery to do the above. thank you
Below is the jquery code i tried but it rather opens all the divs and not only that that a user clicks on
$(document).on('click', '.song-info', function() {
// alert(this.id);
if (this.id) {
window.location = "./song-details.php";
}
});
I think you were going wrong by using the 'this' keyword - you may have wanted to use $(this) instead, which is a keyword in jQuery that gives the DOM node you are currently working on access to jQuery methods (at least as far as I understand it!)
You can use $(this).attr('attribute name') (another jQuery method) to get the 'id' property of the div you clicked and use it within your function.
There are more than a few ways to do this, as mentioned in the comments, but here is how I would go about it. I'm assuming you want to send the fileId in a query string to './song-details.php'.
$(document).on('click', '.song-info', function() {
let id = $(this).attr('id').split('-').pop()
if (id) {
window.location = "./song-details.php" + "?id=" + id
}
})

Two custom multiselect drop down dependent on each other

Two custom multiselect drop down dependent on each other and based on combined result need to show items and when selecting one then in other dropdown value should be disabled if combination is not found
<div class="firstdrop">
<span value="ss">ss</span>
<span value="dd">dd</span>
</div>
<div class="seconddrop">
<span value="game">game</span>
<span value="football">football</span>
</div>
<div class="game ss"></div>
<div class="gamee dd"></div>
<div class="football ss"></div>
<div class="ss"></div>
The way I've done this in the past (loosely based on your example):
if($('#firstdrop').val() == 'some value') {
var oldval = $('#seconddrop').val(); // In case the chosen option exists in the new option set
var opts = '<option value="val1">Val 1</option>';
opts += '<option value="val2">Val 2</option>';
etc...
$('#seconddrop').empty().append(opts).val(oldval);
}
Oh, and you need to use select tags, not divs.
<select multiple id="firstdrop">...
<select multiple id="seconddrop">...

jQuery script works just for one button on the product catalog

I have a product catalog and I want to save on localstorage the products selected by the user.
The jquery script only gets the first product on each page on each click... it simply ignores the rest of the products, and the console prints the same object.
Here is my HTML+TWIG code
{% for products in pagination %}
<div class="product col-sm-6 col-lg-6 col-md-6 hero-feature">
<div id="{{attribute(products ,'id')}}" class="product thumbnail">
<img id="prodImage" class="img-responsive img-rounded" src="{{attribute(products ,'image')}}" style="width:150px;height:150px" >
<div class="product caption">
<h4 id="prodPrice" class="product pull-right"><b>{{ attribute (products, 'price') }}Lei</b></h4>
<h4 id="prodName" style="height:100px;width:200px;">
<a id="prodLink"
href="{{ attribute (products, 'affiliatelink') }}"
target="_blank">{{attribute ( products, 'name') }}</br></a>
</h4>
</div>
<div class="add-to-cart" class="product" >
<button id="buttonProd" class="oneButton btn btn-danger " value="Save" type="button">Adauga</button>
</div>
</div>
</div>
{% endfor %}
Here is the jquery script
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.1/jquery.min.js"></script>
<script type='text/javascript' defer="defer">
$(document).ready(function() {
var prodId = $('.thumbnail').attr("id");
$("#buttonProd").on("click", 'button', function(event){
event.preventDefault();
var products =
{
prodID :$('.thumbnail').attr("id"),
prodName :$('#prodName').text(),
prodPrice :$('#prodPrice').text(),
prodImage :$('#prodImage').attr('src'),
prodLink :$('#prodLink').attr('href')
};
localStorage.setItem('products-' + prodId, JSON.stringify(products));
var retrievedObject = JSON.parse(localStorage.getItem('products-' + prodId));
console.log('retrievedObject: ', retrievedObject);
});
});
</script>
How can I make the script take each product proprieties on click. Thank you in advance.
In JQuery, the assumption is made that all ID's will be unique. Since you're repeating "#buttonProd", JQuery will only select the first one to bind the action to. If you want to bind to multiple elements, you'll either have to give each button a unique ID or use some other selector to attach your jQuery functionality.
From the documentation for the ID Selector:
Calling jQuery() (or $()) with an id selector as its argument will return a jQuery object containing a collection of either zero or one DOM element.
As the other answers have eluded to you should be using a different selector. I recommend simply adding a descriptive class to each element you wish to grab data from.
<div class="products">
<div class="product">
<div class="productName">First Product</div>
<div class="productPrice">5.00</div>
</div>
<div class="product">
<div class="productName">Second Product</div>
<div class="productPrice">4.00</div>
</div>
<button id="buttonProduct">Log Product Info</button>
</div>
If you notice in the above HTML each div that contains a product's name or a product's price shares the same class productName and productPrice respectively. In addition each container class for each product has the same class as well: product.
This will allow us to utilize the JQuery class selector $(".") to iterate over each product container. We do this using the .each() function. We use the .find() function to locate productName and productPrice in each iteration of the loop.
$(document).ready(function() {
$("#buttonProduct").click(function(){
var products = [];
// Notice the dot in $(".product") that is the class selector
// the .each iterates over every element that matches the preceding selector
$(".product").each(function(){
products.push({
// The .find() selects an element inside $(this)
// that matches the parameter (either .productName or .productPrice
productName : $(this) .find('.productName').html(),
productPrice : $(this).find('.productPrice').html()
});
});
console.log(products);
});
});
For a working example of this check out this jsfiddle. (I noticed you had console.log() in your code so that's where I output the result.)
You want to save the product in localStorage on clicking of corresponding button right?
for that instead of binding click event via jquery, put it in html and move the click code to a function saveProduct()
HTML:
<button id="buttonProd" class="oneButton btn btn-danger " value="Save" type="button" onclick="saveProduct({{attribute(products ,'id')}})">Adauga</button>
JS:
function saveProduct(event, prod_id){
event.preventDefault();
var products =
{
prodID :prod_id,
prodName :$('#'+prod_id+' #prodName').text(),
prodPrice :$('#'+prod_id+' #prodPrice').text(),
prodImage :$('#'+prod_id+' #prodImage').attr('src'),
prodLink :$('#'+prod_id+' #prodLink').attr('href')
};
localStorage.setItem('products-' + prod_id, JSON.stringify(products));
var retrievedObject = JSON.parse(localStorage.getItem('products-' + prod_id));
console.log('retrievedObject: ', retrievedObject);
});
}
You need to change #buttonProd from an id to a class. An id is only supposed to appear once on a page, so jQuery will only apply it to one. Change it to a class in your markup and your script and it should work fine. Same for prodName, prodPrice, prodImage, and prodLink. Anything that will be going inside the loop needs to be a class, and any id should be unique, like you have {{attribute(products ,'id')}}

jQuery not extracting text values clicked properly

I am using a php script to extract values from the database as follows,
<div class="col-md-4" >
<?php
$qry = "SELECT * FROM upperbit_categories";
$rslt = mysqli_query($dbc,$qry);
while ($output = mysqli_fetch_array($rslt)) {
?>
<li class="nav" id="test" style= "text-decoration: none;">
<a href="postad" >
<?php echo $output['Classify'].'<br/>'; } ?>
</a>
</li>
</div>
<div class="col-md-4" id="testing">
</div>
this code gives me below result:
General equipment
Test equipment
Renewable energy
Engineering Services
Trade services
Below is the jQuery bit:
<script>
$(document).ready(function(){
$("#test").click(function(){
var classprod = $(this).text();
$("#testing").text(classprod);
event.preventDefault();
})
});
</script>
However this only outputs line-1 but nothing else i.e. General equipment.
What changes do I have to make to my javascript code in order to be able to display any item clicked?
Little errors, but easy to solve. Your php loop leave a lot of tags opened, an closes just one, then you should use a Class instead on an Id for multiple elements.
Another tip is that you should open and close the ul tag before your list.
HTML
<div class="col-md-4" >
<ul>
<?php
$qry = "SELECT * FROM upperbit_categories";
$rslt = mysqli_query($dbc,$qry);
while($output = mysqli_fetch_array($rslt)){?>
<li class="nav test" style= "text-decoration: none;"><a href="postad" ><?php echo $output['Classify'];?></a></li>
<?php };?>
</ul>
</div>
<div class="col-md-4" id="testing"></div>
JS
<script>
$(document).ready(function(){
$(".test").on('click',function(event){
event.preventDefault();
var classprod = $(this).text();
$("#testing").text(classprod);
})
});
</script>
Also, I don't know what you're doing, but consider to use $(".test a") instead of $(".test")
In General, id of HTML elements should be unique, this requirements can be realized when using jQuery or JavaScript. In your code, you used id="test" for the li element inside a loop, and then you referenced to them using $("#test") then, only first li works due to uniqueness of id.
you can use class instead of id.

Angular - Use $index to load product images

I have the following form in my AngularJS app:
<li ng-repeat="device in devices track by $index">
<div class="db-handset-image">
<span class="phone-silhouette"></span>
{{ relative image here }}
</div>
<div class="db-device">
<ul class="opts">
<li>
<select name="manufacturer[ [[$index]] ]" ng-model="selectedManufacturer" ng-change="getManufacturerModels(selectedManufacturer)">
<option value="">Manufacturer</option>
<option ng-repeat="manufacturer in manufacturers" value="[[manufacturer.id]]">[[manufacturer.name]]</option>
</select>
</li>
<li>
<select name="device[ [[$index]] ]" ng-model="selectedModel" ng-change="loadModelImage(selectedModel, $index)">
<option value="">Model</option>
<option ng-repeat="model in manufacturerModels" value="[[model.id]]">[[model.model + ' ' + model.variants[$index].memory + ' ' + model.variants[$index].colour]]</option>
</select>
</li>
</ul>
</div>
</li>
What happens in this form is that a user will select a manufacturer from the first dropdown and a model from the model dropdown. The model dropdown will populate with the relative models after a manufacturer has been selected using Angular's $filter.
When the user has selected a model, loadModelImage is fired and what needs to happen here is that after a model selection, that model image is then loaded into the {{relative image here}} placeholder. This is currently being done like so:
$scope.loadModelImage = function (modelId, $index) {
$http.get(ajaxurl + '?action=get_handset&hid=' + modelId)
.success(function (data) {
$scope.selectedHandsets++;
$scope.modelImages.splice(0, 0, data.handset.images);
})
}
This issue with this is that if I replace the relative image here placeholder text with an <img> loading in the model images, each model that's been selected appears in every row.
My other issue is that if you remain on the same 'row' (see below screenshot) and change the handset image, another array of images is pushed to $scope.modelImages when it in fact the images for that 'row' should effectively be overwritten with the new selection.
To give you a clear understanding of how the form looks, here's a screenshot:
When you click 'add new handset' the row containing the dropdowns is visually duplicated and you can add select another handset.
I hope my problem's explained clearly enough, any Q's ask.

Categories

Resources