marionette control from backbone controls - javascript

I want to create mariontte control that consists of three backbone controls. First is Date Picker, second is numeric stepper and the third one is again Date Picker. The idea is that first date is the initial date and numeric stepper adds days and the result is shown in second Date Picker. Anyway I don't know how to create Marionette view when not all child items are the same. How should I approach this?

I think you can create a compositeview(or even layout can work) having three divs and render three different itemviews in the three divs by explicitly adding the el of the itemViews in the divs
e.g. if following is your compositeview template
<div id="first-datepicker"></div>
<div id="numeric-stepper"></div>
<div id="second-datepicker"></div>
Then in your compositeView JS you can render itemviews as follows
ui:{
firstDatepicker: "#first-datepicker",
numericStepper: "#numeric-stepper",
secondDatepicker: "#second-datepicker"
},
onRender: function(){
this.ui.firstDatepicker.html(new DatePickerView().render().el);
this.ui.numericStepper.html(new NumericStepperView().render().el);
this.ui.firstDatepicker.html(new DatePickerView().render().el);
}
But in case of layout you do not need to explicitly render the view, you can simply use show method of layout as
regions:{
firstDatepickerRegion: "#first-datepicker",
numericStepperRegion: "#numeric-stepper",
secondDatepickerRegion: "#second-datepicker"
},
onRender: function(){
this.firstDatepickerRegion.show(new DatePickerView());
this.numericStepperRegion.show(new NumericStepperView());
this.secondDatepickerRegion.show(new DatePickerView());
}

Related

To limit number of items to be displayed in react predictive input

Implementing React from couple of months. I used 'react-predictive-input' for predicting items from the pre-defined list on onchange event.
With "large" data sets (500/1000 items) the AutoComplete component becomes very slow especially when typing the first 3 characters because it will render many items in the dropdown slowing the entire interface, even using a maxHeight for the component.
Do we have any attribute as 'max-items' to show from the list?
Below is the snippet of code :
<Autocomplete
id="items"
placeholder="My Items"
data={this.props.items}
onSelected={this.onItemSelected.bind(this)} />
Function is invoked if item is selected
onItemSelected(value){
console.log(`${value} was selected`);
}
List of items
static defaultProps = {
items:[
'car','Bicycle','Truck','Green Van'............................1000items]
};
Text prediction works fine, speed and display are becoming an issue to handle.
I used Material UI Autocomplete for retrieving the use cases mentioned in the question. Link for reference here.

Ember 1.13, view lookup

Prior to ember 1.13 i was using
var containerView = Em.View.views[view_id];
to get the ContainerView instance with the view id and manually adding childViews to this container view, which used to work just fine.
As of ember 1.13 this view lookup is not supported. What is the recommended way of doing this?
The problem is there are multiple instances of the same containerView with different id's. So i need to get the right instance of containerView from lookup.
Thanks
Update:
I have a parent (widget) component:
parentComponent.hbs
.....
{{input value=someBinding1 click='showCalendar'}}
{{calendar-component month=month1 disableBefore=disableBefore1}}
{{input value=someBinding2 click='showCalendar'}}
{{calendar-component month=month2 disableBefore=disableBefore2}}
{{input value=someBinding3 click='showCalendar'}}
{{calendar-component month=month3 disableBefore=disableBefore3}}
.....
So essentially i can have multiple date(input) fields which when clicked should show up a calendar component. If i write the code as above it would create 3 (or as many date fields) instances of the calendar component. These number of date fields are dynamic. I did not wanted to create so many calendar components as i see sluggish performance on mobile devices.
So what i did was:
.....
{{input value=someBinding1 click='showCalendar'}}
{{calendar-container-view id='calendarContainerView1'}}
{{input value=someBinding2 click='showCalendar'}}
{{calendar-container-view id='calendarContainerView2'}}
{{input value=someBinding3 click='showCalendar'}}
{{calendar-container-view id='calendarContainerView2'}}
.....
And calendar-container-view had an empty childViews array to start.
When user clicks on input field i get the corresponding containerView instance using Em.View.views[containerViewId] and append the calendar instance to it.
When another input is clicked i remove it from old parent containerView and add it to the new container view.
So there is only one calendar instance created by parentComponent.js and removed and added to container view.
Hope it makes sense. I can create a jsbin if need be.
Thanks a lot!
I think you could operate your logic by model instances instead of views (I mean model concept here, it could be some array of objects or records array).
It's clear you have model (as some array), since you mentioned multiple instances.
You might do:
{{!-- list of input fields --}}
{{#each model as |item|}}
{{item-input-field item=item value=item.someBinding1 clickInput="setCurrentItemWhenInstanceClick"}}
{{/each}}
{{!-- and one calendar-component --}}
{{#if currentItem}}
{{calendar-component item=currentItem month=currentMonth disableBefore=currentDisableBefore}}
{{/if}}
where item-input-field is a component, that extends input and pass it's item up to parent component or controller through action clickInput (action up).
Then setCurrentItemWhenInstanceClick action in parent component (or controller) should set currentItem, currentMonth and currentDisableBefore data (data down to calendar-component), so your calendar-component will be shown.

Emberjs loading dynamic subview

I'm just getting started with emberjs and I have some problems understanding how to dynamically change views within a view.
I want to have a page with a calendar.
This page has some buttons on the top to switch between different calendar views (day, week, month) and some filter options for the appointments within this view.
See this mockup:
Currently I have created a calendar route and a CalendarIndexView and template.
This template will contain the basic filter and view toggle buttons.
Within the index view I can call another view to display the grid.
<div class="calendar-container">
{{view monthView}}
</div>
The collection/context that is attached to these different views should not change because the filter is also applied on this.
The problem I have is that I don't know how to change the monthView to for example dayView after the "day" button is clicked.
Should I handle this in a router, controller or in the main calendar view?
If not view the router, how would make this view switching dynamic?
One of the core strengths of Ember is the router - everything is driven by the URL. I don't think you should part from that.
Use different routes for the different views within a calendar resource (in the router):
this.resource('calendar', { path: '/calendar' }, function() {
this.route('day');
this.route('week');
this.route('month');
});
Set the model on the calendar resource
In the nested routes (day, week (you could make month the default by using the calendar index route for it)), use the same model as in the calendar route, just filter it down to what you want. e.g.:
export default Ember.Route.extend({
model: function() {
return this.modelFor('calendar').filter(function(event) { ... });
}
});
For the people filter create a computed property in the controller that filters the events on the model and use that in the templates instead of the actual model. In that, if a person is selected, you can filter out any events without that person.
selectedPerson: null, // bind that e.g. to a select with all the people or change that with an action
filteredEvents: function() {
if (! this.get('selectedPerson')) {
return this.get('events');
}
return this.get('events').filterBy('attendee', this.get('selectedPerson'));
}.property('events.#each.attendee', 'selectedPerson')
Better than (4.): Do the filtering via query parameters. That way, you could be very flexible and even build powerful text search pretty easily...
Hope that helps and happy to see different approaches...

Collection of template-switching views. Backbone.js

There is a Bckabone view Product:
Product = Backbone.View.extend({
templateBasic: _.template($("#pcard-basic").html()),
templateFull: _.template($("#pcard-full").html()),
initialize: function() {
this.render(this.templateBasic);
},
// ...
Here's my draft: http://jsfiddle.net/challenger/xQkeP/73
How do I hide/show other views when one of them gets chosen/unchosen to view its full template so it could expand to a full container width.
Should I use a view for an entire collection? How do I deal with event handling?
Thanks!
EDIT
That's my final draft: http://jsfiddle.net/challenger/xQkeP/
But still I'm not sure whether I could achieve the same result in more elegant manner? I just think that hiding siblings is not the best way of resolving it:
viewBasic: function(e) {
e.preventDefault();
this.render(this.templateBasic);
if(this.switchedToFull) {
this.$el.siblings().show();
this.switchedToFull = false;
}
},
viewFull: function(e) {
e.preventDefault();
this.render(this.templateFull);
this.$el.siblings().hide();
this.switchedToFull = true;
}
If I understand correctly you want to display all your models inside your collections in two different ways, leaving the choice of how to present them to the user, right?
One way you can do this is to create a main view where the user choice is made. When the user decides you should trigger a method from that view that renders every model from the collection using a different template. On your main view you should have a container (table, div, ul, etc) where you'll append each of the model view.
So, in the end, you have to views. One acting as a container for the collection that takes care of handling the users choice. Then you have another view to render a single model from the collection. This view has to templates that can be used. On the main view you iterate over the collection creating a new view instance for each model to append in the container using a different template depending on the user decision.

Many to many relationship events with backbone.js

I have a many-to-many relationship with two of my backbone.js models implemented using a pivot table on the serverside. I'm trying to figure out how to structure it clientside. My current structure is:
1) I have a Tag model, and a TagView which renders a checkbox and the tag label, I have a checked event on the checkbox which does nothing at the moment.
I have a TagsCollection, which holds a bunch of Tags.
I have a TagsCollectionView, which binds add, reset etc of the TagsCollection, and adds TagViews for the added Tags, renders them, and appends the html to its current html (on reset, the html is reset).
I have a global TagCollection instance which contains all the possible tags
I have a Notes Model which contains an (empty) TagCollection called selectedtags on init.
The server returns an array of selected tagids for each Notes, which I add to its TagCollection.
Now comes the hard part, tying it all together.. my NotesView has its own TagsCollectionView which is bound to the global TagsCollection (so it can list all the Tags).. now, how do I get a checked event on the checkedbox of its sub TagViews to trigger an add to this Notes model's selectedtags? Should I provide a reference to the this Notes model instance to the TagsCollectionView on init which then provides it to all the TagViews it creates, whose checked event then adds/removes items from that model? That's the best way I can figure out how to do this, any other thoughts would be appreciated.
View is only for visual display of model. Please specify the need for TagsCollectionView in more details:
Use change event for checking the checkbox.
I would advise incremental coding. First work with the Tag and TagView, As it works, continue adding collection to hold the Tags. After that you can add Notes. It's a 'divide and conquer' :)
Don't confuse with the whole design, it is very simple when you start.
I can not provide the whole design due to lack of requirement details. but, I think below code should trigger the starting point of your design.
var TagsCollectionView=Backbone.View.extend({
el:$(),
});
var Tag=Backbone.Model.extend({
defaults:{
// define the default properties
}
});
var TagView=Backbone.View.extend({
el:$("body"),
events:{
'change #checkBox':'customFunction'
},
initialize: function(){
_.bindAll(this, 'render','customFunction');
this.render();
},
render:function(){
var tag=new Tag();
// code to render the checkbox and label
},
customFunction:function(){
// whatever you want to do after checking event of checkbox
}
});
// collection to collect all the tags
var TagCollection=Backbone.Collection.extend({
model:Tag
});
var Notes=Backbone.Model.extend({
defaults:{
'tagCollection':TagCollection
}
});
// you do not require TagsCollectionView

Categories

Resources