Emberjs - how to render nested route template without parent route content? - ember.js

Summary
I want to continue to use nested routes but without displaying top level content when the nested route is accessed. I'm not sure this is possible ?
Detail
Initially my requirement was to to display a list of, eg, foods and offer the user the option to add a food item foods/add . Using the outlet tag at the top of the list template allowed a form to add a food item to become visible at the top of the list, transitioning back to food after the add resulted in the list being displayed without the form.
New Requirement
The requirement has now changed and it's necessary to show the form without the the contents of the list and after a succesful add show the list without any form.
Question
I know I could abandon the sub-routes approach and create a route such as food-add but is there any other way of preserving the sub-route (and the corresponding file structure, which I like) but allow the the template for foods/add to be rendered without the list content ?

Each route has an index template which is only visible when a child route is not present.
You could do something like this:
index.hbs
{{#each foods as |food|}}
{{food}}
{{/each}}
<LinkTo #route="food.add">Add</LinkTo>
food/add.hbs
<form>
...
</form>
{{!-- submitting this form would add the new food to the list of foods
and then also transition back to `food` --}}
Here is some more info on how the index route works
https://guides.emberjs.com/release/routing/defining-your-routes/#toc_nested-routes
https://guides.emberjs.com/release/routing/defining-your-routes/#toc_index-routes

Related

Custom attributes and classes on Ember form elements?

So we use CSS tooltips in our project which basically require adding the class "tooltip-extended" and adding the property aria-label to the HTML tag which contains the text of the tooltip. These are purely CSS tooltips and work everywhere. So on link-to helper it was pretty easy. However, I ran into an issue with form elements. Primarily because Ember seems to make the actual form elements display: none in some cases, like with checkboxes, and adds a sub-element A tag which is what is visible.
This is the code for the form stuff, pretty standard:
{{input
type="checkbox"
class="tv-checkbox"
checked=defaultSetup
data-label="Default Settings"
name=defaults
change=(action "toggleDefaults" value="target.checked")}}
{{#radio-button
class="tooltip-enhanced"
value="simple"
name="complexity"
groupValue=passphraseComplexity
changed="complexityChanged"}}
Simple
{{/radio-button}}
If I add tooltip-extended to the class it either doesn't add it at all, or it adds it to the actual form element which is display: none. Even extending the attributes allowed would not put these attributes on the child elements created.
It is desirable that the tooltip appear directly over the element the mouse is over. If the class and attribute are placed on a parent DIV element, this is not the behavior that ensues because it centers on the element.
Is it possible to do what I want?

emberJs giving different routes to links

I got a page that includes 15 pictures and I must redirect user to the details page if one of them is clicked. so, I have 15 different routes like 1,2,3,...15. But as I know, I cant give dynamic variable to #link-to helper. So how am I gonna make every picture go to its own route? this is how my index page .hbs looks like :
{{#each model as |rentalUnit|}}
{{rental-listing rental=rentalUnit}}
{{/each}}
{{outlet}}
This is how I print every picture. And this is how am I trying to go to routes :
{{#link-to "???"}}<img src={{rental.image}} width="200">{{/link-to}}
so, there is ??? because I dont know what to do. Thanks!
Well, first why not use a dynamic segment in your route? Like this:
this.route('image', {path: '/images/:id'});
But what you want can be done by just passing a variable, not a string to the link to helper as first argument:
{{#link-to target}}
Where {{target}} would print your route name. So target is a variable here, not a string.
Checkout this twiddle.

Not able to make the navbar items dynamic in ember

I have navbar component which I have placed in an application.hbs so that it should be visible always.But I want to change the title of the navbar with each page I visit ( say I am on index page it should say "Home" , if I am on profile page it should say profile,etc).Right now what is happening is navbar title always remains "Home" for all the page.This is happening because the navbar gets rendered onlu during the time it loads the page in browser and after that it doesn't change according to page.
application.hbs
{{top-navbar dp_url=model.profile.dp_url first_name=model.profile.first_name title=title}}
{{outlet}}
Here the I am computing the value of title depending upon which page the user is.
application.js(controller)
if (currentPage === "" || currentPage === "#"){
currentState.set('title',"Home")
}
else if(currentPage === "Userprofile"){
console.log('myStudio');
currentState.set('title',"UserProfile");
}
In here the currentpage has the current url of app and I am comparing it and deciding the value of title for navbar.
But the top-navbar title value gets calculated only for the first time when user load the app in browser and not when I move ffrom one route to another.
I have also tried the Ember.Evented but not able to solve it.
I don't know what Ember.js and Ember-data version are you using, currentState is deprecated since 2.1, anyway looks like you're using a private method intended for Ember internals and not meant to be used in an application.
A possible (but maybe unnecessary complicated) way to accomplish what you want is:
Create a model with the information you want to mutate in the navbar (e.g. navbar-data).
In the route where the navbar is rendered, create and return a record for it using a fixed numeric ID (e.g. store.createRecord('navbar-data', { id: 1, title: "index" })).
Pass the created record to the component (instead of just a string).
Whenever you want to change, peek the record with store.peekRecord('navbar-data', 1) and change the value you want to change in the navbar.
Of course, the record you use for that must not be saved with record.save().

Render items in separated placeholder

I'm trying to create a carousel and I want it to be configurable from the Experience Editor. By configurable I meant that it's possible to edit the image, text AND add/or remove slides.
The first time I create the carousel I can add/remove slides but no after saving it and opening it again, after rendering the carousel I can't remove just one slide because they all are part of the same placeholder (I can continue adding new slides and removing the new ones but not the old ones).
I have Carousel.cshtml and CarouselSlide.cshtml and the code look like:
Carousel.cshtml
<div class="carousel">
#foreach (Item slide in Model.Item.Children)
{
#Html.Action("CarouselSlide", "MediaFeature", new { model = slide });
}
#Html.Sitecore().DynamicPlaceholder("slides")
</div>
CarouselSlide.cshtml
<div class="carousel-slide">
<div class="carousel-slide-content">
#Html.Sitecore().BeginField(....)
<div class="background-image">
.....
</div>
<div class="text-container">
....
</div>
#Html.Sitecore().EndField()
</div>
</div>
So far, the issue looks like is related with the placeholders. Any ideas about how to render DynamicPlaceholders?
EDIT
"slides" placeholder is configured to allow only CarouselSlide components
Remove the foreach loop. It is unnecessary. When Sitecore renders the placeholder it renders the previously added slides for you. When in edit mode, it also renders the container that allows you to add additional components.
Using a dynamic placeholder as you have will allow you to have multiple Carousel components on a page. Or more precisely, multiple components containing a placeholder with the key "slides". It is most likely not causing the problems you are seeing with your slides.
Update - additional info requested by OP
It looks like what you have done is mix two different styles of development. In one, you are explicitly rendering the children of the carousel item as slides. In the second you are relying on Sitecore's presentation engine to dynamically render components into a placeholder that could be using data sources from somewhere else in the tree. You need to pick one or the other, but the second approach is generally preferred.
To use the second approach, you would simply remove the foreach loop so that your Carousel view looks like this:
<div class="carousel">
#Html.Sitecore().DynamicPlaceholder("slides")
</div>
If you decide to go with the first approach, you would remove the placeholder and then add Custom Experience Buttons to allow you to insert and sort child items under your carousel item.
With either approach, you may find that page editor does not play all that well with your Carousel javascript. The most common workaround to this problem is to render the carousel as a flat list in page editor mode.

Render Ember Sub-Routes While In Parent Route

What is the correct way to render sub routes while at the parent route? Basically what I'm trying to do is create a table of resources from the parent route but then make the rows "editable" while at their specific sub-route. Examples:
/foos = table of all foo's but each row is a render of /foos/#
/foos/1 = same table of /foos but the specific row is now form fields for editing
/foos/new = row with blank form fields for a new foo (not part of the question, explain below)
The idea is that only one row is "editable" at a time. So if a user navigates from /foos/new to /foos/3 then the "new" row goes away and the foo # 3 is now editable. Similar when navigating between specific /foos/#
Bonus points: What is the best way for the /foos/# route to know if it is active, so the template knows to either display the read-only foo details or form fields for editing.
At this point I have (what I think is) mostly setup for this scenario but am stuck at the rendering sub routes. I have a jsbin setup: http://jsbin.com/jayax/6/