I have two pngs, one with an empty star one with a full star. Depending on the ratings from 1-5 I want to add or remove more star images. Here is my code that doesn't work:
<div>
<img ng-repeat="i in getNumberOfFullStars(company.AverageReview)" ng-src="{{starPhoto}}">
<img ng-repeat="i in getNumberOfEmptyStars(company.AverageReview)" ng-src="{{emptyPhoto}}">
</div>
JS
$scope.getNumberOfFullStars = function(num){
return new Array(num);
};
$scope.getNumberOfEmptyStars = function(num){
var emptyCount = 5-num;
return new Array(emptyCount);
};
Any thoughts? Thank you for the help
Instead of two seperate images, you can just use one and then check against $index. Modify to meet your needs
<div>
<img data-ng-repeat="i in ratings" data-ng-src="{{ ($index < company.AverageReview) && starPhoto || emptyPhoto }}" />
</div>
$scope.ratings=[];
$scope.ratings.length = 5;
Related
I am a beginner in JavaScript and I can't figure out the following problem: I am trying to create a simple JavaScript Movie List. I have 10 lists on the Movie List. I tried to show all of the lists with for loop, but it doesn't work.
Here's the code:
function renderModal() {
for (let i = 0; i < listMovies.length; i++) {
let movieData = listMovies[i];
document.getElementById("poster").src = movieData.img;
document.getElementById("title").innerHTML = movieData.name;
document.getElementById("genre").innerHTML = movieData.genre;
document.getElementById("rating-num").innerHTML = "Rating: "+ movieData.rating + "/10";
document.getElementById("movie-desc").innerHTML = movieData.desc;
document.getElementById("imdb-page").href = movieData.link;
return movieData;
}
}
What do I have to do?
Help me to fix it!.
You can use template tag for list and render it into target element.I am showing an example.
Movie list
<div id="movieList"></div>
template for list
<template id="movieListTemplate">
<div class="movie">
<img src="" class="poster" alt="">
<div class="title"></div>
<div class="genre"></div>
<div class="rating-num"></div>
<div class="movie-desc"></div>
<div class="imdb-page"></div>
</div>
</template>
Javascript code:
if (listMovies.length > 0) {
const movileListTemplate = document.getElementById('movieListTemplate')
const movieRenederElement = document.getElementById('movieList')
for(const movie of listMovies) {
const movieEl = document.importNode(movileListTemplate.content, true)
movieEl.querySelector('.poster').src = movie.img
movieEl.querySelector('.title').textContent = movie.name
//use all queryselector like above
}
}
Your return movieData; will stop the loop dead. Not that running it more than once will change anything since you change the same elements over and over. IDs must be unique.
Here is a useful way to render an array
document.getElementById("container").innerHTML = listMovies.map(movieData => `<img src="${movieData.img}" />
<h3>${movieData.name}</h3>
<p>${movieData.genre}</p>
<p>Rating: ${movieData.rating}/10</p>
<p>${movieData.desc}
IMDB
</p>`).join("<hr/>");
With return movieData, the for loop will ends in advance.You should put it outside the for loop.
I am making a Memory cards game(where cards are flipped on their back and you must open and find the pairs)
I have 12 divs with 12 images and there 6 pairs of images. How can I write JS or jQuery code to check if the images are the same ?
I added data index to divs with setAttribute but on console.log they print undefined.
<div class="frontCard">
<img src="frontCard1.jpg" alt="">
</div>
<div class="frontCard">
<img src="frontCard2.jpg" alt="">
</div>
<div class="frontCard">
<img src="frontCard1.jpg" alt="">
</div>
and js code
const item = document.querySelectorAll(".card");
item.forEach((item, index) => {
item.setAttribute("data-index", index);
})
var openCards = 0;
var points=0;
$(".card").click(function() {
if (openCards >= 2) {
$(".card").removeClass('cardOpen');
$(this).addClass('cardOpen');
openCards = 1;
} else {
$(this).addClass('cardOpen');
openCards++;
if (openCards == 2) {
if (true)//this is where i need the condition
{
const openCard = document.querySelectorAll(".cardOpen");
console.log("index:" + openCard.index);
points++;
console.log(points);
}
}
}
});
basically there are multiple things wrong in your js.
First of - shouldn't .card be .frontCard?
I got a code which is working as expected, even though it might not be the most beuatiful.
Check out the snippet
const item = document.querySelectorAll(".frontCard");
item.forEach((item, index) => {
item.setAttribute("data-index", index);
})
var openCards = 0;
var points=0;
$(".frontCard").click(function() {
if (openCards >= 2) {
$(".frontCard").removeClass('cardOpen');
openCards = 1;
$(this).addClass('cardOpen');
} else {
$(this).addClass('cardOpen');
openCards++;
if (openCards == 2) {
if ($($(".cardOpen")[0]).find("img")[0].src == $($(".cardOpen")[1]).find("img")[0].src){
const openCard = document.querySelectorAll(".cardOpen");
console.log("index:" + openCard.index);
points++;
console.log(points);
$(".frontCard").removeClass('cardOpen');
}else{
console.log("NoPoints")
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="frontCard">
<img src="https://seomofo-da30.kxcdn.com/wp-content/uploads/2010/05/google_logo_new.png" alt="test">
</div>
<div class="frontCard">
<img src="https://i.dlpng.com/static/png/9013_preview.png" alt="test2">
</div>
<div class="frontCard">
<img src="https://seomofo-da30.kxcdn.com/wp-content/uploads/2010/05/google_logo_new.png" alt="test3">
</div>
Assuming that your cards are using the same image, you could check against that. This would require adding ID fields to each card in order to compare the individual cards.
A better way to do this would be to write some JavaScript to contain the cards in an array and fill the array with some ints such as [0,0,1,1,2,2...]. You could then use that to shuffle the cards, or display them and check their values. Just leave yourself a comment as to which number corresponds to which card:)
This would also allow you to display them dynamically if you always start with the back image and then replace the element by ID with the appropriate new image (or lay it over top of it to hide it)
I am being able to provide option's in the menu bar but when I click on any of the option it's working absolutely fine,but if I tried to select twice it is changing at all places.
For Ex.
I want to make a ordered list such as:
1.Some Text here
a.option 1 b.option 2
c.option 3 d.option 4.
When I am trying to select some text its also converting 1 to A.
Please help.Thanks in advance
document.execCommand('insertUnorderedList',true,null);
let selectedStyle = event.target.parentNode.classList.value;
$('li').attr('id', function(i) {
return 'unorder'+(counter+1);
});
$('ol > li').css({'list-style-type':selectedStyle});
You can ignore the counter part its not required.I was trying to put id at every element and use jquery to update only that part.
let counter = 0;
document.querySelectorAll (".unorder-list-select .unorder-list-main .unorder-container ul").forEach((elem)=>{
elem.addEventListener("click",(event)=>{
counter++;
$('li').attr('id', function(i) {
return 'unorder'+(counter+1);
});
$('ul > li').css({'list-style-type':selectedStyle});
}
HTML
<div class="order-list-select" id="orderList" draggable="true">
<div>
<span class="jodit_popup_triangle"></span>
<div class="math-toolbar-top" id="orderlistHeader"></div>
<div class="order-list-main">
<div class="order-list-container"></div>
<div class="order-container">
<ol class="upper-roman">
<li><hr></li>
</ol>
<ol class="decimal">
<li><hr></li>
</ol>
</div>
</div>
</div>
</div>
Actual
1.text
2.text
Some text here
1.Txt
2.Txt
Expected
1.text
2.text
Some text here
a.Txt
b.Txt
I did it by Jquery don't know if its right approach but it has made me achieve my task.
Below is the code for my this.
document.querySelectorAll(".unorder-list-select .unorder-list-main .unorder-container ul").forEach((elem)=>{
elem.addEventListener("click",(event)=>{
counter++;
document.execCommand('insertUnorderedList',true,null);
let selectedStyle = event.target.parentNode.classList.value;
let select = window.getSelection().focusNode.parentElement.parentElement;
let ul_id = ""
$(select).attr('id', function(i) {
ul_id = "unorder"+(counter);
return ul_id;
});
if(selectedStyle == "right-arrow"){
$('#'+ul_id).css({'list-style-image':`url('icons/list-right-editor.svg')`});
}else if(selectedStyle == "open-square"){
$('#'+ul_id).css({'list-style-image':`url('icons/square-open-editor.svg')`});
}else{
$('ul').attr('type',function(){
return selectedStyle;
})
$('#'+ul_id).css({'list-style-type':selectedStyle});
}
document.querySelector(".unorder-list-select").remove();
})
});
Please change the classess accordingly to get the tag and click.
I am trying to have 4 boxes always show up. The boxes are filled by an image,but if there is no image available I want the boxes to be gray. The images variable holds an unknown amount of images, it could be 2 it could be 30.
<div class="container">
<div class="picture" ng-repeat="image in images | limitTo: 4"></div>
// PSEUDO CODE BELOW
<div class="empty" ng-repeat="i in 4 - images.length"></div>
// PSEUDO CODE ABOVE
</div>
"4 - images.length" is pseudo code, This is what I want to achieve, thinking if I only have 3 images available the result will be 1 gray box. But this syntax obviously does not work since ng-repeat require a collection.
Which made me try to provide it said collection through a function:
$scope.getNumber = function(num) {
return new Array(num);
}
and use in the following way:
<div class="empty" ng-repeat="n in getNumber(4 - cookbook.images.length)"></div>
But with no success.
<div class="picture" ng-repeat="image in images | limitTo: 4">hi</div>
<div class="empty" ng-repeat="n in [] | range:images.length:4">hey</div>
I've created a custom filter for it:
app.filter('range', function() {
return function(input, min, max) {
min = parseInt(min);
max = parseInt(max);
for (var i=min; i<max; i++) {
input.push(i);
}
return input;
};
});
DEMO
Possible repeat question
By using this updated syntax you can iterate with a specific index defined
HTML
<div ng-app="myapp">
<div ng-controller="ctrlParent">
<ul>
<li ng-repeat="i in getNumber(4) track by $index"><span>{{$index+1}}</span></li>
</ul>
</div>
Controllers
var app = angular.module('myapp',[]);
app.controller('ctrlParent',function($scope){
$scope.getNumber = function(num) {
return new Array(num);
}
});
Way to ng-repeat defined number of times instead of repeating over array?
I would probably handle this in whatever populates $scope.images. For example, something like:
$http.get('api/some/images?skip=10&take=4')
.success(function(response){
$scope.images = response;
for(var i = $scope.images.length; i<4; i++){
$scope.images.push('empty');
}
});
Then my template would just handle that:
<div class="container>
<div ng-repeat="image in images" ng-class="{empty:image=='empty',picture:image!='empty'}"></div>
</div>
wouldnt be easier to make operation modulo in controller?
function equal_number_of_images(){
for(var i = 0, add = 4 - $scope.some_files%4; i < add; i++ ){
$scope.some_files.push('');
}}
I am creating ListView using my template:
HTML:
<div id="ItemTemplate" data-win-control="WinJS.Binding.Template">
<div class="ItemTemplate">
<div class="back"></div>
<div data-win-bind="innerText:Info.shortName" class="shortName"></div>
<div data-win-bind="innerText:value Converters.BeginValue" class="value"></div>
<div data-win-bind="innerText:value Converters.EndValue" class="valueEnd"></div>
<div data-win-bind="innerText:Info.longName"></div>
<img data-win-bind="src:Info.flag" class="flag" />
<div data-win-bind="innerText:change Converters.BeginChange" class="change"></div>
<div data-win-bind="innerText:change Converters.EndValue" class="changeEnd"></div>
<div data-win-bind="innerText:changePercent Converters.BeginChangePercent" class="changePercent"></div>
<div data-win-bind="innerText:changePercent Converters.EndValue" class="changePercentEnd"></div>
</div>
</div>
The issue is when I meet the very long name I need to adjust font-size.
So I do (for each element in list):
JavaScript:
template = document.getElementById('ItemTemplate');
// Adjust font - size
var name = item.data.Info.longName;
// Split by words
var parts = name.split(' ');
// Count words
var count = parts.filter(function(value) {
return value !== undefined;
}).length;
var longNameDiv = $(template).children("div").children("div").eq(4);
if (count > 2) {
// Display very long names correctly
$(longNameDiv).removeClass();
$(longNameDiv).addClass("veryLongName");
}
var rootDiv = document.createElement('div');
template.winControl.render(item.data, rootDiv);
return rootDiv;
CSS:
.veryLongName {
font-size: 10pt;
}
But it doesn't effect selectivly. Moreover seems like it is check conditions for the first time and then just apply the same setting for remaining items. But it needs to change font-size to smaller only in case if the name is too long. So what am I doing wrong? Thanks.
Try by using following code instead, but u must include jquery for it.
jsfiddle : http://jsfiddle.net/vH6G8/
You can do this using jquery's filter
$(".ItemTemplate > div").filter(function(){
return ($(this).text().length > 5);
}).addClass('more_than5');
$(".ItemTemplate > div").filter(function(){
return ($(this).text().length > 10);
}).removeClass('more_than5').addClass('more_than10');
DEMO