loop through array in each() - javascript

I have a backbone chat web app , i have a javascript array which holds names and other stuff, what i want is to look in this array if this.name() exists and if so read the element before the name wich is a image url and use that in option_h3 in the code below.
hope im clear enough.
thanks i.a.
var PeopleView = Backbone.View.extend({
className: 'peopleView',
initialize: function() {
this.people = Hula.user.get("people");
this.people.on('add', this.addPerson, this);
this.people.on('remove', this.render, this);
$(".nav_item").removeClass("nav_item_s");
$("#people_nav").addClass("nav_item_s");
},
render: function(){
this.$el.empty();
var header = $('<div id="people_header">');
var title = $('<div class="t34 title">');
title.html("Friends");
header.append(title);
this.$el.append(header);
var addOption = $('<div id="people_add_option">');
var addInput = '<div id="addp"><div id="people_add_input_h"><form id="add_person_input_form" ><input id="add_person_input" name="s" type="text" value="Enter Hularing ID..." ></input></form></div></div>';
addOption.html(addInput);
this.$el.append(addOption);
var list = $('<div id="people_list" >');
this.$el.append(list);
this.people.each(this.addPerson, this);
return this;
},
addPerson: function(person){
var view = new PeopleViewPerson({model: person});
this.$("#people_list").prepend(view.render().$el);
},
events: {
'keypress #add_person_input': 'addNewPerson',
},
addNewPerson: function(e){
var ID = $('#add_person_input').val();
if(ID !=="Enter Hularing ID..."){
if(e.which == 13) {
if(validate(ID)){
Hula.subscribe(ID);
this.$('#add_person_input').val("")
$("#add_person_input_form")[0].reset();
$('#add_person_input').blur().focus();
e.preventDefault();
}
}
}
}
});
var PeopleViewPerson = Backbone.View.extend({
className: 'friend_holder',
initialize: function() {
$(this.el).attr('id', jid_to_id(this.model.get("jid")));
this.model.on('all', this.render, this);
this.model.get('conversation').get('messages').on('add', this.onNewMessage, this);
},
render: function() {
var img = $('<div class="friend_img_h">');
if(this.pic() == null){
img.html('<img src="farax/img/default.png" />');
} else {
var img_src = 'data:'+this.picType()+';base64,'+this.pic();
img.html('<img src="'+img_src+'" />')
}
var info_h = $('<div class="friend_info_h">');
var person_name = $('<div class="friend_name">');
person_name.html(this.name());
var line2 = $('<div class="friend_line2">');
var status = this.status();
line2.html(status);
var option_h = $('<div class="friend_option_h">');
option_h.html('<div class="msg_person_icon" ></div>');
// CONTACT INFO DIV.
var option_h1 = $('<div class="friend_option_h1">');
// CONTACT INFO IMAGE IN CSS FILE.
option_h1.html('<div class="msg_person_icon1"></div>');
// CONTACT FACEBOOK TIJDLIJN.
var option_h2 = $('<div class="friend_option_h2">');
// CONTACT FACEBOOK TIJDLIJN IMAGE IN CSS FILE.
option_h2.html('<div class="msg_person_icon2"></div>');
var option_h3 = $('<div class="friend_option_h3">');
option_h3.html('<div class="msg_person_icon3"></div>');
for(var t = 0; t < javaScript_array.length; t++) {
// this one stays the same
var naam = this.name();
var res = javaScript_array[t];
// ignore this it is done to get the name from the database the same as in the collection
var naam1 = naam.replace(" ","0");
// see if it exists
if(naam1 === res){
option_h3.append('<div class="msg_person_icon3"><img src="'+ javaScript_array[t-1] +'" width="35" height="35"/></div>');
} else {
option_h3.html('<div class="msg_person_icon3"></div>');
}
}
if(this.ask()== "subscribe"){
line2.prepend('<span class="pending_out">Request pending.</span>');
}
if(this.pending()){
line2.prepend('<span class="pending_in">Pending authorisation!</span>');
}
info_h.append(person_name).append(line2);
this.$el.html(img);
this.$el.append(info_h);
this.$el.append(option_h);
this.$el.append(option_h1);
this.$el.append(option_h2);
this.$el.append(option_h3);
return this;
},
jid: function() { return this.model.get('jid');},
name: function() { return this.model.get('name'); },
status: function() { return this.model.get('status'); },
pic: function() { return this.model.get('picture').pic; },
picType: function() { return this.model.get('picture').picType; },
ask: function() { return this.model.get('ask'); },
subscription: function() { return this.model.get('subscription'); },
pending: function() { return this.model.get('pending'); },
online: function() { return this.model.get('online'); },
events: {
'click .friend_img_h': 'loadPerson',
'click .friend_info_h': 'loadPerson',
'click .msg_person_icon': 'messagePerson'
},
loadPerson: function(){
Hula.screen.person.render(this.model);
},
messagePerson: function(){
Hula.screen.conversation.render(this.model);
},
onAll: function(person){
},
onNewMessage: function(message){
$('#people_list #'+jid_to_id(this.jid())+' .friend_line2').html(message.get("message"));
},
OnStatusChange: function(change){
$("#people_list #"+id_to_jid(this.ji())).html(this.status().toString());
}
});
it only works on the last element in the array while there are three elements.

I'm looking at your code and to be completely honest, it makes absolutely no sense to me.
I can see that you have option1 option2 and option3 which I assume are the 3 elements you are referring to only, in your array at the bottom, you only ever seem to change option 3.

Related

prevent slideshow from refresh or load content in div

I have a nice working image slideshow, but every time when i open a new page from the menu, the slideshow starts from the beginning. I want it to go on where it was while entering a new page. Now could there be a possibility to change it in the code of my slideshow, but maybe a better solution is to open my content in a div with AJAX, so the whole page doesn't refresh.
I found this on the web:
<div id="navigatie">
<div id="buttons">
<a class="menu" id="page1" href="#">Home</a><span>|</span>
<a class="menu" id="page2" href="#">Projects</a><span>|</span>
<a class="menu" id="page3" href="#">About</a><span>|</span>
</div>
</div>
<script>
$(document).ready(function() {
$("#page1").click(function(){
$('#content').load('index.php #content');
});
$("#page2").click(function(){
$('#content').load('projects.php #content');
});
$("#page3").click(function(){
$('#content').load('about.php #content');
});
});
</script>
But this doesn't workout very well because when i start with my index page and go to projects (where lightbox is present), i get full images instead of thumbnails.(This was because the extended files were not in #content) i get index.php# instead of projects.php. Maybe i should use an easier solution, but im getting stuck. Can someone help me out please?
Edit: Let me also share the code of the slideshow with you, perhaps there is a possibility to resume after loading a new page/refresh.
/*!
* crosscover v1.0.2
* Carousel of a simple background image using jquery and animate.css.
* http://git.blivesta.com/crosscover
* License : MIT
* Author : blivesta <enmt#blivesta.com> (http://blivesta.com/)
*/
;(function(factory) {
'use strict';
if (typeof define === 'function' && define.amd) {
define(['jquery'], factory);
} else if (typeof exports === 'object') {
module.exports = factory(require('jquery'));
} else {
factory(jQuery);
}
}(function($) {
'use strict';
var namespace = 'crosscover';
var __ = {
init: function(options) {
options = $.extend({
inClass: 'fade-in',
outClass: 'fade-out',
interval: 5000,
startIndex: 0,
autoPlay: true,
dotsNav: true,
controller: false,
controllerClass: 'crosscover-controller',
prevClass: 'crosscover-prev',
nextClass: 'crosscover-next',
playerClass: 'crosscover-player',
playerInnerHtml: '<span class="crosscover-icon-player"></span>',
prevInnerHtml: '<span class="crosscover-icon-prev"></span>',
nextInnerHtml: '<span class="crosscover-icon-next"></span>'
}, options);
__.settings = {
currentIndex: options.startIndex,
timer: null,
coverBaseClass:'crosscover-item',
coverWaitClass:'is-wait',
coverActiveClass:'is-active',
playerActiveClass: 'is-playing',
dotsNavClass: 'crosscover-dots'
};
return this.each(function() {
var _this = this;
var $this = $(this);
var data = $this.data(namespace);
var $item = $this.children('.crosscover-list').children('.' + __.settings.coverBaseClass);
if (!data) {
options = $.extend({}, options);
$this.data(namespace, {
options: options
});
if (options.dotsNav) __.createDots.call(_this, $item);
if (options.controller) __.createControler.call(_this, $item);
__.setup.call(_this, $item);
}
});
},
setup: function($item) {
var _this = this;
var $this = $(this);
var options = $this.data(namespace).options;
$item.each(function(index) {
var $self = $(this);
var image = $self.find('img').attr('src');
$self
.addClass(__.settings.coverBaseClass, __.settings.coverWaitClass)
.css({
'background-image': 'url(' + image + ')'
});
});
return __.slideStart.call(_this, $item);
},
slideStart: function($item) {
var _this = this;
__.autoPlayStart.call(_this, $item);
__.show.call(_this, $item);
},
createDots: function($item) {
var _this = this;
var $this = $(this);
var options = $this.data(namespace).options;
var len = $item.length;
$this
.append(
$('<ul>')
.addClass(__.settings.dotsNavClass)
);
for (var i = 0; i < len; i++) {
$this
.children('.' + __.settings.dotsNavClass)
.append(
$('<li>')
.addClass('crosscover-dots-nav-' + i)
.append(
$('<button>')
)
);
}
__.addDots.call(_this, $item);
},
addDots: function($item) {
var _this = this;
var $this = $(this);
var options = $this.data(namespace).options;
var $dots = $this.children('.' + __.settings.dotsNavClass);
var $dot = $dots.children('li').children('button');
$dot.on('click.' + namespace, function(event) {
return __.toggle.call(_this, $item, 'dots', $(this).parent('li').index());
});
},
createControler: function($item) {
var _this = this;
var $this = $(this);
var options = $this.data(namespace).options;
var isClass = options.autoPlay ? __.settings.playerActiveClass : null;
$this
.append(
$('<div>')
.attr({
'data-crosscover-controller': ''
})
.addClass(options.controllerClass)
.append(
$('<button>')
.attr({
'data-crosscover-prev': ''
})
.addClass(options.prevClass)
.html(options.prevInnerHtml)
)
.append(
$('<button>')
.attr({
'data-crosscover-player': ''
})
.addClass(options.playerClass)
.addClass(isClass)
.html(options.playerInnerHtml)
)
.append(
$('<button>')
.attr({
'data-crosscover-next': ''
})
.addClass(options.nextClass)
.html(options.nextInnerHtml)
)
);
return __.addControler.call(_this, $item);
},
addControler: function($item) {
var _this = this;
var $this = $(this);
var options = $this.data(namespace).options;
var $controller = $this.children('[data-crosscover-controller]');
var $navPrev = $controller.children('[data-crosscover-prev]');
var $navNext = $controller.children('[data-crosscover-next]');
var $navPlayPause = $controller.children('[data-crosscover-player]');
$navPlayPause.on('click.' + namespace, function(event) {
$(this).blur();
return __.playToggle.call(_this, $item, $(this));
});
$navPrev.on('click.' + namespace, function(event) {
$(this).blur();
return __.toggle.call(_this, $item, 'prev');
});
$navNext.on('click.' + namespace, function(event) {
$(this).blur();
return __.toggle.call(_this, $item, 'next');
});
},
playToggle: function($item) {
var _this = this;
var $this = $(this);
var options = $this.data(namespace).options;
var $navPlayPause = $this.find('[data-crosscover-player]');
if (options.autoPlay) {
options.autoPlay = false;
$navPlayPause
.removeClass(__.settings.playerActiveClass)
.addClass(options.playClass);
return __.autoPlayStop.call(_this);
} else {
options.autoPlay = true;
$navPlayPause.addClass(__.settings.playerActiveClass);
return __.autoPlayStart.call(_this, $item);
}
},
toggle: function($item, setting, num) {
var _this = this;
var $this = $(this);
var options = $this.data(namespace).options;
__.hide.call(_this, $item);
if (setting === 'next') {
__.settings.currentIndex++;
} else if (setting === 'prev') {
__.settings.currentIndex--;
} else if (setting === 'dots') {
__.settings.currentIndex = num;
}
if (__.settings.currentIndex >= $item.length) {
__.settings.currentIndex = 0;
} else if (__.settings.currentIndex <= -1) {
__.settings.currentIndex = $item.length - 1;
}
__.autoPlayStart.call(_this, $item);
return __.show.call(_this, $item);
},
show: function($item) {
var $this = $(this);
var options = $this.data(namespace).options;
if(options.dotsNav) {
$this
.children('.' + __.settings.dotsNavClass)
.children('li')
.eq(__.settings.currentIndex)
.addClass('is-active')
.children('button')
.prop('disabled', true);
}
return $item
.eq(__.settings.currentIndex)
.addClass(__.settings.coverActiveClass)
.removeClass(__.settings.coverWaitClass)
.addClass(options.inClass)
.csscallbacks('animationEnd',function() {
$(this)
.removeClass(options.inClass + ' ' + __.settings.coverWaitClass)
.addClass(__.settings.coverActiveClass);
});
},
hide: function($item) {
var $this = $(this);
var options = $this.data(namespace).options;
if(options.dotsNav) {
$this
.children('.' + __.settings.dotsNavClass)
.children('li')
.eq(__.settings.currentIndex)
.removeClass('is-active')
.children('button')
.prop('disabled', false);
}
return $item
.eq(__.settings.currentIndex)
.removeClass(__.settings.coverActiveClass)
.addClass(options.outClass)
.csscallbacks('animationEnd', function() {
$(this)
.removeClass(options.outClass + ' ' + __.settings.coverActiveClass)
.addClass(__.settings.coverWaitClass);
});
},
autoPlayStart: function($item) {
var _this = this;
var $this = $(this);
var options = $this.data(namespace).options;
if (options.autoPlay) {
__.autoPlayStop.call(_this);
__.settings.timer = setTimeout(function() {
__.toggle.call(_this, $item, 'next');
__.autoPlayStart.call(_this, $item);
}, options.interval);
}
return _this;
},
autoPlayStop: function() {
return clearTimeout(__.settings.timer);
},
currentIndex: function() {
return __.settings.currentIndex;
}
};
$.fn.crosscover = function(method) {
if (__[method]) {
return __[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return __.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.' + namespace);
}
};
$.fn.csscallbacks = function(type, callback){
var _animationStart = 'animationstart webkitAnimationStart oAnimationStart';
var _animationEnd = 'animationend webkitAnimationEnd oAnimationEnd';
var _transitionEnd = "transitionend webkitTransitionEnd oTransitionEnd";
if(type === 'animationStart'){
type = _animationStart;
} else if(type === 'animationEnd'){
type = _animationEnd;
} else if(type === 'transitionEnd'){
type = _transitionEnd;
}
return this.each(function(index) {
var $this = $(this);
$this.on(type, function(){
$this.off(type);
return callback.call(this);
});
});
};
}));
Its fixed, i just load my content in the #content div and i changed every 'href' to #Home (or name i like) in combination with Benalman's hashchange script

backbone filtering a collection

I am trying to filter a collection based on an attribute called status. Once filtered I want to re-render the view to reflect the filtered results. So far I have come up with this function in my collection.
var ProjectCollection = Backbone.Collection.extend({
url: '/projects',
model: app.Project,
status: function( status ) {
return this.filter(function(project){
return project.get('status') == status;
});
},
});
In my view I the run the following,
filterStatus: function(e) {
e.preventDefault();
var elm = $(e.currentTarget),
status = elm.data('statusid');
this.collection.reset( this.collection.status( status ) );
}
The render function is below along with it's functions that also get called,
render: function() {
this.$el.empty();
console.log("ProjectDashboardView render");
if(this.collection.length < 1) {
var noProjects = new app.noProjectsDashboard;
} else {
this.addAll();
}
$(".month-column").height($(".project-holder").height() + 50);
},
addAll: function() {
console.log("allAdd");
this.collection.each(function(model){
this.addOne(model)
}, this);
},
addOne: function(model) {
var view = new app.ProjectTimelineEntry({
model: model
});
this.$el.append( view.render() );
var number_of_days_in_calendar = 0;
$('.month-column').each(function(){
number_of_days_in_calendar = number_of_days_in_calendar + parseInt($(this).data('days'));
});
var day_width = 1/(number_of_days_in_calendar) * 100;
//Is the start after the end of Feb?
var start_date = new Date(model.get('start_date'));
var march_date = new Date("03/01/2014");
var current_month = start_date.getMonth() + 1;
var march_month = march_date.getMonth() + 1;
console.log(current_month, march_month);
if(current_month <= march_month) {
var start_date_offset = model.get('num_days_from_year_start') * day_width;
var duration_of_project = model.get('run_number_days') * day_width;
//view.$('.duration-bar').css("background-color", model.get('color'));
view.$el.find('.duration-bar').css({
width : duration_of_project + "%",
"margin-left" : start_date_offset + "%"
}, 500);
} else {
var start_date_offset = (model.get('num_days_from_year_start') + 2) * day_width;
var duration_of_project = model.get('run_number_days') * day_width;
//view.$('.duration-bar').css("background-color", model.get('color'));
view.$el.find('.duration-bar').css({
width : duration_of_project + "%",
"margin-left" : start_date_offset + "%"
}, 500);
}
// if(Date.parse(start_date) < new Date("01/03")) {
// console.log("before march");
// }
},
Now this filters the collection, however what happens is that when I try and filter the collection again, it filters the collection that I have just reset too, how can I filter the collection, run the views render() function once a filter is complete, but not keep resetting the collection?
As hindmost mentionned, you should add a visible field to app.Project model.
Then in ProjectView attach a listener to this field:
this.listenTo(this.model, "change:visible", this.onVisibleChange)
and the method definition:
onVisibleChange: function(){
$(this.el).css('display', (this.get('visible')) ? 'block': 'none')
}
In your filter method you run over the collection and change the visible field of each model accordingly to if it should or should not being rendered.
var ProjectCollection = Backbone.Collection.extend({
url: '/projects',
model: app.Project,
status: function( status ) {
return this.each(function(project){
project.set('visible', project.get('status') == status)
});
},
});
You have to add extra attribute to collection's model (app.Project) which will store the flag indicating if a project has to be displayed or not.
var app.Project = Backbone.Model.extend({
defaults: {
...
status: '',
display: true
}
};
Then you have to add the code to model View's render which will show/hide View's element depending on value of display attribute:
var ProjectView = Backbone.View.extend({
...
render: function() {
...
if (this.model.get('display'))
this.$el.show();
else
this.$el.hide();
...
return this;
},
...
};
And, finally you have to modify ProjectCollection's status method to set display attribute on each model:
var ProjectCollection = Backbone.Collection.extend({
url: '/projects',
model: app.Project,
status: function( status ) {
this.each(function(project){
project.set('display', project.get('status') == status);
});
},
...
});

BackBone: get sub view from jquery element

I render a list Post to template after select it from window scroll event and i need to get model and event in this Post.
I want to get view Post for using model or event from route when window scroll event? have a way to do it?
sub view:
Post = Backbone.View.extend({
tagName: "div",
className: "post",
initialize: function () {
this.post = this.model;
this.render();
},
render: function () {
$(this.el).html(this.template(this.post));
return this;
}
});
view:
ListPost = Backbone.View.extend({
tagName: "div",
className: "listpost",
initialize: function(models, options){
this.listpost = options.listpost;
this.render();
},
render: function () {
_.each(this.listpost, function (post) {
$(this.el).append(new Post({model: post}).el);
}, this);
return this;
}});
route:
var AppRouter = Backbone.Router.extend({
initialize: function () {
$('body').html(new ListPost([], {listpost: posts}).el);
window.onscroll = this.scroll;
},
scroll : function() {
var element = $('.post');
var find_out = false;
for(var i = 0; i< element.length; i++) {
if(find_out) break;
var post = element[i];
if(post.getBoundingClientRect) {
var rect = post.getBoundingClientRect();
x = rect.bottom;
y = rect.top;
if(x > 0) {
if(x > 480/3) {
//result is post
// how i can select this post to sub view Post
find_out = true;
}
}
}
}
}});
Move the scroll functionality to the ListPost so you can have an array of views in your scope.
Example:
ListPost = Backbone.View.extend({
tagName: "div",
className: "listpost",
initialize: function(models, options){
this.listpost = options.listpost;
// Add scroll event here ($.proxy makes sure the event can see this.element).
$(document).scrool( $.proxy(this.scroll, this) );
this.render();
// Create an array to hold a reference to all Post views.
this.element = [];
},
render: function () {
_.each(this.listpost, function (post) {
// Create the post views and add them to the array.
var postView = new Post({model: post});
this.element.push( postView );
$(this.el).append(postView.el);
}, this);
return this;
},
scroll: function() {
var find_out = false;
// Make sure you use this with element.
for(var i = 0; i< this.element.length; i++) {
if(find_out) break;
// Post is now a Backbone view.
var post = this.element[i];
// Make sure you use post.el to access the views DOM element.
if(post.el.getBoundingClientRect) {
var rect = post.el.getBoundingClientRect();
x = rect.bottom;
y = rect.top;
if(x > 0) {
if(x > 480/3) {
//result is post
// how i can select this post to sub view Post
find_out = true;
// Do what you want with the backbone view.
post.render();
console.log(post.model);
}
}
}
}
}
});

Trigger invokes the called function multiple time when fired from layout view in marionitte

I am using marionitte framework and i am trying to fire a trigger from one layout view to any other view but its function on the other view is invoked multiple times even though the trigger is fired only once.
Does anyone has got encountered the same issue and has resolved it please let me know the resolution so that i can use in my code.
w.src.SourceTabView = Backbone.Marionette.Layout.extend({
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template: "#src-template-source-tab-view",
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
regions: {
"change results" : "#src-template-change-results-region",
"change pagination" : "#src-template-change-pagination-region",
"document layout" : "#src-template-document-layout-region",
"workflow detail" : "#src-template-workflow-detail-region",
"job log" : "#src-template-job-log-region",
"source job" : "#src-template-job-region"
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
changeInfo: null,
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
mostRecentChange: null,
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
screenCapture: null,
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
regionSelector: null,
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
tab: "details",
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
controls: {
institution: new w.EntitySelector(null,[]),
contentSetGroup: new w.EntitySelector(null,["cs"]),
pageTypes: new w.EntitySelector(null,["page_type"]),
prevTypes: new w.EntitySelector(null,["previous_type"])
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
initialize: function(){
this.listenTo( this.model , 'sync' , this.render );
var instTypes = [] ;
for( var instTypeEntityId in w.INST_TYPES ){
instTypes.push(instTypeEntityId);
}
this.controls.institution = new w.EntitySelector(null,instTypes);
this.controls.institution.minValueLength = 1;
this.controls.contentSetGroup.maxValueLength = 1;
this.controls.contentSetGroup.minValueLength = 1;
this.controls.prevTypes.minValueLength = 1;
this.controls.prevTypes.maxValueLength = 1;
this.fetchMostRecentChange();
this.regionSelector = null;
this.changeInfo = new w.src.ChangeInfo(this.model);
this.changeInfo.vent.on("change-selected", this.render);
this.changeInfo.vent.on("change-refreshed", this.render);
this.changeInfo.vent.on("workflow-selected", this.render);
this.changeInfo.vent.on("workflow-refreshed", this.render);
this.changeInfo.vent.on("jobLog-view", this.render);
this.changeInfo.vent.on("workflow-created", w.refreshWorkflows);
this.changeInfo.vent.on('save-source', this.fromJobRun, this);
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
fetchMostRecentChange: function(){
var self = this;
$.ajax({
url: "/source/" + self.model.id + "/most-recent-change",
dataType: "json",
success: function(mostRecentChange){
if( mostRecentChange ){
$.ajax({
url: "/document?change=" + mostRecentChange.id + "&rendering=screen-capture",
dataType: "json",
success: function(response){
self.mostRecentChange = mostRecentChange;
if( response.results.length > 0 ){
self.screenCapture = response.results[0];
}
self.render.call(self);
}
});
}
}
});
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
serializeData: function(){
var verificationDate = this.model.get('verificationDate');
// Converting timestamp into readable format
if(!verificationDate) {
verificationDate = '';
} else {
verificationDate = moment(verificationDate).format('MM/DD/YYYY');
}
return {
model: this.model,
tab: this.tab,
minimumChangeInterval: this.humanizeDate(this.model.get("minimumChangeIntervalMs")),
verificationDate: verificationDate
}
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
onRender: function(){
var tabRegion = localStorage.getItem("tabRegion"),
rememberTabs = localStorage.getItem("rememberTabs");
if( tabRegion && rememberTabs === "true"){
this.tab = tabRegion;
} else if( this.tab == null ) {
this.tab = "details";
}
localStorage.setItem("tabRegion", this.tab);
// content set group
var contentSetIds = [];
for( var contentSetId in w.CS ){
if( this.model.get("entityIds").indexOf(contentSetId) >= 0 ){
contentSetIds.push(contentSetId);
}
}
this.controls.contentSetGroup.values = contentSetIds;
this.controls.contentSetGroup.bind(this.$("#src-tab-details-group"));
// page types
var pageTypeIds = [];
for( var pageTypeId in w.PAGE_TYPES ){
if( this.model.get("entityIds").indexOf(pageTypeId) >= 0 ){
pageTypeIds.push(pageTypeId);
}
}
this.controls.pageTypes.values = pageTypeIds;
this.controls.pageTypes.bind(this.$("#src-tab-details-page"));
// prev types
var prevTypeIds=[];
for(var prevTypeId in w.PREV_TYPES){
if(this.model.get("entityIds").indexOf(prevTypeId)>=0){
prevTypeIds.push(prevTypeId);
}
}
this.controls.prevTypes.values = prevTypeIds;
this.controls.prevTypes.bind(this.$("#src-tab-details-previousType"));
// changes
var changePaginationView = new w.PaginationView({collection:this.changeInfo.changes});
changePaginationView.autoHide = true;
this["change results"].show(new w.src.ChangeCollectionView({collection:this.changeInfo.changes, changeInfo:this.changeInfo}));
this["change pagination"].show(changePaginationView);
// institution
var institutionIds = [];
_.each(this.model.get("entityIds"),function(entityId){
if( !w.INST_TYPES[entityId] && !w.PAGE_TYPES[entityId] && !w.CS[entityId] && !w.PREV_TYPES[entityId]){
institutionIds.push(entityId);
}
});
this.controls.institution.values = institutionIds;
this.controls.institution.bind(this.$("#src-tab-details-institution"));
// job
this["source job"].show(new w.src.SourceJobView({changeInfo:this.changeInfo}));
// documents
if( this.changeInfo.selectedChange ){
var documentLayoutView = new w.src.DocumentLayoutView({collection:this.changeInfo.documents, changeInfo:this.changeInfo});
this["document layout"].show(documentLayoutView);
var documentPaginationView = new w.PaginationView({collection:this.changeInfo.documents});
documentPaginationView.autoHide = true;
documentLayoutView["document results"].show(new w.src.DocumentCollectionView({collection:this.changeInfo.documents, changeInfo:this.changeInfo}));
documentLayoutView["document pagination"].show(documentPaginationView);
} else {
this["document layout"].close();
}
//view job logs
if(this.changeInfo.viewDetails) {
var self = this;
var jobId = this.changeInfo.selectedChange.get('jobId');
var selectedJobModel = new w.Job({id: jobId});
selectedJobModel.fetch({ success: function(model) {
self["job log"].show(new w.src.JobLogView({logger: model.get('logger')}));
}});
}
// workflow detail
this["workflow detail"].show(new w.src.WorkflowDetailView({changeInfo:this.changeInfo}));
// other setup
this.onUrlType();
this.setTab();
if(!this.model.isNew()) {
this.validate();
}
if(this.model.get("includedRegions").length) {
this.$(".delete-all-selected-region").removeClass("disabled");
}
// Adding datepicker
this.$("#verificationDate").datepicker({
todayHighlight: true,
autoclose: true
});
},
fromJobRun: function() {
var self = this;
this.onUseMyAccountClick();
this.populateDateToModel();
// save the model
this.model.save().success(function() {
self.onSuccess();
self.changeInfo.vent.trigger("job-selected");
}).error(function(response) {
self.onError(response)
});
},
});
sourceJobView.js
w.src.SourceJobView = Backbone.Marionette.Layout.extend({
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template: "#src-template-source-job-view",
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
initialize: function(){
this.options.changeInfo.vent.on("job-selected", this.runJob );
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
onRender : function(){
// decide whether to show the job details link
if( w.IS_ADMIN ){
this.$(".jobDetailsMessage").show();
} else {
this.$(".jobDetailsMessage").hide();
}
} ,
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
serializeData: function(){
return this.options.changeInfo;
},
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
runJob: function() {
console.log('here');
},
onRunJobClick: function() {
this.options.changeInfo.vent.trigger("save-source");
}
});
According to the code here
Onrunjobclick in sourceJobview triggered is fired to sourceTabview which is listened by fromrunJob which on success fires a trigger back to sourceJobview which is listened by runJob which is invoked multiple times
The most common cause of this issue is zombie views - they have been removed from the DOM, but their event handlers remain bound.
You should use listenTo instead of on to bind events. This allows Marionette's View.close method to clean up old event handlers when views are closed.
It's a simple fix:
initialize: function(){
this.listenTo(options.changeInfo.vent, "job-selected", this.runJob);
},

jQuery boilerplate call functions

i use jQuery Boilerplate: http://jqueryboilerplate.com/
and now i have a problem to call a function in a function..
i can't call "openOverlay" in "clickEvents", but i can call "openOverlay" in "init".
here is a snippet:
Plugin.prototype = {
init: function() {
var $me = $(this.element);
this.clickEvents($me);
},
clickEvents: function($el, func) {
$el.on('click', function() {
var $me = $(this);
var overlayName = $me.data('overlay');
this.openOverlay(overlayName);
});
},
openOverlay: function(overlayName) {
var $overlayContainer = $(defaults.$overlayContainer);
var $overlay = $overlayContainer.find('[data-overlay="' + overlayName + '"]');
$overlayContainer.fadeIn(500);
$overlay.delay(500).fadeIn(500);
}
};
the problem is that the on click function overrides "this"
try:
var self=this;
$el.on('click', function() {
var $me = $(this);
var overlayName = $me.data('overlay');
self.openOverlay(overlayName);
});

Categories

Resources