How to show video in Carousel in Ember JS - ember.js

I am newbie in ember. In this ember app, the legacy code displays Images, but I want to add some videos between the images.
My test code is given as below, here simply replace the image with video.
{{!-- Carousel --}}
{{#bs-carousel
class=(concat "carousel" (if imagesLoading ' invisible height-none'))
autoPlay=false
interval=0
wrap=true
model=imageCaptures
showControls=showControls
showIndicators=showIndicators
index=activeImage
as |caro|}}
{{#each imageCaptures as |slide|}}
{{#caro.slide}}
{{!-- <img alt='' src='{{slide.image_url}}'> --}}
<video>
<source src='{{slide.image_url}} type="video/mp4"'>
</video>
{{/caro.slide}}
{{/each}}
{{/bs-carousel}}
Video is shown, but it is cut, not auto scaled in the div where the image was shown.
Can you tell me how to display video in Carousel?

ember-carousel
An ember addon for Carousel component
DEMO
Usage
From within your Ember CLI application, run the following:
ember install ember-carousel
Add invoke the component as follows
{{#carousel-container transitionInterval=400 as |ui controls|}}
<div class="carousel-body">
{{#ui.item}}
Emberjs
{{/ui.item}}
{{#ui.item}}
Reactjs
{{/ui.item}}
{{#ui.item}}
Angularjs
{{/ui.item}}
</div>
<button onclick={{controls.previous}}>
Slide Left
</button>
<button onclick={{controls.next}}>
Slide Right
</button>
{{/carousel-container}}
API
{{carousel-container}}
This is the primary component to start displaying carousel items.
Attributes
transitionInterval - Defaults to 500.
onSlide - Optional, an action that receives one parameter, an object like { index: 3, previousIndex: 2, direction: 'right' }.
Triggered before the transition is completed.
Yielded Params
This component yields two hashes, e.g. {{#carousel-container as |ui act|}}.
These parameters ui and act can be called anything, but they contain the following items:
ui - is a hash with the following component items:
item - A component that should contain your slide contents, used like so {{ui.item}}you content{{/ui.item}}.
controls - is a hash with the following action items:
previous - A closure action that changes to the previous slide.
next - A closure action that changes to the next slide.
Development
git clone this repository
npm install
bower install
Running
ember server
Visit your app at http://localhost:4200.
Running Tests
ember test
ember test --server
Building
ember build
For more information on using ember-cli, visit http://www.ember-cli.com/.
SOURCE:https://github.com/selvagsz/ember-carousel#readme

Related

How to properly set state to allow React Bootstrap Modal to work on mapped data?

Trying to build a D.R.Y. list of vocabulary terms with React Bootstrap (v.2.2.3) using Bootstrap 5.1.
I bring in my data:
import vocData from '../data/vocData'
My component:
const VocList = () => {
const [show, setShow] = useState(false)
const handleClose = () => setShow(false)
return (
<ul className="list-inline">
{Object.keys(vocData).map((item, key) => (
<React.Fragment key={key}>
<li className="list-inline-item voc-item">
<Button>
<small>{vocData[item].title}</small>
</Button>
</li>
<Modal
show={show}
onHide={handleClose}
backdrop="static"
keyboard={false}
aria-labelledby={`contained-modal-title-${vocData[item].href}`}
centered
>
<Modal.Header closeButton>
<Modal.Title id={`contained-modal-title-${vocData[item].href}`}>
{vocData[item].title}
</Modal.Title>
</Modal.Header>
<Modal.Body>{vocData[item].content}</Modal.Body>
</Modal>
</React.Fragment>
))}
</ul>
)
}
I can see my list of vocabulary terms is working but my modal is not appearing when I click the button. I've tried to research and read through:
React-Bootstrap Multiple Modal
React-bootstrap Modal component opens/closes all modals when I map through a list
How do I get my react app to display object information in my bootstrap modal when they click on a list item?
How to use React-Bootstrap modals inside a map array method to display AJAX data on button click in React?
how to show react bootstrap modal inside the function
but I'm unable to find an answer.
How can I dynamically setState and be able to render my modal for that vocabulary term in my list?
Try to use Modal only once and not render it many times. You can show only one Modal at time anyway. I have created a subcomponent for clarity.
There are many ways how to play with state. Here the initial state is null and hides the modal. When we click on button we set state with one vocData entry. This also toggles the visibility of Modal.
Finally, when we close its again, we set our state to null. In this way we use one state for two purposes - control vision and rendering of Modal and holding data for it.

Road to Ember 2.0 - High level Ember app structure feedback?

I find I'm trying to pick up learning Ember at a time of particular fluctuation. The recent "Road to 2.0" blog post has helped me clarify which direction to head, but I'm struggling to validate my approach to Ember at a high level.
I want to be sensitive to people's time. My full code is here for anyone interested in providing more specific feedback (would love), but I'm mostly interested in this high level feedback on my app's structuring and my utilization of Ember's capabilities.
App Background:
I'm working on a user-to-many chat to text SMS app. Visually, each user has multiple chat windows (a Conversation) open w/ messages (Message) specific to a Profile message history. The rails backed sends messages to the target Profile. This project is very much in development.
Key Questions:
What is the best way to associate a model with a component? I'm passing each conversation model to a conversation component. As my component logic becomes so tightly integrated to the view, tt seems like a component class is taking on too much heft outside of UI. I'm starting to add of logic around how UI bubbles up to the model, but wonder if there are better approaches.
Since I'm breaking away from the proxying behavior of Array controller, I find myself referencing my model collection via this.get('content') - is there a better way to deal with the collection of conversations?
Finally, to invoke actions in a component, I've read of using Ember.Evented mixin to trigger and observe events. I.e. when a user tries to open a chat window for a profile when that chat is already open, I'd want to flash the target chat window. Is this a good way to manage these interaction in context of "Road to 2.0"?
What about passing events from the controller to the Message subcomponents? Message subcomponents would be bound to each messages' statuses (success, fail, etc). I imagine i'd just bind some message display to a record's state and status attribute. Any way I could do it better?
I'm super open to feedback. Be harsh! :)
High level code:
(full code)
ChatApp.Router.map(function () {
this.resource('conversations', { path: '/' });
});
ChatApp.ConversationsRoute = Ember.Route.extend({
model: function () { //this is a collection of active conversations
},
activate: function() { //listens to event stream
}
});
ChatApp.ConversationsController = Ember.Controller.extend({
actions: {
openChat: function(user_id, profile_id){ //open chat if one isn't open.
}
},
removeExcessChats: function(){ // removes chats that don't fit in window
},
});
ChatApp.ConversationHolderComponent = Ember.Component.extend({
actions: {
markInactive: function(){
// referencing a passed in conversation is the only way I know to reference the model.
this.get('conversation').markInactive();
},
createMessage: function(){
}
},
isFlashed: false
});
Component templates:
<script type="text/x-handlebars" data-template-name="components/conversation-holder">
<button {{action "markInactive"}}>close</button>
<h3>Profile: {{conversation.profile}} Conversation: {{conversation.id}}</h3>
<ul class="list-unstyled">
{{#each message in conversation.messages}}
<li><strong>{{message.type}}</strong> {{message.body}}</li>
{{/each}}
<li>
<form class="form-inline" {{action "createMessage" on="submit"}}>
{{input class="message_body" placeholder="Start typing a message..." value=conversation.new_message_body type="text"}}
{{input class="btn" type="submit" value="Send"}}
</form>
</li>
</ul>
</script>
<script type="text/x-handlebars" data-template-name="conversations">
<section id="todoapp">
<header id="header">
<h1>Chat Messaging</h1>
</header>
</section>
<section id="main">
<p>Open a new chat with profile id #1 <a href="#" {{action "openChat" 1 1}} >Open w/ profile 1</a> | <a href="#" {{action "openChat" 1 6}} >open profile already in convo</a></p>
<ul id="chat-app" class="list-unstyled clearfix">
{{#each conversation in model}}
<li>{{chat-holder conversation=conversation}}</li>
{{/each}}
</ul>
</section>
</script>
I didn't go through your app design, but I'm answering based on the more general Ember concepts that you mentioned.
1.
There isn't really a model object in Ember. You have a route with a model hook that returns whatever you want as your model. It can be a string, array or just a number.
When you use Ember Data, what will happen is that the model hook returns Ember Data objects.
A component can receive any object as its model/content. So, there isn't a best or worst way of associating a model and component, you just pass it what it needs.
2.
If your component is starting to get too big, probably you should split it in two or more components. Nothing wrong with having a component's template render other components.
Also, if you have logic that is shared among many components, you can refactor that into a mixin and include it in each component.
3.
Your idea for message passing between the controller and the components is *probably* right. The usual flow in Ember apps is events up & data down. Since the controller is at a higher level than a component, you can't send event in that direction, but by updating bound values you can pass new info to the components.

Ember View - Recursive view call throws Stop Script Error

I have to construct a tree structure like the below image.
For this I use a Ember View and recursively call to construct the whole tree like structure based on the supplied model.
My Templates are:
<script type="text/x-handlebars" data-template-name="index">
<div class="zd-fldr fleft" style="width:230px;">
<ul class="fldr-sub">
{{#each item in model}}
{{view App.FoldertreeView model=item contentBinding="item"}}
{{/each}}
</ul>
</div>
</script>
<script type="text/x-handlebars" data-template-name="foldertree">
{{#if item.subfolder }}
<span {{action 'getSubFolder' item}} {{bind-attr class="item.IS_OPENED:fdtree-icon:ftree-icon"}}> </span>
{{else}}
<span class=""> </span>
{{/if}}
<span style="padding-top:20px;" class="fdetail fleft" >{{item.FOLDER_NAME}}</span>
<ul style="margin-top:30px;" {{bind-attr class="item.IS_OPENED:showdiv:hidediv"}}>
{{#each item in item.children}}
{{view "foldertree" model=item contentBinding="item"}}
{{/each}}
</ul>
</script>
JavaScript:
App.IndexRoute = Ember.Route.extend({
model: function() {
var treeArray = [];
for(var i=0; i<4000; i++){
var temp_obj = { 'FETCHED_DATA': false, 'FOLDER_ID': i, 'FOLDER_NAME': 'Folder_'+i, 'IS_OPENED': false, 'opened': true, 'subfolder': true, 'children': [] };
treeArray.push(temp_obj);
}
return treeArray;
}
});
App.FoldertreeView = Ember.View.extend({
tagName: 'li',
templateName: 'foldertree',
classNames: ['treediv', 's-fldr']
});
Initially I load only the first level folders from the server by calling an API.
Then when the open node is clicked, the children array is filled by calling an request to the server.
Now when the model length is greater than 3000 "Stop Script" error is thrown in Firefox browser.
In my tree there is no limit for the number of nodes. How can I solve this problem.
Demo JS Bin (Try it in Firefox)
Ember is a web framework. Given that information, you need to realize that you can't efficiently render 6000 items in a browser without reusing some view elements. Even native applications don't do this: in iOS, for instance, the cells in a TableView are reusable, so a table displaying a collection of 6000 items only has enough cells to cover the height of he view and some scrolling overlap. The view is aware of its scroll location, and renders the 10-20 items that need to be rendered from the collection, and when you scroll down it removes the top element, places an element at the bottom, and renders the next item in the data array. This way, everyone wins. I would suggest you do the same, as JS/HTML just can't handle that many elements efficiently.
I know it's not a fun implementation, but once you come up with a component that does this the first time, you'll be glad you did.
Honorable mentions: https://github.com/emberjs/list-view. You're doing a file tree and not a list, which is more difficult than just a long list, but you may still be able to use it if you change up your UI a little bit. If you have the folder structure navigable with a tree and show files in a list-view, this may mitigate your issue depending on whether the problem is with a number of files or a number of folders.
This is not really an Ember issue but a general javascript issue. When a script is taking to long time to execute this kind of errors message are displayed / fired by the browser and it's different on each browser.
You can read this good blog post about long time runing scripts
If you have browser environment undercontroll (i mean your computer our your companies computers) you can still setup firefox to run longer scripts
However a good practice would be to "split" your script in sub task taking less time to execute.
EDIT
Ass discussed in the comments this is due to the Huge number of view you generate. You can have 6000 models returned from your backend however generating 6000 view at once is heavy.
Here is a proposition on how to handle this : http://jsbin.com/zakisoyesi/6/edit?html,js,output free to you to adapt it to your use case and event to make it transparent to the user by using onScroll or any other event.

In Ember.js templates, how does one print out model's property that will be use by HTML like the src for image or href for link

Using:
ember: v1.0.0-pre.4
ember-data: revision 11
handlebars: 1.0.rc2
So I have a template that I've hooked up to a controller that's receiving info from an REST API. In just print out text, this is fine but these handlebar expression...
<img src="{{ imageUrl }}"/>
...when inserted into the dom look like:
<img src="<script id='metamorph-28-start' type='text/x-placeholder'></script>http://asdf.com/image.jpg<script id='metamorph-28-end' type='text/x-placeholder'></script>">
I'm obviously very new to Ember.js and Handlebars.
I've tried doing searches for "rendering urls in ember templates" and "print out html in ember mustache templates." Ack, probably obvious but I'm missing it.
try this:
<img {{bind-attr src="imageUrl"}} />
but you can have more than just one attribute like:
<img {{bind-attr src="imageUrl" alt="imageTitle"}}>
here is the doc: http://emberjs.com/api/classes/Ember.Handlebars.helpers.html#method_bind-attr
also, can be useful in some cases where you don't need the variable to be bound, you could use:
<img src="{{unbound imageUrl}}" />
ref to the doc: http://emberjs.com/api/classes/Ember.Handlebars.helpers.html#method_unbound
but the first method is usually the best.
Taking this a little bit further to get your feet even more wet, we can actually create a view that represents an image, and use that to add more functionality.
For instance, in the following JSFiddle I've set the view's tagName to img (where its default is a div), and then added an attributeBindings to bind attributes to the view. In our case we want to bind to the src attribute. All we then need to do is specify the src attribute as a property of the view, and give it a default value -- in this example, Google.
Therefore the view works as expected: we've displayed an image as part of a view.
However, taking it one step further, we can now easily change the image's src attribute by using the .set() method. On the magical click event, which is invoked when the user clicks on the view in the DOM (try it yourself by clicking on Google's logo in the JSFiddle!), the src attribute is changed from Google's logo to Yahoo's logo. Since we're observing the src attribute from attributeBindings, this is updated as soon as we call:
this.set('src', 'http://l.yimg.com/dh/ap/default/120910/yahoo_logo_br.png');
Full view code in case JSFiddle disappears:
App.ImageView = Ember.View.extend({
tagName: 'img',
attributeBindings: ['src'],
src: 'https://www.google.com/images/srpr/logo3w.png',
click: function() {
this.set('src', 'http://l.yimg.com/dh/ap/default/120910/yahoo_logo_br.png');
}
});

event.context not set by {{action ...}} when using {{#each ...} (undefined)

I'm trying out Ember.js for the first time by roughly following the Ember.js guide, but I'm running into the following problem.
Relevant code:
https://gist.github.com/3257657 (for complete rails app, see: https://github.com/basveeling/ember-test)
Context:
I'm running the latest ember-rails build with the 1.0 prerelease ember.js. I'm using ember-data for the post model.
Almost everything works in this app, except that the hrefs created by {{action showPost context="post" href=true}} have an undefined id (#/posts/undefined).
Furthermore, the jQuery event passed to the showPost action doesn't have a context property (it does have a view property).
Am I going at this the wrong way, or have I perhaps stumbled on a bug in the prerelease?
edit: this might be related to Url contains 'undefined' instead of id after navigating back from 'edit' to 'show'
Try change {{action showPost context="post" href=true}} to {{action showPost post href=true}}
The 1.0 prerelease has changed the action helper.
More info: https://github.com/emberjs/ember.js/commit/83b7a61a892e55423cf1e66f606b13435bcab8f0