I am using this plugin for ratings (http://wbotelhos.com/raty/). Basically, I am displaying multiple items, each item has its own rating stars. The problem is, it is only displaying the first result which is '2.3' and then apply it to all remaining items. How can I fix this?
<ul>
<li>
<div class="num_ratings">2.3</div>
<p class="rating-stars"></p>
</li>
<li>
<div class="num_ratings">4.1</div>
<p class="rating-stars"></p>
</li>
<li>
<div class="num_ratings">3.0</div>
<p class="rating-stars"></p>
</li>
<li>
<div class="num_ratings">3.3</div>
<p class="rating-stars"></p>
</li>
</ul>
<script>
$.fn.raty.defaults.path = 'img';
rating = parseInt($('.num_ratings').html());
$('.rating-stars').raty(
{
width: 112,
readOnly : true,
score: rating,
});
</script>
Try it like this:
$.fn.raty.defaults.path = 'img';
$("li").each(function(){
rating = $('.num_ratings' , this).text();
$('.rating-stars' , this).raty(
{
width: 112,
readOnly : true,
score: rating,
});
});
In this way it will run on every li , get its num_ratings data and create rating in its specific rating-stars p.
Related
In my e-commerce environment, I need a jQuery validation between 2 product attributes. Simplified it needs to check if the cart has a product which is present on the same page:
<! –– Cart ––>
<ul class="woocommerce-mini-cart cart_list product_list_widget ">
<li class="woocommerce-mini-cart-item mini_cart_item">
<a href="/example-product/" class="remove remove_from_cart_button" data-product_id="6735" data-cart_item_key="..." ></a>
</li>
</ul>
<! –– Product ––>
<article class="post-6735 product" data-id="6735">
<div class="product_wrapper">
<a href="?add-to-cart=6735" data-quantity="1" class="button add_to_cart_button" data-product_id="6735"</a>
</div>
</article>
I would like to be able to check if the attribute and its value from data-product_id within the cart is the exact same as in article a.button element. My approach:
jQuery('.woocommerce-mini-cart .remove_from_cart_button').attr('data-product_id').each( function() {
if( jQuery('article a.button')/*check if it is the same*/){
// do something here
}
});
As you can see the ID number 6735 is in more attributes. So perhaps a different way is also possible?
To get current_ProductId, You just need to get from $('article').data('id')
To loop through all mini cart items, You just need mini_cart_item
As you can see, we can get data attribute value by using data
var current_ProductId = $('article').data('id');
$('.mini_cart_item').each(function() {
var productId_MiniCartItem = $(this).find('a').data('product_id');
if(productId_MiniCartItem == current_ProductId){
// do something here
console.log("ProductId: " + productId_MiniCartItem + " has been ordered");
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<! –– Cart ––>
<ul class="woocommerce-mini-cart cart_list product_list_widget ">
<li class="woocommerce-mini-cart-item mini_cart_item">
<a href="/example-product/" class="remove remove_from_cart_button" data-product_id="6735" data-cart_item_key="..." >6735</a>
</li>
<li class="woocommerce-mini-cart-item mini_cart_item">
<a href="/example-product/" class="remove remove_from_cart_button" data-product_id="6736" data-cart_item_key="..." >6736</a>
</li>
</ul>
<! –– Product ––>
<article class="post-6735 product" data-id="6735">
<div class="product_wrapper">
<a href="?add-to-cart=6735" data-quantity="1" class="button add_to_cart_button" data-product_id="6735"</a>
</div>
</article>
If you only need help to clarify your solution it would be
$('.woocommerce-mini-cart .remove_from_cart_button').each( function() {
if( $('article a.button').data('product_id') == $(this).data('product_id'){
// do something here
}
});
each iterate through collection of jquery elements.
This
jQuery('.woocommerce-mini-cart .remove_from_cart_button').attr('data-product_id')
is the single value, it would take the first element that finds and then executes attr on it.
UPDATE
To update all products button on site based on all products that are inside the card
var product_id = "";
var article = ".post-"; // class of article
$('.woocommerce-mini-cart .remove_from_cart_button').each( function() {
product_id = $(this).data('product_id')
article = article + product_id; // we add strings here, example .post-6225
$(article + " .product_wrapper a").attr('disabled', 'disabled');
});
I am trying to store an image in a json object and display it on a html page with the rest of the data in the object. The image is stored locally in a folder called images. I have some code, but it doesnt seem to work... Can anyone please advise?
"photo":"<img src=images/audir8.jpg"
their is missing a closing ">" tag
Update you json like this
{
"id":2,
"name":"Audi A4",
"make":"Audi",
"model":"A4",
"enginesize":"1968cc",
"power":"140 BHP",
"acceleration":"7.8 seconds",
"topspeed":"139 MPH",
"drivetrain":"Front-wheel drive",
"specification":"Sat Nav, Heated Seats, Convertible, Immobiliser, Traction Control, Metallic paint, Airbags, LED lights",
"photo":"images/audir8.jpg"
}
html
<h1 id="title"></h1>
<ul>
<h2>Performance</h2>
<ul id="make"></ul>
<ul id="model"></ul>
<ul id="enginesize"></ul>
<ul id="power"></ul>
<ul id="acceleration"></ul>
<ul id="topspeed"></ul>
<ul id="drivetrain"></ul>
<ul id="specification"></ul>
<ul ><img id="photo" />
</ul>
</ul>
<script src="js/details.js"></script>
</div>
</div>
javascript
function populateContent(car)
{
titleEl=document.getElementById("title");
makeEL=document.getElementById("make");
modelEl=document.getElementById("model");
enginesizeEl=document.getElementById("enginesize");
powerEl=document.getElementById("power");
accelerationEl=document.getElementById("acceleration");
topspeedEl=document.getElementById("topspeed");
drivetrainEl=document.getElementById("drivetrain");
specificationEl=document.getElementById("specification");
photoEl=document.getElementById("photo");
//document.getElementById("imageid").src="../images/audir8.png";
titleEl.innerHTML = car.name;
makeEL.innerHTML = "<b>Make: </b>"+car.make;
modelEl.innerHTML = "<b>Model: </b>"+car.model;
enginesizeEl.innerHTML = "<b>Engine Size: </b>"+car.enginesize;
powerEl.innerHTML = "<b>Power: </b>"+car.power;
accelerationEl.innerHTML = "<b>0-60: </b>"+car.acceleration;
topspeedEl.innerHTML = "<b>Top Speed: </b>"+car.topspeed;
drivetrainEl.innerHTML = "<b>Drivetrain: </b>"+car.drivetrain;
specificationEl.innerHTML = "<h2>Specification: </h2>"+car.specification;
photoEl.src= car.photo;
}
You are missing the closing of image tag />. Add that and it will work. For demonstration I have used a live URL for the image. You can replace that with yours. Also, <ul> has <li> elements so replace that too.
var jsonData = {
"id":2,
"name":"Audi A4",
"make":"Audi",
"model":"A4",
"enginesize":"1968cc",
"power":"140 BHP",
"acceleration":"7.8 seconds",
"topspeed":"139 MPH",
"drivetrain":"Front-wheel drive",
"specification":"Sat Nav, Heated Seats, Convertible, Immobiliser, Traction Control, Metallic paint, Airbags, LED lights",
"photo":"<img src=http://myanmareiti.org/sites/default/files/styles/medium_retina/public/sample-5_0.jpg?itok=wn8qRWZM />"
};
function populateContent(car)
{
titleEl=document.getElementById("title");
makeEL=document.getElementById("make");
modelEl=document.getElementById("model");
enginesizeEl=document.getElementById("enginesize");
powerEl=document.getElementById("power");
accelerationEl=document.getElementById("acceleration");
topspeedEl=document.getElementById("topspeed");
drivetrainEl=document.getElementById("drivetrain");
specificationEl=document.getElementById("specification");
photoEl=document.getElementById("photo");
//document.getElementById("imageid").src="../images/audir8.png";
titleEl.innerHTML = car.name;
makeEL.innerHTML = "<b>Make: </b>"+car.make;
modelEl.innerHTML = "<b>Model: </b>"+car.model;
enginesizeEl.innerHTML = "<b>Engine Size: </b>"+car.enginesize;
powerEl.innerHTML = "<b>Power: </b>"+car.power;
accelerationEl.innerHTML = "<b>0-60: </b>"+car.acceleration;
topspeedEl.innerHTML = "<b>Top Speed: </b>"+car.topspeed;
drivetrainEl.innerHTML = "<b>Drivetrain: </b>"+car.drivetrain;
specificationEl.innerHTML = "<h2>Specification: </h2>"+car.specification;
photoEl.innerHTML = "<h2>photo: </h2>"+car.photo;
}
populateContent(jsonData);
<h1 id="title"></h1>
<ul>
<h2>Performance</h2>
<li id="make"></li>
<li id="model"></li>
<li id="enginesize"></li>
<li id="power"></li>
<li id="acceleration"></li>
<li id="topspeed"></li>
<li id="drivetrain"></li>
<li id="specification"></li>
<li id="photo"></li>
</ul>
I am trying to create checkboxes that will add an object to an array when checked, but will remove that object when unchecked. I am not sure if this is the correct way, but will show what I have below. Using Angular 2 by the way.
Original Code:
<div>
<ul>
<a *ngFor="let perkResult of perkList.results" (click)="onAddPerk(perkResult)">
<li>{{ perkResult.perk }}</li>
</a>
</ul>
</div>
<div *ngFor="let perk of company.perks;>
{{ perk.perk }}
<a (click)="onDeletePerk(i)"></a>
</div>
Functions:
onAddPerk(perkResult) {
// Adds a new perk to the array
this.company.perks.push({perk: (perkResult.perk)});
}
onDeletePerk(i: number) {
// Delete the perk in the selected index
this.company.perks.splice(i, 1);
}
And I want to do something like this:
<div *ngFor="let benefitResult of benefitList.results" >
<a (click)="onAddBenefit(benefitResult)">
<input type="checkbox" />
//Basically if checked then run add function, if not checked then run delete function
</a> {{ benefitResult.benefit }}
</div>
EDIT:
Got to this point, but cannot reference my other scope for the delete.
<ul *ngIf="benefitList">
<div *ngFor="let benefitResult of benefitList.results; let i = index" >
<input type="checkbox" (change)="updateBenefits($event, benefitResult, i)" >
<li>
{{ benefitResult.benefit }}
</li>
</div>
</ul>
//Original delete
<div *ngFor="let benefit of company.benefits; trackBy: customTrackBy; let i = index">
{{benefit.benefit}}
<a (click)="onDeleteBenefit(i)"></a>
</div>
//function
updateBenefits(event, benefitResult, i) {
if(event.srcElement.checked) {
this.company.benefits.push({benefit: (benefitResult.benefit)});
} else {
this.company.benefits.splice(i, 1);
}
}
You could listen to the change event on the checkboxes. Then pass the event along with the object and index to a method that will look at the status of the checkbox element.
In the component:
optionsList = {
results: [{
perk: 'free coffee',
checked: false
}, {
perk: 'car',
checked: false
}, {
perk: 'pastry',
checked: false
}, {
perk: 'free post-it notes',
checked: false
}]
};
updatePerks(event, perkResult) {
perkResult.checked = event.srcElement.checked;
}
In your HTML template:
<ul>
<li *ngFor="let listItem of optionsList.results">
<label><input type="checkbox" (change)="updatePerks($event, listItem)">
{{ listItem.perk }}</label>
</li>
</ul>
Note: I don't know your data structure, so make the necessary adjustment or post a data sample if you need more help.
I have created a tabular page in which i need to filter the table with filters using a left side facets boxes of different category but with multi-selection options and i need to use Angularjs for this requirement.
I need to check/uncheck using the clear filter selection .
Any helping library can help to achieve the same or we need to do some logic around the checkboxes to achieve this.
My checkbox code looks like this:
<div class="col-sm-2" style="padding-top: 10px; padding-bottom: 20px;">
<div class="facetBx sltBx" ng-show="tabFilters.length > 0">
<p class="facetBxTitle"><i class="fa fa-filter"></i> Filter Selection
<a class="clrSlt" ng-click="clearAllFilters();">Clear</a>
</p>
<div class="facetBxChld" id="uRslctn">
<ul>
<li ng-repeat="item in tabFilters">
<div class="crop">
<strong title="{{item}}">{{item}}</strong>
</div>
<i class="fa fa-remove rmvThs" style="font-size: 14px;color:#000;float: right;" ng-click="checkItem(item, item,false);"></i>
</li>
</ul>
</div>
</div>
<div class="facetBx" ng-repeat="item in filters">
<p class="facetBxTitle bomtype">{{item.label}}</p>
<div class="facetBxChld" id="bomFacet">
<ul class="multiselect" style="max-height: 140px;overflow-y: auto;">
<li ng-repeat="(k,v) in item.values">
<input type="checkbox" ng-model='isSelected' ng-click='checkItem(item.name, k, isSelected)'>
<span> {{k}} ({{v}})</span>
</li>
<li ng-show="value.length == 0">
No Data Available.
</li>
</ul>
</div>
</div>
</div>
Below website are the reference of the code which i am trying to build:
www.jabong.com
The UI(HTML) is done but i am facing the trouble in the maintaining the checking and un-checking of the checkboxes which are not clearing off.
I believe i need to code something in the ng-model of checkbox to achieve it but i am not able to be successfull so need help on the same.
Sample Plunkur for the same:
enter link description here
Thanks in advance.
Basically you need to keep track of ng-model of checkboxes with some property in your $scope. I did this by modifying your $scope.filters and adding selected property inside it, like below.
var filters = [{
label: 'Brand',
name: 'brand',
values: {
Blackberrys: 503,
Arrow: 175,
ParkAvenue: 358
}
}, {
label: 'Color',
name: 'color',
values: {
Black: 100,
Green: 200,
Red: 300
}
}]
function loadFilters() {
$scope.filters = filters.map(function(filter) {
var filter = angular.copy(filter);
for (var key in filter.values) {
filter.values[key] = {
selected: false,
count: filter.values[key]
}
}
return filter;
})
}
loadFilters();
Then you can call loadFilters() any time you want to clear all filters. Please see POC attached below.
https://plnkr.co/edit/SADPoUpftnJkg1rMuSB9?p=preview
You should try 'ng-change' on checkboxes to trigger a method which changes the values according to checked and unchecked checkboxes.
For Ex.
<input type="checkbox" ng-model='isSelected' ng-click='checkItem(key, k, isSelected)' ng-change="yourMethodHere()">
in JS:
$scope.yourMethodHere = function() {
if (isSelected) {
// filter the values here
} else {
// non filtered values
}
}
By doing this you do not need to even maintain the values of exiting checked/unchecked checkbox.
Im trying to find a way to change some html lines of a component dynamically.
<li *ngFor="p in persons" [attr.id]="p.id">
<span> {{ p.name }} </span>
<a (click)="getAge(p.id)">Get Age<a/>
</li>
If the user clicks on the Get Age link i would like to replace the content inside of the corresponding li tag to something like:
<span> {{ p.OtherProperty }} </span>
<a (click)="OtherMethod(p)">Call OtherMethod<a/>
I found that ComponentFactoryResolver to create dynamic components, but i found it too overwhelming for just 2 lines of html. And i tried to change it by hand using jquery but it does not work to create the event bindings:
getAge(id) {
//some work
//remove the corresponding <li> content
$('#' + id).append('<a (click)="getAnotherValue(p.name)">GetAnotherValue<a/>');
$('#' + id).append('<span> {{ p.age}} </span>'); //this obviously doesnt work. But thats the ideia.
}
So how can i replace some html tags with angular attributes dynamically?
You could access the person's Object property dynamically like this:
object[property]; // Where property is a string
// If property equals 'name', the above sentence would equal this:
object.name; // or `object['name'];`
So, following your example, you could do this:
export class App {
persons = [
{
id: 1,
name: 'John',
age: 25
},
{
id: 2,
name: 'Mike',
age: 30
}
];
selectedProperty = 'name';
constructor() {
}
getProperty(prop) {
this.selectedProperty = prop;
}
}
And in your template you could:
<div>
<li *ngFor="let p of persons" [attr.id]="p.id">
<span> {{ p[selectedProperty] }} </span>
<br>
</li>
<button (click)="getProperty('age')">Get Age</button>
<button (click)="getProperty('name')">Get Name</button>
</div>
If I understood well, this should do the trick. You can't use ngIf because if you have 60 properties or persons then will be somewhat caothic.
Check the Plunker
Use ngIf to activate the code as shown:
<li *ngFor="p in persons" [attr.id]="p.id">
<div *ngIf=!p?.touched>
<span> {{ p.name }} </span>
<a (click)="getAge(p)">Get Age<a/>
</div>
<div *ngIf=p?.touched>
<span> {{ p.age}} </span>
<a (click)="getAnotherValue(p.name)">GetAnotherValue<a/>
</div>
</li>
isGetAgeClicked=false;
getAge(person) {
//some work
//remove the corresponding <li> content
person.touched=true
}