I have the following ng-repeat list:
<div class="row msf-row"
ng-repeat="record in recordlist
people-popover>
<div class="col-md-1 msf-centered" ng-show="editItem == false" ng-hide="editItem">
<button class="btn btn-primary form-control msf-paxlist"
rel="popover"
data-content="<li ng-repeat='passanger in record.pax'>
{{passanger.name}}
</li>"
data-original-title="Passanger List">
{{record.pax.length}} <i class="fa fa-user"></i>
</button>
</div>
</div>
I initialize the popover with a directive:
.directive('peoplePopover', function() {
return function(scope, element, attrs) {
element.find("button[rel=popover]").popover({ placement: 'bottom', html: 'true'});
};
})
The problem is the <li ng-repeat="pasanger in record.pax">{{pasanger.name}}</li>, which will not show.
If I use <li ng-repeat="record.pax">{{pax}}</li>, it will display the array, but if I try to list the objects of the array with ng-repeat, it won't work.
This is how the array (record) looks like:
record in recordlist {
date : "02/12/2014"
time : "00.02.01"
car : "369"
pax: [
{
name : "Ben"
chosen : true
},
{
name : "Eric"
chosen : true
}
]
}
Any tips?
I ran into similar problem and I solved it this way.
I wrapped the ng-repeat block in another directive and pass the collection to that external directive.
div class="row msf-row"
ng-repeat="record in recordlist
people-popover>
<div class="col-md-1 msf-centered" ng-show="editItem == false" ng-hide="editItem">
<button class="btn btn-primary form-control msf-paxlist"
rel="popover"
data-content="<new-directive records=record.pax></new-directive>"
data-original-title="Passanger List">
{{record.pax.length}} <i class="fa fa-user"></i>
</button>
</div>
</div>
Inside the new directive, you will have this code.
<li ng-repeat='passanger in record.pax'>
{{passanger.name}}
</li>
Hopefully this helps someone who runs into similar problem.
Related
I have a directive to click on an item and can later be edited. This directive is called click-to-edit. I'm doing an ng-repeat, and every row is an accordion. My idea is to cick the edit button, and I can edit the text, as if I clicked on it.
how can I do it?
<uib-accordion close-others="true">
<div ng-repeat="faq in faqs">
<div class="col-sm-11" >
<div uib-accordion-group class="panel-default" is-open="faq.open">
<uib-accordion-heading >
<span ng-click="ignoreClick($event);" ><a href='' click-to-edit ng-model='faq.pregunta' typeinput='textarea' >{{faq.pregunta}}</a></span> <i class="pull-right glyphicon" ng-class="{'glyphicon-chevron-down': faq.open, 'glyphicon-chevron-right': !faq.open}"></i>
</uib-accordion-heading>
<span click-to-edit ng-model="faq.respuesta" >{{faq.respuesta}}</span>
</div>
</div>
<div class="col-sm-1" >
<button type="button" class="btn btn-default">
<span class="glyphicon glyphicon glyphicon-edit"></span>
</button>
</div>
</div>
</uib-accordion>
https://plnkr.co/edit/K5fXaIzSBkV91V7AFoqw?p=preview
Instead of initializing scope.editState = false inside the directive, you can pass it in from your controller.
Set up your directive to take editState as a parameter:
scope: {
model: '=ngModel',
editState: '='
}
Create an editState variable on each faq in your controller, with a function to toggle it:
Controller:
$scope.faqs=[
{"pregunta": "pregunta1", "respuesta": "respuesta1", "open":true, "editState": false},
{"pregunta": "pregunta2", "respuesta": "respuesta2", "open":false, "editState": false},
{"pregunta": "pregunta3", "respuesta": "respuesta3", "open":false, "editState": false}
];
$scope.toggleEditState = function(index) {
$scope.faqs[index].editState = !$scope.faqs[index].editState;
}
Controller's template:
<a click-to-edit edit-state='faq.editState' ... >
<button ng-click="toggleEditState($index)"></button>
Here is a plnkr.
<div ng-app="appPage" ng-controller="appController">
<div class="nav">
<h1 class="logo">Todlio</h1>
<i class="icon setting" style="color:#fff;font-size:1.8em;;position:absolute;top:11px;right:12px;"/></i>
</div>
<div class="todo">
<div class="todo_column">
<div style="font-weight700;text-align:center; margin:20px;">
<a href="#/add" ng-click="addTodo()" class="ui basic button">
<i class="add square icon"></i>
Add
</a>
</div>
<ul>
<a href="#/"><li ng-href="#/" ng-click="detail($index)" ng-repeat="todo in todos">
<h3 ng-model="title">{{ todo.title }}</h3>
<h6>{{ todo.note_date }}</h6>
</li></a>
</ul>
</div>
<div class="todo_full">
<div class="todo_title" ng-scope="todo in todos">
<span><h1>{{ title }}</h1></span>
<span class="check">
<i style="font-size:2em;" class="square outline icon"></i>
<i class="write icon" style="font-size:1.8em;"></i>
</span>
</div>
<h4>Note:</h4>
<p class="todo_note">{{ note }}
</p>
</div>
</div>
</div>
Controller
app.controller("appController", function ($scope) {
$scope.todos = [
{title: "Call Vaibhav", note: "", note_date: ""},
{title: "Grocery", note: "Lemons, Apple and Coffee", note_date: ""},
{title: "Website design for Stallioners", note: "UI/UX on xyz#mail.com", note_date: ""},
{title: "Fill MCA form", note: "First search for all the colleges", note_date: "" }
];
$scope.detail = function(x){
$scope.todos.title = $scope.title;
$scope.todos.note = $scope.note;
};
I want to get the clicked list item title and the note attached to it to the different div below
Can anybody please help. Its a todo app the left half has the list to todos and the right half has a note attached to it or anything checked or not.
There are a few ways to do this. One easy way is as follows:
Define a $scope variable with a name like $scope.currentTodo.
In the repeat loop, the ng-click would set $scope.currentTodo=todo
This current variable will hold the todo object so you can use {{ $scope.currentTodo.title }} in place of {{title}}
Ditch the ng-scope
I'm currently building a nifty little 'talent point distributor' view, similar to what popular RPG games offer. I didn't want a huge wall of HTML code for all the buttons and textboxes, so I created a template to which I pass two parameters:
the name of the stat I want to alter
the initial value of the stat
The template renders correctly, and I notice that when I log the results to the console, the variable seems to be changed correctly. However, the displayed value does not change and will always stay at 0.
Here is the template itself:
<template name="attributeStepper">
<div class="row" style="margin: 1em;">
<div class="col-sm-3 col-md-2">
<h4>{{toUpper attribute}}</h4>
</div>
<div class="col-sm-6 col-md-4">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default btn-value-dec">
<span class="glyphicon glyphicon-chevron-down"></span>
</button>
<button type="button" class="btn btn-default disabled">{{attributeValue}}</button>
<button type="button" class="btn btn-default btn-value-inc">
<span class="glyphicon glyphicon-chevron-up"></span>
</button>
</div>
</div>
</div>
</template>
Here is the helper I defined for the template:
Template.attributeStepper.helpers({
toUpper : function(str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
})
Template.attributeStepper.events({
'click .btn-value-inc' : function(event, tmpl) {
tmpl.data.attributeValue ++;
},
'click .btn-value-dec' : function(event, tmpl) {
tmpl.data.attributeValue --;
}
});
And this is how I call the templates from the actual view:
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Attributes</h3>
</div>
{{ >attributeStepper attribute="strength" attributeValue="0"}}
{{ >attributeStepper attribute="courage" attributeValue="0"}}
{{ >attributeStepper attribute="intelligence" attributeValue="0"}}
{{ >attributeStepper attribute="agility" attributeValue="0"}}
{{ >attributeStepper attribute="dexterity" attributeValue="0"}}
{{ >attributeStepper attribute="intuition" attributeValue="0"}}
{{ >attributeStepper attribute="charisma" attributeValue="0"}}
</div>
I hope you can make any sense out of this and tell me what I'm doing wrong, because I feel like I'm not following the mindset behind Meteor correctly yet.
Cheers!
There is nothing wrong but also nothing reactive in your code. For the attributeValue you should use a template based ReactiveVar which is created at the onCreate Event
Template.attributeStepper.onCreated(function() {
if (! _.isUndefined(this.data.startingValue))
this.attributeValue = new ReactiveVar(Number(this.data.startingValue));
else
this.attributeValue = new ReactiveVar(0);
})
You can use some initialValue from Template as you like
See complete example at the MeteorPad I created for you.
http://meteorpad.com/pad/Zw7YnnW57uuGKcu3Q/MultipleTemplateUsage
This should solve your question
Cheers
Tom
Do you have idea about reactive-var in meteor (Meteor Doc) or you can also use Session instead of reactive-var (ReactiveVar is similar to a Session variable)
Have a look at changes as per your code.
Here is the template(.html)
<template name="attributeStepper">
<div class="row" style="margin: 1em;">
<div class="col-sm-3 col-md-2">
<h4>{{toUpper attribute}}</h4>
</div>
<div class="col-sm-6 col-md-4">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default btn-value-dec">
<span class="glyphicon glyphicon-chevron-down"></span>
</button>
<button type="button" class="btn btn-default disabled">{{getAttributeValue}}</button>
<button type="button" class="btn btn-default btn-value-inc">
<span class="glyphicon glyphicon-chevron-up"></span>
</button>
</div>
</div>
</div>
</template>
Here is helpers for your template(.js)
Template.attributeStepper.created = function(){
this.attributeValue = new ReactiveVar(parseInt(this.data.attributeValue));
}
Template.attributeStepper.helpers({
toUpper : function(str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
},
getAttributeValue : function(){
return Template.instance().attributeValue.get();
}
});
Template.attributeStepper.events({
'click .btn-value-inc' : function(event, tmpl) {
tmpl.attributeValue.set(tmpl.attributeValue.get()+1)
},
'click .btn-value-dec' : function(event, tmpl) {
tmpl.attributeValue.set(tmpl.attributeValue.get()-1)
}
});
Template.attributeStepper.created = function(){...} method called before your template's logic is evaluated for the first time.
I have a table containing next & previous pages. I am able to navigate to next/previous pages using next & previous buttons.
On previous & next page actions on call(controller methods) I am pushing checked ticket ids by pushing in an array $scope.checkedTicketIds
angular.forEach($scope.tickets, function(ticket) {
if(ticket.checked) {
$scope.checkedTicketIds.push(ticket.id);
}
});
HTML code is
<div class="mail-tools tooltip-demo m-t-md">
<div class="btn-group pull-right">
<button ng-click="previousPage()" ng-disabled="previousPageBtnDisabled()" class="btn btn-white btn-sm"><i class="fa fa-arrow-left"></i></button>
<button ng-click="nextPage()" ng-disabled="nextPageBtnDisabled()" class="btn btn-white btn-sm"><i class="fa fa-arrow-right"></i></button>
</div>
<div class="input-group">
<div class="input-group-btn" dropdown>
<button ng-disabled="ticketsChecked()" class="btn btn-white dropdown-toggle pull-left" dropdown-toggle type="button">{{'ACTIONS' | translate}} <span class="caret"></span></button>
<ul class="dropdown-menu pull-left">
<li ng-repeat="(key, value) in actions"><a ng-click="convertAction(key)">{{key | translate}}</a></li>
</ul>
</div>
</div>
</div>
In controller on clicking previous page button calling method
$scope.previousPage = function() {
angular.forEach($scope.tickets, function(ticket) {
if(ticket.checked) {
$scope.checkedTicketIds.push(ticket.id);
}
});
$scope.ticketsUpdatedQueryCriteria.page = --$scope.page;
Tickets.query($scope.ticketsUpdatedQueryCriteria).then(function(tickets) {
$scope.tickets = tickets.data;
$scope.ticketsPageData = tickets.cursor;
});
};
How to pop/remove id on uncheck & I wanted to maintain checked ticket ids for further bulk actions, like change status of one/more tickets. How can I do this?
I implement an example on jsbin, using an independent checked list.
Please, look at:
http://jsbin.com/rudifa/3/
Hope I help you.
I'm developing a small notifications-like module, where the user can see his 5 latest activities that are logged in the DB (MSSQL). The values that I need are all there, but for some reason knockout binding is not working. Here are code snippets:
<div class="dropdown-menu toolbar pull-right" data-bind="with: layoutLogsModel">
<h3 style="border: none;">Recent activities:</h3>
<!-- "mailbox-slimscroll-js" identifier is used with Slimscroll.js plugin -->
<ul id="mailbox-slimscroll-js" class="mailbox" data-bind="foreach: layoutLogsModel.notification">
<div class="alert inbox">
<a href="javascript:void(0)">
<i class="icon-book" style="color: orange;"></i>
Some text
</a>
<br>
Some text #2
</div>
</ul>
</div>
For now, I only want to display random text for every item that is in the observableArray.
ViewModel is the following:
var layoutLogsModel = {
notification: ko.observableArray()
};
function getLastFiveActivities() {
get(apiUrl + "Logs/GetLastFiveActivities", { ClientUserID: loggedUserID }, function (data) {
layoutLogsModel.notification(data);
});
}
And every time I call this function, the list is empty (IMAGE)
(the function is called on click, and absolutely no errors are shown in the console).
What is it that I am doing wrong?
EDIT:
The thing was, I forgot to execute ko.applyBindings for that viewModel. Then, I changed the HTML to look like this:
<ul id="mailbox-slimscroll-js" class="mailbox" data-bind="foreach: notification">
<div class="alert inbox">
<a href="javascript:void(0)">
<i class="icon-user" style="color: green;"></i>
<span data-bind="text: $data"></span>
</a>
</div>
</ul>
Aslo, I modified the get function slightly, like this:
function getLastFiveActivities() {
get(apiUrl + "Logs/GetLastFiveActivities", { ClientUserID: loggedUserID }, function (data) {
layoutLogsModel.notification(data.Notification);
});
}
(changed data to data.Notification based on the MVC model property that contains the array)
After all that, the data was available immediately.
try removing the layoutLogsModel from the foreach, you are already using it with the binding "with", so eveything in that div will be part of layoutLogsModel.
<div class="dropdown-menu toolbar pull-right" data-bind="with: layoutLogsModel">
<h3 style="border: none;">Recent activities:</h3>
<!-- "mailbox-slimscroll-js" identifier is used with Slimscroll.js plugin -->
<ul id="mailbox-slimscroll-js" class="mailbox" data-bind="foreach: notification">
<div class="alert inbox">
<a href="javascript:void(0)">
<i class="icon-book" style="color: orange;"></i>
Some text
</a>
<br>
Some text #2
</div>
</ul>
</div>