Template renders only after refreshing the page - javascript

I want to have the list of universities and after clicking on one of them, next to this list majors' list is supposed to show. After clicking on one of majors, next to those two lists list of subjects shows. However I did something wrong in routing I suppose. After clicking on one of universities URL changes but the list of majors doesn't show up. But after refreshing the page (with this url) it works perfectly fine. Here is the code:
http://jsbin.com/AQAref/1/edit

Like the other guys said, your jsbin doesn't work. It's pretty apparent the real problem is with your link-to. If it works when you refresh, but not when you click on a link then the difference is where the model is coming from. When you refresh, the model comes from the model hook. When you navigate using a link, the model was supplied by the link-to statement.
In your situation, if you refresh the page you get the majors of a specific university from your university model hook. If you click on the university from your page, the university model is sent to the university resource, not the majors of that university.
So either this needs to say majors
{{#each}}
<li {{bindAttr id="id"}}>
<div class="list-element-title">
{{#link-to 'university' this.majors}}{{name}}{{/link-to}}
</div>
</li>
{{/each}}
instead of
{{#each}}
<li {{bindAttr id="id"}}>
<div class="list-element-title">
{{#link-to 'university' this}}{{name}}{{/link-to}}
</div>
</li>
{{/each}}
Or your route needs to return the university, but I'm guessing the route model hook is correct since you said it works on refresh.
App.UniversityRoute = Ember.Route.extend({
model: function(params) {
var majors = universities.findBy('id', params.univ_id).majors;
return majors;
}
});
I didn't look through the rest of your code, but make sure you are sending the same model through the link-to as you would get if you got the model through the model hook.

Related

Ember Documentation understanding - Model linked to Template or not?

I'm learning Ember right now and i'm beeing a bit confused because of the Docu of Ember and the getting started example.
In the Documentation it says:
In Ember.js, templates get their properties from controllers, which decorate a model.
And
Templates are always connected to controllers, not models.
But after doing the getting started guide i'm not sure if this is correct.
I've uploaded the finished TodoMVC app here: https://github.com/Yannic92/stackOverflowExamples/tree/master/Ember/TodoMVC
In the Index.html you'll find this template:
<script type="text/x-handlebars" data-template-name="todos/index">
<ul id="todo-list">
{{#each todo in model itemController="todo"}}
<li {{bind-attr class="todo.isCompleted:completed todo.isEditing:editing" }}>
{{#if todo.isEditing}}
{{edit-todo class="edit" value=todo.title focus-out="acceptChanges" insert-newline="acceptChanges"}}
{{else}}
{{input type="checkbox" checked=todo.isCompleted class="toggle"}}
<label {{action "editTodo" on="doubleClick"}}>{{todo.title}}</label>
<button {{action "removeTodo"}} class="destroy"></button>
{{/if}}
</li>
{{/each}}
</ul>
</script>
My question refers to the 3rd Line:
{{#each todo in model itemController="todo"}}
The Controller todo is only needed to provide the actions for the todos. The data is accessable even without this controller.
In my opinion there is the model directly connected with the template isn't it?
Or is there a default Controller like the docu mentioned here?
For convenience, Ember.js provides controllers that proxy properties from their models so that you can say {{name}} in your template rather than {{model.name}}.
As you can see in this line: <script type="text/x-handlebars" data-template-name="todos/index"> this is the template for / because the router has this line: this.route('todos', { path: '/'}). Which will have a controller named TodosController, even if you didn't write one ember will generate one for you. So when you delete it that's what happens.
In this template you loop through the todo's list. Each of these Todo models are decorated with a controller the TodoController. And with this line: {{#each todo in model itemController="todo"}} you tell ember to use this TodoController for every element in the list.
If you leave out the itemController ember assumes the todo's are part of the model for the IndexController provided by the IndexRoute.
By default ember has an empty controller which proxies everything to the underlying model. (Note: I believe this will change in ember 2.0). So it may look like it's directly coupled to the model. But you could write a controller that changes everything without changing the model.

Ember Nested Routes and rendering models

I have an invoice application generator and i want to show the invoices with all his transactions in 2 different ways, at the moment i can only do it in 1 way ( Edit Link)
On Edit link where i can see all my invoices and transactions
together ( it s how it works now)
On View link where i want to see only the specific Invoice information with his own transactions
and not any of the other invoices and informations
I have reproduced my case here
This is the route code
App.Router.map(function(){
this.resource('invoices', function(){
this.resource('invoice', { path:'/:invoice_id' }, function(){
this.route('edit');
});
this.route('create');
});
});
The problem is that as long as i am inside the invoices resources i am sharing the invoices templates where everything is generated, but is there a way where i can see only my single invoice with his own transactions inside the invoices route? Is it achievable with the same Route Code? What's the best way to get this done?
<script type="text/x-handlebars" id="invoices">
<div class="large-12 columns">
{{#link-to "invoices.create"}} Add Invoice {{/link-to}}
</div>
<ul class="fatturas-listing">
{{#each invoice in model}}
<li>
{{#link-to "invoice" invoice}}
Edit {{invoice.title}}
{{/link-to}}
</li>
<li>
{{#link-to "invoice" invoice}}
View {{invoice.title}}
{{/link-to}}
</li>
{{else}}
<li>no fatturas… :(
</li>
{{/each}}
</ul>
{{outlet}}
</script>
I don't get your 'edit' part. The problem you have right now is the outlet defined in the invoices template, all sub routes will be rendered in here, so you cannot show an invoice without its parent (invoices) content.
I think the most common way is to remove the outlet and show all invoices in the InvoicesIndex route. Clicking an invoice will then go to a single invoice (a new page without showing the invoices list from the InvoicesIndex route).

How to make the list of results from a search-bar navigatable via up/down arrows?

I am trying to implement a search-bar that displays results from our database. I already have the results displaying, but I need to make it such that I can navigate the results using the up/down arrows.
Given below is the HTML structure of the searchbar: an input segment, and a div with the 'list of results'. Inside the list of results, for each result is a div that includes the result's properties.
I am working with Ember.js.
{{!-- Contains the whole Searchbar. --}}
<div class="searchbarContainer" tabindex="-1" bubbles=false>
{{input type="search" name="searchFor" class="searchTextField" placeholder="Search..." value=searchKey}}
<div class="searchResultsContainer box-shadow" {{bind-attr id="searchBarID"}}>
{{#if searchKeyNotNull}}
{{!-- For each Row, include visual elements. --}}
{{#each toSearch }}
<div class="resultRow" tabindex="-1"{{action 'didClickResultDefault' this}}>
<img {{bind-attr src="resultIcon" class=":resultIcon isRound:roundIcon"}}>
<div class="inline-block">
<div class="resultName">
{{unbound this.resultText}}
</div><br>
<div class="resultTitle">
{{unbound this.secondaryText}}
</div>
</div>
</div>
{{/each}}
{{/if}}
{{/if}}
</div>
</div>
To clarify a few things: the way this works now is that searchKeyNotNull is a property on the controller to check if the input entered is not empty (to avoid unnecessary database call). toSearch is an array that is populated when results are fetched; on each character entry into the input portion, a query is made and toSearch is repopulated.
I should also point out that if the input box loses focus, the searchResultsContainer is immediately hidden. And the search-bar itself is an Ember Component, if that makes a difference at all.
The point is, at this stage, I have an array of results that I am displaying to the page. Each result is displayed in a div 'resultRow'; all 'resultRow's are in a parent div 'searchResultsContainer'. The goal is to be able to navigate through these resultRows using the up and down arrows; hitting enter should be akin to clicking the resultRow.
It seems that pretty much every searchbar in the world can be navigated using the keyboard but I have disheartingly failed to understand how such a feature is implemented - or even approached.
How is such a useful feature implemented?
This answer may be what you are looking for https://stackoverflow.com/a/10341608/1146562
Create a server-side script (PHP, Rails, ASP.net, etc) to generate your search results. The script can fetch data from wherever you like, for example a database or a hardcoded list. Your script must accept a GET parameter named q which will contain the term to search for. E.g. http://www.example.com/myscript?q=query
Link to plugin and documentation http://loopj.com/jquery-tokeninput/
*****************UPDATE********************
here is another answer that might point you in the right direction https://stackoverflow.com/a/17810896/1146562
$("ul").keydown(function (e) {
var searchbox = $(this);
switch (e.which) {
case 40:
$('li:not(:last-child).selected').removeClass('selected').next().addClass('selected');
break;
case 38:
$('li:not(:first-child).selected').removeClass('selected').prev().addClass('selected');
break;
}
});
Hope that helps!

Dynamic Page manipulation with Ember/jQuery/JS

I am building an app using Ember.js with an OAuth system. I have this button for my users to login: http://imgur.com/C8x70ZX
After my user logged in, it changes to this dropdown:
http://imgur.com/cGTsMzA
The problem is, this currently only works after a page reload. Since I am building a single page, dynamic application, this is something I do not want.
This is the implementation I use:
{{#if isNotLoggedIn}}
<li class="has-form" id="logInButton"><button onclick='FBLogin()'>Connect with Facebook</button></li>
{{else}}
<li class='has-dropdown not-click'>
<a href='#'><img class='profilePicture' {{bind-attr src=pictureLinkSquare}} height='25px' width='25px' /> Welcome, {{firstName}} {{lastName}}!</a>
<ul class='dropdown'>
<li>{{#link-to 'profile'}}Profile{{/link-to}}</li>
<li>Sign Out</li>
</ul>
</li>
{{/if}}
So, how would I go about changing that button dynamically, what do I use for that? Can I implement this using ember (I was looking at the {{action}} helper?) or is it better to use something like jQuery to accomplish this task?
This is my first small, single page project, so I feel a bit lost.
Creating a JSBin example would help understand your query better.
However from what I understand, you would have not marked 'isNotLoggedIn' as a computed property that probably would be watching some property in your controller that controls the state of login.
Look at the example #http://emberjs.com/guides/object-model/computed-properties/
In example, pay special attention to how fullName computed property ended by putting a watch on base properties '.property('firstName', 'lastName')'. Usually when this is missed, the computed property does not get 'refreshed' immediately.
Hope this helps!

Ember.js outlets and routes

I've been trying to learn Ember.js for the last two weeks and I've really struggled. I'm hoping for an 'a-ha' moment but each new feature I try to implement always results in hours of failed testing. I just don't seem to be grasping the framework. I feel like I'm working against it. I'm hoping someone can explain a path forward through this simple example.
I am creating a web app that allows the user to pick products that they will sell to a client. There is a list of products they can chose from and then a list of products they've selected.
I imagine a left-column with navigation controls and a main column showing either the selected products or new products they can add to the order. Here is the basic template:
<script type="text/x-handlebars" data-template-name="pc">
<div id="nav">{{outlet nav}}</div>
<div id="main">{{outlet main}}</div>
</script>
Here is the left navigation template:
<script type="text/x-handlebars" data-template-name="nav">
<div class="button">{{#linkTo "pc.add"}}Add Products{{/linkTo}}</div>
</script>
Here is the selected products template:
<script type="text/x-handlebars" data-template-name="selectedProducts">
{{#each p in controller}}
<div class="product">
<h4>{{p.name}}</h4>
</div>
{{/each}}
</script>
Here is the available products template:
<script type="text/x-handlebars" data-template-name="addProducts">
<div id="addProducts" class="addProducts">
{{#each p in controller}}
<div class="product">
<h4>{{p.name}}</h4>
</div>
{{/each}}
<button {{action "addSelectedProducts"}}>Add Selected Products</button>
<button {{action "back"}}>Back</button>
</div>
</script>
I can load the 'pc' template with some already selected products. Great. I can also navigate to the 'Add Products' template. Great. But when I click 'Add Selected Products', I can't figure out how to move the selected products into the controller/model behind the 'Selected Products' template and then get that template to re-render in place of the 'Add Products template'. It's really two question. How do I update the model of another controller from within a different controller? And, how do I then transition from an event to another route?
Can someone show me how you would design the Route(s) and Controllers? I know that's asking a lot. I"m mostly interested in seeing how you respond to an event in the AppProductsController, update SelectedProductsController's model, and then transition to SelectedProductsRoute and have it re-render the template.
I want to believe this is an amazing framework but I just keep hitting walls.
Andrew
How do I update the model of another controller from within a different controller?
Connect controllers using the needs property. So something like:
//in AddProductsController
needs: ['selectedProducts']
addSelectedProducts: function() {
// Now selectedProductsController can be accessed via the controllers property
otherController = this.get('controllers.selectedProducts');
// add the selected ones...
}
See http://emberjs.com/guides/controllers/dependencies-between-controllers/
how do I then transition from an event to another route?
//in AddProductsController
this.transitionToRoute('blogPosts');
See http://emberjs.com/api/classes/Ember.Controller.html#method_transitionToRoute

Categories

Resources