I guess I have to make the jump to directives.
I have a directive in my html:
<ev-filter placeholder='{{pp.srcListFilter}}'
ng-model='data.srcFilter'/>
that I want to replace (using a template) with:
<div class='filterbox'>
<input id='srcFilter' type='text'
placeholder='{{pp.srcListFilter}}'
data-ng-model='data.srcFilter'>
</div>
What I can't seem to get my head around is how to "transfer" the attributes id, placeholder, ng-model, etc,... from the directive to the template. The variable value swill be different for each use, so I might have:
<ev-filter placeholder='{{pp.srcListFilter}}'
ng-model='data.srcFilter'/>
or
<ev-filter placeholder='{{pp.subjectListFilter}}'
ng-model='data.subFilter'/>
i.e. the variable names are not hardcoded. All the example online seem to manage the variables using scope, but they assume the names are hardcoded (always the same). I can't do that because I might have multiple instances on a single page/managed by a single controller
Related
I was following the tutorial Tour of Heroes. While adding a new hero they say
You can use an element paired with an add button.
Insert the following into the HeroesComponent template, after the heading:
<div>
<label for="new-hero">Hero name: </label>
<input id="new-hero" #heroName />
<!-- (click) passes input value to add() and then clears the input -->
<button type="button" class="add-button" (click)="add(heroName.value); heroName.value=''">
Add hero
</button>
</div>
Here I don't understand what is #heroName inside in input element (what is it called) and how does it help in pairing that input element with the button element.
Basically, what is that #<keyword> syntax within that input element. I know that it is not the id as that is already declared.
To answer the question, it's a reference to the input. You can find more details here:
https://angular.io/guide/template-reference-variables
Template variables help you use data from one part of a template in
another part of the template. Use template variables to perform tasks
such as respond to user input or finely tune your application's forms.
In the tutorial context, it's a reference to the input element. It helps to pair it with a button to be able to access it's value, without having to actually define a variable in the component.ts and trying to update the template directly. This help you "skip" a step, and actually have direct access to that value.
Template reference variables can become very handy in certain cases and are commonly used for example in angular material ( to call a function for a component )
<mat-menu #menuComponent ...></mat-menu>
<button (click)="menuComponent.close()"></button>
In the above example, you bind the menuComponent variable to "mat-menu" component, in which case you can access all the variables, public methods of such. In that case we can call "close" method from the mat-menu component.
Let me know if this is still unclear and I can try to give you more examples and explanation
I have a custom component for text input and each of them has an internal field ID'ed as data. It causes the warning below to appear.
[DOM] Found 13 elements with non-unique id #data
I'm clear on why it happens and I understand that's a warning not an actual error. I also recognize the appropriateness of an ID being unique (in its scope).
I'm not entirely sure regarding the implications in my particular case. In my opinion, warnings are tolerable but not acceptable.
Is there a best-practice approach to get rid of the error? By the very concept of a GP component, some parts will be alike in each instance. Or is there a trick to unique'fy the IDs? Or perhaps a directive or such to let Angular know we're cool with the state as is?
The component uses #ViewChild("data") to refer the input control in the template below.
<div id="outer">
...
<label for="data">{{label}}</label>
<input #data id="data" ... >
<div *ngFor="let error of errors" class="row"> ... </div>
</div>
As far as I understand the purpose of using ids is querying it inside of Angular. You could use a directive or another attribute to query without any warnings. Also you could make a kind of wrapper which would apply common ID to input and its label and just concat UUID and ID you want to use. But if it's only about querying just choose another attribute. For example data-id or data-qa whatever gives you an ability to query and have no errors at the same time. Just in case #ViewChild("data") refers to #data and not id="data" whilst you may wrap input with label tag.
I am trying to show the details of the adultJsonArr in different and I want to get it saved on action without going into writing lengthy code.
I'm not getting idea of how to use the index while iterating, I tried as mentioned in line no 5 but didn't work( #index also couldn't do job for me).
Any suggestion on how to save the changes made to the input in the adultJsonArr
1.<form>
2. {{#each adultJsonArr as |adultTravellerDetails index|}}
3. <div id="adult_form{{index}}">
4. Adult{{index}}:
5. <input type="text" value="{{adultJsonArr.[index].traveller_name}}" required>
6. <input type="dob" value="{{adultTravellerDetails.traveller_dob}}">
7. <input type="text" value="{{adultTravellerDetails.traveller_gender}}" required>
8. </div>
9. {{/each}}
10. <div {{action "confirmTravellerUpdate" adultJsonArr }}>
11. {{mdl-button text='submit'}}
12. </div>
13.</form>
You can replace {{adultJsonArr.[index].traveller_name}} with {{adultTravellerDetails.traveller_name}}.
If you would like to access a certain element from a array you should not do this in your template. The ember devs have made it hard to do so because it would likely put to much logic into the template. Use instead a computed property or a helper to retrieve your element from the collection.
E.g. you can create a helper function that receives a collection and a index and returns the desired item.
import { helper } from '#ember/component/helper';
export function colItem(params) {
return params[0][params[1]];
}
export default helper(colItem);
And in your template:
{{helper-name collection 5}}
But remember that for this you would need an array to work. If you would like to access an item from another collection you would have to handle this accordingly.
The index should probably only be used for display purposes. There's no need to look up things within the current index of adultJsonArr because you already have access to adultTravellerDetails.
Having said that, if you really have some use-case where you need to look up the value of the array at the current index, (or maybe you have some other sorted array with meta-data that you want to look up by index?) you can do something like this:
{{get adultJsonArr (concat index ".traveller_name")}}
We are building a path with concat for get to look up on adultJsonArr. This feels a bit hacky, but it works.
I have an Angular JS app I am building along with Angular-UI (bootstrap).
I have a set of multiple input boxes, which the user can input into and then that input is binded into a div. What I would like to do is have a character count that applies to all the boxes, so its one limit on all boxes and as the user types into them boxes the overall counter is affected. So far I can do this:
<p>xxxxxxxx?</p>
<textarea class="form-control" rows="3" ng-model="what[$index]" id="input" maxlength="200"></textarea>
<span>{{200 - what[$index].length}} left</span>
So this will give me a limit on that box, but how Can i get it so I have a overall counter? I have about 8 more text boxes and they are binded into a div as follows:
<div ng-repeat="w in what">
<p style="font-size:22px;"></p>
<p>{{w}}</p>
</div>
app.js
$scope.what=[];
Any help would be appreciated?
Two Way Data-Binding
First you need to set up 2 way data-binding so that when a user makes a change to the model it has an effect on the controller. you will use $scope for this since scope represents your model in Angular. then to build a running total I have 2 options for you.
Quick and Dirty
A quick and dirty way to count up a total across different controllers and other parts of your angular app would be to use $rootScope.YourCountVar. Root scope is a global variable and has its own host of problems because of this.
declare a counter near the top of your application (after angular.module) in app.js like this
.run(function ($rootScope) {
$rootScope.counter= 0;
})
Now in your controllers that you would like to count you need to set the value of $rootScope like
$rootScope.counter += $scope.YourInputData.length;
Repeat that for each of your inputs.
Best Practice
Create a Service that you can instantiate everywhere you need to add onto the running total. This way you only have the service where you need it. Doing things this way is much safer and cleaner and I would recommend it.
I am trying to pass a variable from my classic asp page to ssrs. When I put in a literal value for the parameter, such as 296, it works fine. But I want to put in a variable that is sent by the URL so that it works in different ways for different people who are logged in. So, instead of a URL that is http://servername.net/reportserver....rs:Command=Render&Agency=296 (for the agency that is number 296) I want to use a variable that I have set to the agency of the person who has logged in. Let's say the variable is pAgency. I have tried Agency=" #pAgency (I set pAgency = to the logged in person's agency) and all sorts of other combinations, and have searched the web, but find no answer for this. I've even tried session variables but, no go. You must be able to do this but...
Thanks for any help you can give. Cheers!
That is not how a rest URI works to my knowledge. You need to build the string and present it first fully formed, not define a variable on it. You could do somthing in code like (using HTML Form as a base)
In the example below there are four clear things to understand:
A. The 'action' in the form must be the webservice location of a report and do a post to self. (Or you can do an iframe element potentialy but I have not messed with that as much)
B. The 'input' element is text based but you MUST match the id and name to the name of your parameter passing in.
C. The 'select' element gives a user 'option's of save methods to output directly to common types.
D. The 'input' for a type of 'submit' ensure the form will post to itself with the data prescribed.
<!DOCTYPE HTML>
<html>
<head>
<title>SSRS Tester</title>
</head>
<body>
<form id="SSRSRender" action="http:// (reportservername)/ReportServer?/(pathtoreport)" method="post" target="_self">
<H3>Enter some detail for the report to render</H3>
My Variable 'Test': <input type="text" id="Test" name="Test">
<br/>
My outputs:
<select ID="rs:format" name="rs:format" size=1>
<option value="HTML4.0">HTML 4</option>
<option value="IMAGE">Tiff Image</option>
<option value="PDF">PDF</option>
</select>
<br/>
<input type="submit" value="Render Report">
</form>
</body>
</html>
If you want to do more types of input variables to dynamically get SSRS to render as you want outside of the SSRS landing page you need to determine if you want to use:
The service with some front end with scripting like javascript with HTML
Something more easy to control will pre built tools like 'Report Viewer' with ASP.NET or a client application in C# or VB.NET
Create the service proxy yourself in a class library and do the calls in code directly as well as the formatting
Trying to create a rest URI programatically is better done by contacting the service and using built in methods IMHO rather than trying to make a string. It may be a little more of a learning curve but it will help you in the end.