Search code examples
javascriptcsstextfieldfocusout

Re-arrange elements using JavaScript


I am trying to do a small code exercise that my friend made for me. The point of the app is to type the asset name in the text field and using javascript the text in the box will move up to the center, and when you type in another asset name, the old one will go down and the new one will move up. Below is the HTML, CSS & JavaScript code, any help will be great :)

$(function() {
  $("input[name='faux-address-bar']").focusout(function() {})
})

$("assest1").focusin(function(){
$(span).css("vertical-align", "top");
});
  
$("assest2").focusin(function(){
$(span).css("vertical-align", "top");
});
  
$("assest3").focusin(function(){
$(span).css("vertical-align", "top");
});
body {
  margin: 20px;
  font-family: arial;
}

.container div {
  border: 1px solid black;
  width: 49%;
  float: left;
  height: 300px;
  line-height: 300px;
  text-align: center;
  font-size: 20px;
  &:first-child {
    width: 100%;
    margin-top: 20px;
    margin-bottom: 10px;
  }
  &:nth-child(3) {
    float: right;
  }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<input type="text" value="?asset=1" name="faux-address-bar">

<div class="container">
  <div id="asset1"><span>ASSET 1</span></div>
  <div id="asset2"><span>ASSET 2</span></div>
  <div id="asset3"><span>ASSET 3</span></div>
</div>


Solution

  • I had some free time and wanted to try your friend's exercise as well.

    My solution assumes:

    1. The input box ?asset=n, where n is the number to change, will always follow the pattern ?asset=n.
    2. ES6 is a-o-k.
    3. CSS is not cheating.
    4. Ignoring anything other than the latest version of Chrome...is perfectly fine.

    With that said, I wanted to leverage ordering provided by CSS (I'm old school and contrary to what others may say/that I recently read on-line, I believe Separation-of-Concerns in the wild-wild-west that we call front end development isn't dead).

    With that said, shake-and-bake(tm) in some CSS variables, and re-arranging becomes much easier!

    My algo sucks (I didn't spend too much time thinking about this), but it's one approach that hopefully others may learn from (or be introduced to something new...) If you think of a way to optimize the code, I'd love to see it!

    JSFiddle: http://jsfiddle.net/6hmcv0tn/1/

    // Look ma, no globals!
    {
        // Cache queried elements for quicker reference
        let input = document.querySelector('[name="faux-address-bar"]');
        let container = document.querySelector('.container');
        let children = container.querySelectorAll('div');
    
        // Define our onkeyup handler
        let handler = e => {
    
            // Because we assume ?asset=n is constant, we can
            // reference the number after = as our element to
            // re-arrange
            let val = e.target.value;
            let assetIndex = val.split('=')[1];
    
            // Check for presence of element to re-arrange
            if (assetIndex && container.querySelector('#asset' + assetIndex)) {
    
                // CSS3 variable keys to modify
                let keys = ['--first-item', '--second-item', '--third-item'];
    
                // Our forEach callback for re-arranging elements
                let swapper = (order, idx) => {
                    let el = children[idx];
                    el.style.setProperty(keys[idx], order);
                }
    
                // Default ordering of elements using CSS3
                // flexbox ordering
                let set = [1,2,3];
    
                // Updates ordering based on asset entered
                switch (assetIndex) {
                    case '1':
                        set = [2, 1, 3];
                        break;
                    case '3':
                        set = [1, 3, 2];
                        break;
                    default:
                    break;
                }
    
                // Blindly loop over set and apply order to elements
                set.forEach(swapper);
            }
        }
    
        // Registers our key up handler
        input.addEventListener('keyup', handler, true);
    
        // For fun, update the order on load
        handler({target: input});
    }
    :root {
      --first-item: 1;
      --second-item: 2;
      --third-item: 3;
    }
    
    .container {
      display: flex;
      flex-direction: column;
      justify-content: center;
      align-items: center;
    }
    
    .container>div {
      width: 100px;
      height: 100px;
      border: 5px solid #aec8f2;
      border-radius: 20px;
      background-color: #5b7193;
      color: #fff;
      font-family: monospace;
      justify-content: center;
      align-items: center;
      display: flex;
      margin: 20px;
      transition: all 1s;
      font-size: 30px;
    }
    
    input {
      width: 300px;
      height: 30px;
      margin: 0 auto;
      display: block;
      text-align: center;
      border-radius: 20px;
      border: 5px solid #d8efc2;
      background-color: #82996c;
      color: #fff;
      font-size: 20px;
    }
    
    .container div:nth-child(1) {
      order: var(--first-item);
    }
    .container div:nth-child(2) {
      order: var(--second-item);
    }
    .container div:nth-child(3) {
      order: var(--third-item);
    }
    <input type="text" value="?asset=1" name="faux-address-bar">
    
    <div class="container">
      <div id="asset1"><span>1</span></div>
      <div id="asset2"><span>2</span></div>
      <div id="asset3"><span>3</span></div>
    </div>