I need to get selected item but in nested array.
First check my code:
<div class="column-holder" *ngFor="let training of data.trainingExercise
{
"exerasdasd":""
},
{
"isWsadad":""
}
]
}
]
}
]
}
Now i need on click to get only selected set. Single Value!
dsadsa(e){
dsa.log(e)
dsa.dsadas = e;
}
This is good but i need only single value.
In my selectedSetValue i want to show only single value.
Right now i got values in all array.
I want only selected value and selected index. This is important selected values by index
both here
<div class="column-holder" *ngFor="let training of data.trainingExercises; let i = index;">
and here
<div class="second-box-70" *ngFor="let set of training.sets; let i = index;">
you have let i = index;. Change the second one to let j = index; or something, so they are not the same
please try this, change
<div class="second-box-70" *ngFor="let set of training.sets; let i = index;">
<div class="circle-exercise">
<div class="circle-div">
<div class="num-series">
Series
</div>
<div class="circle" (click)="selectedSet(set)">
<input [(ngModel)]="set.value" class="input-invisible-for-sets" type="type">
</div>
</div>
</div>
</div>
<p class="notes" *ngIf="selectedSetValue">
{{ this.selectedSetValue.note }}
</p>
</div>
to this
<div class="second-box-70" *ngFor="let set of training.sets; let j = index;">
<div class="circle-exercise">
<div class="circle-div">
<div class="num-series">
Series
</div>
<div class="circle" (click)="selectedSet(set,j)">
<input [(ngModel)]="set.value" class="input-invisible-for-sets" type="type">
</div>
</div>
</div>
</div>
<p class="notes" *ngIf="selectedSetValue">
{{ this.selectedSetValue.note }}
</p>
</div>
ts
selectedSet(object,index){
this.selectedSetValue = object;
}
Related
I have a cart page with multiple products that have a new price. I now want to show the customer, using JS, how much he can save. For that I use my very basic knowledge of JS to write the old and new price into a variable, replace stuff I don't want in there like "€" and do my math. Then I create a new div with a certain text and how much the customer can save. What I want to achieve is that he writes that under every product.
As you can see from the snippet he only does that for the first product. I need some kind of loop or anything where he does that code for every product in the cart. So far I searched for 2 hours and couldn't find a hint. Maybe you guys and girls can help me.
var neuerpreis = document.querySelector(".price.price--reduced").childNodes[2].nodeValue.replace(/,/g, '.').replace(/ /g, '');
var alterpreis = document.querySelector(".price.price--reduced .price__old").childNodes[2].nodeValue.replace(/,/g, '.').replace(/ /g, '');
var difference = (alterpreis - neuerpreis).toFixed(2);
var newDiv = document.createElement("div");
var newContent = document.createTextNode(("You save ") + difference + (" €"));
newDiv.appendChild(newContent);
document.querySelector(".cart-item__price").appendChild(newDiv);
<div class="cart-item ">
<div class="cart-item__row">
<div class="cart-item__image">
<div class="cart-item__details">
<div class="cart-item__details-inner">
<div class="cart-item__price">
<div class="price price--reduced">
<span class="price__currency">€</span> 66,95<span class="price__old">
<span class="price__currency">€</span> 79,00</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cart-item ">
<div class="cart-item__row">
<div class="cart-item__image">
<div class="cart-item__details">
<div class="cart-item__details-inner">
<div class="cart-item__price">
<div class="price price--reduced">
<span class="price__currency">€</span> 100,95<span class="price__old">
<span class="price__currency">€</span> 79,00</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You can use querySelecetorAll and relative addressing
I select the .cart-item__price as the relevant container
Then I set some content as default
Note I do not convert to the string (toFixed) until I want to present it.
The INTL number formatter could also be used here
[...document.querySelectorAll(".cart-item__price")].forEach(div => {
const neuerpreis = div.querySelector(".price--reduced").childNodes[2].nodeValue.replace(/,/g, '.').replace(/ /g, '');
const alterpreis = div.querySelector(".price__old").childNodes[2].nodeValue.replace(/,/g, '.').replace(/ /g, '');
const difference = alterpreis - neuerpreis;
let newContent = document.createTextNode("No savings on this product")
const newDiv = document.createElement("div");
if (difference > 0) {
newContent = document.createTextNode(("You save ") + difference.toFixed(2) + (" €"));
}
newDiv.appendChild(newContent);
div.appendChild(newDiv);
})
<div class="cart-item ">
<div class="cart-item__row">
<div class="cart-item__image">
<div class="cart-item__details">
<div class="cart-item__details-inner">
<div class="cart-item__price">
<div class="price price--reduced">
<span class="price__currency">€</span> 66,95
<span class="price__old">
<span class="price__currency">€</span> 79,00
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="cart-item ">
<div class="cart-item__row">
<div class="cart-item__image">
<div class="cart-item__details">
<div class="cart-item__details-inner">
<div class="cart-item__price">
<div class="price price--reduced">
<span class="price__currency">€</span> 100,95<span class="price__old">
<span class="price__currency">€</span> 79,00</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
var el = document.querySelectorAll(".test_class");
for (i = 0; i < el.length; i++) {
el[i].innerHTML = "test"+i
}
<div class="test_class">hey</div>
<div class="test_class">hey</div>
<div class="test_class">hey</div>
<div class="test_class">hey</div>
Here you go
I have some HTML - pretty nasty, but not mine and so I don't have control over it. I need to extract some data from the form, the First name value (ABDIGANI) and the Surname value (AHMED). What is the best way to do this with javascript?
<div class="voffset3"></div>
<div class="container well panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-3">
<span class="ax_paragraph">
First name
</span>
<div class="form-group">
<div class="ax_h5">
ABDIGANI
</div>
</div>
</div>
<div class="col-md-3">
<span class="ax_paragraph">
Surname
</span>
<div class="form-group">
<div class="ax_h5">
AHMED
</div>
</div>
</div>
</div>
</div>
</div>
</div>
You could consider HTML in most cases well structured. Try this the following snippet.
Edit: did a change due to the first comment.
Edit: if you have more than one rows, you should use
document.querySelectorAll('.container > .panel-body > .row');
and fetch the pairs for each found element as below.
const markers = ['First name', 'Surname'];
const mRx = [new RegExp(markers[0]), new RegExp(markers[1])];
function findMarker(element) {
for(let i = 0; i < mRx.length; i++) {
if(element.innerHTML.match(mRx[i])) {
return markers[i];
}
}
return null;
}
function findValue(el) {
return el.parentElement.querySelector('.form-group > div').innerHTML.trim();
}
const pairs = [... document.querySelectorAll('.ax_paragraph')]
.map(el => {
return {el: el, mk: findMarker(el)};
})
.filter(n => n.mk !== null)
.map(o => {
return {key: o.mk, value: findValue(o.el)};
});
console.log(pairs);
var x = document.querySelectorAll(".panel-body > div >.col-md-3 > div > div");
x.forEach(myFunction);
function myFunction(item, index) {
//console.log(item.innerHTML.trim());
if (index===0){
console.log("First name : "+item.innerHTML.trim());
}
if (index===1){
console.log("Surname : "+item.innerHTML.trim());
}
}
<div class="voffset3"></div>
<div class="container well panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-3">
<span class="ax_paragraph">
First name
</span>
<div class="form-group">
<div class="ax_h5">
ABDIGANI
</div>
</div>
</div>
<div class="col-md-3">
<span class="ax_paragraph">
Surname
</span>
<div class="form-group">
<div class="ax_h5">
AHMED
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Check this
const firstName = document.querySelector('.row .form-group div').textContent.trim();
const surname = document.querySelector('.row > div:last-child .form-group div').textContent.trim();
note: Its better to change html according to functionality needs, like if you need firstname then you must keep an id attribute to div which is having first name, same goes to surname. then select those fields using id selector, because even if you change html page structure in future, functionality will not get effected.
Check below for reference on how the html should actually be(just to make sure you know it, but the solution you are seeking is above in first two lines)
eg:
<div class="voffset3"></div>
<div class="container well panel panel-default">
<div class="panel-body">
<div class="row">
<div class="col-md-3">
<span class="ax_paragraph">
First name
</span>
<div class="form-group">
<div class="ax_h5" id="firstNameField">
ABDIGANI
</div>
</div>
</div>
<div class="col-md-3">
<span class="ax_paragraph">
Surname
</span>
<div class="form-group">
<div class="ax_h5" id="surnameField">
AHMED
</div>
</div>
</div>
</div>
</div>
</div>
</div>
document.querySelector('.form-group > div').textContent but without modifying the html there is no way to distinguish first name and surname.
If you can't edit the HTML, you can use the XPATH for Example.
I am trying to build a simple on page search that uses event listeners to look at a containers data and then hides that whole container if it doesn't have the required information.
So far I have:
// get search element
let searchInput = document.getElementById ('searchInput');
// add event listener
searchInput.addEventListener ('keyup', searchPage);
function searchPage(){
//search input detection
let searchValue = document.getElementById('searchInput').value;
//set parameters to search from
let parent = document.getElementById('product-container');
let child = parent.getElementsByTagName('span');
for(let i = 0;i < child.length;i++){
let a = child[i];
if(a.innerHTML.indexOf(searchValue) >= -1) {
child[i].parentNode.style.display = '';
} else {
child[i].parentNode.style.display = 'none';
};
};
};
But this only acts on the first product-container it finds, there are 5 such containers on the page.
How do I make this look through all containers, but hide the ones that don't contain any of the information typed in the search bar.
I am getting products from an API so using html replace to add to the following template:
<script id="template" type="text/template">
<div class="product">
<div class="product--header">{{ type }}</div>
<div class="product--image"><img src="../app/assets/images/no-image.png" alt="no image"> </div>
<div class="product--information" id="product--information">
<div class="product--title"><span>{{ name }}</span></div>
<!--This is just a place holder we would house the prices here if they were on the API -->
<div class="product--price">£55</div>
<div class="product--brand"><strong>Brand:</strong><span> {{ brand }}</span></div>
<div class="product--colour"><strong>Colour:</strong><span> {{ colour }}</span></div>
<div class="product--sizes">
<select>
<option value="" disabled selected>Select Size </option>
{{ options }}
</select>
</div>
<div class="product--description"><strong>Description:</strong><br><div class="product--description__content"><span> {{ description }} </span></div></div>
<div class="product--code"><strong>Product ID:</strong><span> {{ productid }}</span></div>
<div class="product--buttons">
<button class="btn--buy" aria-label="Add to Basket">Add to basket</button>
<button class="btn--save" aria-label="Save for Later">Save for later</button>
</div>
<button class="product--add-to-wishlist" aria-label="Add to Wishlist"><i class="fas fa-heart"></i></button>
</div>
</div>
</script>
The search box code is as follows:
<input type="text" name="search" id="searchInput" placeholder="Enter Search...">
and the code that the template goes into is:
<div id="product-container">
<div class="featured"></div>
<div class="products"></div>
</div>
Because you have multiple product containers, use document.getElementsByClassName() instead of document.getElementById() and provide product-container class as argument.
let searchInput = document.getElementsByClassName ('container');
You need to modify searchPage() method. Instead of using document to find searchValue and parent use this.
let searchValue = this.getElementsByClassName('searchInput')[0].value;
let parent = this.getElementsByClassName('container')[0];
Please, add HTML code.
EDIT: If I understand correctly you have one search input which will search multiple product containers. Here is one simple example, which you can easily apply to your problem.
HTML:
<input type="text" name="search" id="searchInput" placeholder="Enter Search...">
<div class="product-container">
<span class="product">Kiwi</span>
<p>Kiwi description</p>
</div>
<div class="product-container">
<span class="product">Banana</span>
<p>Banana description</p>
</div>
<div class="product-container">
<span class="product">Apple</span>
<p>Apple description</p>
</div>
JS:
let searchInput = document.getElementById ('searchInput');
searchInput.addEventListener ('keyup', searchPage);
function searchPage(){
let searchValue = this.value.toUpperCase();
let products = document.getElementsByClassName('product');
for(let i = 0; i < products.length; i++) {
console.log(products[i].innerHTML.toUpperCase());
if (products[i].innerHTML.toUpperCase().indexOf(searchValue) > -1)
products[i].parentNode.style.display = '';
else
products[i].parentNode.style.display = 'none';
};
};
CSS:
.product-container {
display: flex;
flex-direction: column;
margin-bottom: 10px;
background: grey;
}
.product-container span {
font-size: 20px;
}
.product {
display: block;
}
https://jsfiddle.net/gardelin/koc5eg6v/25/
Im not quite sure something like this is possible but say in my html component I have an ngFor like so..
<div *ngFor="let card of cards">
... stuff in here
</div>
now say I have an array of classNames like so
classNames = [
'red',
'yellow',
'blue',
'green'
]
and inside my *ngFor I have a div like so
<div *ngFor="let card of cards">
<div [class]='...'>
<div class="card">
</div>
</div>
</div>
basically what I want to happen is for every item in the ngFor give loop through the classNames array and dynamically add it to the incoming data so for example
say I have 6 items in cards so each card needs a classname so it loops through classNames and gives it a class so like this..
<div [class]='red'>
<div class="card">
</div>
</div>
<div [class]='yellow'>
<div class="card">
</div>
</div>
<div [class]='blue'>
<div class="card">
</div>
</div>
<div [class]='green'>
<div class="card">
</div>
</div>
<div [class]='red'>
<div class="card">
</div>
</div>
<div [class]='yellow'>
<div class="card">
</div>
</div>
and so on and so forth..
how could i accomplish something like this?
EDIT
component.html
<div class="card" *ngFor="let card of cards; let i = index">
<div [class]="classNames[i%classNames.length]">
....
</div>
</div>
component.ts
export class...
classNames = [
'light-green',
'dark-green',
'aqua',
'blue',
'blue-purple',
'purple',
'purple-pink',
'purple-orange'
];
You can leverage remainder (%) operator to achieve that:
<div *ngFor="let card of cards; let i = index">
<div [class]="classNames[i%classNames.length]">
<div class="card">
{{ card }}
</div>
</div>
</div>
Ng-run Example
Update:
You should define array as follows:
classNames = [
'light-green',
'dark-green',
'aqua',
'blue',
'blue-purple',
'purple',
'purple-pink',
'purple-orange'
];
Note: i use = instead of :
Instead of randomly applying any class to any card or deciding it on view based on some %, the best way, I believe would be read it from the Cards object itself, since it is logical to have all details of a card read from the card itself.
So that view is independent of those extra stuffs.
classNames = ['red','yellow','blue','green'];
cards = [{text: 1, class: this.classNames[0]},{text: 2, class: this.classNames[1]}];
your view should simply do its task (render)
<div *ngFor="let card of cards; let i = index">
<div [class]="card.class">
<div class="card">
{{ card.text}}
</div>
</div>
</div>
I am very new to the smart table. I have gone through its documentation on Smart Table.
But the I haven't found how to bind data on click event in smart table?
Code is very big but I am trying to post it here.
<div class="table-scroll-x" st-table="backlinksData" st-safe-src="backlinks" st-set-filter="myStrictFilter">
<div class="crawlhealthshowcontent">
<div class="crawlhealthshowcontent-right">
<input type="text" class="crserachinput" placeholder="My URL" st-search="{{TargetUrl}}" />
<a class="bluebtn">Search</a>
</div>
<div class="clearfix"></div>
</div>
<br />
<div class="table-header clearfix">
<div class="row">
<div class="col-sm-6_5">
<div st-sort="SourceUrl" st-skip-natural="true">
Page URL
</div>
</div>
<div class="col-sm-2">
<div st-sort="SourceAnchor" st-skip-natural="true">
Anchor Text
</div>
</div>
<div class="col-sm-1">
<div st-sort="ExternalLinksCount" st-skip-natural="true">
External<br />Links
</div>
</div>
<div class="col-sm-1">
<div st-sort="InternalLinksCount" st-skip-natural="true">
Internal<br />Links
</div>
</div>
<div class="col-sm-1">
<div st-sort="IsFollow" st-skip-natural="true">
Type
</div>
</div>
</div>
</div>
<div class="table-body clearfix">
<div class="row" ng-repeat="backlink in backlinksData" ng-if="backlinks.length > 0">
<div class="col-sm-6_5">
<div class="pos-rel">
<span class="display-inline wrapWord" tool-tip="{{ backlink.SourceUrl }}"><b>Backlink source:</b> <a target="_blank" href="{{backlink.SourceUrl}}">{{ backlink.SourceUrl }}</a></span><br />
<span class="display-inline wrapWord" tool-tip="{{ backlink.SourceTitle }}"><b>Link description:</b> {{ backlink.SourceTitle }}</span> <br />
<span class="display-inline wrapWord" tool-tip="{{ backlink.TargetUrl }}"><b>My URL:</b> <a target="_blank" href="{{backlink.TargetUrl}}">{{ backlink.TargetUrl }}</a></span><br />
</div>
</div>
<div class="col-sm-2">
<div class="pos-rel">
{{ backlink.SourceAnchor }}
</div>
</div>
<div class="col-sm-1">
<div>
{{ backlink.ExternalLinksCount }}
</div>
</div>
<div class="col-sm-1">
<div>
{{ backlink.InternalLinksCount }}
</div>
</div>
<div class="col-sm-1">
<div ng-if="!backlink.IsFollow">
No Follow
</div>
</div>
</div>
<div class="row" ng-if="backlinks.length == 0">
No backlinks exists for selected location.
</div>
</div>
<div class="pos-rel" st-pagination="" st-displayed-pages="10" st-template="Home/PaginationCustom"></div>
</div>
and my js code is here.
module.controller('backlinksController', [
'$scope','$filter', 'mcatSharedDataService', 'globalVariables', 'backlinksService',
function ($scope,$filter, mcatSharedDataService, globalVariables, backlinksService) {
$scope.dataExistsValues = globalVariables.dataExistsValues;
var initialize = function () {
$scope.backlinks = undefined;
$scope.sortOrderAsc = true;
$scope.sortColumnIndex = 0;
};
initialize();
$scope.itemsByPage = 5;
var updateTableStartPage = function () {
// clear table before loading
$scope.backlinks = [];
// end clear table before loading
updateTableData();
};
var updateTableData = function () {
var property = mcatSharedDataService.PropertyDetails();
if (property == undefined || property.Primary == null || property.Primary == undefined || property.Primary.PropertyId <= 0) {
return;
}
var params = {
PropertyId: property.Primary.PropertyId
};
var backLinksDataPromise = backlinksService.getBackLinksData($scope, params);
$scope.Loading = backLinksDataPromise;
};
mcatSharedDataService.subscribeCustomerLocationsChanged($scope, updateTableStartPage);
}
]);
module.filter('myStrictFilter', function ($filter) {
return function (input, predicate) {
return $filter('filter')(input, predicate, true);
}
});
But It is working fine with the direct search on textbox.
but according to the requirement I have to perform it on button click.
Your suggestions and help would be appreciated.
Thanks in advance.
You can search for a specific row by making some simple tweaks.
add a filter to the ng-repeat, and filter it by a model that you will insert on the button click, like so: <tr ng-repeat="row in rowCollection | filter: searchQuery">
in your view, add that model (using ng-model) to an input tag and define it in your controller
then pass the value to the filter when you click the search button
here's a plunk that demonstrates this
you can use filter:searchQuery:true for strict search
EDIT:
OK, so OP's big problem was that the filtered values wouldn't show properly when paginated, the filter query is taken from an input box rather then using the de-facto st-search plug-in, So I referred to an already existing issue in github (similar), I've pulled out this plunk and modified it slightly to fit the questioned use case.