IPB

Welcome Guest ( Log In | Register )



Tags
This content has not been tagged yet
 
Reply to this topicStart new topic

Javascript: Move Blocks Of Div's Around And Change Child Attributes

, Help with function


sonesay
no avatar
|||[ n00b King ]|||
*********
Group: [HOSTED]
Posts: 920
Joined: 20-June 07
From: Auckland
Member No.: 45,102
myCENT:50.02



Post #1 post Feb 28 2009, 12:37 AM
OK I have attached an image of the structure of the HTML. I need help on figuring out a good method to be able to:
1. move div sections up or down the order.
2. change div sections child attributes depending on their position in the order
3. update order to database with Ajax (State of order has to be save to MySQL).

There is only one function 'moveItem(direction, id, this)' that is used to move items (div_method_container_n*) around. These div_method_container_b* sit inside a parent div div_method_container_all so it makes grouping them a lot easier.

I am using images for the buttons and have use an onclick="moveItem(direction, id, this)" attribute assigned to them. the current state I have it up to so far is I am able to move items around but I can only get access to the current div that I am working on so I can only change the attributes there. i.e modify the moveItem() only for the div with the button being clicked on.

I cannot figure out a way to transverse to the next div and modify its moveItem() according so its up to date and will function correctly when clicked on. I am after suggests on ways to do this or even a complete rework on the solution so I can get a better functioning application.

CODE
function moveItem(direction, id, obj)
{
        var parent = obj.parentNode;
        var grandParent = parent.parentNode;

        var ipHidden;
        var hNodes = parent.childNodes;
            for(var i=0;i<hNodes.length; i++)
            {
                if(hNodes[i].tagName == 'INPUT')
                {
                    ipHidden = hNodes[i];
                    break;
                }
            }    
        
        // move items around
        if(direction == 'down')
        {
            jQuery(grandParent).insertAfter(jQuery(grandParent).next());
            jQuery(obj).attr("onClick","moveItem('down', "+(id+1)+", this)");
            jQuery(ipHidden).attr("Value",id+1);
        }
        else if(direction == 'up')
        {
            jQuery(grandParent).insertBefore(jQuery(grandParent).prev());
            jQuery(obj).attr("onClick","moveItem('up', "+(id-1)+", this)");
            jQuery(ipHidden).attr("Value",id-1);

        }
}


I had to use a combination jQuery and regular javascript because somethings seem easier to do with one or the other. like I said any suggestions for improvement appreciated thank you.
Attached File(s)
Attached File  Picture_9.png ( 126.84K ) Number of downloads: 7
 
Go to the top of the page
+Quote Post
truefusion
no avatar
Do you want to know?
****************
Group: [MODERATOR]
Posts: 2,672
Joined: 22-June 05
From: 127.0.0.1 — no place like it.
Member No.: 8,528
myCENT:33.50



Post #2 post Feb 28 2009, 07:14 AM
Uh, here's my version of it, at least the view. It imitates a selected item and moves only the selected item up or down depending on which button is pressed. Since its selection is kept track by IDs, i used hidden INPUT elements to keep track of their number. If you notice, the INPUT have a name as "item[]", so when you send the form, the server side script would (or should) receive an array in the order that the items are ordered in. I have not tested this script any further than what i have provided, so you'll have to see for yourself whether it can be implemented or if it is useful for you. I believe it performs most of the work you are trying to do concerning the view of the form from what i can understand in your post.

CODE
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>untitled</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8" />
<script src="/path/to/jquery.js"></script>
<script>
var children;
var index;

$(document).ready(
function (){
children = $("#container").children("div");

$("#container div").click(function () {
$("div#selected").removeAttr("id");
$(this).attr("id", "selected");
index = $("#container div").index(this);
});
}
);

function updateChildrenList(){
children = $("#container").children("div");
index = $("#container div").index($("#container div#selected"));
}

function moveItemUp(){
if (index > 0){
$("#container div#selected").insertBefore($(children[index-1]));
}
updateChildrenList();
}

function moveItemDown(){
if (index < (children.length-1)){
$("#container div#selected").insertAfter($(children[index+1]));
}
updateChildrenList();
}
</script>
<style>
#container {
padding: 3px;
border: 1px solid black;
}

#container div {
margin: 3px;
padding: 5px;
background-color: #EEE;
border: 1px solid #CCC;
}

#container div#selected {
border-color: #999;
}

h3 {
margin: 0;
}
</style>
</head>
<body>

<div id="container">
<button onclick="moveItemUp();">Up</button>
<button onclick="moveItemDown();">Down</button>
<!-- -->
<div>
<input type="hidden" name="item[]" value="1"/>
<h3>One</h3>
</div>
<!-- -->
<div>
<input type="hidden" name="item[]" value="2"/>
<h3>Two</h3>
</div>
<!-- -->
<div>
<input type="hidden" name="item[]" value="3"/>
<h3>Three</h3>
</div>
<!-- -->
</div>

</body>
</html>


This post has been edited by truefusion: Feb 28 2009, 07:23 AM
Go to the top of the page
+Quote Post
sonesay
no avatar
|||[ n00b King ]|||
*********
Group: [HOSTED]
Posts: 920
Joined: 20-June 07
From: Auckland
Member No.: 45,102
myCENT:50.02



Post #3 post Feb 28 2009, 08:57 AM
Yeah you have got my problem solved truefusion and surprisingly with little code. I am just reviewing your javascript code and am still a little confused on how the variable 'index' the the function call of index() is used.

Could you please explain how it works in your javascript code, in the http://docs.jquery.com/Core/index example I am guessing the index() returns an index number based on the current position it is in of similar elements in our case divs?

I've managed to get my version of the code to work correctly minus the ajax and mysql update at this point but the code is very long and there may be some code I can remove. I will post it up just for the sake of sharing but I am still in the process of improving it and reviewing your method then I will choose what to carry on with.
CODE
function moveItem(direction, id, obj)
{
        var parent = obj.parentNode;
        var grandParent = parent.parentNode;

        var ipHidden;
        var hNodes = parent.childNodes;
            for(var i=0;i<hNodes.length; i++)
            {
                if(hNodes[i].tagName == 'INPUT')
                {
                    ipHidden = hNodes[i];
                    break;
                }
            }    
        
        
        // get nodes.
        var div_headerNode = obj.parentNode;
        var div_methodContainerNode = div_headerNode.parentNode;
        var div_methodContainerOtherNode;
        var div_methodContainerAll = div_methodContainerNode.parentNode;
                
        
        // move items around
        if(direction == 'down')
        {        
            if(id <= div_methodContainerAll.childNodes.length - 1)
            {
                for(var i=0; i < div_methodContainerAll.childNodes.length; i++)
                {
                    if(div_methodContainerNode == div_methodContainerAll.childNodes[i])
                    {
                        div_methodContainerOtherNode = div_methodContainerAll.childNodes[i+1];
                    }
                }
                // set other nodes values
                div_methodContainerOtherNode.firstChild.lastChild.value--;
                var imageButtons = div_methodContainerOtherNode.firstChild.getElementsByTagName('img');            
                imageButtons[0].setAttribute("onclick","moveItem('up', "+(id)+", this)");
                imageButtons[1].setAttribute("onclick","moveItem('down', "+(id)+", this)");
                
                // set current nodes values and shuffle
                jQuery(grandParent).insertAfter(jQuery(grandParent).next());
                jQuery(obj).prev().attr("onClick","moveItem('up', "+(id+1)+", this)");
                jQuery(obj).attr("onClick","moveItem('down', "+(id+1)+", this)");
                jQuery(ipHidden).attr("Value",id+1);
                
            }
            
        }
        else if(direction == 'up')
        {
            if(id > 1)
            {
                // get other node
                for(var i=0; i < div_methodContainerAll.childNodes.length; i++)
                {
                    if(div_methodContainerNode == div_methodContainerAll.childNodes[i])
                    {
                        div_methodContainerOtherNode = div_methodContainerAll.childNodes[i-1];
                    }
                }
            
                // set other nodes values
                div_methodContainerOtherNode.firstChild.lastChild.value = id;
                var imageButtons = div_methodContainerOtherNode.firstChild.getElementsByTagName('img');            
                imageButtons[0].setAttribute("onclick","moveItem('up', "+(id)+", this)");
                imageButtons[1].setAttribute("onclick","moveItem('down', "+(id)+", this)");
                
                // set current node and shuffle around
                jQuery(grandParent).insertBefore(jQuery(grandParent).prev());
                jQuery(obj).attr("onClick","moveItem('up', "+(id-1)+", this)");
                jQuery(obj).next().attr("onClick","moveItem('down', "+(id-1)+", this)");
                jQuery(ipHidden).attr("Value",id-1);
            }
        }
}


Thanks yet again for another awesome code truefusion. One last thing I have not been able to find out about is using jQuery selectors. Typically you would pass it a string expression to get your object for instance $('#idhere'); but I am trying to find a way where I can pass it an existing object and then filter it down some more with another string expression like $(object+"new expression here"); but it does not obviously work that way. Is there another method of achieving this?
Go to the top of the page
+Quote Post
truefusion
no avatar
Do you want to know?
****************
Group: [MODERATOR]
Posts: 2,672
Joined: 22-June 05
From: 127.0.0.1 — no place like it.
Member No.: 8,528
myCENT:33.50



Post #4 post Feb 28 2009, 10:29 AM
QUOTE (sonesay @ Feb 28 2009, 03:57 AM) *
Could you please explain how it works in your javascript code, in the http://docs.jquery.com/Core/index example I am guessing the index() returns an index number based on the current position it is in of similar elements in our case divs?

I don't fully understand how it works either laugh.gif, i just tried to mirror the example the best i could, as that seemed the only possible way of getting what i wanted. I didn't think i had to repeat "#container div" to get it to work, which was the reason why it took me a few tries to get the proper index instead of "-1" to show up.

QUOTE (sonesay @ Feb 28 2009, 03:57 AM) *
Typically you would pass it a string expression to get your object for instance $('#idhere'); but I am trying to find a way where I can pass it an existing object and then filter it down some more with another string expression like $(object+"new expression here"); but it does not obviously work that way. Is there another method of achieving this?

I've only done similar but with variables: $("#"+var). I believe in your example, object = $("exp"), which would be like saying $($("exp")+"exp2"). If that's the case, then you would use the selector method to retrieve the expression passed; that is, $($("exp").selector+"exp2"). However, this method doesn't work in cases of $(this). Since selector was introduced in version 1.3 of JQuery, if you have an earlier version, you'd have to update your copy of JQuery.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic

Collapse

> Similar Topics

    Topic Title Replies Topic Starter Views Last Action
No New Posts   6 Echo_of_thunder 1,290 26th March 2009 - 09:04 PM
Last post by: TheDisturbedOne
No new   17 harad 23,045 3rd August 2004 - 11:40 PM
Last post by: MSTR
No New Posts   3 frazmi 2,216 6th August 2006 - 02:20 AM
Last post by: FallenSage
No New Posts   10 Vacant 5,429 3rd June 2009 - 05:11 PM
Last post by: proskiier23
No New Posts   10 ill 17,521 19th August 2004 - 01:29 PM
Last post by: odomike
No New Posts 10 holyium 9,940 25th September 2004 - 12:33 AM
Last post by: spyshow
No New Posts   2 Raptrex 5,905 21st August 2004 - 04:09 PM
Last post by: OpaQue
No New Posts   2 truman69 1,129 29th May 2006 - 10:14 AM
Last post by: Avalon
No New Posts   3 Vacant 7,836 26th August 2004 - 09:09 AM
Last post by: Vacant
No New Posts   1 odomike 4,568 2nd September 2004 - 05:16 AM
Last post by: OpaQue
No New Posts   6 fernan 4,956 8th September 2004 - 12:48 PM
Last post by: OpaQue
No New Posts   11 icss21 2,883 11th April 2009 - 04:31 AM
Last post by: zakaluka
No New Posts 0 EricDrinkard 4,162 15th September 2004 - 04:46 AM
Last post by: EricDrinkard
No New Posts   1 Too_Hot 3,568 23rd September 2004 - 09:16 PM
Last post by: Zenchi
No New Posts   1 farh1n 5,315 11th August 2007 - 02:21 PM
Last post by: odomike


 



RSS Open Discussion Time is now: 8th November 2009 - 04:37 PM

Web Hosting Powered by ComputingHost.com.