angular material mat-checkbox binding problem - javascript

I am using angular material for checkbox.
in component.ts
dataList: any[] = [
{ name: 'EmployeeName', flag: true, 'label': 'Employee Name'},
{ name: 'EmployeeDepartment', flag: false, 'label': 'Employee Department'},
{ name: 'EmployeeExperience', flag: false, , 'label': 'Employee Experience'}
]; // will have 30+ element in array
html (this opens as modal)
<div *ngFor="let data of dataList">
<section>
<mat-checkbox [checked]="data.flag" (change)="onChange($event, data)">{{data.label}}</mat-checkbox>
</section>
</div>
<div>
<button (click)="onClose()">
Close
</button>
<button(click)="onApply()">Apply</button>
</div>
some of the checkbox will be pre-checked, if checked than behind modal there we will be filter dropdown for checked object.
problem is if I check the object(eg- Employee Department), than behind the modal that object(Employee Department) will be added instantly and the change in UI will be visible. what I want is add that filter object (user can select multiple object at a time) only after clicking apply button and changes in UI should be visible. if I click on close that nothing should be added.
html for behind modal page
//<ngx-select-dropdown> whole config is not listed
<div class="grid-container">
<ng-container *ngFor="let data of dataList">
<div class="grid-item" *ngIf="data.flag">
<div>
<p>{{data.name }}</p>
</div>
<ngx-select-dropdown [config]="config">
</ngx-select-dropdown>
</div>
</ng-container>
</div>
I tried keeping checkbox values in another object and set value only on click of apply but the problem persisted. what should I do in onChange($event, data) and onApply() so that I can achieve the behavior I want.
Thanks in Advance

You could simply save the checkbox values in another object and once the user hits the apply button then have your function for example
onApply() that will assign the new values from the checkbox to your data

Related

How to collapse only selected row ? Angular

I want to toggle only the selected row, but I can't do that?
Check my code all and demonstration is here: https://stackblitz.com/edit/test-trainin-2-gv9glh?file=src%2Fapp%2Fapp.component.scss
I'm currently toggle all the row and I only want the row where it was clicked.
Here 90 line of code. Here is start:
<div class="column-holder" *ngFor="let training of trainingExercises; let i = index;">
<div class="single-exe" [class]="{ 'collapse-row' : collapse}">
<h1 class="exerciseNameAbsolute"> {{ training.exerciseName }}</h1>
<i (click)="collapse = !collapse" class="dx-icon-collapse dx-icon-custom-style"></i>
<div class="column-holder" *ngFor="let training of trainingExercises; let i = index;">
<div class="single-exe" [class]="{ 'collapse-row' : training.collapse}">
<h1 class="exerciseNameAbsolute"> {{ training.exerciseName }}</h1>
<i (click)="training.collapse = !training.collapse" class="dx-icon-collapse dx-icon-custom-style"></i>
This is the suggestion I made from the comment. Add a collapse property to each of your training variables and default it to true/false depending upon what state you want them to start out in. Change your [class] to look at that scoped variable, and when you click the element that toggles the collapse, toggle that variable on the training variable.

Passing Dynamic Data Between Two Controllers

I am looking to pass an item from a controller's $scope element (in this case the 'header' and 'content') to a page that is redirected-to upon a click.
The way it is currently set up is as follow:
- Page #1 loads the masterArray, displaying all elements
- User then clicks on a button which is linked with the 'href' attribute
- When user clicks an href button, the new page (Page #2) is displayed.
My Question: How can I pass the 'header' and 'content' onto Page #2 and ensure that only the associated header/content (based on the link that is clicked) are mapped and displayed?
The code below is for the main page with all the data dynamically being displayed
app.controller("SomeController", function ($scope, $window) {
$scope.masterArray = [{
title: "MainTitle",
segments: [{
title: "SubTitle",
articles: [{
header: "Article1Header",
content: "SomeContent",
href: "http://uniqueURL1.com"
}, {
header: "Article2Header",
content: "SomeContent",
href: "http://uniqueURL2.com"
}, {
header: "Article3Header",
content: "SomeContent",
href: "http://uniqueURL3.com"
}, {
header: "Article4Header",
content: "SomeContent",
href: "http://uniqueURL4.com"
}]
}
}]
}];
Page #1
<div ng-controller="SomeController">
<div class="section">
<div class="segment" ng-repeat="m in shownArray">
<div ng-repeat="s in m.segments" ng-if="m.segments">
<h4 ng-show="filtered.length">{{s.title}} ({{filtered.length}})</h4>
<div template="basic" ng-repeat="a in s.articles|articleFilter:query as filtered" is-open="a.isOpen">
<h2 ng-bind-html="a.header | highlight:query"></h2>
<div>
<p ng-bind-html="a.content | highlight:query"></p>
<a class="button button-primary" ng-href="{{a.href}}">View</a>
</div>
</div>
</div>
</div>
</div>
</div>
Page #2 (Desired Result)
<div>
<h2>//DISPLAYS ASSOCIATED 'header'</h2>
<h3>//DISPLAYS ASSOCIATED 'content'</h3>
</div>
If you want to use URL Params, use $location.search:
$rootScope.header = $location.search().header;
You can also use $routeParams if you prefer to build your URL differently.
Both would require you to properly build ng-href:
ng-href="{{a.href+'?header='+a.header+'&content='+a.content}}"
If your architecture allows it, consider a single page app, in which you'd configure states with $stateProvider in your config() then use ui-sref to access them in your HTML.

Clear data object on route change

I have a data object that contains color item (string), and It's associated with radio input, where I have v-model on t.
I have Add To Cart button, which I display conditionally in template using v-if - so if color wasn't selected, the button won't be visible, otherwise it would be.
The problem is that color always keep one value, and If I switch to another product it would keep the value from previous product, and button would be visible instantly.
Is there a way to clear color string after route changes - there is $route.afterEach but I'm not sure how to use it here.
Thanks.
Code:
<div class="Radio">
<input
type="radio"
id="radio-{{ va.attributes.term_id }}"
name="variation"
value="{{ va.attributes.color_name }}"
v-model="color"
>
<label for="radio-{{ va.attributes.term_id }}"></label>
</div>
Stuff about buttons
<div v-if="color">
<button #click="addToBag" class="Btn Btn--primary Btn--expanded">Add to Bag</button>
</div>
<div v-else>
<button class="Btn Btn--primary Btn--expanded" disabled>Add to Bag</button>
</div>
There is data related to JS
data() {
return {
product: [],
shared: State.data,
color: ''
}
}
1.user a global event bus in the entry js
window.eventBus = new Vue();
2.add a event handler to this color picker component , ie in ready()
ready(){
var vm = this
eventBus.$on('clearColorPicker', function(){vm.color = ''})
}
3.trigger the clearColorPicker event in $route.afterEach by
eventBus.$emit('clearColorPicker')
This can help you to trigger some change to certain component during route change.
But I think In your case there is a better way like the changing of product trigger the color picker reset

ngFor hide unhide details

I have the following json array
users= [
{'name':'cliff'
'age':'44'
'bloodtype':'A'
'hobby':'Golf'
},
{'name':'andy'
'age':'30'
'bloodtype':'b'
'hobby':'running'
}]
and i have the following code which will loop through all users and display its details
<div *ngFor='let user of users >
<div>Name:{{user.name}}</div>
<div>Age:{{user.age}}</div>
<div>BloodType:{{user.bloodtype}}</div>
<div>Hobby:{{user.hobby}}</div>
More
</div>
What i want to do is to hide 'bloodtype', 'hobby' field on initial load for all users and unhide individual user details when the 'More' link is clicked. How can i accomplish this?
I have tried the following but clicking 'More' link will unhide all users details
<div *ngFor='let user of users >
<div>Name:{{user.name}}</div>
<div>Age:{{user.age}}</div>
<div [hidden]=isHidden>
<div>BloodType:{{user.bloodtype}}</div>
<div>Hobby:{{user.hobby}}</div>
<div>
<a href="#" (click)='isHidden=!isHidden'>More</a>
</div>
Have a seperate array which holds the current state:
additionalInfo: Array<boolean> = [ false, false ];
users: Array<any> = [
{'name':'cliff'
'age':'44'
'bloodtype':'A'
'hobby':'Golf'
},
{'name':'andy'
'age':'30'
'bloodtype':'b'
'hobby':'running'
}]
And modify your HTML template like this. Add the index variable in your *ngFor and then add the *ngIf on the divs and the anchor and also a (click) event to toggle the state.
<div *ngFor="let user of users; let i=index" >
<div>Name:{{user.name}}</div>
<div>Age:{{user.age}}</div>
<div *ngIf="additionalInfo[i]">BloodType:{{user.bloodtype}}</div>
<div *ngIf="additionalInfo[i]">Hobby:{{user.hobby}}</div>
<a *ngIf="!additionalInfo[i]" (click)="additionalInfo[i] = true">More</a>
</div>
Try with below ngFor :
<div *ngFor="let user of users" >
<div>Name:{{user.name}}</div>
<div>Age:{{user.age}}</div>
<div *ngIf="user.isMore">
<div>BloodType:{{user.bloodtype}}</div>
<div>Hobby:{{user.hobby}}</div>
</div>
<a *ngIf="!user.isMore" (click)="user.isMore = !user.isMore">More</a>
</div>
Use *ngIf
Implement click function, that return current person.
And then yo can do this. In this div you can add your field, that you want hide
<div *ngIf="currentPerson">
//your info
</div>
You can find full answer and exemple here

Knockout Has-focus with multiple inputs

I am using knockoutjs and in my Template i have a foreach loop that will display the data it grabs from the JSON data i want to set the focus to the first input on the screen it works perfectly when there is just on input on the screen but when it gets to the second screen there are two in puts it only sets focus to the last input on the screen
here is my HTML:
<div id="section">
<span data-bind="template: { name: 'screenTemplate', foreach: screens, as: 'screen'}"></span>
<script type="text/html" id="screenTemplate">
<!-- ko if: showFlds -->
<!-- ko if: showNote -->
<span data-bind="template: { name: 'fldTemplate', foreach: flds}"></span>
<!--/ko-->
<!--/ko-->
</script>
<script type="text/html" id="fldTemplate">
<form>
<span class="text" data-bind="text: fieldName"></span>
<br/>
<input type="text" class="inputVal" data-bind="valueUpdate: 'afterkeydown', value: inputValue, disable: (inputValue() == expectedValue()), visible:(inBool() != false)" />
<br/>
</form>
</script>
<div data-bind="visible:screens()[cScreen()].rdtNote() === true">
<h2 style="color: red"><span data-bind="text: rdtNotification()[0].description()"></span></h2>
<button data-bind="click: makeHidden">Acknowledged</button>
</div>
As shown the hasFocus is on the input in the field Template
I want to know if there is a way I can make it set focus on the first input and then move to the next input once that input is correct
If any more information is needed please ask I will do my best to provide
P.s
Any answer to this must also work in IE6 as it will eventually be running on a IE6 scanning gun
Current Progress:
I have used jQuery
$(document).ready(function(){
$('form').find('input[type=text],textarea,select').filter(':input:enabled:visible:first').focus();
})
But when using this it does not automatically select the next input when the screen changes is there a way to get that to work ?
SOLVED MY PROBLEM :
$(document).ready(function() {
$('form').find('input[type=text],textarea,select').filter(':input:enabled:visible:first').focus();
});
$(document).keyup(function(e){
$('form').find('input[type=text],textarea,select').filter(':input:enabled:visible:first').focus();
});
var e = $.Event("keyup", { keyCode: 13}); //"keydown" if that's what you're doing
$("body").trigger(e);
Using this I am able to set the focus to the first visible enabled input and then using jQuery to trigger the Enter Key key up I was able to make sure that the next input was always focused
Thanks #neps for the push in the right direction
Working Plunker

Categories