0

I am trying to add JQuery functionality to my Rails application; however, it is not working. I am using JQuery draggable to move images around the screen. I have it working in a stand alone html file but I'm having a lot of difficulty adding it to my Rails application. This is the stand alone file:

<!DOCTYPE html>
<html>
<head>
  <title>City</title>
  <meta charset="UTF-8">
  <link rel="stylesheet" href="js/jquery-ui-1.10.4/themes/base/jquery-ui.css">
  <script type="text/javascript" src="js/jquery-ui-1.10.4/jquery-1.10.2.js"></script>
  <script type="text/javascript" src="js/jquery-ui-1.10.4/ui/jquery-ui.js"></script>

  <style type="text/css">

  h1, h3
  {
    text-align: center; 
    margin: 0px;
  }

  /* style the list to maximize the droppable hitarea */
  #canvas  
  {
    width: 600px;
    height: 600px;
    border: 1px solid black;
    margin: 0px auto;
    overflow: hidden;
  }
  /*#canvas ol { margin: 0; padding: 1em 0 1em 3em; }*/
  /*li { list-style: none;}*/
  .canvas-area 
  {
    width: 600px;
    height: 600px;
  }

  /* map background */
/*  img {
      position: relative;
      left: 50%;
      top: 50%;
  }*/

  /* draggable icons */
  .draggable 
  { 
    background: transparent url('images/transparent.png') repeat center top;
    width: 40px; 
    height: 40px; 
    padding: 5px; 
    float: left; 
    margin: 0 10px 10px 0; 
    font-size: .9em; 
    border: hidden;
    /*position: absolute;*/
  }
  #draggable
  {
    width: 40px;
    height: 40px;
  }
  div img 
  {
    margin: 0px auto;
    position: relative;
    top: 0px;
    left: 0px;
    width: 40px;
    height: 40px;
  }

  .arrow img
  {
    width: 200px;
    height: 200px;
  }
  .arrow
  {
    width: 200px;
    height: 200px;
    border: 1px solid black;
  }
  .commercial100 img
  {
    width: 100px;
    height: 100px;
  }
  .commercial100
  {
    width: 100px;
    height: 100px;
  }

  #building img
  {
    height: 150px;
  }

  </style>

  <script>

    // jquery ui script for snapping to grid
    $(function() {
      $( ".draggable" ).draggable({ grid: [10,10] });
      $( "#draggable4" ).draggable({ grid: [ 20, 20 ], snap: true });
    });

  </script>
</head>
<body>
<div class="content">

  <!-- Canvas for building the city -->
  <h1>Mock view of my city</h1>
  <h3>600 x 600</h3>
  <div id="canvas">

    <div id="ignoreThis" class="ui-widget-content canvas-area">

      <p class="placeholder">Add your items here</p>

      <div id="arrowSvg" class="draggable ui-widget-content arrow">
        <img src="images/arrow.svg" alt="house" type="image/svg+xml" /> SVG (200px x 200px)
      </div>

      <div id="arrowPng" class="draggable ui-widget-content arrow">
        <img src="images/arrow.png" alt="house"> PNG (200px x 200px) 
      </div>

      <div id="building" class="draggable ui-widget-content commercial100">
        <img src="images/building.png" alt="building" />
      </div>

      <div id="factory" class="draggable ui-widget-content commercial100" >
        <img src="images/factory.png" alt="factory" />
      </div>

      <div id="ferry" class="draggable ui-widget-content commercial100" >
        <img src="images/ferry.png" alt="ferry" />
      </div>

      <div id="house2l" class="draggable ui-widget-content" >
        <img src="images/house2l.png" alt="two level house" />
      </div>

      <div id="houseSvg" class="draggable ui-widget-content"> 
        <img src="images/house.svg" alt="house" type="image/svg+xml" /> SVG
      </div>

      <div id="housePng" class="draggable ui-widget-content">
        <img src="images/house.png" alt="house" />
      </div>

      <div id="houseSF" class="draggable ui-widget-content" >
        <img src="images/housesf.png" alt="SF house" />
      </div>

      <div id="street1" class="draggable ui-widget-content street" >
        <img src="images/street.png" alt="street">
      </div>

      <div id="street2" class="draggable ui-widget-content street" >
        <img src="images/street.png" alt="street">
      </div>

      <div id="street3" class="draggable ui-widget-content street" >
        <img src="images/street.png" alt="street">
      </div>

      <div id="street4" class="draggable ui-widget-content street" >
        <img src="images/street.png" alt="street">
      </div>

    </div> 
    <script>
    // code to make the active div move to the front
    // code from http://www.codingforums.com/javascript-programming/260289-bring-div-element-front-click.html

      // create an array to hold the (buildings, streets, landmarks) element's id
      var ids=[],
      // grab all the divs (each icon) and put it into thedivs
      thedivs = document.getElementById("canvas").getElementsByTagName("div");

      for (var i = 0; i < thedivs.length; i++) {

        // add the id of each div to the ids array
        //alert(thedivs[i].id);
        ids.push(thedivs[i].id);


        thedivs[i].onclick = function() {

          for (var a = 0; a < ids.length; a++) {
            if (this.id == ids[a]) {
              // take current id that matches the selected id and move it to the end
              ids.push(ids.splice(a,1));
            }
            document.getElementById(ids[a]).style.zIndex=a;     
          }
        }
      }
    </script>
  </div>
  <input type="button" value="save" onclick="saveAction()">

  <script>
        //Cycle through images and grab their x/y positions

        var saveAction = function(){

        elementNames = document.getElementById("canvas").getElementsByTagName("div");
        for(var i = 0; i < elementNames.length; i++)
        {
        var idName = $( "#" + elementNames[i].id);


         var offset = idName.offset();
         alert("Left pos: " + offset.left + " Top pos: " + offset.top);
        }


    };
  </script>
</div>
</body>
</html>

I have placed the Javascript in assets/javascripts/custom_map.js and I have placed the html / css in my new_map.html.erb view. The images are showing up fine in the Rails app but they are not draggable. How can I fix this? Thanks!

2
  • 1
    Have you added the JS to your view as well? Commented May 15, 2014 at 2:53
  • What's the problem with the JS if you include it unobtrusively? Commented May 15, 2014 at 8:43

2 Answers 2

1

Perhaps your load order is incorrect or your assets path is wrong. Try linking your script as the last thing on your page and wrap everything in it inside a jquery ready function:

    $(function() {
      // all your scripts here
    });

Also try viewing your source and making sure that your .js file is serving correctly It should be /assets/yourjs.js rather than /assets/javascripts/yourjs.js

Also, I think you may be able to use the jquery ui stack function to make items settle on top (not sure, you might want to try it):

$( ".draggable" ).draggable({ stack: ".draggable" });
Sign up to request clarification or add additional context in comments.

4 Comments

I'm not sure I understand what page you are talking about? The view... new_map.js?
add the link to your script: <script src="/assets/new_map.js"></script> near the bottom of your view.
its still not working. I have added <script src="/assets/new_map.js"></script> to the bottom of the page and I have added my jquery to new_map.js inside $(function) { }
sorry, I couldn't be of more help. try using console.log at various places in your script to see if it's failing somewhere. good luck!
0

Without knowing the specific errors you're receiving, I can only detail why you're having a problem, and how to resolve it generally:


Unobtrusive

You should never put javascript in your HTML code (known as inline JS). Problems being that it's messy & can be easily tampered with... hence making it relatively insecure, and generally seen as amateurish

A better way is to use unobtrusive JS (where the JS is stored in files loaded outside the scope of HTML). Rails uses the asset pipeline for this:

#app/assets/javascripts/application.js
var ready = function() { // -> you said JQuery :)
      $( ".draggable" ).draggable({ grid: [10,10] });
      $( "#draggable4" ).draggable({ grid: [ 20, 20 ], snap: true });

      /////////////////////////////////

      var ids=[],
      // grab all the divs (each icon) and put it into thedivs
      thedivs = document.getElementById("canvas").getElementsByTagName("div");

      for (var i = 0; i < thedivs.length; i++) {

        // add the id of each div to the ids array
        //alert(thedivs[i].id);
        ids.push(thedivs[i].id);


        thedivs[i].onclick = function() {

          for (var a = 0; a < ids.length; a++) {
            if (this.id == ids[a]) {
              // take current id that matches the selected id and move it to the end
              ids.push(ids.splice(a,1));
            }
            document.getElementById(ids[a]).style.zIndex=a;     
          }
        }
      }
 };
 $(document).on("page:load ready", ready);

If you migrate your JS from your views and put into your asset files, you'll be in a much better position to give us feedback, which we can then use to help fix your problem further

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.