jQuery morphing button concept - javascript

I have written some jQuery that will morph a button into a container when clicked.
I now want to use the same script but on a different button. I am not sure the best way to do this though. Would it be to copy and paste the whole morphObject and then change the bits which need changing for the new button, and then run both the object's init functions?
Here is the Fiddle:
https://jsfiddle.net/2a3rp590/
Here is the jQuery:
$(document).ready(function() {
var morphObject = {
button: $('button.morphButton'),
container: $('div.morphContainer'),
overlay: $('div.overlay'),
content: $('h1.content, p.content'),
endPosition: {
top: 100,
left: '50%',
width: 600,
height: 400,
marginLeft: -300
},
init: function() {
var mO = morphObject,
button = mO.button;
button.on('click', function() {
button.fadeOut(200);
setTimeout(mO.containerMove, 200);
});
},
containerMove: function() {
var mO = morphObject,
content = mO.content,
overlay = mO.overlay,
container = mO.container,
span = $('span.close');
overlay.fadeIn();
container.animate(mO.endPosition, 400, function() {
content.fadeIn();
span.fadeIn();
mO.close();
});
},
close: function() {
var mO = morphObject,
container = mO.container,
overlay = mO.overlay,
content = mO.content;
if ( container.find('span.close').length ) return;
$('<span class="close">X</span>').appendTo(container);
var span = $('span.close');
overlay.add(span).on('click', function() {
content.fadeOut();
span.fadeOut();
overlay.fadeOut();
setTimeout(mO.animateBack, 200);
});
},
animateBack: function() {
var mO = morphObject,
container = mO.container;
button = mO.button;
container.animate(mO.startPosition, 400, function() {
button.fadeIn(300);
});
}
}
var container = morphObject.container;
morphObject.startPosition = {
top: container.css('top'),
left: container.css('left'),
width: container.css('width'),
height: container.css('height'),
marginLeft: container.css('margin-left')
};
morphObject.init();
});
You can see in the fiddle, I have added a new button, container and content. How can I make my code work with multiple buttons?
Thanks.

As i said in my comments, you could do the following. Bear in mind that this is an untested version.
init: function(params) {
//object reference
var self = this;
//reassign the button object if it was passed
//else use the default from the object
self.button = typeof params !== "undefined" && params.button || self.button;
self.button.on('click', function() {
$(this).fadeOut(200);
setTimeout(self.containerMove, 200);
});
}
//I am using an object as you my want to
//pass in more options later, just in case
//such as
/*
morphObject.init({
button: $('button.morphButton2'),
container: $('.another-container')
});
*/
morphObject.init({
button: $('button.morphButton2')
});
Or you could have a common class to all buttons that would trigger the click inside the init method. Easy enough?
var morphObject = {
button: $('button.morphButton') //let's say 'morphButton' is the common class
.....
.....
init: function(params) {
//object reference
var self = this;
self.button.on('click', function() {
$(this).fadeOut(200);
setTimeout(self.containerMove, 200);
});
}
.....
.....
.....
}

Related

Error: cannot call methods on tabs prior to initialization; attempted to call method 'destroy'

I'm working on updating an older site to the newer version of jQuery and applying bootstrap.
We are using
backbone.js
jQueryui and
bootstrap.js.
I am getting the following error: Error: cannot call methods on tabs prior to initialization; attempted to call method 'destroy'
The lines of code it is related to is:
Thanks
define([
'jquery',
'jqueryui',
'underscore',
'backbone',
'vm',
'events',
'models/product',
'text!templates/editor/page.html'
], function ($, jui, _, Backbone, Vm, Events, Product, PageTemplate) {
var EditorPage = Backbone.View.extend({
model: Product,
el: '#editor',
_$editorErrorContainer: undefined,
events: {
"click #toolbar": "onToolbarClicked"
},
initialize: function () {
this.bindSaveEvents();
Events.unbind("addText");//HACK: Prevents zombie listeners for this specific situation
Events.bind("addText", this.onAddText, this);
},
onAddText: function (e) {
var layers = this.model.get('layers');
var textCollections = [];
//Search for valid text collections in our layer and push into our array
layers.models.forEach(function (layer) {
var tc = layer.get("textCollection");
if (typeof tc !== "undefined") {
if (layer.get("allowText")) {
var printColor = layer.get("printColor");
var src;
if(printColor) { src = printColor.get("src"); }
var _tc = { 'textCollection': tc, 'src': src, 'name':layer.get('name'), 'cid': layer.cid };
textCollections.push(_tc);
}
}
});
//if there's no choice to make, just add the text element.
if (textCollections.length == 1) {
var textCollection = textCollections[0].textCollection;
AddTextToCollection(textCollection);
return;
}
//Otherwise create dialog for choosing in which text collection to put a new text object
var dialogHTML = "<div> <p>What color would you like this text?</p>";
//Generate selections, use the src attribute of the print color if it uses printcolor
//TODO use other attributes of a textCollection such as rgb color if it uses it etc
textCollections.forEach(function (textCollection, i) {
var imgurl = "";
if(textCollection.src) {
imgurl = "/productEditor/assets/printcolors/icons/" + textCollection.src;
}
//Customers wont like zero indexed option names
var id = i + 1;
dialogHTML += "<p data-id= " + i + " class='selection'> Group " + id + ": " + textCollection.name + "<img src='" + imgurl + "'/> </p>";
});
dialogHTML += "</div>"
$(dialogHTML).dialog({
modal: true,
width: "25%",
height: "auto",
dialogClass: "textAddDialog",
resizable: false,
position: {
my: 'left top',
at: 'left top',
of: $("#editor"),
collision: 'flip'
},
show: 'fade',
create: function() {
var that = this;
//bind dialog events
$(this).children(".selection").click(function(){
$(that).children('.selected').removeClass("selected");
$(this).addClass("selected");
});
},
open: function (event, ui) {
$('.ui-dialog').css('z-index',2003);
$('.ui-widget-overlay').css({
'z-index': 2002,
'opacity': 0.5
});
},
close: function() {
$(this).children(".selection").unbind();
$(this).dialog('destroy').remove();
},
buttons: [{
text: "Accept",
"class": "acceptButton",
click: function() {
var index = $(this).children('.selected').data('id');
if(index >= 0) {
var textCollection = textCollections[index].textCollection;
AddTextToCollection(textCollection);
}
$(this).dialog("close");
}
},
{
text: "Cancel",
click: function() {
$(this).dialog("close");
}
}
]
});
function AddTextToCollection (textCollection) {
//Create text element in chosen group
var entry = textCollection.createEntry();
//Show user that this is a fresh text element that needs changing
entry.set("text", "Edit Me!");
entry.set("freshElement", true);//Fresh element denotes a completely new element, used to delete this element if user adds an element -> cancel button
//Trigger mouseup on element so our text editor dialog will pop for this element
var elem = $('.text_modifier[data-cid="' + entry.cid + '"]');
elem.trigger("click");
}
},
bindSaveEvents: function(){
Events.on('saveError', this.onSaveError.bind(this));
Events.on('saveSuccess', this.onSaveSuccess.bind(this));
},
unbindSaveEvents: function(){
Events.off('saveError', this.onSaveError.bind(this));
Events.off('saveSuccess', this.onSaveSuccess.bind(this));
},
onToolbarClicked: function (e) {
//console.log("toolbar clicked");
//this._productView.clearSelectedChildren();
},
onSaveError: function(errorMessage){
// if(this._$editorErrorContainer === undefined){
// this._$editorErrorContainer = $("<div/>").addClass("error");
// $(this.el).before(this._$editorErrorContainer);
// }
// this._$editorErrorContainer.text(errorMessage).show();
$('#appError').text(errorMessage).show();
},
onSaveSuccess: function(){
// if(this._$editorErrorContainer != null){
// this._$editorErrorContainer.hide();
// }
$('#appError').hide();
},
onRenderComplete: function (e) {
// ADD THE RETURN ELEMENT TO THE LIST OF
this._loadList = _.without(this._loadList, e);
if (this._loadList.length == 0) {
$(this.el).removeClass('loading');
}
},
remove: function(){
this.unbindSaveEvents();
},
renderApp: function () {
var that = this;
// PUT LIST OF ITEMS THAT RENDER INTO ARRAY
// renderComplete WILL REMOVE ITEMS, AND CHANGE STATE TO VISIBLE WHEN ALL ARE LOADED
this._loadList = ['layer', 'product', 'modifiers', 'tabs']
// CREATE PREVIEW MODIFIERS
require(['views/modifiers/product'], function (PreviewModifierView) {
that._modifierView = new PreviewModifierView({ model: that.model });
that._modifierView.on("renderComplete", that.onRenderComplete, that);
that._modifierView.render();
});
// CREATE PREVIEW
require(['views/preview/product'], function (PreviewProductView) {
that._productView = new PreviewProductView({ model: that.model });
that._productView.on("renderComplete", that.onRenderComplete, that);
that._productView.render();
});
// CREATE PRODUCT NAME DISPLAY
require(['views/toolbar/productname'], function (ProductNameView) {
that._productNameView = new ProductNameView({ model: that.model });
that._productNameView.render();
});
// CREATE PRODUCT DESCRIPTION DISPLAY
require(['views/toolbar/productdescription'], function (ProductDescView) {
that._productDescriptionView = new ProductDescView({ model: that.model });
that._productDescriptionView.render();
});
// CREATE TOOLBAR
require(['views/toolbar/layer'], function (ToolbarLayerView) {
that._toolbarView = new ToolbarLayerView({ model: that.model });
that._toolbarView.on("renderComplete", that.onRenderComplete, that);
that._toolbarView.render();
});
// CREATE FINISHED BUTTON
require(['views/toolbar/finished'], function (FinishedView) {
that._finishedView = new FinishedView({ model: that.model });
that._finishedView.render();
});
// CREATE TABS
require(['views/tabs/product'], function (TabsView) {
that._tabsView = new TabsView({ model: that.model });
that._tabsView.on("renderComplete", that.onRenderComplete, that);
that._tabsView.render();
});
},
render: function () {
//console.log("editor render!");
//console.log(this.model);
//$('#productName').html(this.model.get);
var pageTemplate = _.template(PageTemplate, this);
$(this.el).html(pageTemplate);
$('#button-editor-help').show(); // GET'S HIDDEN ON THE APPROVAL PAGE
this.renderApp();
}
});
return EditorPage;
});
In the tabs view, hook up a debugger where you call the destroy and create
Replicate the bug and check if you are calling destroy before initialization
May be you are calling close before the dialog is initialised.

knockout paging retaining old page on jquery dialog cancel and open

I have an issue with knockout paging .I am using knockout paging on jquery dialog.The issue is when i navigate from page1 to page2 ,page3 or page4 and close the dialog and open the dialog again i see the page which i closed last but not from first page .Attached the jsfiddle below.Please let me know if you have any questions.
http://jsfiddle.net/bharatgillala/yuvNt/57/
var data = [
{Player:"PAGE1", runs:"34889"},
{Player:"PAGE1", runs:"83366"},
{Player:"PAGE1", runs:"52534"},
{Player:"PAGE2", runs:"02232"},
{Player:"PAGE2", runs:"55899"},
{Player:"PAGE2", runs:"90483"},
{Player:"PAGE3", runs:"02565"},
{Player:"PAGE3", runs:"98500"},
{Player:"PAGE3", runs:"20285"},
{Player:"PAGE4", runs:"57757"},
];
var StaticDataExample1 = function(data){
// stuff I care about
this.items = ko.observableArray(data);
// pager related stuff
------------------------------
this.currentPage = ko.observable(1);
this.perPage = 3;
this.pagedItems = ko.computed(function(){
var pg = this.currentPage(),
start = this.perPage * (pg-1),
end = start + this.perPage;
return this.items().slice(start,end);
}, this);
this.nextPage = function(){
if(this.nextPageEnabled())
this.currentPage(this.currentPage()+1);
};
this.nextPageEnabled = ko.computed(function(){
return this.items().length > this.perPage * this.currentPage();
},this);
this.previousPage = function(){
if(this.previousPageEnabled())
this.currentPage(this.currentPage()-1);
};
this.previousPageEnabled = ko.computed(function(){
return this.currentPage() > 1;
},this);
};
ko.applyBindings(new StaticDataExample1(data),document.getElementById("test"));
$(document).on("click", "[id*=atest]", function ()
{
$("#test" ).dialog(
{
height: 420,
width: 430,
modal: true,
buttons: [
{
text: "Save",
},
{
text: "Cancel",
tabIndex: -1,
click: function () {
$(this).dialog("close");
}
}
],
close: function () { }
});
});
You're almost there actually.
Change your ko.applyBindings to this:
var model = new StaticDataExample1(data);
ko.applyBindings(model, document.getElementById("test"));
Then add an open: function to your $(...).dialog({ ... }) options right after the close: option:
close: function () {
},
open: function () {
model.currentPage(1);
}
Fiddle here: http://jsfiddle.net/yuvNt/63/
And it occurred to me just now; you could even just add the model.currentPage(1); call into your existing close: function if you don't want to add an open: function.
Hope that's useful.

Hidden menu (jquery, css)

Patient: http://demo.imatte.us/fomru/project_people.html
Screen: http://i.stack.imgur.com/GkBST.png
Hidden menu works incorrect. After click on link, menu shows, but after 'mouseover' it disappears. I need to disable this, and hide menu just after click out of menu.
(function($) {
$(function(){
var $judgments = $('.project .jugdments-list .item');
$judgments.each(function(){
limit($(this).find('.title'), 140);
limit($(this).find('.text'), 200);
});
var $filters = $('.filters-list>li');
$filters.each(function(){
var $filter = $(this);
var $filterBody = $filter.find('.filter');
$filter.find('.filter-name').click(function(){
$('.filters-list .filter').not($filterBody).fadeOut();
$filterBody.fadeToggle();
});
});
$(document).click(function(e){
if ( !$(e.target).closest('.filters-list').length || $(e.target).is('.filters-list') ) {
$('.filters-list .filter').fadeOut();
}
});
});
function limit($elem, length) {
var text = $elem.text();
if ( text.length > length ) {
$elem.text(text.slice(0, 140)+'…');
}
}
})(jQuery);
If I got right what do you mean, then this should help you:
remove
.filters .filters-list>li:hover .filter {
display: block;
}
and add this:
$('.filter-name').each(function() {
var that = $(this);
that.hover(
function() {
$('.filters-list .filter').not(that.parent().find('.filter')).fadeOut();
that.parent().find('.filter').fadeIn();
},
function() {}
)
});

Automatically open the lightbox popup upon opening the page

Here's the JS i have:
jQuery(function ($) {
var OSX = {
container: null,
init: function () {
$("input.osx, a.osx").click(function (e) {
e.preventDefault();
$("#osx-modal-content").modal({
overlayId: 'osx-overlay',
containerId: 'osx-container',
closeHTML: null,
minHeight: 80,
opacity: 65,
position: ['0',],
overlayClose: true,
onOpen: OSX.open,
onClose: OSX.close
});
});
},
open: function (d) {
var self = this;
self.container = d.container[0];
d.overlay.fadeIn('slow', function () {
$("#osx-modal-content", self.container).show();
var title = $("#osx-modal-title", self.container);
title.show();
d.container.slideDown('slow', function () {
setTimeout(function () {
var h = $("#osx-modal-data", self.container).height()
+ title.height()
+ 20; // padding
d.container.animate(
{height: h},
200,
function () {
$("div.close", self.container).show();
$("#osx-modal-data", self.container).show();
}
);
}, 300);
});
})
},
close: function (d) {
var self = this; // this = SimpleModal object
d.container.animate(
{top:"-" + (d.container.height() + 20)},
500,
function () {
self.close(); // or $.modal.close();
}
);
}
};
OSX.init();
});
I'm using this lightbox script for survey and the html includes form,
and this code make the lightbox open by clicking on button, all i need is to use the same lightbox and make it automatically open upon opening the page.
Thanks in advance
You can just trigger click() programatically on a button that shows the popup after page loads.
Example:
$(function () {
$('your_button').click();
})

How can I dynamically name buttons in a jquery modal script?

I have the following script that's used to create a modal with buttons. I just have the first lines below:
$.modal = function(options)
{
var settings = $.extend({}, $.modal.defaults, options),
root = getModalDiv(),
// Vars for resizeFunc and moveFunc
winX = 0,
winY = 0,
contentWidth = 0,
contentHeight = 0,
mouseX = 0,
mouseY = 0,
resized, content = '', contentObj;
and then later:
var buttonsFooter = false;
$.each(settings.buttons, function(key, value)
{
// Button zone
if (!buttonsFooter)
{
buttonsFooter = $('<div class="block-footer align-'+settings.buttonsAlign+'"></div>').insertAfter(contentBlockWrapper);
}
else
{
// Spacing
buttonsFooter.append(' ');
}
Here's the way I create the modal:
$.modal({
title: title,
closeButton: true,
content: content,
complete: function () {
applyTemplateSetup();
$($('#main-form')).updateTabs();
},
width: 900,
resizeOnLoad: true,
buttons: {
'Submit' : function () {
formSubmitHandler($('#main-form'));
}
}
});
What I would like to do is to use this script to create my modal with buttons and dynamically assign the button name. However when I tried replacing 'Submit' with the name of a javascript variable it didn't work. Does anyone have any idea how I could do what I need?
The reason replacing 'Submit' with a variable name doesn't work is because the quotes aren't needed when defining an object in that manner (unless the name contains some special characters). var obj = { 'Submit': function() { } } is exactly the same thing as var obj = { Submit: function() { } }.
You'll notice that you're already omitting the quotes like this in the object you're passing to $.modal().
However, while you can't write
var myVariable = 'abc';
var obj = { myVariable: 3 };
... and expect obj.abc to exist (obj.myVariable will exist), you can write
var myVariable = 'abc';
var obj[myVariable] = 3;
... and obj.abc will exist.
Thus, you could solve your problem in the following manner:
var buttons = { };
buttons[variableName] = function () {
formSubmitHandler($('#main-form'));
};
$.modal({
...
buttons: buttons
});
Edit: David Hedlund beat me to answering, and offered a similar answer which involves a little less code modification. He suggests only breaking out the buttons options instead of the entire options var. End Edit
First, break the options out into a variable:
var modalOpts = {
title: title,
closeButton: true,
content: content,
complete: function () {
applyTemplateSetup();
$($('#main-form')).updateTabs();
},
width: 900,
resizeOnLoad: true,
buttons: {
'Submit' : function () {
formSubmitHandler($('#main-form'));
}
}
};
$.modal(modalOpts);
Then break the button in question out of the options, and use square bracket notation to access and write the property:
var dynamicButtonName = 'Submit'; //Or whatever
var modalOpts = {
title: title,
closeButton: true,
content: content,
complete: function () {
applyTemplateSetup();
$($('#main-form')).updateTabs();
},
width: 900,
resizeOnLoad: true,
buttons: {}
};
modalOpts.buttons[dynamicButtonName] = function () {
formSubmitHandler($('#main-form'));
};
$.modal(modalOpts);

Categories

Resources