Strange behavior with on/off click and jQuery? - javascript

so I'm trying to use link clicks to add buttons to a div, then be able to click those buttons to remove them and re-enable the original links to be clicked again so you can add and remove an infinite number of times. I have it mostly working, but after trying to re-enable the click function I'm getting strange behavior.
1) You need to click the link twice to re-append the button and
2) Sometimes I'm getting multiple instances of the appended button in the div now.
Here is my code:
var selections = ' ';
function add_Button() {
jQuery(".form-unselected").click(function (e) {
jQuery(this).removeClass('form-unselected').addClass('selected').off('click');
var title = jQuery(this).attr("title");
var id = jQuery(this).attr("href");
selections += title + ', ';
var button_content = jQuery('<button class="content-button">').html(title).attr("title", title).attr("id",id);
event.preventDefault();
$( "#selected-items" ).append(button_content);
console.log(selections);
});
}
add_Button();
jQuery(document).on('click','.content-button', function(e){
var removed_content = jQuery(this).attr("title") + ', ';
selections = selections.replace(removed_content,'');
var href = jQuery(this).attr("id");
jQuery(".add-to-form[href='"+ href +"']").addClass('form-unselected').removeClass('selected').on('click', add_Button );
jQuery(this).remove();
console.log(selections);
});
The selections variable is a comma separated list of the values for another purpose, but I'm getting the duplicates there as well. Thanks in advance!

You should not dynamically add and remove the click handler. Initially add the click handlers to all the buttons. Then when clicked you can query the status and decide.
Also there was an unknown reference event that did not match the argument e.
And, repeating jQuery(this) is expensive. Store this value in a local variable and refer to it instead. The code below demonstrates all the changes.
var selections = ' ';
jQuery(".form-unselected").click(function (e) {
var $this = jQuery(this);
if ($this.hasClass("selected")) {
return;
}
$this.removeClass('form-unselected').addClass('selected');
var title = $this.attr("title");
var id = $this.attr("href");
selections += title + ', ';
var button_content = jQuery('<button class="content-button">').html(title).attr("title", title).attr("id",id);
e.preventDefault();
$("#selected-items").append(button_content);
console.log(selections);
});
jQuery(document).on('click','.content-button', function(e) {
var $this = jQuery(this);
var removed_content = $this.attr("title") + ', ';
selections = selections.replace(removed_content,'');
var href = $this.attr("id");
jQuery(".add-to-form[href='"+ href +"']").addClass('form-unselected').removeClass('selected');
$this.remove();
console.log(selections);
});

Related

Clicking Container Containing Checkbox - JQuery

I have a dropdown menu on a site that needs the label, checkbox, and container all clickable to activate the checkbox (and update the label of the element.
I have used e.stopPropogation, e.stopImmediatePropagation, and e.preventDefault (and usually preventDefault and stopPropagation together.)
My current code is below. It works on desktop (and responsive desktop in Chrome) just fine; but NOT on iOS. Any thoughts?
// Get the filter label.
var label = $('#edit-f-wrapper .edit-areas-link').data('filter-label');
// Element used to hold the label.
var title = $('#edit-f-wrapper .edit-areas-link label');
// Get a list with all checkboxes.
var checkboxes = $('#edit-f-wrapper input:checkbox');
// Click triggers
var clickTrigger = $('.form-type-bef-checkbox');
// Determine click action to take depending on browser/device
var action = ('ontouchend' in window) ? 'touchend' : 'click';
var checkBoxID = 'input[id^="edit-f-rc-core-cat-evrn-svgeographic"';
// Act on checkbox click - check if action is set, if not, set it to default click
clickTrigger.one(action, function (e) {
e.stopImmediatePropagation();
// Get child of clicked element
var checkboxChild = $(this).children("input[type=checkbox]").eq(0);
// Check it if the checkbox itself wasn't clicked
checkboxChild.prop('checked', !checkboxChild.prop('checked')).change();
}).on(action, checkBoxID, function(e) {
e.stopImmediatePropagation();
e.preventDefault();
// Check it if the checkbox itself wasn't clicked
$(this).prop('checked', !$(this).prop('checked')).change();
}).on(action, "label", function(e) {
e.stopImmediatePropagation();
e.preventDefault();
var checkboxChild = $(this).parent().children("input[type=checkbox]").eq(0);
// Check it if the checkbox itself wasn't clicked
checkboxChild.prop('checked', !checkboxChild.prop('checked')).change();
});
// When we have a change of state...
$(checkBoxID).on('change', function() {
console.log("Changed!");
// Update the title to reflect how many items have been checked.
var items = [];
checkboxes.each(function () {
var checkbox = $(this);
if (checkbox.prop('checked')) {
items.push(checkbox.next('label').html());
}
})
// Update the label data.
if (!items.length) {
title.html(label);
}
else if (items.length === 1) {
title.html(label + ': ' + items[0]);
}
else {
title.html(label + ': ' + items.length + ' selected');
}
});
And, the HTML markup:
<div class="form-item form-type-bef-checkbox form-item-edit-f-rc-core-
cat-evrn-svgeographicarch-cape">
<input type="checkbox" name="f[]" id="edit-f-rc-core-cat-evrn-svgeographicarch-cape" value="rc_core_cat_evrn_svgeographic:Arch Cape">
<label class="option" for="edit-f-rc-core-cat-evrn-svgeographicarch-cape">Arch Cape</label>
</div>

Insert value into last textarea where cursor was

Basically this question is pretty similar to:
Insert value into TEXTAREA where cursor was
JSFiddle: http://jsfiddle.net/rQXrJ/1/
The thing is, I can't get it to work for multiple textareas.
I've tried multiple combinations of things but still no success:
1)
$("#foo-1").click(function () {
$textBox = $(this);
$textBox.focusout(saveSelection);
});
$("#foo-2").click(function () {
$textBox = $(this);
$textBox.focusout(saveSelection);
});
2)
function changeTextBox(newID) {
var fullID = "#" + newID;
$textBox = $(newID);
$textBox.focusout(saveSelection);
}
$(".txt").click(function () {
var id = $(this).attr("id");
changeTextBox(id);
});
Here's my jsFiddle: https://jsfiddle.net/yneco5ft/
You need to give the same class to your textareas and set $textBox to that class.
Example : http://jsfiddle.net/rQXrJ/283/

Create element from input type='text' JavaScript

I want to create DOM elements with info taken from input type text. To be more specific:
I want the user to be able to write a location and after he presses "Go!" button an element to be created with the text inserted and I also want to have a delete icon which when pressed to delete that insert.
I created a function in which I took the input value but I cannot create the 'del' button
If I create another <img> inside using the same method, when I create the second entry it will put another <img> to the previous entry
search_btn.click(function() {
var place_reg = /^[a-z]+\d*[a-z]*(\s[a-z]+\d*[a-z]*)*?$/i;
var search_value = search_box.val();
var final_result = search_value.trim();
if (place_reg.test(final_result)) {
createDest(final_result);
} else {
alert('Please insert a valid destination');
}
document.getElementById('search_box').value = "";
});
function toTitleCase(str) {
return str.replace(/\w\S*/g, function(txt){ return txt.charAt(0).toUpperCase() +
txt.substr(1).toLowerCase();});
}
function createDest(value) {
var destination_i_search = document.createElement("div");
destination_i_search.innerHTML = toTitleCase(value);
destination_i_search.setAttribute("class" , "place");
$("#dest").append(destination_i_search);
}
It is very difficult to understand what you wish it to do, without a full example, but from comments you may want something like this:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/s6hn0n18/6/
I have converted it to use jQuery where appropriate.
var search_btn = $('#search');
var search_box = $('#searchbox');
search_btn.click(function () {
var place_reg = /^[a-z]+\d*[a-z]*(\s[a-z]+\d*[a-z]*)*?$/i;
var search_value = search_box.val() || "";
var final_result = search_value.trim();
if (place_reg.test(final_result)) {
createDest(final_result);
} else {
alert('Please insert a valid destination');
}
search_box.val("");
});
function toTitleCase(str) {
return str.replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
}
function createDest(value) {
// use a div container
var div = $("<div/>");
div.html(toTitleCase(value));
div.addClass("place");
// If you want to replace the previous entry
$("#dest").append(div);
var del = $('<input class="delete" type="button" value="X"/>');
$("#dest").append(del);
}
// This is a delegated event handler, attached to a non-changing ancestor
$(document).on('click', '.delete', function(){
// Remove the previous div (if of class place)
$(this).prev('.place').remove();
// Remove the delete button too
$(this).remove();
});
The key is to add a delegated event handler for the delete buttons. These work by listening for the specified event (click in this case) bubbling up to a non-changing ancestor. It the applies the jQuery selector. It the calls the function for any matching element that caused the event. The default ancestor is document if nothing closer to the changing content is available. In this case you could use #dest
e.g.
$('#dest').on('click', '.delete', function(){

JavaScript/jQuery: Select on change event not firing

I have this problem trying to getting one single function attach multiple individual functions on "Change" event of a dropdown list using for ... in loop. The $('select') object top has no method 'on' is the Type error detected by Chrome Debugger.
Here is my code: (I don't have much JavaScript / jQuery knowledge so please be bear up with my coding)
function AKaizerDropdown(HiddenFeild) { //#id of hidden field passed as parameter
var select = $('select'); // select object assigned to variable
var selectcount = 0;
var Selecthold=new Array();
for (select in this) {
select.on('change', function() {
var SelectedIndex = this.attr('selectedIndex');
selecthold[selectcount] = [select.attr('id'), selectedindex];
//Select ID and Selected index assigned as an array into Selecthold Array element
});
selectcount +=1;
}
var item= new array();
//Elements in selecthold array printed onto hidden field
for (item in selecthold) {
$(HiddenFeild).val += item[0] + item[1]; //Assigns values to element Hiddenfield in DOM
}
}
Edited Code :
$.fn.AKaizerDropdown = function (HiddenFeild) {
var select_ = $(this).find('select');
var selectcount = 0;
var Selecthold=new Array();
select_.each(function () {
$(this).on('change', function () { //everything runs fine except dropdownlist doesn't enter into this event when an item is chosen
var SelectedIndex = this.selectedIndex;
Selecthold[selectcount] = [this.id, Selectedindex];
});
});
var button_ = $(this).find('input')
button_.on('click', function () {
for (item in Selecthold) {
$(HiddenFeild).val += item[0] + item[1]+','; //Assigns values to element Hiddenfeild in DOM seperated by ","
}
});
}
Somewhat fixed code still doesn't work
Here is the part where i attach it to popover Bootstrap(twitter 2.3.2) .
//think the problem lies here where the pop up seems to re-render the same same html found in ($#KaizerDragon") where all JavaScript is probably discarded?
$("#ContentPlaceHolder1_ADragonTreeviewt41").popover({
html: true, container: 'body',
trigger: 'click',
content: function () {
$(function () {
$("#KaizerDragon").AKaizerDropdown();
});
return $("#KaizerDragon").html();
}
});
So my question is how can I correct the above code to get the intended output(as in comments within code) ?
You are declaring
var select = $('select'); // select object assigned to variable
But then overriding the value in your for loop
for (select in this) ...
That is to say, the select inside the loop isn't the same as you declared above.
try something like this
select.each(function(){
$(this).on('change', function() {
var SelectedIndex = this.selectedIndex;
Selecthold[selectcount] = [this.id, SelectedIndex];
//Select ID and Selected index assigned as an array into Selecthold Array element
});
})

How to change a single value of checkbox inside a localStorage?

I'm trying to change a value inside localstorage. This item is the status of a checkbox. I want, everytime that a checkbox is checked to set the value to true or false of that checkbox. I tried many ways until I realized that there is no way you can change a value without using JSON.
To add the value I use:
localStorage.setItem("status-" + i, $status.is(":checked"));
and to delete I use:
var parentId = $this.parent().attr('id');
localStorage.removeItem("'" + parentId + "'");
Now to change the value I tried:
$itemList.delegate("#status-" + i, 'click', function(e) {
var $this = $(this);
var parentId = this.parent().attr('id');
if ($this.is(":checked")) {
localStorage.setItem("'" + parentId + "'".val("fdgsdagf"));
// Note that alert here works.
}
});
This is how my local storage looks like:
I hope someone could help me. I've been working on it for few days...
Here is a fiddle for it: http://jsfiddle.net/CC5Vw/7/
Thanks alot
look at this: http://jsfiddle.net/Rh4Au/6/ works well..
changes http://jsfiddle.net/CC5Vw/7/ to http://jsfiddle.net/Rh4Au/6/
line 30:
+ "<div class='checkbox'><input type='checkbox' class='test' id='status-" + i + "'></div>"
i chaged to j because i is the length and j is the iterator.
insertion after line 34:
var tempasd = orderList[j].split("-")[1];
if(localStorage.getItem("status-"+tempasd) == "true") {
$("#status-"+j).get(0).checked = true
}
else {
$("#status-"+j).get(0).checked = false
}
}
The code loads the data from localStorage and check in the checked checkboxes.
The tempasd is a temporary variable store the current ID num of the checkbox (because they not always come ascending.
changes from line 99 to 117:
// ON STATUS CLICK
console.log('i=',i,' j=',j, 'k=',k);
$itemList.delegate("#status-" + i, 'click', function(e) { // ON CLICK
var $this = $(this);
var parentId = $this.attr('id');
if ($this.is(":checked")) {
console.log('set ', parentId, 'to foo');
localStorage.setItem(parentId, 'foo');
// localStorage.setItem("'" + parentId + "'".val("fdgsdagf"));
// localStorage.setItem($this.parent().attr('checked', true));
// window.location = "http://mail.aol.com"
}
});
to
// ON STATUS CLICK
console.log('i=',i,' j=',j, 'k=',k);
var tempxx;
for(tempxx = 0;tempxx < j; tempxx++) {
$itemList.delegate("#status-" + tempxx, 'click', function(e) { // ON CLICK
var $this = $(this);
var parentId = $this.parent().parent().attr('id').split("-")[1];
console.log('set ', parentId, 'to foo');
localStorage.setItem("status-"+parentId, $this.is(":checked"));
// localStorage.setItem("'" + parentId + "'".val("fdgsdagf"));
// localStorage.setItem($this.parent().attr('checked', true));
// window.location = "http://mail.aol.com"
});
}
i need the loop because it needs to delegate an event to each checkbox, and also the event must set the localStorage to false when it gets unchecked.
btw the .parent().parent() is unnecesarry now because i fixed at line 30.

Categories