Create complex view (form) with Marionette - backbone.js

I want to create a complex form with Backbone.Marionette. I think the form should be like this:
Any change on products or payments should affect "sale" model. The model structure is:
sale : {
date : '10/01/2010',
customer : 'Jaime Rivera'
products : [{product_name:'ZZZZZZ', price: 100, quantity: 2},
{product_name:'yyyyyy', price: 33, quantity: 1}],
payments : [{type:'check', other_data: '', amount: 160},
{type:'credit-card', other_data: '', amount: 73}]
}
I would like to know the best way to structure the views to create the form. I'm not sure if i should use layout, compositeview or collectionview.

There are multiple ways to make this work with Marionette's views, and none of them are right or wrong necessarily. Some will work better for your other constraints, like what data needs to be used to render this, what events need to be handled, etc.
Given the data that you've shown, though, this looks like a Layout with two CompositeViews.
The Layout would render the the date picker, input box and two empty divs for products and payments. Each of these empty divs would have a region definition associated in the Layout, so you can show the products and payments.
You could then have a CompositeView for products - a template that renders the list of products and the Add Product button. The CompositeView itself would handle the Add Product button click. An ItemView would be specified to render each Product in the list.
Payments would be done the same way as Products.
... again, this is only one option for making it work. You could do the entire thing with one Layout and 2 Collection views, or the entire thing as a single ItemView (which would be difficult to maintain, but still possible).
Hope that helps.

Related

How to load different content(content which is different from already loaded content) on button click in React JS

I am displaying results from json in a react bootstrap table. On clicking compare, the results get filtered within the table. Now I wanted to reload and display the selected products in a different tabular format on clicking "Compare". The page should reload and then only the selected products should display in a table with headers vertically aligned. Can any one please help? Full code here - https://codesandbox.io/s/o4nw18wy8q
Expected output sample on clicking compare -
Probably you need to have a function inside your class to return two different views based the state of your filter status. If the filter status is not true, then display the normal view, if filter status is true, then display the view that you have just mentioned in the above view. As far as the design is concerned, you should be able to work out the table designs.
And when you hit clear, then you should set the filter status back to false
This is not a full working code. I am just giving you some idea.
Here is a codesandbox
https://codesandbox.io/s/2x450x3rqn
You can return a view from the function
onButtonClick = () => {
...
...
return <BootstrapTable
keyField="PartNumber"
selectRow={updatedData}
data={updatedData}
columns={updatedData}
/>
}

Ant design bar chart hide label

I use ant design bar chart in my react project.
https://codesandbox.io/s/9qmjm0k7yw
Doc: https://pro.ant.design/components/Charts
I want to show the data with x-axis as date format (29/09/2018 for example). If I show like 30 days, it would not have enough space for all the label so it looks weird.
I want to hide the label of bar chart. Like this
if (more than 15 days) chart shows label
else hide label
Or is there any way that I show the chart for 30 days but only show the label for let's say 10 days?
How can I hide the label?
Unfortunately what you want to do is not supported by Antd-Pro Charts. It is stated in the docs that they designed the charts components with focus on ease-of-use over customization.
However Antd-Pro Charts are just a simplified subset of BizCharts (which itself is a port of G2) with reduced api options. If you need complicated chart options consider using the parent BizCharts library instead. You can do what you want by adjusting the < Axis > object in BizCharts.
In my example below, I have used a Column chart with x field of "week" and y field of "views". I did not want to display the label on the x field.
render() {
// console.log(this.state.data)
const config = {
data: this.state.data,
title: {
visible: true,
text: 'Your Stats',
},
xField: 'week',
yField: 'views',
meta: {
week: {
alias: " "
}
}
};
return (
<React.Fragment>
<Column {...config} />
</React.Fragment>
);
}
The data used is as follows:
Which yielded this outcome:
In order to develop your own project, I strongly recommend that you keep all of your software business in your own project, and use third party libraries just for their own business, rather than manipulating your software business because they simply change these libraries and To apply these changes, you may need to do a lot of work.
it does not only give you more performance but also increases your ability to develop.
for your topic, you can simply get an array and handle whatever you want and pass your processed array to component

How to structure recusrive categories in Angular, perhaps using ui-router?

I'm a beginner Angular guy and I need some help structuring an application. The part I'm having difficulty with is a categorization system.
The Category model has the fields: title, slug, parent category, image, type. Categories can be of simple type (title only, no image) or full (title and image). Other category types should be possible to create in the future - for example, category with lengthy description and no children. Categories can be automatically expanded (a simple category with subcategories has its children expanded by default) or not (a full category by default is not expanded).
Visually, it should look like the following: a category has a title, and inside it the images and titles of subcategories, like apps look on your phone's home screen:
https://s3.amazonaws.com/ish-archive/2016/bjjcollective/20160215.bjjc-uiux.png
When you click one of those "app"-looking things, that subcategory's title gets added to the hierarchy of titles (so the categorization acts as a tree), and the subsubcategories are shown, as app-looking things.
When you click on the title of a parent directory, the children tree gets replaced with the expanded view of that category's subcategories.
Additionally, each category should have a url associated with it, for example: /categories/houses/kitchen/silverware ( /categories/:slug_0/:slug_1 or /categories/*slugs ? ) should be the page where silverware category is expanded, and its subcategories are shown. The slugs are not unique! So you can have a path like /categories/camping/kitchen/silverware as well, which would be different from "houses" silverware.
The backend API can have any shape that's usable by the frontend. /api/categories.json, /api/categories/houses.json?depth=2, /api/category/houses.json - it's completely flexible.
So I am looking into ui-router and directives to make this happen but I don't see how I should structure my code. To tie views to the url I have to use ui-router, not directives, right? Is recursive views a thing in Angular? And, if each category has a sub-view, how do I restrict rendering of subcategories to only the one relevant subview? I have a pretty solid idea how to do it in jQuery, but how do you do it in Angular?

Initializing ngModel with data - AngularJS Bootstrap bs-select

I am maintaining a site that allows users to create a profile of sorts that will allow them to broadcast activities to a feed. I implement ng-grid to keep track of all the profiles that are created, and have created two buttons that allow users to create/edit these profiles. My only problem right now is, when users select a row on the grid and attempt to edit that specific row, the drop-down menu is not auto-populated with the data from ngModel.
This is the part of the form I am having trouble with:
<select ng-model="source.canSendTo" ng-options="value.name for value in sourceCanSendTo" data-style="btn" bs-select></select>
And within the controller, I have sourceCanSendTo defined as:
$scope.sourceCanSendTo = [ {"id":"abc", "name": "ABC"}, {"id":bcd", "name": "BCD"} ... ];
On row selection, I simply set source = the selected item, and console.logs show that all the data is there. The other parts of the form are being populated properly (mainly s), and console.log($scope.source.canSendTo) shows that the original data is there, it's just that select is defaulted to being blank...how would I go about trying to pre-select certain elements on the drop-down select I currently have?
For example, if the profile has 'abc', 'bcd' selected, how can I make it so that when I edit that profile, the drop down box shows 'abc,bcd' instead of just "Nothing Selected"?
Edit: I previously responded to a comment inquiring about bs-select, saying that it simply controlled some CSS elements of the drop down box - seems like this is completely incorrect after a quick google search when everything else led to dead ends. Does anyone have any idea how to properly initialize the model with data so that when I preload my form, the 'can send to' drop down select actually has the selected options selected, as opposed to saying "Nothing Selected"? Thanks in advance for all help!
As you are binding source.canSendTo to the name (value.name) of sourceCanSendTo then you just need to initially have an structure binding the names which had been saved, something like this:
source.canSendTo = ['abc', 'bcd']; //And all the selected values
So you need to construct your source.canSendTo property to this structure.
PS: If you show how you bring your data from the server, I can help you to construct the source.canSendTo property.
$scope.canSendTo must be initialized with a reference to the selected option.
var initialSelection = 0;
$scope.source = { canSendTo : [ {"id":"abc", "name": "ABC"}, {"id":bcd", "name": "BCD"} ... ] };
$scope.canSendTo = $scope.source.canSendTo[initialSelection];
Finally found out what was wrong with my code - seems like the data being stored in the model wasn't the same as what was in ngOptions, played around a bit with ngOptions and managed to get something that works. Working snippet of code:
<select ng-model="sendTo.name" ng-option="value.name as value.name for value in sourceCanSendTo" data-style="btn" multiple bs-select>
(Realized that the variable being used for ngModel was a fairly ambiguous in terms of naming convention, changed it)

Binding a javascript object to another object on a different path, ngOptions

var user = {
vetClinics: [{name: "VetsRUs",...},...],
pets: [{name: "Lassy", vetClinic: ??},...]
}
Say I have a user with many pets and he goes to a standard vet clinic for his dogs but goes to a specialized clinic for his Iguana.
Using angular, I want to be able to provide a select box that the user can associate each pet with any one of the clinics the user has registered in their system. Angular has a select directive with ngOptions attribute that I can point to the list of clinics.. Great.
When this data goes through the ser/deser dance via an api, that link that was made with the angular select box is broken. I can rebind these entities in an imperative style based on their identity and the select box will work again.
What's a better way of doing this? Is there any way I instruct angular that these objects are equal and so it will do the appropriate binding?
Edit 1: What my ngOptions markup looks like
<div ng-repeat="pet in user.pets">
<label>{{pet.name}}</label>
<select ng-model="pet.vetClinic"
ng-options="vc.name for vc in user.vetClinics"
ng-change="updateUserResource()"></select>
</div>

Resources