Skip to content

Instantly share code, notes, and snippets.

@snnwolf
Forked from vladimir-e/1.catgories.js.coffee
Last active August 29, 2015 14:14
Show Gist options
  • Save snnwolf/410f67b2cacbd6bce1df to your computer and use it in GitHub Desktop.
Save snnwolf/410f67b2cacbd6bce1df to your computer and use it in GitHub Desktop.
#= require jquery.ui.sortable
#= require jquery.ui.nestedSortable
#= require sortable_tree/initializer
#= require_self
# case insensitive jQuery Contains http://goo.gl/IrNmk
jQuery.expr[":"].Contains = (a, i, m) ->
jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0
jQuery.expr[":"].contains = (a, i, m) ->
jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0
$ ->
window.router = new Outdoorshop.Routers.Categories();
Backbone.history.start();
class Outdoorshop.Routers.Categories extends Backbone.Router
routes:
"index" : "index"
"new" : "new"
":id/edit" : "edit"
":id/delete" : "delete"
initialize: (options) ->
@page = new Outdoorshop.Views.Categories.Container()
before: ->
@view.reset() if @view?
index: ->
@before()
new: ->
@before()
model = new Outdoorshop.Models.Category()
itemView = new Outdoorshop.Views.Categories.Item(model: model)
model.on "create", ->
itemView.render()
_helper.flash(i18n.category_created)
@setView model
edit: (id) ->
@before()
model = new Outdoorshop.Models.Category(id: id)
itemView = new Outdoorshop.Views.Categories.Item(model: model)
model.on "change", ->
itemView.update()
_helper.flash(i18n.category_updated)
@setView model
delete: (id) ->
@before()
@model = new Outdoorshop.Models.Category(id:id)
itemView = new Outdoorshop.Views.Categories.Item(model: @model)
@model.on "destroy", ->
itemView.del()
_helper.flash(i18n.category_deleted)
self = @
$ ->
_helper.confirm =>
jQuery.fallr('hide');
self.model.destroy()
window.location.hash = "index"
, =>
jQuery.fallr('hide');
window.location.hash = "index"
setView: (model) ->
@view = new Outdoorshop.Views.Categories.Form(model: model)
@view.render()
class Outdoorshop.Models.Category extends Backbone.Model
paramRoot: 'category'
urlRoot: '/admin/categories'
defaults:
name_de: null
name_en: null
description_de: null
description_en: null
parent_id: null
validate: (attrs) ->
if !attrs.name_de and !attrs.name_en
i18n.error_blank
getName: ->
@get("name_#{i18n.locale}")
Outdoorshop.Views.Categories ||= {}
class Outdoorshop.Views.Categories.Container extends Backbone.View
el: '#container'
events:
"click a.create, a.edit" : "showForm"
"click .inactive": ->
false
"click .actions a.delete" : "delete"
delete: (e) ->
e.preventDefault()
e.stopPropagation()
id = $(e.currentTarget).attr('href').split('/')[3]
window.router.navigate("#{id}/delete", {trigger: true})
initialize: ->
@searchForm = new Outdoorshop.Views.Categories.SearchForm()
showForm: (e) ->
e.preventDefault()
e.stopPropagation()
@searchForm.resetSearch()
route = @get_route($(e.currentTarget).attr('href'))
window.router.navigate(route, {trigger: true})
get_route: (url) ->
pieces = url.split('/').slice(-2)
if pieces[0] == 'categories'
'new'
else
"#{pieces[0]}/edit"
Outdoorshop.Views.Categories ||= {}
class Outdoorshop.Views.Categories.Form extends Backbone.View
events:
"submit .new_category" : "save"
"submit .edit_category": "update"
"click .cancel_action" : "cancel"
constructor: (options) ->
super(options)
@model = options['model']
@action = if @model.isNew() then 'new' else 'edit'
save: (e) ->
e.preventDefault()
e.stopPropagation()
@model.save(@formValues(),
success: (category) =>
@model = category
@model.trigger('create')
window.location.hash = "index"
error: (category, response) =>
msg = if typeof(response)=='string' then response else 'Error'
_helper.flash response, type: 'error'
)
update : (e) ->
e.preventDefault()
e.stopPropagation()
@model.save(@formValues(),
success : (category) =>
@model = category
window.location.hash = "index"
)
cancel: (e) ->
e.preventDefault()
e.stopPropagation()
window.router.navigate('index', {trigger: true})
# loads form dynamically instead of using template
# TODO cache "new" form and form for same object
render : ->
@targetContainer().after('<div class="inline_loader">&nbsp;</div>')
self = @
@$el.load @requestUrl(), =>
# if @action == 'edit'
# self.$("select").parent().parent().hide()
# else
self.$("select.chzn-select").chosen(allow_single_deselect: true)
self.$('div').removeClass('grid-3-12')
self.$('div').removeClass('grid-9-12')
$(self.el).next('.inline_loader').remove()
_helper.scrollTo self.$('form')
@targetContainer().after(@el)
reset: (e) ->
$(@el).remove()
@targetContainer().next('.inline_loader').remove()
$(@el).next('.inline_loader').remove()
# helpers
requestUrl: ->
return @url if @url?
if @action == 'new'
parent = $('.create').attr('href').split('?').slice(1).toString()
@url = "/admin/categories/new?#{parent}"
else
@url = "/admin/categories/#{@model.get('id')}/edit"
# returns jquery element
targetContainer: ->
return @$target if @$target?
if @action == 'new'
@$target = if $("#subcategories").length then $('#subcategories').prev() else $('#categories').prev()
else
@$target = $("##{@model.get('id')}_category .link .actions").first()
formValues: ->
values = new Object
_.each @$('form').serializeArray(), (obj) ->
if obj.name.substr(0, 9) == "category["
key = obj.name.substr(9).replace("]", '')
values[key] = obj.value
values
Outdoorshop.Views.Categories ||= {}
class Outdoorshop.Views.Categories.Item extends Backbone.View
constructor: (options) ->
super(options)
@model = options['model']
# attach existing element on edit
if !@model.isNew()
@el = "##{@model.get('id')}_category"
@$el = $(@el)
update: ->
item = @$(".category a").first()
item.text @model.getName()
if @model.get('gender') == "1"
item.append(' <i class="icon16_sprite i_couple"></i>')
else
item.find('.i_couple').remove()
# build element for new category
render: ->
# load nested tree branch, but get only actual item from it
if !@$el.attr('id') && @model.get('id')?
self = @
@$el.load "/admin/categories/#{@model.get('id')}", ->
# get new category row
self.$el = self.$('li.current')
self.el = self.$el.attr('id')
self.$el.removeClass('current')
# insert into DOM
container = self.findContainer()
if $(container).length > 0
$(container).append(self.$el)
_helper.scrollTo self.$el
# refresh if first category added in case to init sortable tree
if $('#subcategories li').length == 1
window.location.reload()
del: ->
# redirect to index if current category deleted
if $("#categories #{@el}.current").length > 0
$("#subcategories ol").remove()
window.location = '/admin/categories'
@$el.remove()
findContainer: ->
pid = @model.get('parent_id')
# if child
if pid?
# insert to root level of right panel
if $("#categories ##{pid}_category").length > 0
return '#subcategories'
# any other descendant for current page
else if $("#subcategories ##{pid}_category").length > 0
@.$('.category a').addClass('inactive')
return "##{pid}_category"
# try to insert to root level of the page (left panel)
else
current_category_id = $('.act_panel:first').find('a').last().attr('href').split('/').reverse()[0]
return '#categories' if current_category_id != 'categories' and current_category_id > 0
# if root
else
# created on index page or on root-level show page
if $('.act_panel:first').find('a').length == 1
return "#categories"
@snnwolf
Copy link
Author

snnwolf commented Feb 6, 2015

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment