Checkbox selected in tree-checklist - angularMateriel2 - angular-material2

I used the tree-checklist component in my app. Somebody know how I can get the nodes selected ?
I used this example : https://stackblitz.com/angular/nkmjydodvnp?file=app%2Ftree-checklist-example.ts
I tried to used the method isSelected(node) but it is not relevant.
Thanks !

component.ts
checkUncheckAll() {
this.nestedNodeMap.forEach((val: TodoItemFlatNode) => {
if (!val.level) {
this.todoItemSelectionToggle(val);
}
});
}
template.html
<button mat-raised-button color="primary" (click)="checkUncheckAll()">Check/Uncheck</button>

To check all by default i did this ,call this function inside constructor
selectAllIntial() {
for (let node in this.dataSource.data) {
this.todoItemSelectionToggle(this.transformer(this.dataSource.data[node], 0))
}
}

Related

Pass data to methods in Vue from template

I am using Vue.JS in my build in visualforce page.
I have below piece of Vue template code where I am able to get acc.name print on page. But now I need to send this value to addtoterriotry method inside methods section of Vue app.
Please find below my Vue app component.
<v-dialog v-model="addToTerr" max-width="1000">\
<v-card>\
<v-card-title class="headline">Review Selected Accounts</v-card-title>\
<v-card-text>\
<div v-for="acc in this.items" v-if="acc.selected">{{acc.Name}}</div>\
</v-card-text>\
<v-card-actions>\
<v-btn color="secondary" v-on:click="addToTerriotry">Add</v-btn>\
<v-btn v-on:click="addToTerr = false">Close</v-btn>\
</v-card-actions>\
</v-card>\
</v-dialog>\
addtoterriotry method :
methods: {
selectDeselectAccount: function (props) {
props.item.selected = props.item.selected ? false : true;
if (props.item.selected)
this.accountsSelected = this.accountsSelected + 1;
else
this.accountsSelected = this.accountsSelected - 1;
},
showaccount: function (props) {
this.selectedaccount = props.item;
this.accdetails = true;
},
addToTerriotry: function () {
alert('Invoke Controller Action');
// Fetch acc.name value here.
CallApexMethod();
}
Assuming that you mean that you are trying to access the acc with a selected value of true, just find that element from the items array at the beginning of your addToTerriotry method:
addToTerriotry: function () {
alert('Invoke Controller Action');
let acc = this.items.find(i => i.selected);
console.log(acc.name);
CallApexMethod();
}

Angular2 how to call a method only after subscribed data is completely bounded to a table using ng-for? [duplicate]

In Angular 1 I have written a custom directive ("repeater-ready") to use with ng-repeat to invoke a callback method when the iteration has been completed:
if ($scope.$last === true)
{
$timeout(() =>
{
$scope.$parent.$parent.$eval(someCallbackMethod);
});
}
Usage in markup:
<li ng-repeat="item in vm.Items track by item.Identifier"
repeater-ready="vm.CallThisWhenNgRepeatHasFinished()">
How can I achieve a similar functionality with ngFor in Angular 2?
You can use #ViewChildren for that purpose
#Component({
selector: 'my-app',
template: `
<ul *ngIf="!isHidden">
<li #allTheseThings *ngFor="let i of items; let last = last">{{i}}</li>
</ul>
<br>
<button (click)="items.push('another')">Add Another</button>
<button (click)="isHidden = !isHidden">{{isHidden ? 'Show' : 'Hide'}}</button>
`,
})
export class App {
items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
#ViewChildren('allTheseThings') things: QueryList<any>;
ngAfterViewInit() {
this.things.changes.subscribe(t => {
this.ngForRendred();
})
}
ngForRendred() {
console.log('NgFor is Rendered');
}
}
origional Answer is here
https://stackoverflow.com/a/37088348/5700401
You can use something like this (ngFor local variables):
<li *ngFor="#item in Items; #last = last" [ready]="last ? false : true">
Then you can Intercept input property changes with a setter
#Input()
set ready(isReady: boolean) {
if (isReady) someCallbackMethod();
}
For me works in Angular2 using Typescript.
<li *ngFor="let item in Items; let last = last">
...
<span *ngIf="last">{{ngForCallback()}}</span>
</li>
Then you can handle using this function
public ngForCallback() {
...
}
The solution is quite trivial. If you need to know when ngFor completes printing all the DOM elements to the browser window, do the following:
1. Add a placeholder
Add a placeholder for the content being printed:
<div *ngIf="!contentPrinted">Rendering content...</div>
2. Add a container
Create a container with display: none for the content. When all items are printed, do display: block. contentPrinted is a component flag property, which defaults to false:
<ul [class.visible]="contentPrinted">
...items
</ul>
3. Create a callback method
Add onContentPrinted() to the component, which disables itself after ngFor completes:
onContentPrinted() {
this.contentPrinted = true;
this.changeDetector.detectChanges();
}
And don't forget to use ChangeDetectorRef to avoid ExpressionChangedAfterItHasBeenCheckedError.
4. Use ngFor last value
Declare last variable on ngFor. Use it inside li to run a method when this item is the last one:
<li *ngFor="let item of items; let last = last">
...
<ng-container *ngIf="last && !contentPrinted">
{{ onContentPrinted() }}
</ng-container>
<li>
Use contentPrinted component flag property to run onContentPrinted() only once.
Use ng-container to make no impact on the layout.
Instead of [ready], use [attr.ready] like below
<li *ngFor="#item in Items; #last = last" [attr.ready]="last ? false : true">
I found in RC3 the accepted answer doesn't work. However, I have found a way to deal with this. For me, I need to know when ngFor has finished to run the MDL componentHandler to upgrade the components.
First you will need a directive.
upgradeComponents.directive.ts
import { Directive, ElementRef, Input } from '#angular/core';
declare var componentHandler : any;
#Directive({ selector: '[upgrade-components]' })
export class UpgradeComponentsDirective{
#Input('upgrade-components')
set upgradeComponents(upgrade : boolean){
if(upgrade) componentHandler.upgradeAllRegistered();
}
}
Next import this into your component and add it to the directives
import {UpgradeComponentsDirective} from './upgradeComponents.directive';
#Component({
templateUrl: 'templates/mytemplate.html',
directives: [UpgradeComponentsDirective]
})
Now in the HTML set the "upgrade-components" attribute to true.
<div *ngFor='let item of items;let last=last' [upgrade-components]="last ? true : false">
When this attribute is set to true, it will run the method under the #Input() declaration. In my case it runs componentHandler.upgradeAllRegistered(). However, it could be used for anything of your choosing. By binding to the 'last' property of the ngFor statement, this will run when it is finished.
You will not need to use [attr.upgrade-components] even though this is not a native attribute due to it now being a bonafide directive.
I write a demo for this issue. The theory is based on the accepted answer but this answer is not complete because the li should be a custom component which can accept a ready input.
I write a complete demo for this issue.
Define a new component:
import {Component, Input, OnInit} from '#angular/core';
#Component({
selector: 'app-li-ready',
templateUrl: './li-ready.component.html',
styleUrls: ['./li-ready.component.css']
})
export class LiReadyComponent implements OnInit {
items: string[] = [];
#Input() item;
constructor() { }
ngOnInit(): void {
console.log('LiReadyComponent');
}
#Input()
set ready(isReady: boolean) {
if (isReady) {
console.log('===isReady!');
}
}
}
template
{{item}}
usage in the app component
<app-li-ready *ngFor="let item of items; let last1 = last;" [ready]="last1" [item]="item"></app-li-ready>
You will see the log in the console will print all the item string and then print the isReady.
I haven't yet looked in depth of how ngFor renders elements under the hood. But from observation, I've noticed it often tends to evaluate expressions more than once per each item it's iterating.
This causes any typescript method call made when checking ngFor 'last' variable to get, sometimes, triggered more than once.
To guarantee a one call to your typescript method by ngFor when it properly finishes iterating through items, you need to add a small protection against the multiple expression re-evaluation that ngFor does under the hood.
Here is one way to do it (via a directive), hope it helps:
The directive code
import { Directive, OnDestroy, Input, AfterViewInit } from '#angular/core';
#Directive({
selector: '[callback]'
})
export class CallbackDirective implements AfterViewInit, OnDestroy {
is_init:boolean = false;
called:boolean = false;
#Input('callback') callback:()=>any;
constructor() { }
ngAfterViewInit():void{
this.is_init = true;
}
ngOnDestroy():void {
this.is_init = false;
this.called = false;
}
#Input('callback-condition')
set condition(value: any) {
if (value==false || this.called) return;
// in case callback-condition is set prior ngAfterViewInit is called
if (!this.is_init) {
setTimeout(()=>this.condition = value, 50);
return;
}
if (this.callback) {
this.callback();
this.called = true;
}
else console.error("callback is null");
}
}
After declaring the above directive in your module (assuming you know how to do so, if not, ask and I'll hopefully update this with a code snippet), here is how to use the directive with ngFor:
<li *ngFor="let item of some_list;let last = last;" [callback]="doSomething" [callback-condition]="last">{{item}}</li>
'doSomething' is the method name in your TypeScript file that you want to call when ngFor finishes iterating through items.
Note: 'doSomething' doesn't have brackets '()' here as we're just passing a reference to the typescript method and not actually calling it here.
And finally here is how 'doSomething' method looks like in your typescript file:
public doSomething=()=> {
console.log("triggered from the directive's parent component when ngFor finishes iterating");
}

ColdFusion ajax validation

in cf9 i have a page where i want to check if field value exist in db (via ajax). If it doesn't exist, i want to stop processing (return false). Everything works fine, except i don't know how to pass back to the main function the result of the ajax call
please help
<cfajaximport tags="cfmessagebox, cfwindow, cfajaxproxy">
<cfajaxproxy cfc="reqfunc" jsclassname="jsobj" />
<script language="JavaScript">
function checkRequired() {
var testVal = document.getElementById('myField').value;
return testAjax(testVal);
/* more processing that should stop if ajaxCallBack returns false */
}
function testAjax(testVal) {
var instance = new jsobj();
instance.setCallbackHandler(ajaxCallBack);
instance.checkProfile(testVal);
}
function ajaxCallBack(returns) {
alert(returns);
// returns correctly "true" if value checks against db, "false" if it doesn't
// HOW DO I PASS THIS VALUE BACK TO checkRequired ???
}
</script>
<form>
<input type="text" name="myField" id="myField" value=""><p>
<input type="button" value="Check with Ajax" onClick="return checkRequired()">
</form>
many thanks
Unless you build your main function to 'wait' for the return, you can't return your result to that instance of the function; it has already exited, so to speak. Using cfajax it is probably possible to tweak the main function to call and wait, but the simple solution is to have the callback subsequently recall your main function and treat the existence of the result/return as the flag as to whether to process or call the ajax.
function checkRequired(return) {
if(return != null) {
/* more processing */
} else {
testAjax(testVal);
}
}
function ajaxCB(return) {
checkRequired(return);
}
I would probably refactor a bit more but you should get the idea.
it's really kind of a hack, not what i was looking for, but for what it's worth: if i put this stanza at the very end of my function, with the callBack collapsed within the main function, it would work
function checkRequired() {
var testVal = document.getElementById('myField').value;
var instance = new jsobj();
var r = instance.setCallbackHandler(
function(returns) {
if(returns == 1) {
document.getElementById('testForm').submit();
} else { alert("Something wrong"); }
}
);
instance.checkProfile(testVal);
}

iScroll - property undefined error

I'm trying to add 2 instances of iScroll on one page yet I don't think that is the cause of this:
function loaded() {
$('.iScrolls').each(function(){
var $this = $(this);
var $id = $this.attr('id');
if( $id ) {
$scrollers[$id] = new iScroll( $id, {
snap: true,
momentum: false,
hScrollbar: false,
onScrollEnd: function () {
$('#indicator > li.active').removeAttr('class');
$('#indicator > li:nth-child(' + ( this.currPageX + 1) + ')').removeAttr('class').addClass('active');
}
});
$('.prev', $this).click(function(){
$scrollers[$id].scrollToPage('prev', 0);
return false;
});
$('.next', $this).click(function(){
$scrollers[$id].scrollToPage('next', 0);
return false;
});
}
});
}
document.addEventListener('DOMContentLoaded', loaded, false);
when the "scrollToPage is triggered I get the error:
Uncaught TypeError: Cannot read property 'length' of undefined
iScroll.scrollTo iScroll.js:984
iScroll._end iScroll.js:614
iScroll.handleEvent
My question being has anyone come across this before and know what causes it?
regards
Was trying to initialise within a hidden container... thats a no no... cheers!
Just ran into this. Ended up being a silly error as I was passing jQuery style "#wrapperID" instead of just the element id "wrapperID"
Hope that helps someone.
.iScrolls is your div class name. Can you create an id on that div?
Example:
<div class="iScrolls" id="iScrolls">
<div id="main">
<div id="thelist">
// Body part
</div>
</div>
</div>

Get current page URL from a firefox sidebar extension

I'm writing a sidebar extension for Firefox and need a way to get the URL of the current page so I can check it against a database and display the results. How can I do this?
I stumbled over this post while looking for an answer to the same question.
Actually I think it's as easy as
alert(window.content.location.href)
See also https://developer.mozilla.org/en/DOM/window.content
window.top.getBrowser().selectedBrowser.contentWindow.location.href;
might work, otherwise I think you need to use:
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
mainWindow.getBrowser().selectedBrowser.contentWindow.location.href;
This seems to work fine for me
function getCurrentURL(){
var currentWindow = Components.classes["#mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow("navigator:browser");
var currBrowser = currentWindow.getBrowser();
var currURL = currBrowser.currentURI.spec;
return currURL;
}
https://developer.mozilla.org/En/Working_with_windows_in_chrome_code
If you need to access the main browser from the code running in a sidebar, you'll something like what Wimmel posted, except the last line could be simplified to
mainWindow.content.location.href
(alternatively you could use 's API returning an nsIURI).
Depending on your task, it might make sense to run the code in the browser window instead (e.g. in a page load handler), then it can access the current page via the content shortcut and the sidebar via document.getElementById("sidebar").contentDocument or .contentWindow.
If you need only domain and subdomain;
Usage;
PageDomain.getDomain(); // stackoverflow.com
PageDomain.getSubDomain(); // abc.stackoverflow.com
Code;
PageDomain = {
getDomain : function() {
var docum = Components.classes["#mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow("navigator:browser");
var domain = PageDomain.extractDomain(new String(docum.location));
return domain;
},
getSubDomain : function() {
var docum = Components.classes["#mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow("navigator:browser");
var subDomain = PageDomain.extractSubDomain(new String(docum.location));
return subDomain;
},
extractDomain: function(host) {
var s;
// Credits to Chris Zarate
host=host.replace('http:\/\/','');
host=host.replace('https:\/\/','');
re=new RegExp("([^/]+)");
host=host.match(re)[1];
host=host.split('.');
if(host[2]!=null) {
s=host[host.length-2]+'.'+host[host.length-1];
domains='ab.ca|ac.ac|ac.at|ac.be|ac.cn|ac.il|ac.in|ac.jp|ac.kr|ac.nz|ac.th|ac.uk|ac.za|adm.br|adv.br|agro.pl|ah.cn|aid.pl|alt.za|am.br|arq.br|art.br|arts.ro|asn.au|asso.fr|asso.mc|atm.pl|auto.pl|bbs.tr|bc.ca|bio.br|biz.pl|bj.cn|br.com|cn.com|cng.br|cnt.br|co.ac|co.at|co.il|co.in|co.jp|co.kr|co.nz|co.th|co.uk|co.za|com.au|com.br|com.cn|com.ec|com.fr|com.hk|com.mm|com.mx|com.pl|com.ro|com.ru|com.sg|com.tr|com.tw|cq.cn|cri.nz|de.com|ecn.br|edu.au|edu.cn|edu.hk|edu.mm|edu.mx|edu.pl|edu.tr|edu.za|eng.br|ernet.in|esp.br|etc.br|eti.br|eu.com|eu.lv|fin.ec|firm.ro|fm.br|fot.br|fst.br|g12.br|gb.com|gb.net|gd.cn|gen.nz|gmina.pl|go.jp|go.kr|go.th|gob.mx|gov.br|gov.cn|gov.ec|gov.il|gov.in|gov.mm|gov.mx|gov.sg|gov.tr|gov.za|govt.nz|gs.cn|gsm.pl|gv.ac|gv.at|gx.cn|gz.cn|hb.cn|he.cn|hi.cn|hk.cn|hl.cn|hn.cn|hu.com|idv.tw|ind.br|inf.br|info.pl|info.ro|iwi.nz|jl.cn|jor.br|jpn.com|js.cn|k12.il|k12.tr|lel.br|ln.cn|ltd.uk|mail.pl|maori.nz|mb.ca|me.uk|med.br|med.ec|media.pl|mi.th|miasta.pl|mil.br|mil.ec|mil.nz|mil.pl|mil.tr|mil.za|mo.cn|muni.il|nb.ca|ne.jp|ne.kr|net.au|net.br|net.cn|net.ec|net.hk|net.il|net.in|net.mm|net.mx|net.nz|net.pl|net.ru|net.sg|net.th|net.tr|net.tw|net.za|nf.ca|ngo.za|nm.cn|nm.kr|no.com|nom.br|nom.pl|nom.ro|nom.za|ns.ca|nt.ca|nt.ro|ntr.br|nx.cn|odo.br|on.ca|or.ac|or.at|or.jp|or.kr|or.th|org.au|org.br|org.cn|org.ec|org.hk|org.il|org.mm|org.mx|org.nz|org.pl|org.ro|org.ru|org.sg|org.tr|org.tw|org.uk|org.za|pc.pl|pe.ca|plc.uk|ppg.br|presse.fr|priv.pl|pro.br|psc.br|psi.br|qc.ca|qc.com|qh.cn|re.kr|realestate.pl|rec.br|rec.ro|rel.pl|res.in|ru.com|sa.com|sc.cn|school.nz|school.za|se.com|se.net|sh.cn|shop.pl|sk.ca|sklep.pl|slg.br|sn.cn|sos.pl|store.ro|targi.pl|tj.cn|tm.fr|tm.mc|tm.pl|tm.ro|tm.za|tmp.br|tourism.pl|travel.pl|tur.br|turystyka.pl|tv.br|tw.cn|uk.co|uk.com|uk.net|us.com|uy.com|vet.br|web.za|web.com|www.ro|xj.cn|xz.cn|yk.ca|yn.cn|za.com';
domains=domains.split('|');
for(var i=0;i<domains.length;i++) {
if(s==domains[i]) {
s=host[host.length-3]+'.'+s;
break;
}
}
} else {
s=host.join('.');
}
// Thanks Chris
return s;
},
extractSubDomain:function(host){
host=host.replace('http:\/\/','');
host=host.replace('https:\/\/','');
re=new RegExp("([^/]+)");
host=host.match(re)[1];
return host;
}
}
From a Firefox extension popup ;
You'll need
"permissions": [
"activeTab"
]
in your manifest or possibly tabs instead of activeTab
async function getCurrentTabUrl(){
let tabs = await browser.tabs.query({active: true, currentWindow: true}) ;
return tabs[0].url ;
}
let hostUrl = await getCurrentTab();
alert(hostUrl);
This works from a firefox "popup" extension.
browser.tabs.query({active: true, windowId: browser.windows.WINDOW_ID_CURRENT})
.then(tabs => browser.tabs.get(tabs[0].id))
.then(tab => {
console.log(tab);
});
Hallo,
I have tried to implement this in JavaScript, because I need that in my project too, but all three possible solutions didn't work. I have also implemented a small site to test it, but this also didn't work.
Here is the source code of the small site:
<html>
<head>
<title>Test</title>
<script type="text/javascript">
function Fall1 () {
alert(window.top.getBrowser().selectedBrowser.contentWindow.location.href);
}
function Fall2() {
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindow);
alert(mainWindow.getBrowser().selectedBrowser.contentWindow.location.href);
}
function Fall3() {
alert(document.getElementById("sidebar").contentWindow.location.href);
}
</script>
</head>
<body>
<form name="Probe" action="">
<input type="button" value="Fall1"
onclick="Fall1()">
<input type="button" value="Fall2"
onclick="Fall2()">
<input type="button" value="Fall3"
onclick="Fall13()">
</form>
</body>
</html>

Resources