Page 1 of 3 123 LastLast
Results 1 to 10 of 28

Thread: jQuery get position of div then save it to a cookie.

  1. #1
    Join Date
    Apr 2010
    Posts
    89
    Thanks
    9
    Thanked 0 Times in 0 Posts

    Default jQuery get position of div then save it to a cookie.

    Hi guys, need some help here. I was getting help on the jQuery forum but the person who was working with me stopped replying, so I'm hoping one of you can help me. Here's what's happening. I have divs on a webpage that you can drag around the page on the iPhone/iPad (this is only meant for those devices). I want the position of the divs to be saved when the page is reloaded, by putting it into a cookie. So far, I am using these plugins..

    http://plugins.jquery.com/project/Cookie
    http://www.manifestinteractive.com/iphone/touch/

    to drag the boxes around and save it to a cookie. Now I just need the code that get's the position and saves it. I got some help with it, and have this script:

    Code:
    $(document).ready(function(){
          // does cookie exist?
          if ($.cookie('the_cookie1')) {
                var coordsOne = $.cookie('the_cookie1').split(',');
                $('#theBox').css({top:coordsOne[0],left:coordsOne[1]});
          }
       
          if ($.cookie('the_cookie2')) {
                 var coordsTwo = $.cookie('the_cookie2').split(',');
                $('#theBox2').css({top:coordsTwo[0],left:coordsTwo[1]});     
          }
    });
    Which gets the position of the boxes, and then saves it to a cookie. Now, I need to figure out how to have the boxes get record their position and set it as a cookie (does that make sense?). I was told to use this script:

    Code:
     $.cookie('the_cookie',$('#theBox').css('top')+','+$('#theBox').css('left'));
    And I was supposed to put it on the "drag stop event" of the boxes, but I don't think the boxes have a drag stop event, or at least one I can't find. So, here is my JS code for the draggable boxes, where I think the code above would go...

    http://jsbin.com/iraxe/edit
    http://jsbin.com/akogu3/edit

    Thank you for reading this, and any help is much appreciated.

  2. #2
    Join Date
    Apr 2010
    Posts
    89
    Thanks
    9
    Thanked 0 Times in 0 Posts

    Default

    Any ideas?

  3. #3
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    I have no iAnything to test this on, but . . .

    If you could bind() touch(), you might be able to use bind's callback.

    Also, you might consider, instead of applying touch() to all of those many elements by their id, trying it out like if you could just give each one of them the same class and just apply touch() to that class.

    This, if it works, will not solve your problem, but will greatly simplify your code.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  4. #4
    Join Date
    Apr 2010
    Posts
    89
    Thanks
    9
    Thanked 0 Times in 0 Posts

    Default

    Yeah, I am pretty sure I could make them classes instead of ID's. And the cookie would work if that piece of code was run when the box was moved. There has to be some place in my JS that details it?

  5. #5
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    I think you want to edit the touch code. Here seems a likely candidate location (addition highlighted):

    Code:
    function touchmove(e){
      
      if(_dragging && !_sizing && _animate) {
        
        var _lastleft = (isNaN(parseInt($('#'+_target).css("left")))) ? 0:parseInt($('#'+_target).css("left"));
        var _lasttop = (isNaN(parseInt($('#'+_target).css("top")))) ? 0:parseInt($('#'+_target).css("top"));
      }
      
      $(e.changedTouches).each(function(){
        
        e.preventDefault();
        
        _left = (this.pageX-(parseInt($('#'+_target).css("width"))/2));
        _top = (this.pageY-(parseInt($('#'+_target).css("height"))/2));
        
        if(_dragging && !_sizing) {
          
          if(_animate){
            _xspeed = Math.round((_xspeed + Math.round( _left - _lastleft))/1.5);
            _yspeed = Math.round((_yspeed + Math.round( _top - _lasttop))/1.5);
          }
          
          if(_dragx || _dragy) $('#'+_target).css({ position: "absolute" });
          if(_dragx) $('#'+_target).css({ left: _left+"px" });
          if(_dragy) $('#'+_target).css({ top: _top+"px" });
           $.cookie('the_cookie',$('#theBox').css('top')+','+$('#theBox').css('left'));
          $('#'+_target).css({ backgroundColor: "" });
          $('#'+_target+' b').text('');
        }
      });
    };
    But that's not exactly what you want to store at that point. You would probably want a reference to each draggable item's id and its coordinates (css left and top). A fair amount of information considering all the draggable elements you are working with. But probably not too much for a cookie in modern browsers, choose your delimiter wisely, don't use one that could be mistaken for part of the data, nor one that must be escaped. Remember, cookie information can only be stored as a string. So you would need some code to create that string with delimiters so that it could be parsed upon retrieval.

    When this cookie is retrieved, you parse its string into sets of element id's with their coordinates, then find each of the elements by its stored id and set its position according to its stored coordinates.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  6. #6
    Join Date
    Apr 2010
    Posts
    89
    Thanks
    9
    Thanked 0 Times in 0 Posts

    Default

    Then maybe a cookie wouldn't be the best way to do it? Are there other options available?

  7. #7
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    As far as for what's available without server side code, a javascript cookie is about the best. Cookies can be disabled though, even when javascript is active. Usually they are active. Whatever method you choose, as far as I know, the information can only be stored as a string.

    I see that the touch() code uses the element's id. I don't think it needs to be activated by that id. If so, you can give each draggable the same class, and keep each ones unique id. That way you could initialize them all with - say the class was, 'draggable', replacing this and similar:

    Code:
      $('#touchme1').touch({
        animate: false,
        sticky: false,
        dragx: true,
        dragy: true,
        rotate: false,
        resort: false,
        scale: false
      });
    with a single:

    Code:
      $('.draggable').touch({
        animate: false,
        sticky: false,
        dragx: true,
        dragy: true,
        rotate: false,
        resort: false,
        scale: false
      });
    But it might not work like that. But if we add the class anyway, we can simplify the cookie. You could make the name be the id. That way we could be setting a cookie for each draggable, only if they get moved:

    Code:
    function touchmove(e){
      
      if(_dragging && !_sizing && _animate) {
        
        var _lastleft = (isNaN(parseInt($('#'+_target).css("left")))) ? 0:parseInt($('#'+_target).css("left"));
        var _lasttop = (isNaN(parseInt($('#'+_target).css("top")))) ? 0:parseInt($('#'+_target).css("top"));
      }
      
      $(e.changedTouches).each(function(){
        
        e.preventDefault();
        
        _left = (this.pageX-(parseInt($('#'+_target).css("width"))/2));
        _top = (this.pageY-(parseInt($('#'+_target).css("height"))/2));
        
        if(_dragging && !_sizing) {
          
          if(_animate){
            _xspeed = Math.round((_xspeed + Math.round( _left - _lastleft))/1.5);
            _yspeed = Math.round((_yspeed + Math.round( _top - _lasttop))/1.5);
          }
          
          if(_dragx || _dragy) $('#'+_target).css({ position: "absolute" });
          if(_dragx) $('#'+_target).css({ left: _left+"px" });
          if(_dragy) $('#'+_target).css({ top: _top+"px" });
          if(_dragx || _dragy) $.cookie(_target,($('#'+_target).css('top')||'')+'_'+($('#'+_target).css('left')||''));
          $('#'+_target).css({ backgroundColor: "" });
          $('#'+_target+' b').text('');
        }
      });
    };
    resulting in up to eight short cookies if all of the draggables get moved.

    Then, when the page loads again, you could do as part of your document ready code:

    Code:
    $('.draggable').each(function(){
    		if($.cookie(this.id)){
    			var pos = $.cookie(this.id).split('_');
    			$(this).css({position: 'absolute', top: pos[0], left: pos[1]});
    		}
    	}
    );
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  8. #8
    Join Date
    Apr 2010
    Posts
    89
    Thanks
    9
    Thanked 0 Times in 0 Posts

    Default

    Right, I see what you're saying. And if none of them were moved, they would be in the default position? Plus, this would allow me to add more boxes, right?

  9. #9
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    This all assumes I've read the touch code properly, anticipated all important contingencies, and made no typos in my code. As I cannot test this, try it out. It should work with as many elements as the browser will allow cookies. I'm uncertain of the limits on cookies. It probably varies by browser, and these days, for most modern browsers, that's probably quite high.

    If a particular element is not moved, no cookie will be set for it. So when the page loads the next time, no action will be taken as regards that element. It will remain wherever its default position is.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  10. #10
    Join Date
    Apr 2010
    Posts
    89
    Thanks
    9
    Thanked 0 Times in 0 Posts

    Default

    Ok, I set up the code like this.

    1.) I changed the DIVs that get moved to this:

    Code:
    <div id="touchme1" class="draggable">
    <!--Content Start -->
    Test Box
    <!--Content End -->
    </div>
    2.) I updated the #touchme 1, #touchme 2, etc. to .draggable:

    Code:
     $('.draggable').touch({
        animate: false,
        sticky: false,
        dragx: true,
        dragy: true,
        rotate: false,
        resort: false,
        scale: false
      });
    3.) I put this code in the head of my page:

    Code:
    $('.draggable').each(function(){
    		if($.cookie(this.id)){
    			var pos = $.cookie(this.id).split('_');
    			$(this).css({position: 'absolute', top: pos[0], left: pos[1]});
    		}
    	}
    );
    4.) I then put this in my external JS file:

    Code:
    function touchmove(e){
      
      if(_dragging && !_sizing && _animate) {
        
        var _lastleft = (isNaN(parseInt($('#'+_target).css("left")))) ? 0:parseInt($('#'+_target).css("left"));
        var _lasttop = (isNaN(parseInt($('#'+_target).css("top")))) ? 0:parseInt($('#'+_target).css("top"));
      }
      
      $(e.changedTouches).each(function(){
        
        e.preventDefault();
        
        _left = (this.pageX-(parseInt($('#'+_target).css("width"))/2));
        _top = (this.pageY-(parseInt($('#'+_target).css("height"))/2));
        
        if(_dragging && !_sizing) {
          
          if(_animate){
            _xspeed = Math.round((_xspeed + Math.round( _left - _lastleft))/1.5);
            _yspeed = Math.round((_yspeed + Math.round( _top - _lasttop))/1.5);
          }
          
          if(_dragx || _dragy) $('#'+_target).css({ position: "absolute" });
          if(_dragx) $('#'+_target).css({ left: _left+"px" });
          if(_dragy) $('#'+_target).css({ top: _top+"px" });
          if(_dragx || _dragy) $.cookie(_target,($('#'+_target).css('top')||'')+'_'+($('#'+_target).css('left')||''));
          $('#'+_target).css({ backgroundColor: "" });
          $('#'+_target+' b').text('');
        }
      });
    };
    5.) I linked to the jQuery Cookie JS file like so:

    Code:
    <script type="text/javascript" language="javascript" src="js/cookie.js"></script>

    And here's what happens, the DIVs can be moved around the page, but when I reload the page they are in their original positions. I don't know if these affects the cookie, but the DIVs are set up in CSS to be positioned in the middle of the page. I don't think it does affect it though.

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •