class Peta.Item extends Backbone.Model initialize: (attr = {}, options = {}) -> @url = @default_url() super(attr, options) @expire_time = options.expire_time @boosters = {} @templates = {} @child_models: () -> @my_manifest().child_models() @child_element_names: () -> @my_manifest().child_element_names() # ClassMethods @default_url: () -> '/' + @table_name() + '/' @my_class: () -> this my_class: () -> @constructor @my_peta: () -> return null if not Manifest.manifest().items Manifest.manifest().items[@item_name()] @my_manifest: () -> return null if not Manifest.manifest().models Manifest.manifest().models[@item_name()] @singular: () -> 'Name' @plural: () -> table_name = Manifest.manifest().pluralize @item_name() Pettanr.camelize(table_name) @class_name: () -> @singular() @model_name: () -> @class_name() @item_name: () -> Pettanr.underscore(@singular()) @table_name: () -> Pettanr.underscore(@plural()) @is_item: () -> true @is_content: () -> false @is_element: () -> false @is_root: () -> false @parent_model: () -> null @has_picture: () -> false @path_name: (with_engine = false) -> @table_name() @find_boost_name: (column_name) -> @my_peta().find_boost_name column_name @is_extend_column: (column_name) -> @my_peta().is_extend_column column_name @fold_extend_settings: (attr) -> _.each my_peta().boost, (name, manifest) -> my_settings = attr[manifest.settings_column_name] if my_settings attr[manifest.settings_column_name] = my_settings.to_json @retrieve: (id, context, options = {}) -> item = new this({id: id}) item.retrieve(context, options) @trace_routes: () -> {} @default_label_shorten_length = 13 #InstanceMethods default_url: () -> r = @my_class().default_url() r = r.concat( @id ) if @id r singular: () -> @my_class().singular() plural: () -> @my_class().plural() item_name: () -> @my_class().item_name() model_name: () -> @item_name() table_name: () -> @my_class().table_name() path_name: (with_engine = false) -> @my_class().path_name(with_engine) form_template: (with_engine = false) -> @path_name(with_engine) + '/form' form_name: () -> if @extend_column() @get(@extend_column()) else @item_name() _label: (label_column_name, options) -> shorten = options.shorten l = if _.isBoolean(shorten) if shorten # supply default shorten_length @constructor.default_label_shorten_length else # False be no shorten null else # numeric shorten Pettanr.truncate(@get(label_column_name), l) label: (options) -> '' get_association: (routes, context, options) -> routes = [routes] if _.isString(routes) route = routes.shift() if _.isEmpty(routes) # fetching terminate association. callback cxt = options.context || context @fetch_association(route, cxt, { success: (association_item, options) => options.success.call(context, association_item) fail: (response, opt) => options.fail.call(context, response, opt) context: context, options: options }) else # fetching through associations @fetch_association(route, this, { success: (association_item, options) => association_item.get_association(routes, this, options) fail: (response, opt) => options.fail.call(context, response, opt) context: context, options: options }) fetch_association: (name, context, options) => a = @my_class().my_manifest().associations fetch_options = { success: (association_item) => options.success.call(context, association_item, options.options) fail: (response, opt) => options.fail.call(context, response, opt) } if a.belongs_to[name] @get_parent(name, context, fetch_options) else if a.has_many[name] @get_children(name, context, fetch_options) else if a.has_one[name] @get_child(name, context, fetch_options) else console.error('association does not exist in model manifest') get_parent: (belongs_to_name, context, options = null) -> m = Manifest.item_name_to_model(belongs_to_name) retriever = new Pettanr.Cache.Retriever(m, @get(belongs_to_name + '_id')) return retriever if !options @listenTo(retriever, 'retrieve', (item) => options.success.call(context, item) ) @listenTo(retriever, 'fail', (response, opt) => options.fail.call(context, response, opt) ) retriever.retrieve() get_child: (has_one_name, context, options = null) -> list = @has_one(has_one_name) list.open(context, { success: (items) => callback = options.success item = items[0] callback.call(context, item) fail: (response, opt) => options.fail.call(context, response, opt) }) get_children: (has_many_name, context, options = null) -> list = @has_many(has_many_name) list.open(context, { success: (items) => callback = options.success callback.call(context, items) fail: (response, opt) => options.fail.call(context, response, opt) }) has_many: (has_many_name) -> has_many_manifest = @my_class().my_manifest().associations.has_many[has_many_name] action_name = has_many_manifest.list_action_name Locmare.ListGroup.list( has_many_name, action_name, {id: @get('id')} ) has_one: (has_one_name) -> has_one_manifest = @my_class().my_manifest().associations.has_one[has_one_name] controller_name = has_one_manifest.model().table_name() action_name = has_one_manifest.list_action_name Locmare.ListGroup.list( controller_name, action_name, {id: @get('id')} ) trace_to: (trace_name, context, options) -> routes = @my_class().trace_routes()[trace_name] if !routes console.error('no trace route') return @get_association(routes, this, { success: (association) => options.success.call(context, association) fail: (response, opt) => options.fail.call(context, response, opt) }) boosts: (level) -> c = @my_class().my_peta().boost _.each c, (boost_manifest, boost_name) => return if level == 'read' and boost_manifest.level == 'post' @boost boost_manifest boost: (boost_manifest) -> @boosters[boost_manifest.name] = new Locmare.Booster(boost_manifest, this) # fetched item is not cleared . force write booster #@boosters[boost_manifest.name] ||= new Locmare.Booster(boost_manifest, this) is_extend_column: (column_name) -> @is_extend_column column_name is_visible: (operators = Pettanr.cache.operators) -> if Manifest.manifest().magic_numbers['run_mode'] == 0 return false if not operators.is_guest() else return false if not operators.is_resource_reader() true retriever: () -> new Pettanr.Cache.Retriever(@my_class(), @get('id')) retrieve: (context, options = {}) -> retriever = new Pettanr.Cache.Retriever(@my_class(), @get('id')) @listenTo(retriever, 'retrieve', (item) => callback = options.success callback.call(context, item) ) @listenTo(retriever, 'fail', (response, opt) => callback = options.fail callback.call(context, response, opt) ) retriever.retrieve(options.force) @pick_item_name: () -> null @pick_model: () -> Manifest.item_name_to_model(@pick_item_name()) @traceable_item_names: () -> [] @is_traceable: (item_name) -> _.contains(@traceable_item_names(), item_name) @is_picker_inspire: (item_name) -> item_name == @item_name() @is_picker_trace: (item_name) -> @is_traceable(item_name) @is_picker_pick: (item_name) -> item_name == @pick_item_name() @pick_type: (item_name) -> if @is_picker_inspire(item_name) 'inspire' else if @is_picker_trace(item_name) 'trace' else if @is_picker_pick(item_name) 'pick' else 'none' symbol_option: (context, options) -> @trace_to('symbol', this, { success: (symbol_item) => options.success.call(context, symbol_item.symbol_file()) fail: (response, opt) => options.fail.call(context, response, opt) }) @face_file: () -> new Pettanr.ImageFile('/images/' + @item_name() + '.gif') face_file: () -> @my_class().face_file() # thumbnail size picture symbol_file: (subdir) -> new Pettanr.PictureFile(this, subdir) # real size picture picture_file: (subdir = null) -> new Pettanr.PictureFile(this, subdir) real_picture: (subdir = null) -> new Pettanr.View.RealIcon(@picture_file(subdir)) # item.face_button({ # context: this, # click: () -> # # ... # }) face_button: (options) -> Pettanr.View.face_button(this, @face_file(), options) mini_face_button: (options) -> Pettanr.View.mini_face_button(this, @face_file(), options) prof_button: (options) -> Pettanr.View.prof_button(@prof_url(), options) mini_prof_button: (options) -> Pettanr.View.mini_prof_button(@prof_url(), options) symbol_button: (options) -> Pettanr.View.face_button(this, @symbol_file(), options) mini_symbol_button: (options) -> Pettanr.View.mini_face_button(this, @symbol_file(), options) # pencil button edit_button: (options) -> icon = new Pettanr.View.Icon(Pettanr.View.Image.icon_edit_file()) Pettanr.View.any_button(this, @edit_url(), icon, options) mini_edit_button: (options) -> icon = new Pettanr.View.Minicon(Pettanr.View.Image.icon_edit_file()) Pettanr.View.mini_any_button(this, @edit_url(), icon, options) # x button destroy_button: (options) -> icon = new Pettanr.View.Icon(Pettanr.View.Image.icon_destroy_file()) Pettanr.View.any_button(this, @destroy_url(), icon, options) mini_destroy_button: (options) -> icon = new Pettanr.View.Minicon(Pettanr.View.Image.icon_destroy_file()) Pettanr.View.mini_any_button(this, @destroy_url(), icon, options) label_button: (label_options, button_options) -> url = button_options.url || @show_url() new Pettanr.View.Button(url, _.escape(@label(label_options)), button_options) # faced_label_button({ # shorten: true # }, { # url: @show_url(), # context: this, # click: () => # # ... # }) faced_label_button: (label_options, button_options) -> new Pettanr.View.FacedLabelButton(this, label_options, button_options) mini_faced_label_button: (label_options, button_options) -> new Pettanr.View.MiniFacedLabelButton(this, label_options, button_options) summary: (context, options) -> klass = Pettanr.Views[@singular()].Summary new klass(this, context, options) @index_url: () -> Pettanr.url(@table_name(), 'index', {id: null}) index_url: () -> @my_class().index_url() list_url: (action_name = 'index') -> Pettanr.url(@table_name(), action_name, {id: @get('id')}) show_url: () -> Pettanr.url(@table_name(), 'show', {id: @get('id')}) prof_url: () -> Pettanr.url(@table_name(), 'show', {id: @get('id'), format: 'prof'}) new_url: () -> Pettanr.url(@table_name(), 'new', {}) create_url: () -> Pettanr.url(@table_name(), 'create', {}) edit_url: () -> Pettanr.url(@table_name(), 'edit', {id: @get('id')}) update_url: () -> Pettanr.url(@table_name(), 'update', {id: @get('id')}) destroy_url: () -> Pettanr.url(@table_name(), 'destroy', {id: @get('id')}) hold: () -> Pettanr.cache.hold(this) fix: () -> Pettanr.cache.fix(this) release: () -> Pettanr.cache.release(this) free: () -> Pettanr.cache.free(this) save: (model_attr) -> super(model_attr || @attributes, { success: (model, response, options) => @trigger('save:success', model, response) error: (model, response, options) => @trigger('save:fail', model, response) }) destroy: () -> super({ success: (model, response, options) => @free() @trigger('destroy:success', model, response) error: (model, response, options) => @trigger('destroy:fail', model, response) }) is_editize: () -> @editor dom_id: () -> (@get('id') || '').toString() cache_key: () -> @table_name() + '-' + @dom_id() dom_pool_type: () -> @new_record ? 'stored' : 'new' merge_dom_item_id: (attr, name = null) -> if @is_editize() _.extend(attr, {'id': @dom_item_id(name)}) else attr tag_attributes: (name = null, opt = {}) -> r = { 'data-pool_type': @dom_pool_type(), 'data-id': @dom_id(), 'data-item_name': @item_name() } r = @merge_dom_item_id(r, name) _.extend(r, opt) r field_tag_attributes: (column_name, opt = {}) -> r = @tag_attributes(column_name, opt) _.extend(r, {'data-column_name': column_name}) r post_attribute_key: () -> @dom_id @test: () -> console.log(@child_models()) console.log(@child_element_names()) console.log(@my_peta()) console.log(@my_manifest()) console.log() console.log() test: () -> console.log(@my_class()) console.log(@item_name()) console.log(@model_name()) console.log(@table_name()) console.log(@path_name()) console.log(@pickup_item_name()) console.log(@pickup_column_name()) console.log(@dom_id()) console.log(@dom_pool_type()) console.log(@tag_attributes()) console.log(@field_tag_attributes('id')) console.log(@post_attribute_key())