Backbone: Toggle methods on some event - javascript

I want one button to toggle two methods in backbone but I'm having issues. I'm pretty much new to JS in general.
If you click on a button:
I want to show a hidden div
change the text of the button clicked
Then, if you click the button again (which has the new text and the hidden div is shown)
Change the text
Hide the shown div
The second method of .hide is not being fired? I'm wondering if this is because .hide is not in the DOM initially, because it's being added on the show method. Just a guess and maybe there's a better way to toggle methods on one class?
Here's my JS
'touchstart .share-btn' : 'show',
'touchstart .hide' : 'hide'
'show' : function (e) {
var view = this;
$(e.currentTarget).closest('.tile').find('.share-tools').fadeIn('fast');
$(e.currentTarget).addClass('hide');
if ($(e.currentTarget).hasClass('hide')){
$(e.currentTarget).find('.button-copy').closest('.button-copy').html('close');
}
},
'hide' : function (e) {
var view = this;
if($(e.currentTarget).hasClass('hide')) {
$('.share-tools').fadeOut('fast');
$(e.currentTarget).removeClass('hide');
$(e.currentTarget).find('.button-copy').closest('.button-copy').html('share');
}
},

Maybe reworking your code a bit will help. I've created a working jsfiddle based on what I think you're trying to accomplish.
Here is the relevant view code:
var View = Backbone.View.extend({
...
// Make it clear that these are the same element.
// Ensure they will not both fire by making them exclusive.
events: {
'mousedown .share-btn:not(.hide)' : 'show',
'mousedown .share-btn.hide' : 'hide'
},
'show' : function (e) {
console.log('show');
var $e = $(e.currentTarget);
$e.closest('.tile').find('.share-tools').fadeIn('fast', function () {
$e.addClass('hide');
});
$e.find('.button-copy').closest('.button-copy').html('close');
},
'hide' : function (e) {
console.log('hide');
var $e = $(e.currentTarget);
$e.closest('.tile').find('.share-tools').fadeOut('fast', function () {
$e.removeClass('hide');
});
$e.find('.button-copy').closest('.button-copy').html('share');
}
});
You can find the working jsfiddle here: http://jsfiddle.net/somethingkindawierd/7rfs9/

Try to return false in your event listener to prevent call both methods on first click.

Related

Don't execute the function when div has active class

I am trying to build basic animation of two divs with jQuery .toggle() function.
The main concept is to toggle the visibility of two additional divs with map and contact form.
I made everything working as I wanted but noticed a bug.
Here is the link to the demo on Codepen -- Link
To see the bug just hit 'Location' then 'Get in touch' and again
'Location'.
I think that it could be fixed with simple if else function, but I can't come up with the right solution since I don't know JS that much.
Anybody, help me, please.
Thanks in advance!
How about something like this. Basically just keeping track of whether the form and map are showing, and only doing the animation when necessary.
$(document).ready(function() {
// toggle map visibility
$("#toggle-map").click(function() {
$(".target-map").toggle('left');
});
// toggle contact form visibility
$("#toggle-form").click(function() {
$(".target-form").toggle('left');
});
var showingMap = false
var showingForm = false
function animate() {
var changeInLeft = !showingMap && !showingForm ? "0px" : "-245px"
$(".left-part").stop().animate({ left: changeInLeft }, 100);
}
// hide one on click
$(document).on("click", "#toggle-map", function(event) {
$(".target-form").hide();
event.preventDefault();
if (showingForm) showingForm = !showingForm;
showingMap = !showingMap;
animate();
});
$(document).on("click", "#toggle-form", function(event) {
$(".target-map").hide();
event.preventDefault();
showingForm = !showingForm;
if (showingMap) showingMap = !showingMap;
animate();
});
});

How do I trigger a click event on a disabled button element (using pure vanilla JS)?

I have this event: this.show.onclick = this.sendData.bind(this);
in my bindEvents() function:
bindEvents: function() {
var that = this;
// On click "Show" BTN
this.show.onclick = this.sendData.bind(this);
// On Change inputs
this.$form.change(function(){
that.updateDatesInputs(this);
});
},
That runs this:
sendData: function(e) {
e.preventDefault();
let that = this;
console.log(this.show.disabled);
if (this.show.disabled) {
alert('a disabled button has just been clicked!');
this.showErrorDiv("Please select a new date range.");
} else {
$.ajax({
....
}
});
that.dataDisplayed = true;
}
Clicking on my "show" button-element doesn't activate any click event. All I found googling this is that jQuery can fix it, but I want to use vanilla JS.
How can I trigger an event on a disabled element so that my alert will get executed using only pure JS?
It cannot be done, nor should it for accessibility reasons. Someone who navigates with a keyboard can never get to the button to interact with it.

Restore page content and retain event listeners

How would you "save" a page somewhere (on the client), then restore it, with all its event listeners intact?
I have a sample at http://jsfiddle.net/KellyCline/Fhd55/ that demonstrates how I create a "page", save it and go to a "next" page on a button click, and then restore the first page on another button click, but now the first page's click listeners are gone.
I understand that this is due to the serialization that html() performs, so, obviously, that's what I am doing wrong, but what I'd like is a clue to doing it right.
This is the code:
var history = [];
$(document).ready(function () {
var page1 = $(document.createElement('div'))
.attr({
'id': 'Page 1'
}).append("Page ONE text");
var nextButton = $(document.createElement('button'));
nextButton.append('NEXT');
nextButton.on('click', function () {
CreateNextPage();
});
page1.append(nextButton);
$("#content").append(page1);
});
function CreateNextPage() {
history.push( $("#content").html( ) );
$("#content").html( 'Click Me!');
var page1 = $(document.createElement('div'))
.attr({
'id': 'Page 2'
}).append("Page TWO text");
var nextButton = $(document.createElement('button'));
nextButton.append('NEXT');
nextButton.on('click', function () {
CreateNextPage();
});
var prevButton = $(document.createElement('button'));
prevButton.append('PREVIOUS');
prevButton.on('click', function () {
GoBack();
});
page1.append(nextButton);
page1.append(prevButton);
$("#content").append(page1);
}
function GoBack() {
$("#content").html( history[history.length - 1]);
history.pop( );
}
and this is the html:
Click Me!
I think this is best solved via event delegation. Basically, you encapsulate content that you know you are going to refresh within a wrapper element and bind your listeners to that. The jQuery .on() method allows you to pass a selector string as a filter and will only trigger the handler if the originating element matches. Give your buttons a class or something to get a handle on them and then bind them up above. This article has some examples.
$( '#content' ).on( 'click', 'button.next', createNextPage )
for instance.

Invoking jQuery toggle method inside object literal

I'm struggling to get the below piece of code working. The problem is that when I wrap the two functions in the editItems property inside the parenthesis (), the code behaves strangely and assigns display: none inline css property to the edit button.
If I don't wrap the two functions inside the parenthesis, I get a javascript syntax error function statement requires a name.
var shoppingList = {
// Some code ...
'init' : function() {
// Capture toggle event on Edit Items button
(shoppingList.$editButton).toggle(shoppingList.editItems);
},
'editItems' : function() {
(function() {
$(this).attr('value', 'Finish editing');
(shoppingList.$ingrLinks).unbind('click', shoppingList.ingredients) // disable highlighting items
.removeAttr('href');
$('.editme').editable("enable");
$('.editme').editable('http://localhost:8000/edit-ingredient/', {
indicator : 'Saving...',
tooltip : 'Click to edit...',
submit : 'OK',
cancel : 'Cancel'
});
}), (function() {
$(this).attr('value', 'Edit item');
(shoppingList.$ingrLinks).attr('href', '#');
$('.editme').editable("disable");
(shoppingList.$ingrLinks).bind('click', shoppingList.ingredients) // re-enable highlighting items
})
}
}
$(document).ready(shoppingList.init);
However, if I invoke the toggle event "directly" like this, it works:
var shoppingList = {
// Some code ...
'init' : function() {
// Toggle event on Edit Items button
(shoppingList.$editButton).toggle(
function() {
$(this).attr('value', 'Finish editing');
(shoppingList.$ingrLinks).unbind('click', shoppingList.ingredients) // disable highlighting items
.removeAttr('href');
$('.editme').editable("enable");
$('.editme').editable('http://localhost:8000/edit-ingredient/', {
indicator : 'Saving...',
tooltip : 'Click to edit...',
submit : 'OK',
cancel : 'Cancel'
});
}, function() {
$(this).attr('value', 'Edit item');
(shoppingList.$ingrLinks).attr('href', '#');
$('.editme').editable("disable");
(shoppingList.$ingrLinks).bind('click', shoppingList.ingredients) // re-enable highlighting items
});
}
};
$(document).ready(shoppingList.init);
Is there a way I could store the toggle event inside the editItems object literal and still have it working as expected?
editItems function looks really odd. I guess you just need to define 2 functions: startEdit and endEdit. And bind them on even and odd clicks using toggle.
var shoppingList = {
// Some code ...
init : function() {
// Bind on edit button click
this.$editButton.toggle(this.startEdit, this.endEdit);
},
startEdit : function() {
$(this).attr('value', 'Finish editing');
shoppingList.$ingrLinks.unbind('click', shoppingList.ingredients) // disable highlighting items
.removeAttr('href');
$('.editme').editable("enable");
$('.editme').editable('http://localhost:8000/edit-ingredient/', {
indicator : 'Saving...',
tooltip : 'Click to edit...',
submit : 'OK',
cancel : 'Cancel'
}),
endEdit: function() {
$(this).attr('value', 'Edit item');
(shoppingList.$ingrLinks).attr('href', '#');
$('.editme').editable("disable");
(shoppingList.$ingrLinks).bind('click', shoppingList.ingredients) // re-enable highlighting items
})
};
$($.proxy(shoppingList, 'init'));

jQuery jeditable trigger on click

I need to use inline edit in my application. For this purpose I am using the Jeditable plugin for jQuery.
I want to trigger editable mode for an element only when I click on it. This is my code which doesn't work:
var tet = "";
$(".edit-client").click(function(event) {
tet = "#"+event.target.id;
//alert(tet);
});
$(tet).editable("/bestcredit/admin.php/request/editClient", {
submitdata : function (value,settings){
return {"Client[id]":'.$model->client->id.' };
},
//indicator : "Saving...",
//tooltip : "Click to edit...",
submit : "OK",
name : "Client["+tet.substr("1")+"]"
//alert(1);
});
How can I add this functionality?
There are many ways to do it and it all depends on your HTML, but for example if you have following HTML:
<div class="edit" id="unique_id">Editable text</div>
Edit me!!
Then you can use following JavaScript:
/* Bind Jeditable instances to "edit" event. */
$(".edit").editable("http://www.example.com/save.php", {
event : "edit"
});
/* Find and trigger "edit" event on correct Jeditable instance. */
$(".edit_trigger").bind("click", function() {
$(this).prev().trigger("edit");
});

Categories

Resources