I am trying to remove an object and store it (in case a user wants to retrieve it later). I have tried storing the object in a variable like it says in the thread below:
How to I undo .detach()?
But the detach() does not remove the element from the DOM or store it. I am also not getting any error messages. Here is the code I am using to detach the element:
function MMtoggle(IDnum) {
var rowID = "row" + IDnum;
var jRow = '#' + rowID;
thisMMbtn = $(jRow).find(".addMMbtn");
var light = false;
var that = this;
if (light == false) {
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var cellStr = '<div class = "mmCell prep"></div>';
$(cellStr).appendTo(thisTxt);
$(this).unbind("click");
light = true;
}
);
}
else {
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
thisMM = thisRow.find(".mmCell");
SC[rowID].rcbin = thisMM.detach(); //here is where I detach the div and store it in an object
$(this).unbind("click");
light = false;
}
);
}
}
MMtoggle(g.num);
A fiddle of the problem is here: http://jsfiddle.net/pScJc/
(the button that detaches is the '+' button on the right. It is supposed to add a div and then detach it when clicked again.)
Looking at your code I don't think so you need detach for what you are trying to achieve.
Instead try this code.
thisMMbtn.bind("click",
function() {
var thisRow = $(this).closest(".txtContentRow");
var thisTxt = thisRow.find(".txtContent");
var $mmCell = thisTxt.find('.mmCell');
if($mmCell.length == 0){
$mmCell = $('<div class = "mmCell prep"></div>')
.appendTo(thisTxt).hide();
}
$mmCell.toggle();
//$(this).unbind("click");
}
);
Demo
Related
I have tried searching for what I am trying to accomplish, however I have not found what I am looking for.
I am looking to create a Next and Previous button inside the content of the Spry Accordion provided with Dreamweaver CS6. I have searched the SpryAccordion.js and found this code below:
Spry.Widget.Accordion.prototype.openNextPanel = function()
{
return this.openPanel(this.getCurrentPanelIndex() + 1);
};
Spry.Widget.Accordion.prototype.openPreviousPanel = function()
{
return this.openPanel(this.getCurrentPanelIndex() - 1);
};
So I attempted to do this with "#acc-step-1-next" being my "Next" button in Panel 1.
<script>
$(document).ready(function(){
$("#acc-step-1-next").click(function(){
Spry.Widget.Accordion.prototype.openNextPanel = function(){
return ('#Accordian1').openPanel(this.getCurrentPanelIndex() + 1);
};
});
});
</script>
I was wondering if doing it this way might make it easy! How would I go about applying this? Would this work or not?
Also, with the "Next" button, could I just make it ".acc-step-next" and use it universally, instead of individually assigning new ID's?
EDIT:
Sorry, yes I read your answer incorrectly. I have tried searching for the init property, however have had no success.
This is what starts in the Accordion JS file:
(function() { // BeginSpryComponent
if (typeof Spry == "undefined") window.Spry = {}; if (!Spry.Widget) Spry.Widget = {};
Spry.Widget.Accordion = function(element, opts)
{
this.element = this.getElement(element);
this.defaultPanel = 0;
this.hoverClass = "AccordionPanelTabHover";
this.openClass = "AccordionPanelOpen";
this.closedClass = "AccordionPanelClosed";
this.focusedClass = "AccordionFocused";
this.enableAnimation = true;
this.enableKeyboardNavigation = true;
this.currentPanel = null;
this.animator = null;
this.hasFocus = null;
this.previousPanelKeyCode = Spry.Widget.Accordion.KEY_UP;
this.nextPanelKeyCode = Spry.Widget.Accordion.KEY_DOWN;
this.useFixedPanelHeights = false;
this.fixedPanelHeight = 0;
Spry.Widget.Accordion.setOptions(this, opts, true);
if (this.element)
this.attachBehaviors();
};
Which I added this after, but still no luck:
var acc_next = document.getElementById("acc-step-next");
var acc_prev = document.getElementById("acc-step-prev");
$("acc_next").click(function(){
accordion.openNextPanel();
});
$("acc_prev").click(function() {
accordion.openPreviousPanel();
});
I have never worked with Spry.Widget.Accordion, but I would try something like the following.
Search for the code, where your accordion is initialized, it should look something like that:
var accordion = new Spry.Widget.Accordion("Accordian1",{});
And add this just below:
$(".acc-step-next").click(function(){
accordion.openNextPanel();
});
Together it could look something like that:
<script type="text/javascript">
$(document).ready(function(){
var accordion = new Spry.Widget.Accordion("Accordian1",{});
// Add a click handler to all buttons with the class 'acc-step-next' (yes you can do that)
$(".acc-step-next").click(function(){
// when the button is clicked, call the openNextPanel method of the accordion instance we saved above
accordion.openNextPanel();
});
});
</script>
So I am working on this but of jQuery that gets the element id through a click event. This then triggers a function that acts like the deprecated .toggle()- it slides an element down on the fist click and slides that element up on the second click. However, there is a bug that causes the element to slide up and down the amount of times that it has been clicked on. For instance, if this is the second time I use the .clickToggle function, the element (table) slides up and down twice before settling, and so on. I suspect it has something to do with the event object, e, tracking the number of clicks-- i.e. I probably shouldn't set id = e.target.id-- but I'm not sure how to fix while still getting the relevant element id that I need.
Here is the relevant clickToggle plug in (courtesy of an answer here on stackoverflow).
(function($) {
$.fn.clickToggle = function(func1, func2) {
var funcs = [func1, func2];
this.data('toggleclicked', 0);
this.click(function() {
var data = $(this).data();
var tc = data.toggleclicked;
$.proxy(funcs[tc], this)();
data.toggleclicked = (tc + 1) % 2;
});
return this;
};
}(jQuery));
Here is the buggy code that fits the above description.
$(document).click(function(e) {
//get the mouse info, and parse out the relevant generated div num
var id = e.target.id;
var strId = id.match(/\d$/);
//clickToggle the individual table
$('#showTable' + strId).clickToggle(function () {
$('#table' + strId).slideDown();
$('#table' + strId).load('files.php');
},
function () {
$('#table' + strId).slideUp();
});
});//close mousemove function
Any help would be much appreciated. Thanks.
The problem is that you're registering a new click handler for the element each time you invoke clickToggle:
this.click(function() {...
On each subsequent click, you add another handler, as well as invoking all previous handlers. Bleagh.
Better to be straightforward: (DEMO)
var showTable = function($table) {
$table.slideDown();
$table.load('files.php');
$table.removeClass('hidden');
};
var hideTable = function($table) {
$table.slideUp();
$table.addClass('hidden');
};
$(document).click(function (e) {
//get the mouse info, and parse out the relevant generated div num
var id = e.target.id;
var strId = id.match(/\d$/)[0];
var $table = $('#table' + strId);
if ($table.hasClass('hidden')) {
showTable($table);
} else {
hideTable($table);
}
});
I have a div that I'm appending to another div when a button is clicked. I'm also calling a bunch of functions on the div that gets created.
HTML
<a onClick="drawRect();">Rect</a>
JS
function drawRect(){
var elemRect = document.createElement('div');
elemRect.className = 'elem elemRect';
elemRect.style.position = "absolute";
elemRect.style.background = "#ecf0f1";
elemRect.style.width = "100%";
elemRect.style.height = "100%";
elemRect.style.opacity = "100";
renderUIObject(elemRect);
$('.elemContainer').draggableParent();
$('.elemContainer').resizableParent();
makeDeselectable();
handleDblClick();
}
var createDefaultElement = function() {
..
..
};
var handleDblClick = function() {
..
..
};
var renderUIObject = function(object) {
..
..
};
var makeDeselectable = function() {
..
..
};
I could clone the element when the browser detects a keydown event
$(window).keydown(function(e) {
if (e.keyCode == 77) {
$('.ui-selected').clone();
return false;
}
});
then append it to #canvas. But the problem is, none of the functions I mentioned above get called with this method.
How can I copy/paste an element (by pressing CMD+C then CMD+V) and call those above functions on the cloned element?
The jQuery.clone method returns the cloned node. So you could adjust your code to do something like this:
var myNodes = $('.ui-selected').clone();
myNodes.each(function () {
createDefaultElement(this);
appendResizeHandles(this);
appendOutline(this);
});
function getH4() {
var xyz = document.getElementsByClassName('bucket_left');
for(var i=0;i<xyz.length;i++){
var x=document.getElementsByTagName("h4")[i].innerHTML;
var current_bucket = xyz[i];
var y=current_bucket.firstChild.href;
var newdiv = document.createElement('div');
newdiv.innerHTML = ""+x+"";
newdiv.className = "hover_title_h4";
current_bucket.appendChild(newdiv);
}
}
window.onscroll=getH4;
In above code i want to append new div in set of divs having class bucket_left and this divs generated from infinite scrolling. above code is working fine but on scroll it appends so many divs.
so how do i append only once ?
Add the following line at the end of your function:
function getH4() {
// ...
window.onscroll = null;
}
create a global boolean variable and set it to false. again set it to true in the window scroll event and chk the variable is false using a if block. put your code inside that if block.
var isScrolled = false;
function getH4() {
if(!isScrolled){
//your code
}
isScrolled = true
}
You only have to set the onscroll property to none as following at the end of you JavaScript function:
window.onscroll = null;
Now when the script executes for the first time, it will perform its function and the above line will set the onscroll to null and thus will not invoke any event on scroll of your mouse and so your function wont be invoked again and again on the event except for the first time.
Or you could handle it logically by setting a public var say var check = 0 and then set the variable to 1 when entered for the first time. So you need to check the value of check and based on that execute the function
var check = 1;
function getH4() {
if(check==1)
{
var xyz = document.getElementsByClassName('bucket_left');
for(var i=0;i<xyz.length;i++){
var x=document.getElementsByTagName("h4")[i].innerHTML;
var current_bucket = xyz[i];
var y=current_bucket.firstChild.href;
var newdiv = document.createElement('div');
newdiv.innerHTML = ""+x+"";
newdiv.className = "hover_title_h4";
current_bucket.appendChild(newdiv);
}
check=0;
}
}
you can try this:
when scrolling,the check equal false, and the append event will happen just once;
when the scroll end(mouseup or mouseout), the check equal true, you can append again.
var check = true;
function getH4(event) {
event.target.onmouseup = function() {
check = true;
}
event.target.onmouseout = function() {
check = true;
}
if (check) {
var xyz = document.getElementsByClassName('bucket_left');
for(var i=0;i<xyz.length;i++){
var x=document.getElementsByTagName("h4")[i].innerHTML;
var current_bucket = xyz[i];
var y=current_bucket.firstChild.href;
var newdiv = document.createElement('div');
newdiv.innerHTML = ""+x+"";
newdiv.className = "hover_title_h4";
current_bucket.appendChild(newdiv);
}
check = false;
}
window.onscroll=getH4
I am trying to fill an array with strings, the elements that will be added are the HTML of the clicked <\li>, im probably filling it correctly.
My problem is when the user clicks on the checked link again, i want to remove this item from the array
Here is a code sample:
$(document).ready(function(){
var chosen = [];
var chosenCounter = 0;
find("ul").find("li").click(function(){
var checkBox = $(this).find("img").first();
var checkBoxSrc = checkBox.attr("src");
if(checkBoxSrc == "images/unchecked.png"){
checkBoxSrc = "images/checked.png";
checkBox.attr("src",checkBoxSrc);
checkBox = "";
checkBoxSrc = "";
var temp = this.outerHTML;
chosen[chosenCounter] = temp;
chosenCounter ++;
}
if(checkBoxSrc == "images/checked.png"){
checkBoxSrc = "images/unchecked.png";
checkBox.attr("src",checkBoxSrc);
checkBox = "";
checkBoxSrc = "";
for (var j =0; j<=chosen.length; j++){
var tempRemove = this.outerHTML;
chosen.splice( chosen.indexOf( tempRemove ), 1 );
tempRemove = '';
}
}
});
});
I have been trying all functions and ways i found on internet .. but the results doesn't works well, i would be very thankful for a correction and explanation.
Thanks all in advance.
I've gone through an rewritten the code to work much better. There were a number of issues but here is the fixed version that I tested.
Your original code had an if statement and then another if statement. You needed an if and then an else if.
Notice when finding the child element I just use $('img', this) instead of the find operator and first().
Use ID instead of HTML
For debugging there is a console.log statement in there. Remove this so it works in IE.
To add an element to an array use push
No need to loop over splice to remove the item. Just call splice once.
$(document).ready(function () {
var chosenIDs = [];
$("ul li").click(function () {
var checkBox = $('img', this);
var checkBoxSrc = checkBox.attr("src");
var id = $(this).attr('data-id');
console.log(id + ' ' + chosenIDs.length + ' ' + checkBoxSrc);
if (checkBoxSrc == "images/unchecked.png") {
checkBoxSrc = "images/checked.png";
checkBox.attr("src", checkBoxSrc);
chosenIDs.push(id);
}
else if (checkBoxSrc == "images/checked.png") {
checkBoxSrc = "images/unchecked.png";
checkBox.attr("src", checkBoxSrc);
chosenIDs.splice(chosenIDs.indexOf(id), 1);
}
});
});