I am a noob with emberjs and I am stuck at the issue for a while now. I created an itemController with the variable fav, but it keeps saying that it is not defined.
My index.html snippet looks like this:
<table class='table'>
{{#each model itemController='hotel'}}
<tr><td>
{{#if fav}}
<h4>{{title}}
<button {{action 'rmFav'}} type="button" class="btn btn-default btn-sm pull-right">
<span class="glyphicon glyphicon-heart"></span>
</button>
</h4>
{{else}}
<h4>{{title}}
<button type="button" class="btn btn-default btn-sm pull-right" {{action 'putFav'}}>
<span class="glyphicon glyphicon-heart-empty"></span>
</button>
</h4>
{{/if}}
<p> {{description}} </p>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star"></span>
<span class="glyphicon glyphicon-star-empty"></span>
</td></tr>
{{/each}}
</table>
and my app.js has the following snippet related to the itemController:
App.HotelController = Ember.ObjectController.extend({
actions: {
putFav: function(){
this.set(fav,true)
},
rmFav: function() {
this.set(fav,false);
}
}
});
UPDATE: Just a clarification, I have an array of objects in json format in app.js file, and each object in it contains fav attribute.
Your problem is with HotelController you are referencing an undeclared variable fav in this.set(fav,...) you need to change to a string, like this.set("fav",...):
App.HotelController = Ember.ObjectController.extend({
actions: {
putFav: function(){
this.set("fav",true);
},
rmFav: function() {
this.set("fav",false);
}
}
});
Related
i am new in ngx-bootstrap.. working with ngx-bootstrap modals..
using child modal component (#ViewChild('childModal') childModal: CommonModalComponent)
i am able to create simple modals.
the requirement is to show multiple draggable modals at the same page.
Eg. two buttons on page. button1 & button2.
if I click on button1 than respective modal-1 should show.
and now modal-1 should remain open and I can click on button2 and it will show modal2.
now I can see both modal1 and modal2 on the same page and able to drag both..?
how to do it with ngx-bootstrap?
modal-dailog.component.ts
import {Component,Input, ViewChild} from '#angular/core';
import { ModalDirective } from 'ngx-bootstrap';
#Component({
selector: 'common-modal',
templateUrl: './modal-dailog.component.html',
})
export class CommonModalComponent {
#ViewChild('childModal') public childModal:ModalDirective;
#Input() title?:string;
constructor() {
}
show(){
this.childModal.show();
}
hide(){
this.childModal.hide();
}
}
modal-dailog.component.html
<div id='wrapper'>
<div bsModal #childModal="bs-modal" class="modal fade" role="dialog" aria-labelledby="mySmallModalLabel" [config]="{backdrop: false, ignoreBackdropClick: true}" aria-hidden="false">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title pull-left">{{title}}</h4>
<button type="button" class="close pull-right" aria-label="Close" (click)="hide()">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<ng-content select=".modal-body"> </ng-content>
<ng-content select=".modal-footer"> </ng-content>
</div>
</div>
</div>
</div>
</div>
parent.component.ts
import {Component, ViewChild, ViewContainerRef} from '#angular/core'
import {CommonModalComponent} from './core/modal-dailog/modal-dailog.component';
#Component({
selector: 'modal-demo',
templateUrl: './parent.component.html',
})
export class demoComponent {
#ViewChild('childModal') childModal: CommonModalComponent;
#ViewChild('childModal2') childModal2: CommonModalComponent;
constructor() {
}
onCancle() {
this.childModal.hide();
}
onCancle2() {
this.childModal2.hide();
}
}
parent.component.html
<button type="button" class="btn btn-primary"
(click)="childModal.show()">Open modal</button>
<common-modal #childModal [title]="'common modal'">
<div class="modal-body">
hii, modal-body 1
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
(click)="onCancle()" >Cancle
<span aria-hidden="true">×</span>
</button>
</div>
</common-modal>
<button type="button" class="btn btn-primary"
(click)="childModal2.show()">Open modal2</button>
<common-modal #childModal2 [title]="'common modal2'">
<div class="modal-body">
hii, modal-body 2
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary"
(click)="onCancle2()" >Cancle
<span aria-hidden="true">×</span>
</button>
</div>
</common-modal>
I would like to have an action that prints all the selected check-boxes on my table to the console.
in my controller I have
removedSelected: function() {
let selected = this.filterBy('isSelected', true);
console.log(selected);
}
in my template file I have
{{input type="checkbox" checked="isSelected"}}
I have setup my controller to filter all the records that are "isSelected" in the table by using input helper on ember.
I am getting an error on the console which states this.filterBy is not a function
Do i need to setup an array to handle this first?
Below is more of the code for a better picture.
Thanks!
// templates/warranty/index.hbs
<div class="container">
<h4>List</h4>
<div class="row">
<div class="col-sm-3">
<div class="control-group">
{{#link-to 'warranty.new' class="btn btn-primary btn-sm"}}New Claim{{/link-to}}
<button class="btn btn-primary btn-sm" {{action "toggleMultiple"}}>Select</button>
{{#if canDeleteMultiple}}<button class="btn btn-danger btn-sm"{{action "removedSelected" warranty}}>Delete Selected</button>{{/if}}
</div>
</div>
<div class="container">
<table class="table table-striped table-hover ">
<thead>
<tr>
{{#if canDeleteMultiple}}<th>Select</th>{{/if}}
<th>Action</th>
<th>Claim ID</th>
<th>Claim Status</th>
<th>Serial Number</th>
<th>Issue Description</th>
</tr>
</thead>
<tbody>
{{#each model as |warranty|}}
<tr>
{{#if canDeleteMultiple}}{{input type="checkbox" checked="isSelected"}}{{/if}}
<td>{{#link-to 'warranty.edit' warranty.id class='btn btn-success btn-xs'}}Edit{{/link-to}}<button class="btn btn-danger btn-xs" {{action "deleteWarranty" warranty}}>Delete</button></td>
<td>{{warranty.id}}</td>
<td>{{warranty.claimStatus}}</td>
<td>{{warranty.serialNumber}}</td>
<td>{{warranty.issueDescription}}</td>
</tr>
{{/each}}
</tbody>
</table>
</div>
</div>
// app/controllers/warranty/index.js
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
toggleMultiple() {
this.toggleProperty('canDeleteMultiple');
},
removedSelected: function() {
let selected = this.filterBy('isSelected', true);
console.log(selected);
}
}
});
I have done this way, you can check the twiddle (https://ember-twiddle.com/aa88cd0442ec0d2219e792d58ab8b703?openFiles=templates.index.hbs%2Ctemplates.components.checkbox-component.hbs), same thing as mention by kumkanillam,
in your index.hbs i used checkbox as a component,
{{checkbox-component isChecked=warranty.isSelected action=deleteItems index=index}}{{/if}}
and in controller actions,
removedSelected: function() {
let selected = this.get('model').filterBy('isSelected', true);
console.log(selected);
}
In your hbs file,
{{input type="checkbox" checked=warranty.isSelected }}
OR
<input type="checkbox" checked={{warranty.isSelected}} onchange={{action (mut warranty.isSelected) value="target.checked" }}>
and in your controller,
removedSelected: function() {
let selected = this.get('model').filterBy('isSelected', true);
console.log(selected);
}
I'm new to ember and trying to build a very simple app as a learning exercise in 2.4. I have a list of tasks that appear on the index page. And I've attached actions to each one to delete. And have one form row on the bottom of the page with an action to saveTask.
I have one index controller.
No defined index routes.
One model for tasks at app/models/task.js
My function to saveTask is working. But I can't get the deleteTask to work. I know I'm not passing the object I want to delete correctly. The error returned is that Uncaught TypeError: undefined is not a function index.js:26
deleteTask.
Can someone explain the correct syntax to me?
app/templates/index.hbs
{{#each model as |task| }}
<div class="form-horizontal form-group row">
<div class="col-xs-4 col-md-3">
{{input type="text" value=task.taskname class="form-control"}}
</div>
<div class="col-xs-3 col-md-2">
{{input type="text" value=task.startdate class="form-control"}}
</div>
<div class="col-xs-3 col-md-2">
{{input type="text" value=task.enddate class="form-control"}}
</div>
<div class="col-xs-3 col-md-2">
{{input type="text" value=task.duration class="form-control"}}
</div>
<div class="col-xs-3 col-md-2">
{{input type="text" value=task.banding class="form-control"}}
</div>
<div class="col-xs-2 col-md-1">
<button type="button" class="btn btn-default btn-sm" aria-label="Remove task" {{action 'deleteTask' task}}>
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>
</button>
</div>
</div>
{{/each}}
and the controller
app/controllers/index.js
import Ember from 'ember';
export default Ember.Controller.extend({
actions: {
deleteTask(task) {
this.destroyRecord();
this.transitionTo('index');
}
}
});
You call destroyRecord in deleteTask on this not on the task, which is actually the record. I think that's all.
You should be able to see in developer tools the line in code which throws. I bet it's this.destroyRecord();.
I created a panel component with a button which contains some actions in controller.
So the first doubt: What's the main difference between components and views?
I really dont know if i'm doing things in the correct way
First i created a "father" controller which will contain the method to send a panel action to the specified controller action
App.BasicArrayController = Ember.ArrayController.extend({
actions : {
panelActions : function(action) {
this.send(action)
},
},
});
App.BasicObjectController = Ember.ObjectController.extend({
actions : {
panelActions : function(action) {
this.send(action);
},
},
});
Next i created the controller which will extend the "father" and created a object which contains the name to display in panel and the name of action in controller
App.AlbumController = App.BasicObjectController.extend({
arrayActions : [Em.Object.create({name: 'Edit'},{action:'edit'}),Em.Object.create({name: 'Delete'},{action:'delete'})],
actions : {
edit:function(){
this.transitionToRoute('album.edit');
},
confirmDelete:function(){
this.get('model').deleteRecord();
this.get('model').save();
this.transitionToRoute('albums');
}
}
});
This is the correct way to extend a controller in ember?
Next i created the component template (.hbs) with bootstrap
<div {{bind-attr class=bootStrapClass}}>
<div class="panel-heading">
{{#if arrayActions}}
<div style="margin-top: -1.3%" class="btn-group pull-right">
<button type="button" class="btn btn-default dropdown-toggle"
data-toggle="dropdown">
Actions <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
{{#each arrayActions}}
<li><a href="#" {{action 'panelActions' this on='click'}}>{{name}}</a></li>
{{/each}}
</ul>
</div>
{{/if}}
<h3 data-toggle="collapse" data-parent="#accordion" {{bind-attr
href=hrefCollapseId}} {{action 'collapse' on='click'
}} class="panel-title">
<span {{bind-attr id=collapseId}}
class="glyphicon glyphicon-collapse-up">{{title}}
</h3>
</div>
<div {{bind-attr id=customId}} class="panel-collapse collapse in">
<div class="panel-body">{{yield}}</div>
</div>
</div>
<!-- Modal -->
<div class="modal fade" {{bind-attr id=myModalId}} tabindex="-1"
role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button {{action 'cancelDelete'}} type="button" class="close"
data-dismiss="modal">
<span aria-hidden="true">×</span><span class="sr-only">Close</span>
</button>
<h4 class="modal-title" id="myModalLabel">Album</h4>
</div>
<div class="modal-body">Are you shure?</div>
<div class="modal-footer">
<button type="button"
{{action 'cancelDelete'}} class="btn btn-default"
data-dismiss="modal">Cancel</button>
<button type="button"
{{action 'confirmDelete' this}} class="btn btn-primary">Confirm</button>
</div>
</div>
</div>
</div>
Now the component .js
App.PanelPrimaryComponent = Ember.Component.extend({
setupIds: function(){
this.setProperties({
collapseId: "collapse" + this.get('customId'),
hrefCollapseId:"#" + this.get('customId'),
myModalId: "myModal" + this.get('customId')
});
}.on("init"),
actions : {
panelActions : function(obj) {
if(obj.action==="delete") this.send('delete');
else
this.sendAction('panelActions',obj.action);
},
delete:function(){
var jqueryModalId = "#"+ this.get('myModalId');
$(jqueryModalId).modal('toggle')
},
cancelDelete:function(){
this.set('deleteMode',false);
},
confirmDelete:function(){
$(".close").click();
this.sendAction('panelActions','confirmDelete');
},
collapse:function(){
var jQueryCollpaseId= "#"+this.get('collapseId');
if($(jQueryCollpaseId).hasClass("glyphicon-collapse-down")){
$(jQueryCollpaseId).removeClass("glyphicon-collapse-down").addClass("glyphicon-collapse-up")
}
else{
$(jQueryCollpaseId).removeClass("glyphicon-collapse-up").addClass("glyphicon-collapse-down")
}
}
}
});
Next a template which uses the component
<div class="col-xs-6">
{{#panel-primary title="Album" bootStrapClass="panel panel-success" customId="album" arrayActions=arrayActions panelActions='panelActions'}}
<span class="label label-default">Name: </span> {{name}} <span
class="label label-default">Description: </span> {{description}} {{/panel-primary}}
</div>
{{outlet}}
In general this is the best way to do that kind of component? What shold i do different in general?
Since i can have multiple panels i have to bind a dynamic id("collpase" and "modalId" , this is the correct way?
This is the best way to send that kind of action to controller in a component?
In general this is the best way to do that kind of component? What shold i do different in general?
I use the following template to display a table of all users.
<script type="text/x-handlebars" data-template-name="users">
<table>
{{#each model itemController="user"}}
<tr>
<td>{{lastName}}</td>
<td>
{{#if isNew}}
<button {{action 'save' this}} class="btn btn-small">Save</button>
<button {{action 'discard' this}} class="btn btn-small">Discard</button>
{{else}}
{{#linkTo 'user.edit' this activeClass="disabled" classNames="btn btn-small"}}Edit{{/linkTo}}
{{/if}}
</td>
</tr>
{{/each}}
</table>
{{#unless newUserCreate}}
<p>
{{#linkTo 'users.new' classNames="btn btn-small"}}Create a new user{{/linkTo}}
</p>
{{/unless}}
</script>
Below the table I use a {{#unless newUserCreate}} which I'd like to use within the table too but because of a different scope I can't. How can I fix the following snippet to get it working? The User doesn't have a newUserCreate. Only the Users has.
{{#if isNew}}
{{#unless newUserCreate}}
<button {{action 'save' this}} class="btn btn-small">Save</button>
<button {{action 'discard' this}} class="btn btn-small">Discard</button>
{{/unless}}
{{else}}
{{#linkTo 'user.edit' this activeClass="disabled" classNames="btn btn-small"}}Edit{{/linkTo}}
{{/if}}
app.js
App.UsersRoute = Ember.Route.extend({
model: function() {
return App.User.find();
}
});
App.UsersNewRoute = Ember.Route.extend({
model: function() {
return App.User.createRecord();
},
renderTemplate: function() {
this.render({ into: 'users' });
},
activate: function() {
this.controllerFor('users').set('newUserCreate', true);
},
deactivate: function() {
this.controllerFor('users').set('newUserCreate', false);
}
});