Unchecking all checkbox inserted with an each loop - ember.js

I want to know how I could uncheck all checkboxes in this template, I tried using jquery but it messes up with my observer on isChecked :
<script type="text/x-handlebars" data-template-name="conversations">
{{#each conv in model itemController='singleconv'}}
<div class="conversation-content-wrapper" {{action "clickConv" conv preventDefault=false}}>
<div class="history-message-assigned in-progress-closed" style="display:none;"><p><i class="icon-x"></i>Conversation closed</p></div>
<div class="history-message-assigned in-progress-assignation" style="display:none;"><p><i class="icon-assign"></i>Conversation assigned</p></div>
<div class="history-message-assigned in-progress-reopen" style="display:none;"><p><i class="icon-re-opened"></i>Conversation re-opened</p></div>
<div class="conversation-history">
<div class="conversation-time-history">{{{conv.timeAgoElement}}}</div>
<div class="conversation-details">
<span class="unread-numbers"></span>
{{input type='checkbox' class='chk-conversation' checked=conv.isChecked}}
<span class="conversation-name">{{conv.customer.name}}</span>
<span class="phone-number">{{conv.customer.cellPhoneNumber}}</span>
<p class="conversation-text">{{conv.lastMessage}}</p>
</div>
</div>
</div>
{{/each}}
</script>
How can I retrieve all the instances of this model's checkboxes and uncheck them all in a function?

The check box is checked based on each models isChecked property.
If you loop through each model and change isChecked to false it will uncheck all the check boxes.

Related

Delete a record in Ember data not working

I have a table (a component) and a delete button in each row. When the the delete button is clicked the specific row should be deleted.
Tried the following code:
MyComponent.js
import Ember from 'ember';
export default Ember.Component.extend({
actions:{
deleteCartRecord(cartDetails){
debugger;
this.sendAction('deleteRecord',cartDetails);
}
}
});
In MyComponent.hbs
{{#each model.orderParts as |newCart|}}
<div class="card-wrapper col-lg-12 col-md-12">
<div class="col-lg-2 col-md-2">
<div class="order-id">{{newCart.partNumber}}</div>
{{#if (gte newCart.promiseQty newCart.quantity)}}
<div class="order-status delivered">{{env.APP.StockAvailable}}</div>
{{else}} {{#if (gt newCart.promiseQty '0'(and (lt newCart.promiseQty newCart.quantity)))}}
<div class="order-status intransit">{{env.APP.LowInStock}}</div>
{{else}} {{#if (eq newCart.promiseQty '0')}}
<div class="order-status outofstock">{{env.APP.OutofStock}}</div>
{{/if}} {{/if}} {{/if}}
</div>
<div class="col-lg-3 col-md-3">
<div class="item-header">Delivery Date</div>
<div class="item-data">{{newCart.deliveryDate}}</div>
</div>
<div class="col-lg-2 col-md-2">
<div class="item-header">Required Qty.</div>
<div class="item-data">
{{increse-required-quantity incresedQuantity=newCart.quantity}}
</div>
</div>
<div class="col-lg-2 col-md-2">
<div class="item-header">Unit Price</div>
<div class="item-data">{{newCart.unitPrice}}</div>
</div>
<div class="col-lg-2 col-md-2">
<div class="item-header">Total Price</div>
<div class="item-data">{{newCart.partTotalPrice}}</div>
</div>
<div class="col-lg-1 col-md-1 button-colum"><button type="button" class="btn btn-danger" {{action "deleteCartRecord" newCart}}>Delete</button> </div>
</div>
{{/each}}
My Controller
import Ember from 'ember';
export default Ember.Controller.extend({
actions:{
deleteRecord(data){
debugger;
let confirmation = confirm("are you sure to delete");
if(confirmation)
{
debugger;
data.deleteRecord();
data.save();
}
}
}
});
The template file in which component is called
<hr>
</div>
<div class="col-lg-12 col-md-12">
<div class="checkout-summery-wrapper">
<div class="total-label">Total</div>
<div class="total">{{model.totalPrice}}</div>
<!--<div class="tax-text">( Inclusive of all taxes )</div>-->
<div class="place-order-button"><button type="button" class="btn siemens-btn">Place Order</button></div>
</div>
</div>
<div class="col-lg-12 col-md-12">
{{#if model.orderParts.isGeneric}}
<div class="panel panel-default card-list-panel">
<div class="panel-heading-cart col-lg-12 col-md-12">
<div class="col-lg-11 col-md-11 heading">Generic Parts</div>
<div class="col-lg-1 col-md-1">Delete All</div>
</div>
<div class="panel-body">
{{cart-record model = model}}
</div>
</div>
{{/if}}
{{#unless model.orderParts.isGeneric}}
<div class="panel panel-default card-list-panel">
<div class="panel-heading-cart col-lg-12 col-md-12">
<div class="col-lg-11 col-md-11 heading">Hot Gas Path</div>
<div class="col-lg-1 col-md-1">Delete All</div>
</div>
<div class="panel-body">
{{cart-record model = model deleteRecord=(action 'deleteRecord')}}
</div>
</div>
{{/unless}}
</div>
MyRoute
import Ember from 'ember';
export default Ember.Route.extend({
model: function()
{
return this.get('store').queryRecord('cart',{userId:1})
}
});
My Serializer
import DS from 'ember-data';
export default DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {
primaryKey: 'totalPrice',
attrs: {
orderParts:
{
serialize: 'records',
deserialize: 'records'
}
}
});
I have the following issues:
In MyComponent.hbs, will newCart being passed as a parameter delete all the records or the specific record I want deleted?
Any ideas on why MyController is not invoked from the component?
Is this the correct way of deleting a record in ember?
Thank you in advance.
In MyComponent.hbs newCart is passed as a parameter will this delete all the record or the specific record i want?
It will delete the particular record alone. if you want to delete all the record then you can try unloadAll('model-name')
MyController is not invoked from the component why is that?
You need to send action upcon calling component, {{my-component deleteRecord=(action 'deleteRecords') }} . Actually real problem is, you are calling deleteRecord but in controller you got deleteRecords.
Is this the correct way of deleting a record in ember?
If you want to delete right away then you can use destroyRecord this will delete and save record immediately
Well, your example is full of bugs...
In MyComponent.hbs, will newCart being passed as a parameter delete all the records or the specific record I want deleted?
Nope.
Firstly, you need to understand that the result of store.query in your route returns a DS.ManyArray(an Array like object, which is model in your example) contains group of DS.Model instances (which should be newCart in your example, but you must change to {{#each model as |newCart|}} first). And only this DS.Model has method .save() and .deleteRecord().
The action you set on the button is {{action "deleteCartRecord" newCart.partNumber}}, so you actually passing a property called partNumber to deleteRecord and running deleteRecord and save on this property. Unless this partNumber is a DS.belongsTo pointing to another DS.Model, or it cannot work at all.
But what you wanted is to delete newCart, right?
Any ideas on why MyController is not invoked from the component?
Your invoke is right. But since your component is full of bugs, it must be throwing exceptions somewhere else and the app cannot run already.
Is this the correct way of deleting a record in ember?
I think I answered enough in the first question.

Ember 2 - Hide / show content component

I have a component app/components/offer-listing.js:
import Ember from 'ember';
export default Ember.Component.extend({
isOfferShowing: false,
actions: {
offerShow() {
if (this.get('isOfferShowing')) {
this.set('isOfferShowing', false);
} else {
this.set('isOfferShowing', true);
}
}
}
});
and his template app/templates/components/offer-listing.hbs:
<div class="offer__container">
<div class="row">
<div class="gr-3">
<div class="offer__avatar" style="background-image: url('{{ offer.avatar }}')"></div>
</div>
<div class="gr-9">
<div class="offer__name" {{action "offerShow"}}>{{ offer.firstname }} {{ offer.lastname }}</div>
<div class="offer__age" {{action "offerShow"}}>{{ offer.age }} ans</div>
{{#if isOfferShowing}}
<div class="offer__description" {{action "offerShow"}}>{{offer.description}}</div>
{{else}}
<div class="offer__description" {{action "offerShow"}}>{{word-limit offer.description 50}}</div>
{{/if}}
{{#if isOfferShowing}}
<div class="+spacer"></div>
<a class="offer__button"><i class="fa fa-envelope"></i> Contacter par email</a>
<a class="offer__button"><i class="fa fa-phone"></i> Voir le numéro de téléphone</a>
{{/if}}
</div>
</div>
</div>
which is rendered in app/templates/index.hbs:
{{#each model as |offerUnit|}}
{{offer-listing offer=offerUnit}}
{{/each}}
The example is working great, however I would like to hide every "more" content when a new one is showing.
A working solution for this is available here : Using Ember component's methods inside template
Basically, either you keep a reference to the selected element in your controller and pass it to each of your offer-listing components. This way they could compare themselves with this reference to known if they need to be displayed or not.
Or you set a flag in each of your offer model depending on whether is needs to be displayed or not.

Template not displaying anything when add an if/else statement to it

I am making an ember app and trying to add a log in | sign up to the upper right of the screen if the user is not logged in and a link to their profile | logout button if they are logged in. However, while I can get one or the other to display, when I add an if statement to the Handlebars template nothing shows up. Any ideas on why this is happening?
Here is my template:
<div class="row">
<div class="medium-2 columns">
<img src={{"http://placehold.it/200x200"}} alt="Logo">
</div>
<div class="medium-2 columns">
{{#if session.isAuthenticated}}
<p>{{#link-to 'profile'}}Joe Schmidt{{/link-to}} | <a {{action 'invalidateSession'}}>Logout</a></p>
{{else}}
<p>{{#link-to 'login'}}Login{{/link-to}} | {{#link-to 'signup'}}Sign Up{{/link-to}}</p>
{{/if}}
</div>
</div>
{{outlet}}

Rendering hundreds of datas : lazy loading, partial rendering?

I can seem to find a good answer for my problem. I have a sidebar template which contains a div for each item my model contains. When I have hundreds of items to render, it takes up to 8-10 seconds to render the template. I am using ember-data.
How can I render the items that are loaded before it finishes fetching the entire model?
Here is my template :
{{#each conv in model itemController='singleconv'}}
{{#if (equals conv.url selectedSubuserEmail)}}
<div class="conversation-content-wrapper" {{action "clickConv" conv preventDefault=false}}>
<div class="history-message-assigned in-progress-closed" style="display:none;"><p><i class="icon-x"></i>Conversation closed</p></div>
<div class="history-message-assigned in-progress-assignation" style="display:none;"><p><i class="icon-assign"></i>Conversation assigned</p></div>
<div class="history-message-assigned in-progress-reopen" style="display:none;"><p><i class="icon-re-opened"></i>Conversation re-opened</p></div>
<div class={{conv.selectedClass}}>
<div class="conversation-time-history">{{{conv.status}}}</div>
<div class="conversation-details">
<span class="unread-numbers"></span>
{{input type='checkbox' class='chk-conversation' checked=conv.isChecked}}
<span class="conversation-name">{{conv.customer.name}}</span>
<span class="phone-number">{{conv.customer.cellPhoneNumber}}</span>
<p class="conversation-text">{{conv.lastMessage}}</p>
</div>
</div>
</div>
{{/if}}
{{/each}}
This is the main problem in ember's rendering which is getting much better by time, Ember connects all your binding to your created models so it re-renders the view on every added model, and hence the delay.
And I've been in the same situation, you have a couple of solutions here
1- Using Ember.ListView
You can use Ember list-view which is an Ember plug-in that adds lazy rendering to a List of items, very useful if you have items that can be displayed in the same height in pixels.
2- Using Ember Cloaking
Ember Cloaking is about the same as list-view but has flexible heights, although you still need to compute them before rendering.
3- Using visibility checker like waypoints
I've done this myself and its a little tedious but plug-in free none the less
You create a variable in your component that is set to true when it's visible in the waypoint.
sample code, not a real one
export default Ember.Component.extend({
visible:false,
didInsertElement:function() {
var waypoint = new Waypoint({
element: this.$()[0],
handler: function(direction) {
this.set('visibile',true)
}.bind(this)
})
}
})
Then Move your content into this component
And then inside this component:
{{#if visibile}}
<div class="conversation-content-wrapper" {{action "clickConv" conv preventDefault=false}}>
<div class="history-message-assigned in-progress-closed" style="display:none;"><p><i class="icon-x"></i>Conversation closed</p></div>
<div class="history-message-assigned in-progress-assignation" style="display:none;"><p><i class="icon-assign"></i>Conversation assigned</p></div>
<div class="history-message-assigned in-progress-reopen" style="display:none;"><p><i class="icon-re-opened"></i>Conversation re-opened</p></div>
<div class={{conv.selectedClass}}>
<div class="conversation-time-history">{{{conv.status}}}</div>
<div class="conversation-details">
<span class="unread-numbers"></span>
{{input type='checkbox' class='chk-conversation' checked=conv.isChecked}}
<span class="conversation-name">{{conv.customer.name}}</span>
<span class="phone-number">{{conv.customer.cellPhoneNumber}}</span>
<p class="conversation-text">{{conv.lastMessage}}</p>
</div>
</div>
</div>
{{/if}}
and then the "for-each" block
{{#each conv in model itemController='singleconv'}}
{{the-component conv=conv}}
{{/each}}
Then use a counter or something to make the first 10 visible.
As I said this is only a simple example you can dig more into it.

In EmberJS my event triggers all the sub-views instead of just the targeted one

i'm learning EmberJS and building a comment section that allows 1 level of sub comments. I have an Ember View listing all the comments, when you click "reply" on a particular comment, it should display a textarea input for a user to write a sub-comment.
In my EmberJS code when you click "reply" it shows the textarea input for all the comments not just the specific one. Any advice would be appreciated :)
// View
App.commentsView = Em.View.create({
templateName: 'commentsTmpl',
showReply: false,
reply: function(e) {
e.view.set('showReply', true);
e.preventDefault();
}
});
App.replyCommentsView = Em.View.extend({
showReplyBinding: 'App.commentsView.showReply'
});
// Template
<script data-template-name="commentsTmpl" type="text/x-handlebars">
</h2>comment</h2>
{{#each App.commentsController}}
<div class="comment-group clearfix">
<div class="comment">
<img class="comment-pic" {{bindAttr src="userPic"}} alt="user pic">
<div class="comment-content">
{{userName}}
<span class="comment-body">{{text}}</span>
<div class="comment-actions clearfix">
<a href="#" {{action "reply"}}>Reply</a>
</div>
</div>
</div>
{{#view App.replyCommentsView}}
{{#if showReply}}
<div class="comment-reply">
<h2>sub-comment</h2>
<textarea class="txt-comment-reply" rows="2" cols="65"></textarea>
</div>
{{/if}}
{{/view}}
</div>
{{/each}}
</script>
Currently you are binding the showReply to App.commentsView which is the whole container. To be make it easy activate single comments, I'd suggest looking into a CollectionView, this way each of your comments will have their own view and you can toggle showReply on an individual comment's view.
Something like this: (Sorry, I haven't tested it)
App.commentsView = Em.View.create({
templateName: 'commentsTmpl'
});
App.CommentView = Em.View.extend({
classNames: "comment-group clearfix".w(),
showReply: false,
reply: function(e) {
e.preventDefault()
this.set("showReply", true)
}
})
// Template
<script data-template-name="commentsTmpl" type="text/x-handlebars">
</h2>comment</h2>
{{#collection contentBinding="App.commentsController" itemViewClass="App.CommentView"}}
<div class="comment">
<img class="comment-pic" {{bindAttr src="content.userPic"}} alt="user pic">
<div class="comment-content">
{{content.userName}}
<span class="comment-body">{{content.text}}</span>
<div class="comment-actions clearfix">
<a href="#" {{action "reply"}}>Reply</a>
</div>
</div>
</div>
{{#if showReply}}
<div class="comment-reply">
<h2>sub-comment</h2>
<textarea class="txt-comment-reply" rows="2" cols="65"></textarea>
</div>
{{/if}}
{{/each}}
</script>