Created
October 1, 2014 10:29
-
-
Save maiordom/c0fabccb72fb3c81c079 to your computer and use it in GitHub Desktop.
simple refactoring №3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function( $ ) { | |
'use strict'; | |
var ElementRegion = function( $el ) { | |
this.cacheObjects( $el ); | |
this.bindEvents(); | |
}; | |
ElementRegion.prototype = { | |
cacheObjects: function( $el ) { | |
this.$el = $el; | |
this.state = 'default'; | |
this.$regions = this.$el.find( '.js-location-regions' ); | |
this.$submit = this.$el.find( '.js-location-submit' ); | |
this.$add = this.$el.find( '.js-location-add' ); | |
this.$notify = this.$el.find( '.js-location-notify' ); | |
this.$panel = this.$el.find( '.js-location-panel' ); | |
this.$input = this.$el.find( '.js-location-input' ); | |
this.$loader = this.$el.find( '.js-location-loader' ); | |
this.$anotherRegion = this.$el.find( '.js-location-another-region' ); | |
this.$currLoader = $( {} ); | |
this.form = '.js-location-form'; | |
}, | |
bindEvents: function() { | |
this.$regions.on( 'click', '.del', _.bindEvent( this.onDeleteKladdr, this ) ); | |
this.$anotherRegion.on( 'click', 'a', _.bindEvent( this.onAnotherRegionClick, this ) ); | |
this.$add.on( 'click', _.bindEvent( this.onAddClick, this ) ); | |
this.$input.enterKey( _.bindEvent( this.onEnterKey, this ) ); | |
this.$input.focus( _.bindEvent( this.onFocus, this ) ); | |
this.$submit.on( 'click', this.onSubmit.bind( this ) ); | |
}, | |
onAnotherRegionClick: function( eventContext, e ) { | |
if ( this.state === 'local' ) { | |
var $region = $( eventContext ), | |
kladdrName = $region.text(), | |
kladdrId = $region.attr( 'href' ).match( /sk=(\d+)/ )[ 1 ]; | |
this.$el.data( 'pluginModal' ).close(); | |
this.$regions.empty(); | |
this.addKladdr( { id: kladdrId, label: kladdrName, parentIds: [], subDomain: '' } ); | |
this.$notify.hide(); | |
this.$panel.show(); | |
AM.PubSub.pub( 'submit:regions', [ [ kladdrName ], [ kladdrId ] ] ); | |
e.preventDefault(); | |
} | |
}, | |
onSubmit: function() { | |
if ( this.state === 'local' ) { | |
var kladdrNames = this.getKladdrNames(), | |
kladdrIds = this.getKladdr(); | |
if ( !kladdrNames.length && !kladdrIds.length ) { | |
kladdrNames.push( 'Россия' ); | |
kladdrIds.push( '0' ); | |
} | |
AM.PubSub.pub( 'submit:regions', [ kladdrNames, kladdrIds ] ); | |
this.$el.data( 'pluginModal' ).close(); | |
return false; | |
} else { | |
this.submit(); | |
} | |
}, | |
setState: function( state ) { | |
this.state = state || null; | |
}, | |
onDeleteKladdr: function( eventContext ) { | |
this.deleteKladdr( $( eventContext ) ); | |
}, | |
onAddClick: function( eventContext, e ) { | |
this.hideAdd(); | |
e.preventDefault(); | |
}, | |
onEnterKey: function( eventContext ) { | |
var $target = $( eventContext ), | |
drop = $target.data( 'drop' ); | |
if ( ( $target.val() == '') && ( drop ) ) { | |
this.$submit.trigger( 'click' ); | |
} | |
if ( !drop ) { | |
$target.data( 'drop', true ); | |
} | |
}, | |
onFocus: function( eventContext ) { | |
// http://stackoverflow.com/questions/4132058/display-jquery-ui-auto-complete-list-on-focus-event | |
if ( $( eventContext ).autocomplete( "widget" ).is( ":visible" ) ) { | |
return; | |
} | |
$( eventContext ).autocomplete( "search" ); | |
}, | |
getKladdrQuery: function( request, response ) { | |
$.ajax({ | |
url: '/int/controls/get-kladdrs-by-query/', | |
dataType: 'jsonp', | |
data: { q: request.term }, | |
success: this.onSuccessGetKladdrQuery.bind( this, request, response ) | |
}); | |
}, | |
createLoader: function( input ) { | |
this.$currLoader = input.closest( this.form ).find( this.$loader ); | |
this.$currLoader.ajaxLoader( { opacity: false, valign: 'center' } ); | |
}, | |
onSuccessGetKladdrQuery: function( request, response, data ) { | |
var kladdrs = this.getKladdr(), hasparent; | |
this.$currLoader.ajaxLoader( { mode: 'off' } ); | |
response( | |
$.map( data, function( item ) { | |
hasparent = false; | |
$.map( kladdrs, function( id ) { | |
if ( jQuery.inArray( '' + id + '', item.ParentIds ) > -1 ) { | |
hasparent = true; | |
} | |
} ); | |
if ( (jQuery.inArray( item.CurrentId, kladdrs ) > -1 ) || hasparent ) { | |
return null; | |
} else { | |
return { | |
label: item.FullName, | |
value: item.FullName, | |
id: item.CurrentId, | |
parentIds: item.ParentIds, | |
subDomain: item.SubDomain | |
} | |
} | |
}) | |
); | |
}, | |
renderItem: function( ul, item ) { | |
var $class = ( item.parentIds.length == 0 ) ? "class='au-bold'" : ""; | |
return $( "<li>" ) | |
.data( "item.autocomplete", item ) | |
.append( "<a " + $class + ">" + item.label + "</a>" ) | |
.appendTo( ul ); | |
}, | |
modal: function() { | |
var self = this; | |
this.$el.modal({ | |
center: true, | |
size: [ '570' ], | |
onOpen: function() { | |
self.$input.each( function() { | |
self.initAutocomplete( $( this ) ); | |
$( this ).data( "autocomplete" )._renderItem = self.renderItem; | |
}); | |
} | |
} ); | |
}, | |
initAutocomplete: function( $input ) { | |
$input.autocomplete({ | |
appendTo: $input.closest( '.au-form-input' ), | |
minLength: 1, | |
autoFocus: true, | |
source: _.bindEvent( this.onSourceAutocomplete, this ), | |
select: _.bindEvent( this.onSelectAutocomplete, this ) | |
}); | |
}, | |
onSourceAutocomplete: function( eventContext, request, response ) { | |
this.createLoader( eventContext.element ); | |
this.getKladdrQuery( request, response ); | |
}, | |
onSelectAutocomplete: function( eventContext, event, ui ) { | |
var selected = $( 'input.kladdrs[value=' + ui.item.id + ']' ).length, | |
$el = $( eventContext ); | |
if ( selected > 0 ) { | |
return false; | |
} | |
if ( $el.data( 'location' ) == 'single' ) { | |
this.submit( ui.item.id ); | |
} else { | |
this.addKladdr( ui.item ); | |
this.checkKladdrs(); | |
this.changeLabel(); | |
$el.val( '' ).data( 'drop', false ); | |
} | |
return false; | |
}, | |
submit: function( kladdr ) { | |
var kladdrs = ( typeof kladdr == 'undefined' ) ? this.getKladdr() : [ kladdr ], | |
$change = this.$el.find( ".js-location-changelink" ), | |
link = $change.data( 'domain' ) + $change.data( 'path' ), | |
sk = ( kladdrs.length >= 1 ) ? kladdrs.join( ',' ) + document.location.hash : 0 + document.location.hash; | |
this.changeAction(); | |
this.$el.modal( 'close' ); | |
document.location.href = ( link.indexOf( '?' ) > 0 ) ? link + '&sk=' + sk : link + '?sk=' + sk; | |
}, | |
hideAdd: function() { | |
this.$add.hide().siblings( this.form ).show().find( this.$input ).focus(); | |
}, | |
showAdd: function() { | |
this.$add.show().siblings( this.form ).hide(); | |
}, | |
getKladdr: function() { | |
var kladdrs = []; | |
$( '.name', this.$regions ).not( '.child' ).siblings( 'input:hidden' ).each( function () { | |
kladdrs.push( $( this ).val() ); | |
}); | |
return kladdrs; | |
}, | |
getKladdrNames: function() { | |
var regions = []; | |
$( '.name', this.$regions ).not( '.child' ).each( function() { | |
regions.push( $( this ).text() ); | |
}); | |
return regions; | |
}, | |
addKladdr: function( item ) { | |
var $hidden = $( '<input type="hidden" class="kladdrs" value="' + item.id + '" />' ).data( 'parents', item.parentIds ).data( 'subdomain', item.subDomain ), | |
$span = $( '<span class="name">' + item.label + '</span>' ), | |
$del = $( '<span class="del">×</span>' ); | |
var $el = $( '<li></li>' ).append( $hidden ).append( $span ).append( $del ); | |
this.$regions.append( $el ); | |
}, | |
deleteKladdr: function( element ) { | |
element.parent().remove(); | |
$( 'input:hidden', this.$regions ).data( 'skip', false ); | |
if ( $( 'input:hidden', this.$regions ).length <= 1 ) { | |
$( '.name', this.$regions ).removeClass( 'child' ); | |
$( '.comment', this.$regions ).remove(); | |
} else { | |
this.checkKladdrs(); | |
} | |
this.changeLabel(); | |
}, | |
checkKladdrs:function () { | |
var self = this; | |
$( 'input:hidden', self.$regions ).each( function () { | |
if ( $( this ).data( 'skip' ) ) return; | |
var $self = $( this ); | |
$( 'input:hidden', self.$regions ).each( function () { | |
if ( $( this ).data( 'skip' ) ) return; | |
if ( $self.val() == $( this ).val() ) return; | |
var parents = $( this ).data( 'parents' ); | |
if ( parents.length <= 0 ) return; | |
// on parent | |
if ( $.inArray( $self.val(), parents ) >= 0 ) { | |
var comment = $( '<span class="comment">выбран более крупный регион</span>' ); | |
$( this ).siblings( '.name' ).addClass( 'child' ).parent().append( comment ); | |
$( this ).data( 'skip', true ); | |
} else { | |
$( this ).siblings( '.name' ).removeClass( 'child' ).parent().find( '.comment' ).remove(); | |
$( this ).data( 'skip', false ); | |
} | |
} ); | |
} ); | |
}, | |
changeLabel: function() { | |
var count = $( '.name', this.$regions ).length; | |
this.showAdd(); | |
if ( count > 0 ) { | |
this.$notify.hide(); | |
this.$panel.show(); | |
} else { | |
this.$notify.show(); | |
this.$panel.hide(); | |
} | |
this.$submit.show(); | |
}, | |
changeAction: function() { | |
var $change = this.$el.find( 'js-location-changelink', this.$elem ), | |
subDomain = '', | |
change = false; | |
$( 'input:hidden.kladdrs', this.$regions ).each( function() { | |
var regionSubDomain = $( this ).data( 'subdomain' ); | |
if( ( subDomain == '' && regionSubDomain != '' ) || ( subDomain == regionSubDomain ) ) { | |
subDomain = regionSubDomain; | |
change = true; | |
} else if( subDomain != regionSubDomain ) { | |
change = false; | |
} | |
}); | |
if ( false && change && subDomain != '' ) { | |
$change.data( 'domain', subDomain ); | |
} | |
} | |
}; | |
$( document ).ready( function() { | |
var location = new ElementRegion( $( '.js-location-modal' ) ), state; | |
$( '.js-top-city' ).click( function( e ) { | |
state = $( this ).data( 'state' ); | |
location.setState( state ); | |
location.modal(); | |
e.preventDefault(); | |
}); | |
$( document ).on( 'click', '.js-another-city', function() { | |
state = $( this ).data( 'state' ); | |
location.setState( state ); | |
location.modal(); | |
return false; | |
}); | |
}); | |
})( jQuery, window, undefined ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Change location modal | |
// TODO - realize external plugin for region autocomplete | |
var modalLocations = { | |
$elem : $( '#js-location' ) | |
, $regions : $( '#js-location-regions' ) | |
, $submit : $( '#js-location-submit' ) | |
, $add : $( '#js-location-add' ) | |
, $block1 : $( '#js-location-block1' ) | |
, $block2 : $( '#js-location-block2' ) | |
, $input : $( '.js-location-input' ) | |
, $loader : $( '.js-location-loader' ) | |
, form : '.js-location-form' | |
, bindEvents: function () { | |
var self = this; | |
// delete kladdr | |
$( self.$regions ).on( 'click', '.del', function () { | |
self.deleteKladdr( $( this ) ); | |
} ); | |
// add region link | |
self.$add.click( function (e) { | |
self.hideAdd(); | |
e.preventDefault(); | |
} ); | |
// autocomplete input field - Enter keypress | |
self.$input.enterKey(function (event) { | |
var drop = $( this ).data( 'drop' ); | |
if ( ($( this ).val() == '') && (drop) ) { self.$submit.trigger( 'click' ); } | |
if ( !drop ) { $( this ).data( 'drop', true ); } | |
} ).focus( function () { | |
// refs 21693 | |
// http://stackoverflow.com/questions/4132058/display-jquery-ui-auto-complete-list-on-focus-event | |
if ( $( this ).autocomplete( "widget" ).is( ":visible" ) ) { | |
return; | |
} | |
$( this ).autocomplete( "search" ); | |
} ); | |
} | |
, modal: function () { | |
var self = this; | |
self.$elem.modal( { | |
center: true, | |
size: ['570'], | |
onOpen: function(obj) { | |
// submit | |
self.$submit.one('click', function () { | |
self.submit(); | |
} ); | |
// Top menu - showing location popup window - city autocomplete | |
// TODO - replace by global wrapper plugin for autocomplete for region select | |
self.$input.each( function () { | |
$( this ).autocomplete( { | |
appendTo: $( this ).closest( '.au-form-input' ) | |
, source:function (request, response) { | |
var $loader = this.element.closest( self.form ).find( self.$loader ); | |
$loader.ajaxLoader( {'opacity': false, 'valign': 'center'} ); | |
$.ajax( { | |
url : "/int/controls/get-kladdrs-by-query/", | |
dataType : "jsonp", | |
data : { q:request.term } | |
, success:function (data) { | |
var kladdrs = self.getKladdr() | |
, hasparent; | |
$loader.ajaxLoader( {'mode':'off'} ); | |
response( $.map( data, function (item) { | |
hasparent = false; | |
$.map( kladdrs, function (id) { | |
if ( jQuery.inArray( '' + id + '', item.ParentIds ) > -1 ) { | |
hasparent = true; | |
} | |
} ); | |
if ( (jQuery.inArray( item.CurrentId, kladdrs ) > -1) || hasparent ) { | |
return null; | |
} else { | |
return { | |
label:item.FullName, | |
value:item.FullName, | |
id:item.CurrentId, | |
parentIds:item.ParentIds, | |
subDomain:item.SubDomain | |
} | |
} | |
} ) ); | |
} | |
} ); | |
} | |
, minLength: 1 | |
, autoFocus: true | |
, select:function (event, ui) { | |
var selected = $( 'input.kladdrs[value=' + ui.item.id + ']' ).length; | |
if ( selected > 0 ) { | |
return false; | |
} | |
if ( $( this ).data( 'location' ) == 'single' ) { | |
self.submit(ui.item.id); | |
} else { | |
self.addKladdr(ui.item); | |
self.checkKladdrs(); | |
self.changeLabel(); | |
$( this ).val( '' ).data( 'drop', false ); | |
} | |
return false; | |
} | |
} ).data( "autocomplete" )._renderItem = function( ul, item ) { | |
var $class = ( item.parentIds.length == 0 ) ? "class='au-bold'" : ""; | |
return $( "<li>" ) | |
.data( "item.autocomplete", item ) | |
.append( "<a " + $class + ">" + item.label + "</a>" ) | |
.appendTo( ul ); | |
}; | |
} ); | |
} | |
} ); | |
} | |
, submit: function (kladdr) { | |
var kladdrs = ( typeof kladdr == 'undefined' ) ? this.getKladdr() : [kladdr] | |
, $change = $( "#js-location-changelink" ) | |
, link = $change.data( 'domain' ) + $change.data( 'path' ) | |
, sk = ( kladdrs.length >= 1 ) ? kladdrs.join( ',' ) + document.location.hash : 0 + document.location.hash; | |
this.changeAction(); | |
this.$elem.modal( 'close' ); | |
document.location.href = ( link.indexOf( '?' ) > 0 ) ? link + '&sk=' + sk : link + '?sk=' + sk; | |
} | |
, hideAdd: function () { | |
this.$add.hide().siblings( this.form ).show().find( this.$input ).focus(); | |
} | |
, showAdd: function () { | |
this.$add.show().siblings( this.form ).hide(); | |
} | |
, getKladdr: function () { | |
var kladdrs = []; | |
$( '.name', this.$regions ).not( '.child' ).siblings( 'input:hidden' ).each( function () { | |
kladdrs.push( $( this ).val() ); | |
} ); | |
return kladdrs; | |
} | |
, addKladdr: function (item) { | |
var $hidden = $( '<input type="hidden" class="kladdrs" value="' + item.id + '" />' ).data( 'parents', item.parentIds ).data( 'subdomain', item.subDomain ); | |
var $span = $( '<span class="name">' + item.label + '</span>' ) | |
, $del = $( '<span class="del">×</span>' ); | |
var $li = $( '<li></li>' ); | |
this.$regions.append( $li.append( $hidden ).append( $span ).append( $del ) ); | |
} | |
, deleteKladdr: function (element) { | |
var self = this; | |
element.parent().remove(); | |
$( 'input:hidden', self.$regions ).data( 'skip', false ); | |
if ( $( 'input:hidden', self.$regions ).length <= 1 ) { | |
$( '.name', self.$regions ).removeClass( 'child' ); | |
$( '.comment', self.$regions ).remove(); | |
} else { | |
self.checkKladdrs(); | |
} | |
self.changeLabel(); | |
} | |
, checkKladdrs:function () { | |
var self = this; | |
$( 'input:hidden', self.$regions ).each( function () { | |
if ( $( this ).data( 'skip' ) ) return; | |
var $self = $( this ); | |
$( 'input:hidden', self.$regions ).each( function () { | |
if ( $( this ).data( 'skip' ) ) return; | |
if ( $self.val() == $( this ).val() ) return; | |
var parents = $( this ).data( 'parents' ); | |
if ( parents.length <= 0 ) return; | |
// on parent | |
if ( $.inArray( $self.val(), parents ) >= 0 ) { | |
var comment = $( '<span class="comment">выбран более крупный регион</span>' ); | |
$( this ).siblings( '.name' ).addClass( 'child' ).parent().append( comment ); | |
$( this ).data( 'skip', true ); | |
} else { | |
$( this ).siblings( '.name' ).removeClass( 'child' ).parent().find( '.comment' ).remove(); | |
$( this ).data( 'skip', false ); | |
} | |
} ); | |
} ); | |
} | |
, changeLabel:function () { | |
var count = $( '.name', this.$regions ).length; | |
this.showAdd(); | |
if ( count > 0 ) { | |
this.$block1.hide(); | |
this.$block2.show(); | |
} else { | |
this.$block1.show(); | |
this.$block2.hide(); | |
} | |
this.$submit.show(); | |
} | |
, changeAction:function () { | |
var $change = $( "#js-location-changelink", this.$elem ) | |
, subDomain = '' | |
, change = false; | |
$( 'input:hidden.kladdrs', self.$regions ).each( function () { | |
var regionSubDomain = $( this ).data( 'subdomain' ); | |
if( ( subDomain == '' && regionSubDomain != '' ) || ( subDomain == regionSubDomain ) ) { | |
subDomain = regionSubDomain; | |
change = true; | |
} else if( subDomain != regionSubDomain ) { | |
change = false; | |
} | |
} ); | |
if( false && change && subDomain != '' ) { | |
$change.data( 'domain', subDomain ) ; | |
} | |
} | |
}; | |
modalLocations.bindEvents(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment