mirror of
https://github.com/frappe/books.git
synced 2024-11-10 07:40:55 +00:00
updated docs
This commit is contained in:
parent
18544d0d28
commit
5c3a52186e
@ -5,7 +5,7 @@ const frappe = require('frappejs');
|
||||
module.exports = class FormPage extends Page {
|
||||
constructor(doctype) {
|
||||
let meta = frappe.getMeta(doctype)
|
||||
super({title: `Edit ${meta.name}`});
|
||||
super({title: `Edit ${meta.name}`, hasRoute: true});
|
||||
this.meta = meta;
|
||||
this.doctype = doctype;
|
||||
|
||||
|
@ -7,7 +7,7 @@ nunjucks.configure({ autoescape: false });
|
||||
module.exports = class PrintPage extends Page {
|
||||
constructor(doctype) {
|
||||
let meta = frappe.getMeta(doctype);
|
||||
super({title: `View ${meta.name}`});
|
||||
super({title: `${meta.name}`, hasRoute: true});
|
||||
this.meta = meta;
|
||||
this.doctype = doctype;
|
||||
|
||||
@ -35,6 +35,7 @@ module.exports = class PrintPage extends Page {
|
||||
|
||||
try {
|
||||
this.body.innerHTML = `<div class="print-page">${nunjucks.renderString(this.printFormat.template, context)}</div>`;
|
||||
this.setTitle(doc.name);
|
||||
} catch (e) {
|
||||
this.renderError('Template Error', e);
|
||||
throw e;
|
||||
|
@ -87,7 +87,7 @@ class BaseControl {
|
||||
}
|
||||
|
||||
setDisabled() {
|
||||
if (this.readonly || this.disabled) {
|
||||
if (this.disabled) {
|
||||
this.input.disabled = true;
|
||||
}
|
||||
}
|
||||
|
@ -106,12 +106,12 @@ module.exports = class BaseForm extends Observable {
|
||||
setTitle() {
|
||||
const doctypeLabel = this.doc.meta.label || this.doc.meta.name;
|
||||
|
||||
if (this.doc.meta.isSingle || !this.doc.meta.showTitle) {
|
||||
if (this.doc.meta.isSingle || this.doc.meta.naming == 'random') {
|
||||
this.container.setTitle(doctypeLabel);
|
||||
} else if (this.doc._notInserted) {
|
||||
this.container.setTitle(frappe._('New {0}', doctypeLabel));
|
||||
} else {
|
||||
this.container.setTitle(`${doctypeLabel} ${this.doc.name}`);
|
||||
this.container.setTitle(this.doc.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ const Observable = require('frappejs/utils/observable');
|
||||
const Dropdown = require('frappejs/client/ui/dropdown');
|
||||
|
||||
module.exports = class Page extends Observable {
|
||||
constructor({title, parent, hasRoute=true}) {
|
||||
constructor({title, parent, hasRoute=true} = {}) {
|
||||
super();
|
||||
Object.assign(this, arguments[0]);
|
||||
if (!this.parent) {
|
||||
@ -20,7 +20,7 @@ module.exports = class Page extends Observable {
|
||||
make() {
|
||||
this.wrapper = frappe.ui.add('div', 'page hide', this.parent);
|
||||
this.wrapper.innerHTML = `<div class="page-head clearfix hide">
|
||||
<span class="page-title"></span>
|
||||
<span class="page-title font-weight-bold"></span>
|
||||
</div>
|
||||
<div class="page-body"></div>`
|
||||
this.head = this.wrapper.querySelector('.page-head');
|
||||
|
@ -7,9 +7,13 @@ Frappe.js is a meta-data driven framework that enables rapid application develop
|
||||
- [Making a new App](app.md)
|
||||
- Models and Documents
|
||||
- [Declaring Models](models/index.md)
|
||||
- [Fields](models/fields.md)
|
||||
- [Controllers](models/controllers.md)
|
||||
- [Formula](models/fields.md)
|
||||
- [Metadata](models/metadata.md)
|
||||
- [Managing Documents](models/document.md)
|
||||
- [Single Documents](models/singles.md)
|
||||
- [Parent Child](models/parent-child.md)
|
||||
- [Server](server/index.md)
|
||||
- [REST API](server/rest.md)
|
||||
- [Client](client/index.md)
|
||||
@ -21,6 +25,11 @@ Frappe.js is a meta-data driven framework that enables rapid application develop
|
||||
- [UI](client/ui/index.md)
|
||||
- [Dropdown](client/ui/dropdown.md)
|
||||
- [Desk](client/desk.md)
|
||||
- Utilities
|
||||
- [Observable](utilities/observable.md)
|
||||
- [Print Format](utilities/print-format.md)
|
||||
- [Number Series](utilities/number-series.md)
|
||||
- [System Settings](utilities/system-settings.md)
|
||||
- [Backends](server/backends.md)
|
||||
- [Errors](errors.md)
|
||||
- [Testing](testing.md)
|
||||
|
@ -4,6 +4,8 @@ In Frappe.js you can extend the metadata class as well as the document class for
|
||||
|
||||
You can write event handlers in controllers, by declaring a `.js` file in the `models/doctype/` folder along with the model file.
|
||||
|
||||
You must also mind the controller to the model file by the `documentClass` property.
|
||||
|
||||
## Naming
|
||||
|
||||
1. The name of the controller class must be the slugged name of the DocType (example `todo`)
|
||||
@ -22,9 +24,6 @@ const frappe = require('frappejs');
|
||||
|
||||
// extend the document and add event handlers
|
||||
class todo extends frappe.document.Document {
|
||||
setup() {
|
||||
this.add_handler('validate');
|
||||
}
|
||||
validate() {
|
||||
if (!this.status) {
|
||||
this.status = 'Open';
|
||||
@ -40,16 +39,9 @@ The `meta` class contains actions that are done on a group of objects and a docu
|
||||
```js
|
||||
// extend the meta class
|
||||
class todo_meta extends frappe.meta.Meta {
|
||||
setupMeta() {
|
||||
Object.assign(this, require('./todo.json'));
|
||||
this.name = 'ToDo';
|
||||
this.list_options.fields = ['name', 'subject', 'status', 'description'];
|
||||
}
|
||||
|
||||
getRowHTML(data) {
|
||||
return `<a href="#edit/todo/${data.name}">${data.subject}</a>`;
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
77
docs/models/fields.md
Normal file
77
docs/models/fields.md
Normal file
@ -0,0 +1,77 @@
|
||||
# Fields
|
||||
|
||||
Fields are properties a the document instance that are defined in its DocType.
|
||||
|
||||
## Field Types
|
||||
|
||||
### Data
|
||||
|
||||
Small, single line text (140 chars)
|
||||
|
||||
### Text
|
||||
|
||||
Long multi-line text
|
||||
|
||||
### Int
|
||||
|
||||
Integer
|
||||
|
||||
### Float
|
||||
|
||||
Number
|
||||
|
||||
### Currency
|
||||
|
||||
Number with currency
|
||||
|
||||
### Code
|
||||
|
||||
Code string (like Text but monospaced)
|
||||
|
||||
### Date
|
||||
|
||||
Date (formatted by [SystemSetings.dateFormat](../utilities/system-settings.md))
|
||||
|
||||
### Select
|
||||
|
||||
Dropdown with fixed options. Options must be set in the `options` property
|
||||
|
||||
```
|
||||
{
|
||||
fieldtype: "Select",
|
||||
fieldname: "status",
|
||||
label: "Status",
|
||||
options: [
|
||||
"Open",
|
||||
"Closed",
|
||||
"Pending"
|
||||
]
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
### Link
|
||||
|
||||
Reference to another document set by `target`
|
||||
|
||||
```
|
||||
{
|
||||
fieldtype: "Link",
|
||||
fieldname: "customer",
|
||||
label: "Customer",
|
||||
target: "Customer"
|
||||
}
|
||||
```
|
||||
|
||||
### Table
|
||||
|
||||
Property with child documents, the type of children is defined by `childtype` property
|
||||
|
||||
```
|
||||
{
|
||||
fieldtype: "Table",
|
||||
fieldname: "items",
|
||||
label: "Items",
|
||||
target: "InvoiceItem"
|
||||
}
|
||||
```
|
65
docs/models/formula.md
Normal file
65
docs/models/formula.md
Normal file
@ -0,0 +1,65 @@
|
||||
# Formula
|
||||
|
||||
Formulas are dynamic document properties that can be set on the fields
|
||||
|
||||
Forumlas are defined as javascript functions and are called whenever any property of the document is updated using the `set` method, or just before inserting or updating the document.
|
||||
|
||||
### Example
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
name: "FormulaExample"
|
||||
fields: [
|
||||
{
|
||||
fieldtype: "Float",
|
||||
fieldname: "a"
|
||||
},
|
||||
{
|
||||
fieldtype: "Float",
|
||||
fieldname: "b"
|
||||
}
|
||||
{
|
||||
fieldtype: "Float",
|
||||
fieldname: "c",
|
||||
formula: doc => doc.a + doc.b
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Formula on child tables
|
||||
|
||||
In child tables, both the parent and the child records are passed
|
||||
|
||||
### Example
|
||||
|
||||
```js
|
||||
{
|
||||
fieldname: "amount",
|
||||
fieldtype: "Float",
|
||||
formula: (doc, row) => row.qty * row.rate
|
||||
}
|
||||
```
|
||||
|
||||
## Sequence
|
||||
|
||||
All child tables are executed first and all fields are executed in the sequence as defined in the DocType
|
||||
|
||||
## Fetching Values
|
||||
|
||||
You can use the `getFrom` function to fetch values from another document
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
{
|
||||
"fieldname": "rate",
|
||||
"label": "Rate",
|
||||
"fieldtype": "Currency",
|
||||
formula: (row, doc) => row.rate || doc.getFrom('Item', row.item, 'rate')
|
||||
}
|
||||
```
|
||||
|
||||
## Async
|
||||
|
||||
Forumlas are evaluated as promises, so you can either directly pass a value or a `Promise`
|
@ -1,14 +1,25 @@
|
||||
# Declaring Models
|
||||
|
||||
Models are declared by adding a `.json` model file in the `models/doctype` folder of the module/app.
|
||||
Models are declared by adding a `.js` model file in the `models/doctype` folder of the module/app.
|
||||
|
||||
Note: A model is called `DocType` in Frappe.js
|
||||
|
||||
### Fields
|
||||
|
||||
Every model must have a set of fields (these become database columns). All fields must have
|
||||
|
||||
- `fieldname`: Column name in database / property name
|
||||
- `fieldtype`: Data type ([see details](fields.md))
|
||||
- `label`: Display label
|
||||
- `required`: Is mandatory
|
||||
- `hidden`: Is hidden
|
||||
- `disabled`: Is disabled
|
||||
|
||||
### Example
|
||||
|
||||
```json
|
||||
{
|
||||
"autoname": "hash",
|
||||
```js
|
||||
module.exports = {
|
||||
"naming": "random",
|
||||
"name": "ToDo",
|
||||
"doctype": "DocType",
|
||||
"issingle": 0,
|
||||
|
40
docs/models/parent-child.md
Normal file
40
docs/models/parent-child.md
Normal file
@ -0,0 +1,40 @@
|
||||
# Parent Child Relationship
|
||||
|
||||
All documents can have child documents, identified by the `Table` field.
|
||||
|
||||
Though child documents have their own DocType and database table, but are not to handled or viewed on their own. FrappeJS will automatically load child documents along with the parent when you use the `frappe.getDoc` method.
|
||||
|
||||
### Example
|
||||
|
||||
A sample parent-child records looks like this:
|
||||
|
||||
```
|
||||
{
|
||||
doctype: "Invoice",
|
||||
customer: "Harry Potter",
|
||||
items: [
|
||||
{
|
||||
item: "Wand",
|
||||
qty: 1,
|
||||
rate: 300,
|
||||
amount: 300
|
||||
},{
|
||||
item: "Invisibility Cloak",
|
||||
qty: 1,
|
||||
rate: 3000,
|
||||
amount: 3000
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## Child Properties
|
||||
|
||||
Child documents have special properties that define their relationship to their parent
|
||||
|
||||
- `parent`: name of the parent
|
||||
- `parenttype`: DocType of the parent
|
||||
- `parentfield`: Field in the parent that links this child to it
|
||||
- `idx`: Sequence (row)
|
||||
|
||||
These properties are maintained in the table automatically by FrappeJS
|
21
docs/models/singles.md
Normal file
21
docs/models/singles.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Single Documents
|
||||
|
||||
Single doctypes have only one instance. They are useful for using DocTypes as views or for settings.
|
||||
|
||||
To make a Single DocType, set the `isSingle` property as true.
|
||||
|
||||
Single documents are best viewed in a modal since they do not have a corresponding list view.
|
||||
|
||||
Values of single documents are stored in the table `SingleValue`
|
||||
|
||||
## API
|
||||
|
||||
### frappe.getSingle
|
||||
|
||||
Load a single document
|
||||
|
||||
```js
|
||||
let systemSettings = frappe.getSingle('SystemSettings');
|
||||
```
|
||||
|
||||
Since Single documents are also documents, you can update them with the `update()` method.
|
@ -24,7 +24,7 @@ Connection paramter required for the sqlite backend is the path of the file
|
||||
```js
|
||||
sqllite = require('frappejs/frappe/backends/sqlite');
|
||||
|
||||
frappe.db = await new sqlite.Database({db_path: db_path})
|
||||
frappe.db = await new sqlite.Database({dbPath: dbPath})
|
||||
```
|
||||
|
||||
### SQL Queries
|
||||
|
25
docs/utilities/number-series.md
Normal file
25
docs/utilities/number-series.md
Normal file
@ -0,0 +1,25 @@
|
||||
# Number Series
|
||||
|
||||
A number series is used to maintain a series for numbering documents (like invoices)
|
||||
|
||||
Properties:
|
||||
|
||||
- `name`: Prefix of the series example `INV-`
|
||||
- `current`: Its current (or starting) value. This will be auto updated everytime the series is updated.
|
||||
|
||||
### API
|
||||
|
||||
You can get the next number in the series by using the utiltiy function
|
||||
|
||||
```js
|
||||
const model = require("frappejs/model")
|
||||
let nextValue = model.getSeriesNext("INV-");
|
||||
```
|
||||
|
||||
### Setting naming series in a document
|
||||
|
||||
To setup a number series for a DocType:
|
||||
|
||||
- It must have its own "Settings" [single document](../models/singles.md. For example (InvoiceSettings for Invoice).
|
||||
- The settings document must be set via the `settings` property in the DocType
|
||||
- The settings document must have a `numberSeries` property with value of the number series
|
29
docs/utilities/observable.md
Normal file
29
docs/utilities/observable.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Observable Base Class
|
||||
|
||||
The `Observable` base class makes and subclass trigger events and accept event listeners.
|
||||
|
||||
### Example
|
||||
|
||||
```js
|
||||
class Test extends Observable {
|
||||
doSomething() {
|
||||
// work
|
||||
this.trigger('work-done', {some: params})
|
||||
}
|
||||
}
|
||||
|
||||
let test = new Test();
|
||||
test.on('work-done', (params) => yay());
|
||||
```
|
||||
|
||||
### With Sockets
|
||||
|
||||
You can also bind sockets (SocketIO) to an `Observable` and all events will also be emitted or received via the socket. See the API below for binding sockets.
|
||||
|
||||
### Methods
|
||||
|
||||
- `on(event, listener)`: Listen to an event
|
||||
- `trigger(event)`: trigger an event
|
||||
- `once(event, listener)`: trigger an event once
|
||||
- `bindSocketServer(socket)`: Emit triggers on this socket
|
||||
- `bindSocketClient(socket)`: Listen for events on this socket
|
102
docs/utilities/print-format.md
Normal file
102
docs/utilities/print-format.md
Normal file
@ -0,0 +1,102 @@
|
||||
# Print Format
|
||||
|
||||
A PrintFormat represents an HTML template that is used to create a printer-friendly version of the DocType
|
||||
|
||||
## Creating a Print Format
|
||||
|
||||
To make a printer friendly version, you must create a "PrintFormat" for the doctype
|
||||
|
||||
Example:
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
doctype: "PrintFormat",
|
||||
name: "Standard Invoice Format",
|
||||
for: "Invoice",
|
||||
template: require('./invoice.html')
|
||||
}
|
||||
```
|
||||
|
||||
This must be referenced in the `print.printFormat` property of the DocType.
|
||||
|
||||
```js
|
||||
"print": {
|
||||
"printFormat": "Standard Invoice Format",
|
||||
},
|
||||
```
|
||||
|
||||
## Templating
|
||||
|
||||
The templating system used by frappe is [nunjucks](https://mozilla.github.io/nunjucks/) and is very similar to Jinja2 system from Python
|
||||
|
||||
### Example
|
||||
|
||||
Example of a print format for an Invoice
|
||||
|
||||
```html
|
||||
<h1>{{ doc.name }}</h1>
|
||||
<div class="row py-4">
|
||||
<div class="col-6">
|
||||
<div><b>{{ frappe._("Customer") }}</b></div>
|
||||
<div>{{ doc.customer }}</div>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<div><b>{{ frappe._("Date") }}</b></div>
|
||||
<div>{{ frappe.format(doc.date, 'Date') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{{ frappe._("Item") }}</th>
|
||||
<th class='text-right'>{{ frappe._("Qty") }}</th>
|
||||
<th class='text-right'>{{ frappe._("Rate") }}</th>
|
||||
<th class='text-right'>{{ frappe._("Amount") }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in doc.items %}
|
||||
<tr>
|
||||
<td class='text-right'>{{ row.idx + 1 }}</td>
|
||||
<td>{{ row.item }}<br>{{ frappe.format(row.description, 'Text') }}</td>
|
||||
<td class='text-right'>{{ row.quantity }}</td>
|
||||
<td class='text-right'>{{ frappe.format(row.rate, 'Currency') }}</td>
|
||||
<td class='text-right'>{{ frappe.format(row.amount, 'Currency') }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
<div class='row'>
|
||||
<div class='col-6'></div>
|
||||
<div class='col-6'>
|
||||
<div class='row'>
|
||||
<div class='col-6'>
|
||||
{{ frappe._("Total") }}
|
||||
</div>
|
||||
<div class='col-6 text-right'>
|
||||
{{ frappe.format(doc.netTotal, 'Currency')}}
|
||||
</div>
|
||||
</div>
|
||||
{% for tax in doc.taxes %}
|
||||
<div class='row'>
|
||||
<div class='col-6'>
|
||||
{{ tax.account }} ({{ tax.rate }}%)
|
||||
</div>
|
||||
<div class='col-6 text-right'>
|
||||
{{ frappe.format(tax.amount, 'Currency')}}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<div class='row py-3'>
|
||||
<div class='col-6'>
|
||||
<h5>{{ frappe._("Grand Total") }}</h5>
|
||||
</div>
|
||||
<div class='col-6 text-right'>
|
||||
<h5>{{ frappe.format(doc.grandTotal, 'Currency')}}</h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
```
|
11
docs/utilities/single-value.md
Normal file
11
docs/utilities/single-value.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Single Value
|
||||
|
||||
The SingleValue table is where all [Single documents](../model/singles.md) are stored.
|
||||
|
||||
A `SingleValue` record is created for each property of the doctype
|
||||
|
||||
Properties:
|
||||
|
||||
- `parent`: name of single document
|
||||
- `fieldname`: name of the field (property)
|
||||
- `value`: value of the field
|
11
docs/utilities/system-settings.md
Normal file
11
docs/utilities/system-settings.md
Normal file
@ -0,0 +1,11 @@
|
||||
# System Settings
|
||||
|
||||
SystemSettings is a [Single document](../models/singles.md) that has system defaults like
|
||||
|
||||
- `dateFormat`: default date format
|
||||
|
||||
You can get system settings as
|
||||
|
||||
```js
|
||||
frappe.getSingle("SystemSettings")
|
||||
```
|
@ -8,7 +8,7 @@ module.exports = {
|
||||
"fields": [
|
||||
{
|
||||
"fieldname": "name",
|
||||
"label": "Name",
|
||||
"label": "Prefix",
|
||||
"fieldtype": "Data",
|
||||
"required": 1
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
module.exports = {
|
||||
"autoname": "random",
|
||||
"naming": "random",
|
||||
"name": "ToDo",
|
||||
"doctype": "DocType",
|
||||
"isSingle": 0,
|
||||
|
Loading…
Reference in New Issue
Block a user