Re-execute model hook and rerender in Ember js - ember.js

I have in my Ember App, a route displaying a list of offers;
the model is loaded by jquery ajax (I don't use Ember-data):
Ember.$.ajax({
type: 'GET',
url: App.restAPIpath + '/offers/',
headers: {
"tokens": localStorage.tokens
},
async: false
}).then(function(res) {
data = res.offers;
});
return data;
The offers are shown in the template using a datatable and in each row there's a delete button that sends an ajax delete request to the server and correctly deletes the right offer:
{{#view App.dataTableView}}
<thead>
<tr>
<th>Created</th>
<th>Name</th>
<th>Deadline</th>
<th>Duration</th>
<th>Delete?</th>
</tr>
</thead>
<tfoot>
<tr>
<th>Created</th>
<th>Name</th>
<th>Deadline</th>
<th>Duration</th>
<th>Delete?</th>
</tr>
</tfoot>
<tbody>
{{#each offer in model}}
<tr>
<td>
{{offer.createdAt}}
</td>
<td>
{{#link-to 'eng.offers.edit' offer}}{{offer.name}}{{/link-to}}
</td>
<td>
{{offer.deadline}}
</td>
<td>
{{offer.optionDuration}}
</td>
<td>
<button class="form-button-red" {{action "deleteOffer" offer}}>Delete</button>
</td>
</tr>
{{/each}}
</tbody>
{{/view}}
but then I need to update the model (and refresh the view?) because if not the deleted offer is still shown until you refresh the page...

I'd recommend switching your ajax to async, you'll block the router from doing other important things. You should be able to accomplish the same results doing this:
return Ember.$.ajax({
type: 'GET',
url: App.restAPIpath + '/offers/',
headers: {
"tokens": localStorage.tokens
},
}).then(function(res) {
return res.offers;
});
Then I'd do something like this for your delete (I'm going to guess a bit of your code) in your controller's delete action:
actions:{
delete: function(item){
var self = this;
Ember.$.ajax({
type: 'DELETE',
url: App.restAPIpath + '/delete/' + item.get('id'),
headers: {
"tokens": localStorage.tokens
},
}).then(function(){
//manually remove the item from your collection
self.removeObject(item);
});
}
}
BTW I think delete is a reserved key word and jslint and some minimizers are total haters, so you might do something like deleteItem

Related

How to get table row values in a javascript function from a dynamically created table using for loop in django?

So basically, I am passing a context from views to my template.
In my template I am using 'for loop' to view the context in a tabular form and also attaching a button for every table row.
When that button is clicked, I want to call a javascript function(that has ajax call).
I need to get values of row elements for that particular row to use in my function.
My view function:
def asset_delivery(request):
deliverylist = Delivery.objects.filter(status='Added to Delivery List')
context = {'deliverylist': deliverylist}
return render(request, 'gecia_ass_del.html', context)
So far I tried passing those values as parameters in the following way.
My html template table:
<table class="table">
<thead style="background-color:DodgerBlue;color:White;">
<tr>
<th scope="col">Barcode</th>
<th scope="col">Owner</th>
<th scope="col">Mobile</th>
<th scope="col">Address</th>
<th scope="col">Asset Type</th>
<th scope="col">Approve Asset Request</th>
</tr>
</thead>
<tbody>
{% for i in deliverylist %}
<tr>
<td id="barcode">{{i.barcode}}</td>
<td id="owner">{{i.owner}}</td>
<td id="mobile">{{i.mobile}}</td>
<td id="address">{{i.address}}</td>
<td id="atype">{{i.atype}}</td>
<td><button id="approvebutton" onclick="approve({{i.barcode}},{{i.owner}},{{i.mobile}},{{i.address}},{{i.atype}})" style="background-color:#288233; color:white;" class="btn btn-indigo btn-sm m-0">Approve Request</button></td>
</tr>
{% endfor %}
</tbody>
</table>
The table is displayed perfectly but the button or the onclick or the function call does not seem to work.
My javascript function:
<script>
function approve(barcode2, owner2, mobile2, address2, atype2){
console.log('entered approved');
var today = new Date().getFullYear()+'-'+("0"+(new Date().getMonth()+1)).slice(-2)+'-'+("0"+new Date().getDate()).slice(-2);
$.ajax({
type:'POST',
url: 'deliveryupdate/'+barcode+'/',
dataType: 'json',
data:{
barcode: barcode2,
owner: owner2,
mobile: mobile2,
address: address2,
atype: atype2,
status:'Authority Approved',
statusdate: today,
csrfmiddlewaretoken:$('input[name=csrfmiddlewaretoken]').val()
},
beforeSend: function() {
console.log('before send');
},
success: function(){
console.log("success log");
swal("Success!","Asset request has been approved","success");
},
error: function(){
console.log("error");
}
});
}
</script>
I checked the browser logs and it looks like the function is not getting executed, meaning the problem lies with the function call or the button. Please help.
The code is working on my end. I have reduced the function to:
function approve(){console.log('entered approved');}
without any parameters and 'entered approved' is logged to the console. Check if you are setting the correct parameters and if the console throws an error. Simplify your function and add the parameters one by one in order to troubleshoot this.

Link-to the previous nested resource in ember

Router.map(function() {
this.resource('users', { path: '/stores/'+store_id+'/users' });
this.route('user', { path: '/stores/'+store_id+'/users/:user_id'}, function() {
this.resource('devices', { path: '/devices' });
});
});
On devices page I want to go back to /users/:user_id.
Here is my template/devices.hbs
<table>
<tr>
<th>model</th>
<th>user_id</th>
</tr>
{{#each model as |device|}}
<tr>
<td>{{device.model}}</td>
<td>{{#link-to "???" ?? ???}}{{device.user_id}}{{/link-to}}</td>
</tr>
{{/each}}
</table>
I don't how to go back to the specific resource.
Use user.index, because it's fully qualified route name with URL: /users/:user_id.
{{#link-to 'user.index'}}Go back to /users/:user_id{{/link-to}}
<table>
<tr>
<th>model</th>
<th>user_id</th>
</tr>
{{#each model as |device|}}
<tr>
<td>{{device.model}}</td>
<td>{{#link-to "???" ?? ???}}{{device.user_id}}{{/link-to}}</td>
</tr>
{{/each}}
</table>
Thanks to #daniel-kmak for the tips. The route is fully qualified at user.index
<table>
<tr>
<th>model</th>
<th>user_id</th>
</tr>
{{#each model as |device|}}
<tr>
<td>{{device.model}}</td>
<td>{{#link-to 'user.index'}}{{device.user_id}}{{/link-to}}</td>
</tr>
{{/each}}
</table>

Ember list of checkbox on check one send rest

I have a list of checkboxes in my template:
<table>
<thead>
<tr>
<th></th>
<th>Sender</th>
<th>Title</th>
</tr>
</thead>
<tbody>
{{#each message in model.entities}}
<tr>
<td class="cell-star">
{{input type="checkbox" name=message.id tabindex=message.id class="starBox" checked=message.isStar }}
</td>
<td class="cell-broadcaster">
{{message.notification.autor.firstName}} {{message.notification.autor.lastName}}
</td>
<td class="cell-title">
{{#link-to 'notifications.details' message.notification.id}}{{message.notification.title}}{{/link-to}} {{#unless message.isRead}} (new) {{/unless}}
</td>
</tr>
{{/each}}
</tbody>
</table>
And now i want to send rest query every time when i change some of the checkbox state with id of changed checkbox.
What should i write in my controller?
i have tried something like that but i cannot get data of changed checkbox:
updateStarStatus: function() {
console.log('checkbox clicked');
//here should be something like that:
//$.getJSON(apiHost + "/api/forum/star/"+id);
}.observes('model.entities.#each.isStar'),
im not using emberData. My model looks like this:
model: function() {
return $.getJSON(apiHost + "/api/forum");
},
You could use the observesBefore method to track the changes and make a diff in the observes method, but I'd rather use the native on change event, to trigger an action and pass the object:
<div {{action "updateStarStatus" message on="change"}}>
{{input type="checkbox" checked=message.isStar}}
and in the controller
actions: {
updateStarStatus: function(message) {
alert(message.id)
}
}
http://emberjs.jsbin.com/zohaqodese/2/

Ember.js dynamic link

I need some information about the {{link-to}} on ember. I've made some test and there is something I really don't understand..
Example :
I have a blog with with different post like that :
App.Router.map(function() {
this.resource('login', { path: '/' });
this.resource('home');
this.resource('posts', function(){
this.resource('post', { path: '/:post_id' }, function(){
this.route('update');
});
this.route('create');
});
});
Let's say that I have this template :
<script type="text/x-handlebars" data-template-name="enquiries">
<table>
<thead>
<tr>
<th>id</th>
<th>type</th>
<th>name</th>
<th>last update</th>
<th>Detail</th>
</tr>
</thead>
<tbody>
{{#each post in model}}
<tr>
<td>{{post.id}}</td>
<td>{{post.type}}</td>
<td>{{post.name}}</td>
<td>{{post.updatedAt}}</td>
<td>{{#link-to 'post' post}}View{{/link-to}}</td>
</tr>
{{/each}}
</tbody>
</table>
</script>
My simple post template
<script type="text/x-handlebars" data-template-name="post">
<div class="post-info">
<button {{action "update"}}>Update</button>
<table>
<tr>
<td>{{title}}</td>
</tr>
<tr>
<td>{{content}}</td>
</tr>
<tr>
<td>{{author}}</td>
</tr>
</table>
</div>
</script>
Those link a dynamic one and there is on all of them the good url such as localhost/posts/1 or 2 etc...
When I click on the link, nothing happend. I have to had {{oulet}} to show it. but my problem is that its show on the same page as my table (underneath), but I wanted to only display the post template..
I have some trouble to understand why, and also what is the main purpose of the outlet in my case...
Thanks.
The reason the post is shown within the posts template is because your Router defines it that way. If you want a separate page, try this:
App.Router.map(function() {
this.resource('login', { path: '/' });
this.resource('home');
this.resource('posts');
this.resource('post', { path: 'posts/:post_id' }, function(){
this.route('update');
});
this.route('create');
});
When you have a nested resource, the {{outlet}} helper designates where the nested template will be rendered.

handling ajax and jquery in django template

I am trying to load page in two parts.
second part is only render when user click on 'show more details'
<script>
$(document).ready(function(){
$('#toggle_details').click(function(e){
e.preventDefault();
if ($(this).hasClass('up')){
$(this).removeClass('up').addClass('down');
$('#toggle_text').html('Show More Details');
}
else {
$(this).removeClass('down').addClass('up');
$.ajax({
url: 'some_url_returning_json',
data: $(this).serialize(),
processData: false,
dataType: "json",
success: function(data) {
$( '.name' ).html(data.name);
$( '.lname' ).html(data.lname);
alert(data.name);
}
})
$('#toggle_text').html('Hide Details');
}
$('#details').slideToggle("slow");
return false;
});
$('#details').hide();
});
</script>
and my html is :
<div class="ad-grp-tbl creative-tbl custom-tbl">
<table width="100%">
<tr>
<th>Status:</th>
<td id='status'>{{ status }}</td>
</tr>
</table>
<table width="100%" id="details">
<tr>
<th>Name:</th>
<td id="name" >{{data.name}}</td>
</tr>
<tr>
<th>Last Name:</th>
<td id ="lname">{{ data.lname}}</td>
</tr>
</table>
<table>
<tr>
<th class="tog">
<span id="toggle_text" style="color:blue;font-weight:bold">Show More Details</span>
<span class="down" id="toggle_details"></span>
</th>
<td></td>
</tr>
</table>
</div>
So Basically I am not able to load the json return value in the template.
hw can i fix it. or my approach for solving the problem is wrong.
Thanks.
I show you an example:
def post_ajax(request):
TOTLE = 5
OFFSET = int(request.GET.get('offset', 0))
END = OFFSET + TOTLE
if OFFSET + 1 >= Post.objects.count():
LOADED = "已经全部加载完毕"
return HttpResponse(LOADED)
posts = Post.objects.filter(pub_time__lte=timezone.now())[OFFSET:END]
json_list = []
for post in posts:
t = get_template('blog/ajax_post.html')
html = t.render(Context({'post': post}))
# print(html)
json_list.append({
'html': html,
})
data = json.dumps(json_list)
return HttpResponse(data, content_type="application/json")
Is this you need?
Ajax + JQuery will get response and should put data appropriately in the page. Template of original page doesn't have much role to play.
However, you have to implement separate url+view+template that will handle the ajax request. You can use existing view but need to handle for ajax request (i.e. just to send part of html, likely using another template).
The template for ajax response should send only the relevant part of html and not the entire html page.
In the HTML you have ids set but you are using the class selector.
It should be:
$( '#name' ).html(data.name);
$( '#lname' ).html(data.lname);
instead of:
$( '.name' ).html(data.name);
$( '.lname' ).html(data.lname);
. is the class selector and # is the id selector.
You can try using Firebug or Chrome Dev Tools to see that the above returns the items.