Knockout JS with Razor layout - razor

Dev and libraries
ASP.NET 5
Razor
KnockoutJS
I am building a dashboard and I want to create a knockoutjs filter of when you switch clients. The data will update for just that client. The dropdown for the client will be in the _Layout.cshtml file. Here is the code I have for that:
_Layout.cshtml
<ul id="clients" class="dropdown-menu dropdown-user" data-bind="foreach: storeList()">
<li>
<a data-bind="attr: {href: '#'}, text: storeList.ClientName"></a>
</li>
</ul>
_Dashboard.cshtml
$.getJSON("/System/GetClients", function (clientList) {
function Event(event) {
var self = this;
self.event = ko.observable(event);
}
function EventsModel() {
...
self.storeList = ko.computed(function () {
return clientList;
});
$('#clients').unbind();
ko.applyBindings(self, $('#clients'));
...
}
ko.applyBindings(new EventsModel());
});
I think the problem lies is the foreach: storeList is bound before the data is received. When I look at the page there are no errors in the console. The dropdown has 6 li > a elements as it should but they are not rendered
<ul id="clients" class="dropdown-menu dropdown-user" data-bind="foreach: storeList()">
<li>
<a data-bind="attr: {href: '#'}, text: storeList.ClientName" href="#"></a>
</li>
<li>
<a data-bind="attr: {href: '#'}, text: storeList.ClientName" href="#"></a>
</li>
<li>
<a data-bind="attr: {href: '#'}, text: storeList.ClientName" href="#"></a>
</li>
<li>
<a data-bind="attr: {href: '#'}, text: storeList.ClientName" href="#"></a>
</li>
<li>
<a data-bind="attr: {href: '#'}, text: storeList.ClientName" href="#"></a>
</li>
</ul>
Here is the stringify version of the clientList
[{"ClientName":"admin","Description":"Admin Sample Account","Enable":true},{"ClientName":"DSG","Description":"DSG TEST","Enable":true},{"ClientName":"Pet","Description":"PetTEST","Enable":true},{"ClientName":"Test","Description":"Test Sample Account","Enable":true},{"ClientName":"Toys","Description":"Toy's","Enable":true}]
Not sure what is wrong

storeList is a computed observable. As such, it's OK to treat it as a function in the foreach. Your mistake occurs on the a tags.
you're calling again storeList, which is wrong. Apart, you're using it as a getter property, but it's a function.
Just use a with the ClientName property, without clientList.ClientName and you're done.
Knockout is rendering the elements correctly,as you can see a list of li elements rendered

Related

Angular 6 routerLinkActive not working

I am building a site using Angular 6 and have been stuck for a few days now on a problem. I am trying to change text color (list items) on a navbar based on the active page. I have seen examples on how to do this using AngularJS and javascript. I have come across the routerActiveLink library documentation at https://angular.io/api/router/RouterLinkActive library for Angular 5+ which seems to be a simple solution, but it is not working for me. I have tried many different examples I have seen online and none have worked. Am I missing something? Here are some code snippets:
header.component.html
<div class="navbar-collapse collapse navbar-nav pull-right" id="navbar">
<ul class="navbar-nav" style="align-items: center;">
<li class="main-links" [routerLinkActive]="['active']">
<a class="al" [routerLink]="['home']" id="home-button" href="home">Home</a>
</li>
<li class="main-links">
<a class="al" routerLink="/about" routerLinkActive="active" id="about-button" href="about">About</a>
</li>
<li class="main-links">
<a class="al" id="blog-button" href="https://tspace.web.att.com/blogs/financelive/?lang=en_us" target="_blank">Blog</a>
</li>
<li class="main-links">
<a class="al" routerLink="/albums" routerLinkActive="active" id="albums-button" href="albums">Platinum Albums</a>
</li>
<li class="main-links">
<a class="al" routerLink="/programs" routerLinkActive="active" id="programs-button" href="programs">Development Programs</a>
</li>
<li class="main-links">
<a class="al" routerLink="/contact" routerLinkActive="active" id="contact-button" href="contact">Contact Us</a>
</li>
</ul>
This is my declaration for active in header.component.less:
.active {
color: #009fdb;
font-family: font-bold;
}
When I use [routerLinkActive] with the brackets, the page does not load at all, and when I user routerLink and routerLinkActive in the a tag, it does not register at all. Are there some imports I am missing. I have tried importing router, routerlinkactive, and routerlink from #angular/core.
I purposely left both different styles of using routerLinkActive in the code example. It was not like this when I actually ran it.
I have Angular 6, bootstrap 4.1.1, jquery 3, and popperjs installed.
After further review, I have discovered that routerLinkActive works correctly on elements inside the root app-module. I created a new module for my header and footer called UiModule and the functionality is not working inside the header. Any ideas on how to get routerLinkActive to work on this module?
Try importing RouterModule into your UiModule, it won't be able to make use of that imported in your app.module.ts file
import { RouterModule } from '#angular/router';
// some other imports here
#NgModule({
imports: [
RouterModule
],
exports: [
// export UI components
],
declarations: [
// declare UI components
]
})
When I had this issue, I imported everything right. It took me days before I figured the problem was from how I structured my HTML
<li class="nav-list">
<a routerLinkActive="active"
[routerLinkActiveOptions]="{exact: true}"
routerLink="/"
href="/">
<i class="material-icons nav-link-icon">person</i>
<span class="nav-link-text">Profile</span>
</a>
</li>
The problem there was that I was watching for the .active class to appear in the li element while it had always been appearing in the anchor element. Just be sure that is not what is happening in your case.

How should I pass a variable to my HTML file from app.js?

I am currently finishing the Authentication side of my server and could use some help.
I'm trying to disable and enable specific tabs depending on wether an User is authenticated. As I was following a video (part 8), the author was using if conditions ( {{#if}} {{/if}} ) in the HTML file to check if a variable in the app.js file was true or not.
I tried it but with no success. Is there a I need to pass in the top of the HTML file? Or is there a better way of doing it?
app.js:
app.use(function(req, res, next) {
res.locals.isAuthenticated = req.isAuthenticated(); //variable in question
next();
});
HTML:
<ul class="nav navbar-nav navbar-right">
{{#if isAuthenticated}} //check if this variable is true or not and if so, show the following elements
<li class="nav-item" class="navbar-right">
<a class="nav-link" href="/Profile">Profile</a>
</li>
<li class="nav-item" class="navbar-right">
<a class="nav-link" href="/Logout">Logout</a>
</li>
{{else}}
<li class="nav-item" class="navbar-right">
<a class="nav-link" href="Register.html">Register</a>
</li>
<li class="nav-item" class="navbar-right">
<a class="nav-link" href="Login.html">Login</a>
</li>
{{/if}}
</ul>
Thanks in advance!
Edit 1: Better explanation
The best option is to use view engine (e.g. EJS) and then render the view with given variables.
app.set('view engine', 'ejs')
^ to set view engine (firstly npm install ejs)
app.set('views', './views')
^ allows you to set your views directory
Then create views directory and, for example, index.ejs file:
<h1> <%= title %> </h1>
Next, write your route:
app.get('/', (req, res) => {
res.render('index', { title: 'Sample title' }) // refers to views/index.ejs
})
Within render method you can pass an object (2nd argument) with parameters that you can use in your view. Further info: http://www.embeddedjs.com/

Avoid writing multiple variable values in Angular 2 when changing class of clicked items

I hope this is a good question and I am not just missing something total simple. I am very new to Angular 2 and I am always into saving code lines and time :)
I want to change the active css class of my tabs (I dont want to use router!) and I ended up with something like this:
activeTab: string;
switchActiveTab(newTab: string) {
this.activeTab = newTab;
}
<div class="buttonLine">
<ul class="nav nav-pills">
<li role="presentation" [ngClass]="{'active': activeTab === 'Example Tab 1'}" (click)="switchActiveTab('Example Tab 1');">
<a>Example Tab 1</a>
</li>
<li role="presentation" [ngClass]="{'active': activeTab === 'Example Tab 2'}" (click)="switchActiveTab('Example Tab 2');">
<a>Example Tab 2</a>
</li>
</ul>
</div>
So I had to declare the string value "Example Tab 1" three times in my HTML. This is pretty annoying, especially when I would have 5 or more tabs here.
Is it possible to avoid reapeating the expression "Example Tab 1" three times in my HTML? Or is it possible to do this kind of stuff in a more elegant way?
Method 1
To simplify the template code, you can declare the list of tabs in the component class:
public tabList: Array<string> = ["Example Tab 1", "Example Tab 2"];
and generate the li elements with the *ngFor directive:
<li *ngFor="let tab of tabList" [ngClass]="{'active': activeTab === tab}" (click)="switchActiveTab(tab);" role="presentation">
<a>{{tab}}</a>
</li>
Method 2
To keep the code more declarative, each item could refer to itself with a template reference variable instead of using the tab caption (as illustrated in this plunker):
<div class="buttonLine">
<ul class="nav nav-pills">
<li #tab1 [ngClass]="{'active': activeTab === tab1}" (click)="switchActiveTab(tab1);" role="presentation">
<a>Example Tab 1</a>
</li>
<li #tab2 [ngClass]="{'active': activeTab === tab2}" (click)="switchActiveTab(tab2);" role="presentation">
<a>Example Tab 2</a>
</li>
</ul>
</div>
The code would be modified accordingly:
activeTab: HTMLElement;
switchActiveTab(newTab: HTMLElement) {
this.activeTab = newTab;
}

How to find Xpath for read the list of elements use list<Webelement>

webdriver finding xpath its too dificult for me. i used fire path most of fire path given xpath not working and its too lengthy. some one give me idea about xpath will work all conditions and i know relative xpath
some times this posibilities also not working like {//ul[#class='review-nav']}. some one help me for find xpath that xpath will work all conditions
<ul class="review-nav">
<li id="pend" class="pend tabclass">
<a onclick="OnTabSelect(1,'pend',0)" href="#">Pending (197)</a>
<span class="glyphicon glyphicon-filter filterclass" style="color:#185daa;top:4px;display:none"/>
</li>
<li id="flag" class="flag tabclass active">
<a onclick="OnTabSelect(4,'flag',1)" href="#">Flagged (96)</a>
<span class="glyphicon glyphicon-filter filterclass" style="color:#185daa;top:4px;display:none"/>
</li>
<li id="esca" class="esca tabclass">
<a onclick="OnTabSelect(5,'esca',2)" href="#">Escalated (88)</a>
<span class="glyphicon glyphicon-filter filterclass" style="color:#185daa;top:4px;display:none"/>
</li>
<li id="closed" class="closed tabclass">
<a onclick="OnTabSelect(3,'closed',3)" href="#">Closed (99)</a>
<span class="glyphicon glyphicon-filter filterclass" style="color:#185daa;top:4px;display:none"/>
</li>
<li id="all" class="all tabclass">
<a onclick="OnTabSelect(0,'all',3)" href="#">All (1,355)</a>
<span class="glyphicon glyphicon-filter filterclass" style="color:#185daa;top:4px;display:none"/>
</li>
</ul>
I try this Xpath to read above list its not working
xpath = //ul[#class='review-nav']
Sorry for that, I am little bit not clear for what you need xpath..
If you are trying to get all link ('a') to collect into List
//ul[#class='review-nav']/li/a
If you are trying to get all 'span' element to collect into List
//ul[#class='review-nav']/li/span
If you want to get specific element in specific li, you can try with id of 'li', for example if you like to find xpath of 'a' in first li
//li[#id='pend']/a
Thank You
Try with CSS:
.tabclass
You should get the 'li' elements with this.

Angular JS Display String Array From Json

<li ng-repeat="address in search.result.addresses">
<a href ng-click="selectAddress(address)">
{{address.addressLines}}
</a>
</li>
The problem is with my {{address.addressLines}}
This is currently a string array so my value on screen is printed out like
["address1","address2","address3","address4"]
But I just want it printed like
address1,address2,address3,address4
There are fundamentally 2 ways:
1) By using native angular directives:
<span ng-init="foo=[1,2,3,4]" ng-app="app">
<span ng-repeat="f in foo">{{f}}<span ng-if="!$last">,</span></span>
</span>
2) By writing a simple filter (best way):
angular.module('app', []).filter('arrayToList', function(){
return function(arr) {
return arr.join(',');
}
});
<p>{{foo|arrayToList}}</p>
This is the working example on jsfiddle: http://jsfiddle.net/g0dmazzk/
You can do this using join also :
<li ng-repeat="address in search.result.addresses">
<a href ng-click="selectAddress(address)">
{{address.addressLines.join()}}
</a>
</li>
I thing somthing like this would work...
<li ng-repeat="address in search.result.addresses">
<a href ng-click="selectAddress(address)">
<span ng-repeat="a in address.addressLines"> {{a}},</span>
</a>
</li>
To avoid dealing with the comma in the last item on the list, I used a class (label from Bootstrap) like this:
<span ng-repeat="a in address.addressLines" class="label label-default"> {{ a }} </span>