uris77
5/30/2013 - 3:43 AM

Cool Form Template in Marionettejs

Cool Form Template in Marionettejs

@PlanetExpress.module "Components.Form", (Form, App, Backbone, Marionette, $, _) ->
  
	class Form.Controller extends App.Controllers.Base
		
		initialize: (options = {}) ->
			@contentView = options.view
			
			@formLayout = @getFormLayout options.config
			
			@listenTo @formLayout, "show", @formContentRegion
			@listenTo @formLayout, "form:submit", @formSubmit
			@listenTo @formLayout, "form:cancel", @formCancel
		
		formCancel: ->
			@contentView.triggerMethod "form:cancel"
		
		formSubmit: ->
			data = Backbone.Syphon.serialize @formLayout
			if @contentView.triggerMethod("form:submit", data) isnt false
				model = @contentView.model
				collection = @contentView.collection
				@processFormSubmit data, model, collection
		
		processFormSubmit: (data, model, collection) ->
			model.save data,
				collection: collection
		
		onClose: ->
			console.log "onClose", @
		
		formContentRegion: ->
			@region = @formLayout.formContentRegion
			@show @contentView
		
		getFormLayout: (options = {}) ->
			config = @getDefaultConfig _.result(@contentView, "form")
			_.extend config, options
			
			buttons = @getButtons config.buttons

			new Form.FormWrapper
				config: config
				model: @contentView.model
				buttons: buttons
		
		getDefaultConfig: (config = {}) ->
			_.defaults config,
				footer: true
				focusFirstInput: true
				errors: true
				syncing: true
		
		getButtons: (buttons = {}) ->
			App.request("form:button:entities", buttons, @contentView.model) unless buttons is false
	
	App.reqres.setHandler "form:wrapper", (contentView, options = {}) ->
		throw new Error "No model found inside of form's contentView" unless contentView.model
		formController = new Form.Controller
			view: contentView
			config: options
		formController.formLayout
    
    
    
  @PlanetExpress.module "Components.Form", (Form, App, Backbone, Marionette, $, _) ->
  
	class Form.FormWrapper extends App.Views.Layout
		template: "form/form"
		
		tagName: "form"
		attributes: ->
			"data-type": @getFormDataType()
		
		regions:
			formContentRegion: "#form-content-region"
		
		ui:
			buttonContainer: "ul.inline-list"
		
		triggers:
			"submit"														: "form:submit"
			"click [data-form-button='cancel']"	: "form:cancel"
		
		modelEvents:
			"change:_errors" 	: "changeErrors"
			"sync:start"			:	"syncStart"
			"sync:stop"				:	"syncStop"
		
		initialize: ->
			@setInstancePropertiesFor "config", "buttons"
		
		serializeData: ->
			footer: @config.footer
			buttons: @buttons?.toJSON() ? false
		
		onShow: ->
			_.defer =>
				@focusFirstInput() if @config.focusFirstInput
				@buttonPlacement() if @buttons
		
		buttonPlacement: ->
			@ui.buttonContainer.addClass @buttons.placement
		
		focusFirstInput: ->
			@$(":input:visible:enabled:first").focus()
		
		getFormDataType: ->
			if @model.isNew() then "new" else "edit"
		
		changeErrors: (model, errors, options) ->
			if @config.errors
				if _.isEmpty(errors) then @removeErrors() else @addErrors errors
		
		removeErrors: ->
			@$(".error").removeClass("error").find("small").remove()
		
		addErrors: (errors = {}) ->
			for name, array of errors
				@addError name, array[0]
		
		addError: (name, error) ->
			el = @$("[name='#{name}']")
			sm = $("<small>").text(error)
			el.after(sm).closest(".row").addClass("error")
		
		syncStart: (model) ->
			@addOpacityWrapper() if @config.syncing
		
		syncStop: (model) ->
			@addOpacityWrapper(false) if @config.syncing
      
      
      
    
  @PlanetExpress.module "CrewApp.New", (New, App, Backbone, Marionette, $, _) ->
  
	class New.Crew extends App.Views.ItemView
		template: "crew/new/new_crew"
		
		form:
			buttons:
				placement: "left"