kitchen-site icon indicating copy to clipboard operation
kitchen-site copied to clipboard

Collection2 usage with meteor-kitchen

Open kadirerdogan opened this issue 9 years ago • 9 comments

I am using collection2 with meteor-kitchen and it works great but while showing error messages i am having difficulties. To make collection2 (and simple-schema) work with kitchen-generated code there needs to make a small change. I'll try to explain what i did and i'll propose a solution :)

  • i have added schema.js which includes schema for my collections and custom error messages
  • i have cloned bootstrap template (it's not necessary but i dont want to loose my changes upon new version installs)
  • i have modified form.html so that all span's having the id error-text to have id FIELD_NAME-error. this way when the code is generated i'll have uniq error fields for each field
  • i have modified errorAction function in form.js file. The problem is that the parameter passed to this function is not the whole error object but just the error string. With collection2 the error object has all the fields with errors and the error message. With the error object i can identify field name, find the element with the name FIELD_NAME-error and print the error message to there.

What needs to be done is a modification in the generated insert method. It's originally as below.

newId = Invoice.insert(values, function(e) { if(e) errorAction(e.message); else submitAction(); });

It would be great if it was like below

newId = Invoice.insert(values, function(e) { if(e) errorAction(e); else submitAction(); });

Btw with this change there needs a small change in the original errorAction in form.js function to show the message insted of the object .

kadirerdogan avatar Apr 22 '15 16:04 kadirerdogan

@kadirerdogan makes sense. Form component is to be completely refactored anyway. I'l change these two things in next version (v0.9.35) to help you out.

BTW, can schema.js be automatically generated from data passed via collection & fields? Did you find some missing property useful to auto-generate schema for collections2? Asking this because I'l add collections2 in the near future, so your thoughts are useful.

Thanks.

perak avatar Apr 22 '15 19:04 perak

Kitchen collection & fields are similar to the collection2 schema definition and a basic schema can be auto generated from it but collection2 has a few more feature. For instance you can define a regex for each field (i like this very much :).

Let me paste my schema.js and collection and fields from the json file for the Payments collection so that you can compare :)

Btw, I didn't use every feature of collection2 schema.

//my manually written schema.js file
var Schemas = {};
Schemas.Payments = new SimpleSchema({
    amount: { type: String, label: "Miktar", allowedValues:["70.00"] },
    tckno: { type: String,regEx: /^[0-9]{11}$/, label: "TCK no", min: 11, max: 11 },
    cc_no: { type: String, regEx: /^[0-9]{16}$/,label: "Kart no", min: 16, max: 16 },
    cc_name: { type: String, label: "Kart sahibi" },
    cc_cvv2: { type: String, regEx: /^[0-9]{3}$/,label: "cvv2", min: 3, max: 3 },
    size: { type: String, max:4, allowedValues:["XXL","XL","L","M","S","XS"], label: "Beden" },
    check: { type: Boolean, allowedValues:[true] , label: "Kullanım ve gizlilik koşulları" },
    cc_expiry: { type: String, max:7, label: "Son kullanma tarihi" },
    department: { type: String, label: "Bolum", optional: true, max: 15 }
});
SimpleSchema.messages({
  required: "[label] zorunlu bilgidir",
  minString: "[label] en az [min] karakter olmalıdır.",
  maxString: "[label] en çok [max] karakter olmalıdır",
  minNumber: "[label] en az [min] olabilir",
  maxNumber: "[label] en çok [max] olabilir",
  minDate: "[label] [min] tarihinden daha erken olamaz",
  maxDate: "[label] [max] tarihinden daha gec olamaz",
  badDate: "[label] geçerli bir tarih değil",
  minCount: "You must specify at least [minCount] values",
  maxCount: "You cannot specify more than [maxCount] values",
  noDecimal: "[label] geçerli bir rakam olmalıdır",
  notAllowed: "[label] seçili değil",
  expectedString: "[label] bir karakter kümesi olmalı",
  expectedNumber: "[label] bir rakam olmalı",
  expectedBoolean: "[label] evet yada hayır değeri olmalı",
  expectedArray: "[label] must be an array",
  expectedObject: "[label] bir obje değeri taşımalı",
  expectedConstructor: "[label] must be a [type]",
  "regEx cc_cvv2":"[label] 3 basamaklı bir rakam olmalıdır",
  "regEx cc_no":"[label] 16 basamaklı bir rakam olmalıdır",
  "regEx tckno":"[label] 11 basamaklı bir rakam olmalıdır",
keyNotInSchema: "[key] veriyapısında bulunmuyor"
});
Payments.attachSchema(Schemas.Payments);
"collections": [{
  "name": "payments",
  "fields": [{
    "name": "amount",
    "input": "tl",
    "show_in_update_form": false,
    "default": "70.00",
    "title": "Miktar",
    "exportable": true
  }, {
    "name": "tckno",
    "show_in_update_form": false,
    "title": "Tck No",
    "required": true,
    "exportable": true
  }, {
    "name": "cc_name",
    "show_in_update_form": false,
    "title": "Kart Sahibi",
    "required": true,
    "exportable": true
  }, {
    "name": "cc_no",
    "show_in_update_form": false,
    "title": "Kart No",
    "required": true,
    "exportable": true
  }, {
    "name": "cc_cvv2",
    "show_in_update_form": false,
    "title": "CVV",
    "required": true,
    "exportable": true
  }, {
    "name": "cc_expiry",
    "show_in_update_form": false,
    "input": "ccexpiry",
    "format": "MM/YY",
    "show_in_dataview": false,
    "title": "Gecerlilik Tarihi",
    "required": true,
    "exportable": true
  }, {
    "name": "department",
    "title": "Bölüm",
    "required": true,
    "exportable": true,
    "input": "select",
    "lookup_query": {
      "name": "department",
      "collection": "department",
      "options": {
        "sort": {
          "name": 1
        }
      }
    },
    "lookup_key": "name",
    "lookup_field": "name"
  }, {
    "name": "size",
    "title": "Beden",
    "input": "select",
    "input_items": ["XXL", "XL", "L", "M", "S", "XS"],
    "required": false,
    "exportable": true
  }, {
    "name": "check",
    "title": "",
    "required": true,
    "show_in_read_only_form": false,
    "show_in_update_form": false,
    "show_in_dataview": false,
    "input": "checkbox",
    "input_items": ["Kullanım ve gizlilik koşullarını kabul ediyorum"],
    "exportable": true
  }, {
    "name": "type",
    "title": "Kayıt türü",
    "show_in_update_form": false,
    "show_in_insert_form": false,
    "exportable": true
  }, {
    "name": "status",
    "title": "Durum",
    "show_in_update_form": false,
    "show_in_insert_form": false,
    "exportable": true
  }, ],

  "owner_field": "ownerId",
  "roles_allowed_to_read": ["admin", "owner"],
  "roles_allowed_to_update": ["admin"],
  "roles_allowed_to_delete": ["nobody"],
  "before_insert_source_file": "js/vpos.js",
}]

kadirerdogan avatar Apr 22 '15 19:04 kadirerdogan

Thanks for that. Did you tried autoform too? I gave a look at both and collection2 would certainly be a nice addition. Concerning autoform, I'm not sure if it would be the best choice since it would outsource the form fields type choices. The reactive validation would be nice however. My (very personnal) concern is that I need a proper upload control and a file api (see https://github.com/perak/kitchen-site/issues/68) and I would love to see it available in meteor-kitchen.

Billybobbonnet avatar Apr 22 '15 21:04 Billybobbonnet

No i didnt try autoform since i like the existing form generation method. It's very flexible and easy to customize via template modification. But i would like to have reactive way of showing errors feature too :)

kadirerdogan avatar Apr 23 '15 04:04 kadirerdogan

hi kadirerdogan i have been going through this issue and its very clear but i just want to know how do show the form in the html side. like in autoform they show it the following way...

{{> quickForm collection="collectoinName" id="insertForm" type="insert"}} so how do i do this in kitchen?

Maqhosha avatar Mar 16 '16 07:03 Maqhosha

Hi @Maqhosha , You can find the generated templates at "client/views/" folder.

Form generation of kitchen is not like quickForm. Generation does not happen on the fly. The forms are generated when you run the meteor-kitchen to generate the code. Then the forms are there statically to be used until you generate them again with meteor-kitchen.

Let's say you have a page named invoices, then you will find that "client/views/invoices/insert/insert.html" is the insert form template to be used to insert new invoice. You can use that template as you wish. But don't modify it directly since you'll loose all modification when you run meteor-kitchen again to generate the code.

I hope i understood your question correct :)

kadirerdogan avatar Mar 16 '16 07:03 kadirerdogan

@kadirerdogan yes u did thank you, I finally managed to modify the code manually and use autoform :)

Maqhosha avatar Mar 16 '16 08:03 Maqhosha

@Maqhosha maybe you still can use meteor-kitchen instead manually editing generated code: use "custom_component" instead "form".

{
  "name": "my_form",
  "type": "custom",
  "html": "<div>{{> quickForm collection=\"COLLECTION_VARIABLE\" id=\"COMPONENT_ID\" type=\"insert\"}}</div>"
  "js": "",
  "query_name": "YOUR_QUERY_NAME_HERE",
  "query_params": []
}

Or simply by hard-coding collection name:

{
  "name": "my_form",
  "type": "custom",
  "html": "<div>{{> quickForm collection=\"YourCollectionNameHere\" id=\"COMPONENT_ID\" type=\"insert\"}}</div>"
  "js": ""
}

?

perak avatar Mar 16 '16 08:03 perak

its working fine thank you

Maqhosha avatar Mar 16 '16 10:03 Maqhosha