How to change the number of rows using a st-template - javascript

I've created a st-template that contains specific pagination functionality.
Here is mine the div that calls the st-template:
<div st-pagination="" st-items-by-page="itemsPerPage" st-displayed-pages="7" st-template="dashboard-pagination.html"></div>
Within this pagination we have a dropdown/button where the user can select the number of rows to display within the table.
<ul aria-activedescendant=""
class=""
role="menu"
tabindex="0"
>
<li class="" ng-repeat="page in pages">
<input
id="items-per-page-{{page * 10}}"
name="items-per-page-options"
type="radio"
value=""
role="menuitemradio"
aria-checked="true"
checked
ng-model="itemsPerPage"
>
<label for="items-per-page-{{page * 10}}">
<span class=""></span> {{ page * 10 }}
</label>
</li>
</ul>
So 'itemsPerPage' updates in the template but does not reach the , which is in another html file.
I have been looking for an answer for a few hours and haven't really found one. This is my first experience working with smart-table and angularJS so I may not be using the correct key words.
Any help would be appreciated.

I ended up moving the items per-page html out of the template into the datatable html file. I created an array of static values that represents the number of row to display ['10','20','30','40','50']. Once the user selects one I send in the ng-model itemPerPage and the items update to that selection.
The reason it wasn't working in the template was because of the ng-repeat created a child scope so when I used ng-model it was not modify the original scope.

Related

Angular 4 - Scroll To item in list based on search input

I can do this with custom javascript but was wondering if there is anything built into Angular 4 that I might be able to make use of. I have a list of checkboxes that can be scrolled through and a search input above. I want to be able to jump to a section in the list as a user types in the search input. My HTML:
<!-- Sold To -->
<div class="col-md-12 input-container">
<div class="checkbox-group">
<input type="search" placeholder="Jump to Soldto...">
<div class="checkbox-wrap">
<mat-checkbox *ngFor="let option of soldToOptions">
{{ option }}
</mat-checkbox>
</div>
</div>
</div>
And a sample list of the array that I am looping through for the checkboxes (there will actually be about 300 entries in this array)...
soldToOptions = [
'1028341000-MITSUBISHI WONOKE MENTOR-DALLAS',
'1018551000-ADVANCE STARTER TEST-CINCINNATI',
'1030591000-AMERICAN JOYRIDE CARTHAGE-SAN FRANCISCO',
'1023221000-TESTING GENERAL OAKLAND-OAKLAND'
];
I will first need to order these alphabetically based on the the first part of the string after the initial '-'. Just wondering if there is anything built in to Angular 4 that would allow me to match the user's input string to the value from the array and jump to that section in the scrollable checkboxes. I strictly do not want to filter the list, just move the the proper place in the list. Any help is much appreciated.
ngx-page-scroll should be able to meet your needs. You would just need a way to dynamically add the markup to identify each element generated.

Nested ng-repeat with dynamic input

I am trying to display a JSON response in a table using ng-repeat. The problem is that not all objects recieved are the same. All of them have a date, short message and long message. There are also ones with an additional value list, differing in length. This list should be diplayed underneath the long message within its own table or list. I use the alert.slice().reverse() because I want the newest entries to be on top. The new objects are inserted using .push({values}).
<tbody class="AlTbody" ng-repeat="alerts in alerts.slice().reverse()" ng-class="className">
<tr class="Altr Aldate">
<td ng-show="{{alerts.Date}}"><b>{{alerts.Date}}:</b>
</td>
</tr>
<tr class="Altr Alshort " ng-click="toggleDetail($index)">
<td>{{alerts.S}}</td>
</tr>
<tr class="Altr " ng-show="activePosition == $index">
<td class="msgL">{{alerts.L}}
<!-- 1) <p ng-show="{{item.List}}"><br><ul><li>Previous values:</li> <li ng-repeat="vals in ValueList">{{vals.value}}</li></ul> </p>-->
<!-- 2) <p ng-show="{{List.txt}}"> <br><ul><li>Previous values:</li> <li ng-repeat="List in alerts.List">{{List.txt}}</li></ul> </p>-->
</td>
</tr>
</tbody>
I already tried two approaches as seen in the code. The first one displayed the list correct however it was displayed underneath every long message instead of only the one it belongs to. I used a new variable.
var l=valList.length;
scope.List=true;
while(l>-1){
scope.ValueList.push({value: valList[l]});
l--;
}
The second approach did not work at all because I could not find an index.
var l=valList.length;
var indexV= jQuery.inArray(currdate,scope.alerts.Date);
while(l>-1){
scope.alerts[indexV].List.push({txt: valList[l]});
l--;
}
edit:
This is the current output. There you can see two objects( date, short message and long message) and both of them have the previous values section. However only the upper object is supposed to diplay the list of previous values.
What you are trying to achieve is entirely possible, my advice is to start at a known point and work from there.
I have put together a jsfiddle to show you how nested ng-repeats will work. try and work from that point. As a side note it looks like your JSON structure is overly complex, if you can simplify that down I would.
https://jsfiddle.net/roscorcoran/wyu7tgxm/
<div ng-app="App" ng-controller="Ctrl1">
<div ng-repeat="alert in alerts">
<a ng-if="alert.Date">{{alert.Date}}</a>
<p ng-repeat="val in alert.L.vals">
<a ng-if="val && val.value">{{val.value}}</a>
</p>
<p ng-repeat="item in alert.List">
<a ng-if="item && item.txt">{{item.txt}}</a>
</p>
</div>
</div>
You can try to add a ng-if statement inside the ng-repeat loop:
<p ng-if="{{values.list}}"><br><ul><li>Previous values:</li> <li ng-repeat="vals in values.list">{{vals.value}}</li></ul> </p>-->
Okay so this works for me now. It still always displays "Previous Values:" but the values only display when they actually belong to the message.
<ul ng-if="alerts.List.vals"><li>Previous values:</li> <li ng-repeat="val in alerts.List.vals" >{{val.value}}</li></ul>
This might not be the best and most elegant solution but it works.
if(valList){
scope.alerts.push({Date:currdate,S:msgSn,L:msgLn, List:{ vals:[{value:valList[0]},{value:valList[2]},{value:valList[4]},{value:valList[6]}] } });
}else{
scope.alerts.push({Date:currdate,S:msgSn,L:msgLn });
}
I only display the even indexes of the value array because the list of values was a string which I split and every uneven entry is "):" which I don't need to display.

Maintaining an array of ints representing option indices in Angularjs

I have an array of ints in my model which is meant to represent the indices of a list of options the user will pick from using a select list. The idea is there's a list you can expand and you keep picking things from the select list. I have code along these lines:
<ul>
<li ng-repeat="item in model.arrayOfInts">
<select ng-model="item"
ng-options="choice.id as choice.name for choice in common.options">
<option value="">---</option>
</select>
<button ng-click="model.arrayOfInts.splice($index, 1)" type="button">
Delete
</button>
</li>
</ul>
<button ng-click="model.arrayOfInts.push(null)" type="button">
Add
</button>
I have two problems which seem to be related:
the ng-model does not seem to actually bind properly; if I inspect the scope I can see that newly-pushed members of arrayOfInt are still set to null even after I select something from the select menu representing them.
When I attempt to push another item into the array, Angular complains that duplicate options are not allowed.
What is the proper way to do what I'm trying to do?
JSFiddle sample
The first issue ("ng-model does not bind properly") is because you're not targeting the array with ng-model. item in your ng-repeat is a new property on the scope (created by the ng-repeat). It doesn't contain any information on where it came from (arrayOfInts).
The following code tells ng-model to point to the right index of the array, rather than a new scope property.
<select ng-model="model.arrayOfInts[$index]"
ng-options="choice.id as choice.name for choice in common.options">
The second issue is because model.arrayOfInts can have multiple duplicates in it (click "add" twice and you've just added two nulls). Angular needs some way to tell the difference between them, so you need to add a tracking property, in this case $index.
<li ng-repeat="item in model.arrayOfInts track by $index">

How to select data from my controller with button click

I have a view that takes data from JSON, uses that data to populate a list of buttons (with basic information about the data) and then upon clicking the button, I want another panel to be populated with the data bound to the data in the button.
<div ng-controller="QueueCtrl">
<ul class="list-unstyled" ng-repeat="ticket in tickets">
<li><div data-queue-item></div></li>
</ul>
</div>
This part populates the list with each list item containing the ticket information I want displayed.
How do I select only the data for the ticket when I press its button to populate my other panel? For example, the next section on the page might be a button that will build an email to the person in the data: (haven't tested this code, please give me pointers if I'm doing it all wrong.
{{ ticket.email_address || "cannot find email address"}}
Problem is, I don't know how to tell it which ticket in tickets to reference...
Thanks!
Here is a working example, hope it will help you
http://plnkr.co/edit/7rAqx9nMBuzhdEAUQpZF?p=preview
You just need to use a reference
$scope.selectedTicket = {};
You can simply create a reference to the selected ticket in your scope. For example:
<div ng-controller="QueueCtrl">
<ul class="list-unstyled" ng-repeat="ticket in tickets">
<li ng-click="cont.selectedTicket = ticket"><div data-queue-item></div></li>
</ul>
</div>
And then in your panel below:
<div class="slected-ticket-info">
<div>{{cont.selectedTicket.someValue}}</div>
</div>
Where someValue is just some child key on your ticket object. Or as per your <a> example:
<a href="mailto:{{ cont.selectedTicket.email_address }}?...
Just make sure in your parent controller you create the container variable so the children can reference it:
$scope.cont = {};

One way binding + dynamic binding in AngularJS

I will start by explaining what we are trying to achieve.
We have just jumped on the Angular bandwagon and are building a prototype with it to see what it is capable of.
Currently there is a load of data (grades in this case) on the server and we display that data using Angular.
The following is the code we use:
<ul class="phones">
<li class="list-group-item" onclick="toggleExpandedView(this, true, 500)" ng-repeat="grade in grades | filter:query | orderBy:orderProp">
<span ng-show="grade.comment"><img src="../Content/images/comment.gif"/></span>
<a class="btn btn-primary editButton" style="float: right; position: absolute; right:10px;" ng-href="#/grades/{{grade.gradeId}}">Edit</a>
<div class="heading1"><a ng-href="{{grade.url}}" target="_blank">{{grade.gradeValue}}</a></div>
<div>Provided by {{grade.assessorFirstname}} {{grade.assessorLastname}} on {{grade.dateModifiedFormatted}} </div>
<div class="expandedGrade" onclick="childDivClick(event)" style="display: none" id="grade-{{grade.gradeId}}">
<label>Attachments</label>{{grade.attachmentCount}}
<br />
<span ng-hide="editing" ng-click="editing = true"><b>{{grade.comment || 'No comments yet'}}</b></span>
<form ng-show="editing" ng-submit="editing = false">
<input type="text" ng-model="grade.comment" placeholder="Comment" ng-required />
<br />
<input id="saveChanges" type="submit" class="btn btn-primary" ng-click="saveChanges(this, grade)" text="Save changes" />
</form>
</div>
</li>
</ul>
As you can see we have a parent ul and for each grade in grades we simply display a li and a div that is hidden and when you click on the li we use jQuery to animate and display the hidden div. In the child div we have a comments field which users can update and click save. On save the current object gets fired back to the server however we are concerned about the fact that Angular has to go through all 2000 grades until it finds the one we are updating (due to two way binding) and this means that everything will be really slow and we cannot afford that.
This is what we want to achieve:
1 We want to bind the data one way so that we can display the list of all grades on the screen and as soon as they are all displayed we want to somehow remove the bindings.
2. When users update the comments for a particular grade we then want to dynamically bind that particular grade so that Angular knows exactly which one it has to update without having to go through the whole collection of 2000+ grades.
I have find a tutorial however I am still unsure how to integrate that into my code.
I have also watched this video and I understand the concept behind it but again, I am struggling to write something that actually works ( we have just started using Angular so I am pretty much a newbie)
Could anyone out there point me in the right direction and provide me with some code samples that would solve the issue we are facing? Any advice and help would be greatly appreciated
You could always use a directive
The logic should go like this
use a service to hold your grades
inject the service into your directive
make a copy and just bind the 'read only view' in your directive
you could watch the service for changes and makes updates as needed
in your directive
as far a lazy loading / updating when needed - use a data service
and call the data service for an update whenever the trigger fires
if your trigger needs to come as a push from some other 'web service' consider a technology
like http://socket.io/
I can put together an example if you would like to see how the services and directives should interact

Categories