Skip to content

Instantly share code, notes, and snippets.

@johnbintz
Last active December 20, 2015 14:29
Show Gist options
  • Save johnbintz/6146557 to your computer and use it in GitHub Desktop.
Save johnbintz/6146557 to your computer and use it in GitHub Desktop.
Going from pure jQuery to AngularJS
$(->
# set up or retrieve our local storage
navStatus = $.totalStorage('left_nav') || {}
# set up the initial state of each site opener and nav links
for id, status of navStatus
siteLink = $("#user_sites [data-id='#{id}']")
opener = siteLink.prev()
opener.toggleClass('open', status)
opener.toggleClass('closed', !status)
container = siteLink.parent().next()
container.toggleClass('open', status)
container.toggleClass('closed', !status)
# handle clicking the opener
$('#user_sites .opener').click ->
# figure out what else to modify on click...
container = $(this).parent().next()
# and figure out if it's open or not
isOpen = container.hasClass('open')
# open or close each thing
container.toggleClass('open', openSpeed)
container.toggleClass('closed', openSpeed)
$(this).toggleClass('open')
$(this).toggleClass('closed')
# get the id to use with the local storage
siteID = $(this).next().data('id')
# initialize the storage, just in case...
leftNav = $.totalStorage('left_nav') || {}
# set this nav's state...
leftNav[siteID] = !isOpen
# and serialize the current state data to storage
$.totalStorage('left_nav', leftNav)
false
)
# create a new left nav data store
angular.module('admin').factory 'leftNavStore', ->
->
# create a simple proxy to the local storage
store = {
set: (id, state) ->
@store[id] = state
@save()
get: (id) ->
@store[id] || 'open'
retrieve: ->
@store = $.totalStorage('left_nav') || {}
save: ->
$.totalStorage('left_nav', @store)
}
# retrieve the current store data...
store.retrieve()
# and return the store to us
store
# define how each user site should behave
angular.module('admin').directive 'userSite', (leftNavStore) ->
# get our store via dependency injection
store = leftNavStore()
{
# this directive applies to .user_site, .user-site, .userSite
restrict: 'C'
# we need our own scope, data is handled through our dependency
scope: true
# if it's a simple thing, i'll create a controller on the directive
# and handle anything that theortically doesn't work with a DOM element
# in here.
controller: ($scope) ->
# toggle the open/close state and set the value in the store
$scope.toggle = ->
if $scope.state == 'open'
$scope.state = 'closed'
else
$scope.state = 'open'
store.set($scope.id, $scope.state)
# handle hooking into the DOM elements that encompass this directive
link: (scope, element, attrs) ->
# add an opener. the original jQuery used one that was on the page
element.find('> .nav-link').prepend('<a class="opener" />')
# get our DOM nodes that we care about
scope.opener = element.find('.opener')
scope.target = element.find('.site-parts')
# whenever scope.state changes (which isn't set yet!)...
scope.$watch 'state', (state) ->
for obj in [ scope.opener, scope.target ]
# set that state string value as the active class on each of our nodes
obj.removeClass('open closed').addClass(state)
# get the ID...
scope.id = element.find('> .nav-link a[data-id]').data('id')
# then get our initial state from the store
scope.state = store.get(scope.id)
# handle clicking the opener
scope.opener.on 'click', (e) ->
e.preventDefault()
# ensure that changes to scope.state notify the rest of angular to do stuff
scope.$apply -> scope.toggle()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment