How can I pull a specific title from an array using Angular? - javascript

I am trying to pull a specific title from an array using Angular.
Whilst I can use ng-repeat to loop through all titles and print these to my news listing webpage, I only wish to pull the first heading in my array for the news details page. Do I need to use the ng-repeat or can I use something different?
I have tried using number:0 as well as json:0.
$scope.newsListings = [
{
title: "Why cooking is great";
},
{
title: "Windsurfing is fun";
}
];
<div ng-controller="primaryController">
<article>
<div ng-repeat="item in newsListings | json:0">
<h1>{{item.title }}</h1>
<p class="synopsis">{{item.synopsis}}</p>
</div>
<article>
</div>

If you want to show only one item, you can omit the ng-repeat part as you want only one item from your array. You need just to use index.
<div ng-controller="primaryController">
<article>
<div>
<h1>{{ newsListings[0].title }}</h1>
<p class="synopsis">{{ newsListings[0].synopsis }}</p>
</div>
<article>
</div>

You can actually use ng-model for this with a first element of array if you need 2 way binding as well (for inputs of course). For other purposes you can use just index.
<div ng-controller="primaryController">
<article>
<div>
<input type="text" ng-model="newsListings[0].title" />
</div>
<div ng-bind="newsListings[0]">
<h1>{{newsListings[0].title }}</h1>
<p class="synopsis">{{newsListings[0].synopsis}}</p>
</div>
<article>
</div>

Related

How to get the first class from two same classes with cheerio

currently i'm making a web scraper with node.Js using cheerio. i want to get the data inside the first of class="panel-items-list.
the html look like this
<div class="margin-bottom-=30">
<div class="side-list-panel">
<ul class="panel-item-list">...</ul>
</div>
</div>
<div class="margin-bottom-=30">
<div class="side-list-panel">
<ul class="panel-item-list">...</ul>
</div>
</div>
i already did like this
const relateArticle = $('.panel-items-list').map((i, section)=>{
let articles = $(section).find('h5');
return articles.text();
}).get();
but it return the data from both class="panel-items-list". how do i get data just from one class ? sorry my english is bad. thanks in advance !
To get the first class only from the .panel-item-list use .get(0) that means you are only selecting the first index found using .map
Also, in your current code jQuery your are not selecting the right class selector.
In addition use .trim() method when getting the text to clean up any unseen spaces within the text.
Live Working Demo:
const relateArticle = $('.panel-item-list').map((i, section) => {
let articles = $(section).find('h5');
return articles.text().trim();
}).get(0)
console.log(relateArticle) //Foo
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="margin-bottom-=30">
<div class="side-list-panel">
<ul class="panel-item-list">
<h5>
Foo
</h5>
</ul>
</div>
</div>
<div class="margin-bottom-=30">
<div class="side-list-panel">
<ul class="panel-item-list">
<h5>
Bar
</h5>
</ul>
</div>
</div>
Use first():
$('.panel-items-list').first().find('h5').text()

How can I use jquery to append a div for me which also includes all of it's nested divs as well?

When a user creates a product, I want that product to be broadcasted to all other users and dynamically added to their screens. So far the broadcast aspect works amazingly.
But how can I dynamically add in this '.product' class, as well as all of a nested divs in an easy way? At the moment the only thing I can think of is copying and pasting all of it's divs in a jquery variable and adding it that way- there must be an easier way.
Here is where products are first loaded in when the page loads
<div class="product" id="{{$product->id}}">
<div class="product-image"><img src="/imgs/products/{{$product->type_id}}.png"></div>
<div class="product-content">
<div class="product-title" id="product-title">
{{ strtoupper(\App\ProductType::where('id', $product->type_id)->first()->name)}}
</div>
<div class="product-price">PRICE PER UNIT: <div class="price-value" id="price">{{$product->price}}</div> EXENS</div>
<br/>
QUANTITY: <div class="quantity-value" id="quantity">{{$product->quantity_available}}</div>
#if(strpos(\App\Group::where('id', $player->group_id)->first()->options, "\"showName\":true") !== false)
<br/>
SELLER: <div class="seller" id="seller">{{\App\User::where('id',$product->seller_id)->first()->name}}</div>
#endif
<br/>
PRICE: <div class="total-price" id="total-price">{{$product->price * $product->quantity_available}}</div>
<form class="buy-product-form" action="/UoE/buy-product/{{$product->id}}" method="POST">
{{csrf_field()}}
<button class="pull-right btn btn-primary">BUY NOW</button>
</form>
</div>
</div>
When the event is received the only way I can think of doing it as:
var productToAdd="<div class='buy-product-form'><div id='price'></div> " +
"" +
"" + //insert a massive string here containing all the other aforementioned sub-divs
"" + //And populate with json data
"" +
"</div>";
$('.content').append(productToAdd);
My solution was to take the entire code posted in the question and do make it as a one big HTML tag. That way my JS function can append the page with a HTML product div and it will already be bound with the necessary event listeners.

Angulajs:Nested JSON array in ng-repeat not displaying the values

Here is my other_prizeJSON data
[{"prizeno":2,"prizedesc":"Rs
:100,000/-","totalamt":100000,"conslation":"f","prizeticket":[{"seriesname":"RJ","digit":443581,"district":"THRISSUR"},{"seriesname":"RK","digit":633225,"district":"THIRUVANANTHAPURAM"},{"seriesname":"RL","digit":328674,"district":"KOTTAYAM"},{"seriesname":"RG","digit":753947,"district":"PALAKKAD"},{"seriesname":"RE","digit":153871,"district":"ERNAKULAM"},{"seriesname":"RD","digit":394850,"district":"PALAKKAD"},{"seriesname":"RC","digit":162287,"district":"KOZHIKKODE"},{"seriesname":"RB","digit":315428,"district":"ALAPPUZHA"},{"seriesname":"RA","digit":706397,"district":"KOTTAYAM"},{"seriesname":"RH","digit":213805,"district":"IDUKKI"},{"seriesname":"RK","digit":633435,"district":"THIRUVANANTHAPURAM"},{"seriesname":"RL","digit":801842,"district":"KOTTAYAM"},{"seriesname":"RA","digit":275046,"district":"KOTTAYAM"},{"seriesname":"RB","digit":352182,"district":"KASARGODE"},{"seriesname":"RC","digit":347419,"district":"WAYANAD"},{"seriesname":"RD","digit":909948,"district":"MALAPPURAM"},{"seriesname":"RE","digit":138627,"district":"IDUKKI"},{"seriesname":"RG","digit":583798,"district":"KOTTAYAM"},{"seriesname":"RH","digit":557799,"district":"THIRUVANANTHAPURAM"},{"seriesname":"RJ","digit":837793,"district":"PALAKKAD"}]},{"prizeno":3,"prizedesc":"Rs
:10,000/-","totalamt":10000,"conslation":"f","prizeticket":{"seriesname":[],"digit":52012,"district":[]}},{"prizeno":4,"prizedesc":"Rs
:5,000/-","totalamt":5000,"conslation":"f","prizeticket":[{"seriesname":[],"digit":3795,"district":[]},{"seriesname":[],"digit":4012,"district":[]},{"seriesname":[],"digit":146,"district":[]},{"seriesname":[],"digit":7857,"district":[]},{"seriesname":[],"digit":5581,"district":[]},{"seriesname":[],"digit":4553,"district":[]},{"seriesname":[],"digit":1200,"district":[]},{"seriesname":[],"digit":7683,"district":[]},{"seriesname":[],"digit":5295,"district":[]},{"seriesname":[],"digit":7791,"district":[]}]},{"prizeno":5,"prizedesc":"Rs
:2,000/-","totalamt":2000,"conslation":"f","prizeticket":[{"seriesname":[],"digit":1841,"district":[]},{"seriesname":[],"digit":4560,"district":[]},{"seriesname":[],"digit":5234,"district":[]},{"seriesname":[],"digit":8664,"district":[]},{"seriesname":[],"digit":7982,"district":[]},{"seriesname":[],"digit":7335,"district":[]},{"seriesname":[],"digit":3849,"district":[]},{"seriesname":[],"digit":8760,"district":[]},{"seriesname":[],"digit":3543,"district":[]},{"seriesname":[],"digit":7865,"district":[]}]},{"prizeno":6,"prizedesc":"Rs
:1,000/-","totalamt":1000,"conslation":"f","prizeticket":[{"seriesname":[],"digit":9090,"district":[]},{"seriesname":[],"digit":8105,"district":[]},{"seriesname":[],"digit":6440,"district":[]},{"seriesname":[],"digit":8793,"district":[]},{"seriesname":[],"digit":1035,"district":[]},{"seriesname":[],"digit":7703,"district":[]},{"seriesname":[],"digit":7414,"district":[]},{"seriesname":[],"digit":1059,"district":[]},{"seriesname":[],"digit":3944,"district":[]},{"seriesname":[],"digit":7595,"district":[]},{"seriesname":[],"digit":5854,"district":[]},{"seriesname":[],"digit":6580,"district":[]},{"seriesname":[],"digit":7488,"district":[]},{"seriesname":[],"digit":4921,"district":[]},{"seriesname":[],"digit":7977,"district":[]},{"seriesname":[],"digit":158,"district":[]},{"seriesname":[],"digit":8635,"district":[]},{"seriesname":[],"digit":5597,"district":[]},{"seriesname":[],"digit":1997,"district":[]},{"seriesname":[],"digit":9732,"district":[]},{"seriesname":[],"digit":891,"district":[]},{"seriesname":[],"digit":5797,"district":[]},{"seriesname":[],"digit":1806,"district":[]},{"seriesname":[],"digit":8352,"district":[]},{"seriesname":[],"digit":3870,"district":[]},{"seriesname":[],"digit":3115,"district":[]}]},{"prizeno":7,"prizedesc":"Rs
:500/-","totalamt":500,"conslation":"f","prizeticket":[{"seriesname":[],"digit":8629,"district":[]},{"seriesname":[],"digit":3004,"district":[]},{"seriesname":[],"digit":2960,"district":[]},{"seriesname":[],"digit":4344,"district":[]},{"seriesname":[],"digit":9959,"district":[]},{"seriesname":[],"digit":1768,"district":[]},{"seriesname":[],"digit":367,"district":[]},{"seriesname":[],"digit":9917,"district":[]},{"seriesname":[],"digit":8403,"district":[]},{"seriesname":[],"digit":947,"district":[]},{"seriesname":[],"digit":2276,"district":[]},{"seriesname":[],"digit":4566,"district":[]},{"seriesname":[],"digit":2522,"district":[]},{"seriesname":[],"digit":6844,"district":[]},{"seriesname":[],"digit":430,"district":[]},{"seriesname":[],"digit":8319,"district":[]},{"seriesname":[],"digit":1661,"district":[]},{"seriesname":[],"digit":4134,"district":[]},{"seriesname":[],"digit":6830,"district":[]},{"seriesname":[],"digit":5016,"district":[]},{"seriesname":[],"digit":8097,"district":[]},{"seriesname":[],"digit":7708,"district":[]},{"seriesname":[],"digit":6577,"district":[]},{"seriesname":[],"digit":134,"district":[]},{"seriesname":[],"digit":5229,"district":[]},{"seriesname":[],"digit":2329,"district":[]},{"seriesname":[],"digit":9174,"district":[]},{"seriesname":[],"digit":3712,"district":[]},{"seriesname":[],"digit":7316,"district":[]},{"seriesname":[],"digit":8242,"district":[]},{"seriesname":[],"digit":3538,"district":[]},{"seriesname":[],"digit":4243,"district":[]},{"seriesname":[],"digit":7288,"district":[]},{"seriesname":[],"digit":8270,"district":[]},{"seriesname":[],"digit":4060,"district":[]}]},{"prizeno":8,"prizedesc":"Rs
:100/-","totalamt":100,"conslation":"f","prizeticket":[{"seriesname":[],"digit":7062,"district":[]},{"seriesname":[],"digit":7981,"district":[]},{"seriesname":[],"digit":3890,"district":[]},{"seriesname":[],"digit":4997,"district":[]},{"seriesname":[],"digit":3009,"district":[]},{"seriesname":[],"digit":2103,"district":[]},{"seriesname":[],"digit":325,"district":[]},{"seriesname":[],"digit":3995,"district":[]},{"seriesname":[],"digit":3587,"district":[]},{"seriesname":[],"digit":1667,"district":[]},{"seriesname":[],"digit":3737,"district":[]},{"seriesname":[],"digit":3277,"district":[]},{"seriesname":[],"digit":9228,"district":[]},{"seriesname":[],"digit":6854,"district":[]},{"seriesname":[],"digit":9008,"district":[]},{"seriesname":[],"digit":8170,"district":[]},{"seriesname":[],"digit":7364,"district":[]},{"seriesname":[],"digit":199,"district":[]},{"seriesname":[],"digit":4286,"district":[]},{"seriesname":[],"digit":9285,"district":[]},{"seriesname":[],"digit":2873,"district":[]},{"seriesname":[],"digit":2636,"district":[]},{"seriesname":[],"digit":337,"district":[]},{"seriesname":[],"digit":8529,"district":[]},{"seriesname":[],"digit":7677,"district":[]},{"seriesname":[],"digit":1236,"district":[]},{"seriesname":[],"digit":1142,"district":[]},{"seriesname":[],"digit":5923,"district":[]},{"seriesname":[],"digit":2026,"district":[]},{"seriesname":[],"digit":2461,"district":[]},{"seriesname":[],"digit":4696,"district":[]},{"seriesname":[],"digit":9062,"district":[]},{"seriesname":[],"digit":4848,"district":[]},{"seriesname":[],"digit":9409,"district":[]},{"seriesname":[],"digit":5198,"district":[]},{"seriesname":[],"digit":5735,"district":[]},{"seriesname":[],"digit":7926,"district":[]},{"seriesname":[],"digit":8557,"district":[]},{"seriesname":[],"digit":3853,"district":[]},{"seriesname":[],"digit":713,"district":[]},{"seriesname":[],"digit":8026,"district":[]},{"seriesname":[],"digit":4445,"district":[]},{"seriesname":[],"digit":3326,"district":[]},{"seriesname":[],"digit":1485,"district":[]},{"seriesname":[],"digit":2219,"district":[]},{"seriesname":[],"digit":6833,"district":[]},{"seriesname":[],"digit":6948,"district":[]},{"seriesname":[],"digit":757,"district":[]},{"seriesname":[],"digit":1226,"district":[]},{"seriesname":[],"digit":5657,"district":[]},{"seriesname":[],"digit":5052,"district":[]},{"seriesname":[],"digit":7343,"district":[]},{"seriesname":[],"digit":5222,"district":[]},{"seriesname":[],"digit":6426,"district":[]},{"seriesname":[],"digit":148,"district":[]},{"seriesname":[],"digit":5230,"district":[]},{"seriesname":[],"digit":5701,"district":[]},{"seriesname":[],"digit":4860,"district":[]},{"seriesname":[],"digit":2885,"district":[]},{"seriesname":[],"digit":7078,"district":[]}]}]
I am trying to display prizeticket nested array in an html
<p ng-repeat="prize in other_prize">
{{prize.prizeno}}PRIZE
<p ng-repeat="each in prize.prizeticket">
{{each.district}}
</p>
</p>
But this ng-repeat didn't display the data
<p ng-repeat="each in prize.prizeticket">
{{each.district}}
</p>
However {{prize.prizeticket}} will returns the JSON array ,but it doesn't display the values in ng-repeat
Use for the outside element
<div ng-repeat="prize in other_prize">
{{prize.prizeno}}
<p ng-repeat="each in prize.prizeticket">
{{each.district}}
</p>
</div>
DEMO

Directive take other directive's data after deletion

Edit: Thanks to Simon Schüpbach, I was able to resolve the issue by changing the template. See the end for the solution.
Let's preface this by saying that we are beginner to soft-intermediate in Angular.
On one of our project, we are using angularjs 1.4.x and also ng-cart (https://github.com/snapjay/ngCart). It worked great but then we were confronted with a demand from our client that created new weird issues.
We added fsCounter, as a directive, to the cart page so user can add or remove items. This all work great but the users also have the option to delete an item from the cart view. Deletion works as expected BUT it seems to affect the scope to the item that takes it place.
Let me make it clearer :
Let's say we have 2 products in our cart page, it displays something like that
Product_1 {price} {counter} {total} delete_btn
Product_2 {price} {counter} {total} delete_btn
Each fsCounter is its own scope
return {
restrict: "A",
scope: {
value: "=value",
index: "=index"
},
link: //other logic
However when we delete the first item, visually and in the directives, the data seems to shift. So our second row will now inherit the first row's counter.
Directive's data looks like this:
Product_1:
itemId:3,
quantity:2,
{other data}
Product_2:
itemId:8,
quantity:5,
{other data}
But once we delete the first directive (We get the scope, remove the DOM element, destroy the scope) the second directive will now have this data:
Product_2:
itemId:3,
quantity:2,
{other data}
Here is the template code :
<div class="unItem" ng-repeat="item in ngCart.getCart().items track by $index">
<div class="photo"><img src="{[{ item.getImage() }]}" alt=""></div>
<div class="details">
<h3>{[{ item.getName() }]} <span>{[{ item.getPrice() | currency:$}]}</span></h3>
<md-select ng-model="attributes" placeholder="Attribut" class="select-attribut" ng-show="item.hasAttributes()" ng-change="item.updateSelected(attributes)">
<md-option ng-repeat="attr in item.getAttributes()" ng-selected="attr == item.getSelected()" ng-value="attr">{[{ attr }]}</md-option>
</md-select>
</div>
<div class="quantity">
<div fs-counter-dynamic value="itemQuantity"
data-min="1"
data-max="999"
data-step="1"
data-addclass="add-quantity"
data-width="130px"
data-itemid="{[{ item.getId() }]}"
data-editable
ng-model="itemQuantity"
name="quantity" id="quantity-{[{ item.getId() }]}",
index="{[{ item.getId() }]}"
></div>
</div>
<div class="total">Total : {[{ item.getTotal() | currency }]}</div>
<div class="delete"><a ng-click="ngCart.removeItemById(item.getId());"></a></div>
</div>
Is this normal behavior? Is there any way to force the directive to keeps its own data? From what I've understood, each directive has its own scope, so what I think happens is that, when we remove the first one, it keeps the data stored in some kind of array that says "directive 1 data is : " and when we delete the first directive, the second one becomes the first.
So basically, are we doing anything wrong or is there anyway to remap the data?
Hope it was clear enough,
Thanks!
Edit: added html code
Edit2: Answer :
New FsCounter template looks like this:
<div fs-counter-dynamic value="item._quantity"
data-min="1"
data-max="999"
data-step="1"
data-addclass="add-quantity"
data-width="130px"
data-itemid="{[{ item.getId() }]}"
data-editable
ng-model="item._quantity"
name="quantity" id="quantity{[{ item.getId() }]}"
></div>
Do you know ng-repeat, then you don't have such problems
<div ng-repeat="product in products">
<fs-counter index="product.index" value="product.value"></fs-counter>
</div>
and in your controller
$scope.products = [
{index:1, value:"Cola"},
{index:2,,value:"Fanta"}
]
to remove an element you just have to do
$scope.products.splice(0,1);
Edit:
I suggest to save all necessary data inside the item you use inside ng-repeat. Your problem is, that you mix data from array with other data from your $scope. It is possible to $watch changes in your directive, but if you set them with ng-repeat everything is done automatically.
$scope.products = [
{index:1, name:"Cola", price:1.50, image:"your/path.png", attributes:{...}},
{index:2, name:"Fanta", price:1.40, image:"your/path.png"}
]
And then in your html
<div class="unItem" ng-repeat="item in ngCart.products track by $index">
<div class="photo"><img ng-src="item.image" alt=""></div>
<div class="details">
<h3>{{item.name}} <span>{{item.price | currency}}</span></h3>
</div>
<div class="quantity">
<div fs-counter-dynamic value="item.quantity"
data-min="1"
data-max="999"
data-step="1"
data-addclass="add-quantity"
data-width="130px"
data-itemid="item.index"
data-editable
ng-model="item.quantity"
name="quantity" id="{{'quantity-' + $index}}",
index="item.index"
></div>
</div>
<div class="total">Total : {{ item.price * item.quantity | currency }}</div>
<div class="delete"><a ng-click="ngCart.removeItemById(item.index);"></a></div>
</div>

How to show the first n number of elements in jQuery?

I have a page that has 50 elements with the same class "fields" which are all display none at the moment
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
<div class="fields" style="display:none;">
...
</div>
...
How to I only show the first 3 or whatever number. Plus count them with a count on top like the following example below.
So for example if I needed the first 3 this is what i need the divs to look like
<div class="fields">
<h1>Station 1</h1>
</div>
<div class="fields">
<h1>Station 2</h1>
</div>
<div class="fields">
<h1>Station 3</h1>
</div>
<div class="fields" style="display:none;">
...
</div>
...
So basically only some the number of divs that I need...I already have the number of elements I need to show in this blur statement in the station_count variable. Also notice i need a span tag with the count..any ideas on how to do this
$("#number_station").blur(function(){
var station_count = $(this).val();
//code goes there
});
How to I only show the first 3 or whatever number.
$('div.fields:lt(3)').show();
Plus count them with a count on top
$('div.fields:lt(3)').each(function (index)
{
$('<h1></h1>', {text: 'Station ' + index}).prependTo(this);
}).show();
Demo: http://jsfiddle.net/mattball/TssUB/
Read the jQuery API docs for basic questions like this:
:lt() selector
.prependTo()
jQuery() (for creating new elements)
While the other answers will work, I recently discovered and love the jQuery slice() method.
$(".fields").slice(0, 3).each(function(index) {
// Do whatever you want to the first three elements
}
With
$(".fields").each(function() {
//do whatever like count then show/hide
});
you can iterate over the hidden divs. So with a simple variable you can start/stop whenever you need.

Categories