Ember.js index of child components (for striping effect) - ember.js

I have two Ember js components: x-group and x-item. In my template they're arranged like this:
{{#x-group title='Park details'}}
{{#x-item prop='poolSize'}}Pool Size{{/x-item}}
{{#x-item prop='shelters'}}Shelters{{/x-item}}
{{#x-item prop='benches'}}Benches{{/x-item}}
{{#x-item prop='recRooms'}}Rec Center Rooms{{/x-item}}
...
{{/xgroup}}
The {{x-item}} template looks like:
{{#if prop}} <div>{{ yield }}: {{ prop }}</div>{{/if}}
I'm trying to stripe the visible, odd {{x-item}} elements.
Things I've tried:
Finding an index for the child component--turned up a goose egg.
Trying to create a css rule like .group .item:nth-of-type(odd) but the rule matches every x-item
On x-group didInsertItem, using jQuery to find matching items and setting my stripe color. This almost works except that if the x-item doesn't display the x-group still calculates it as though it were visible (even with a selector specifically meant to find only visible elements).
I'm open to any solution.

You want to use nth-child(odd). Try: .group .item:nth-child(odd)

Related

how to backtrack an ember application code

How to understand an ember application code .
I want to backtrack where a variable is defined from web page to component.
example :
in web page Title : "Wonder boy"
in template it is mentioned as
{{title-works field as |f|}}
title = field.label
{{#titel-works}}
but in the component for this template i am not able to find the varaible field nor field.label . can you please provide me any resource to understand how to backtrack a ember application from web front to variable . thanks .
First of all, your template looks a bit wrong. First the variable f is never used, next title = field.label is not hbs syntax and should literally print the string "title = field.label". Is it maybe emblem?
Now I just assume you actually use a variable as in {{field.label}}.
If you dont have the variable in the component it is passed down to it when the component is called.
So either by {{your-component field=something}} (old syntax) or <YourComponent #field={{something}} /> (newer syntax).
This is indeed not very clear. That is the reason why {{field}} (and {{field.something}}) is deprecated in favor of either {{this.field}} (or {{this.field.something}}) when the data comes from the component.js (or controller.js in case of a route template) or {{#field}} (and {{#field.something}}) when it is passed down to the component, so it is always clear from where it comes.
Your best resource when debugging is the ember-inspector. It can show you the component tree, so you know exactly from where your component is called and where to look.

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

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

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.

Replace string in HTMLbars/Handlebars expression with component

I've got a blog. Each blog-posts can have multiple downloads. For the downloads I created a component downloads
Currently I render them at the end of each post like this:
{{#each download in sortedDownloads }}
<p>
<a class="dl-button" {{ action "incDownload" download }}>
{{ download.name }} ({{ download.size}}MB)
</a> - {{ download.downloadcount }} Hits
</p>
{{/each}}
I'd like to be able to write something like [downloads] in the post content itself (which is simply rendered via {{{post.parsedBody}}}and replace it with a partial like the above one.
Is this possible or do you have a better way to achieve this?
This does not really look achievable by using either outlet or yield, since the post content will not be interpreted by the render engine.
What should be working though is to have the placeholder in your content just as you mentioned it, and replace it by some identifiable HTML placeholder in your post.parsedBody.
You could then create a View on didInsertElement, and call that view's appendTo() method to render the downloads inside the placeholder.
One could say writing some jquery-ish elements also works, but I think inserting arbitrary elements in the views tree is horrible and goes against the Ember way of managing views tree.
Cheers!

How to extensively configure an Ember.Component

I am creating an Ember.Component which displays a CRUD table. As the component shall be reusable it needs a lot configuration, such as columns to display, pagination options, etc. ...
At the moment I am inserting the component using handlebars:
<div class="some-div">
{{power-table items=this.model columns='...'}}
</div>
I wouldn't want to use this nice way of inserting a component. However, it is pot really possible to extensively configure a component here, is it? I found out it's not even possible to pass an object as parameter, e.g. the following it not possible:
<div class="some-div">
{{power-table items=this.model columns=[id, name, foo, bar] }}
</div>
How and where should I configure the component?
What you can do is that instead of setting columns=[id,name,foo,bar] in the handlebar like this:
<div class="some-div">
{{power-table items=this.model columns=[id, name, foo, bar] }}
</div>
You can set the columns property in the controller for the handlebar template and use the name of the property in the handlebar file. So all the logic would come from the controller and the handlebar would just tell which property is accessible in the component and by what name. So the controller for the enclosing template would be the best place to heavily configure the component. Have a look at the following page for more info:
http://emberjs.com/guides/components/passing-properties-to-a-component/
I am not sure if I understood your problem correctly.