Search code examples
javascriptjquerygun

Two different forms in gun.js


been coding for a few months and new to gun.js , been playing around with the todo example for days and cant seem to figure out how to create two seperate forms which don't sync the todos and put them in each others list. Below is code which doesn't get todos at all, if you could take a look I'd appreciate it.

<html>
  <body>
    <h1>Todos</h1>

    <div id="div1"><div/>
    <div id="div2"><div/>
    
    <form id="form1"><input id="input1"><button>Add</button></form>   
    <form id="form2"><input id="input2"><button>Add</button></form>

    <!-- Load GUN itself. -->
    <script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>

    <!-- Load jQuery to help make things a bit easier. -->
    <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>

    <script>
      // Initialize GUN and tell it we will be storing all data under the key 'todos'.
      var todos = Gun().get('todos')

      // Get the form1 element.
      var form1 = $('form1')
      // Listen for submits of the form1.
      form1.on('submit', function (event) {
        // Get the input1 element.
        var input1 = form1.find('input1')
        // Tell GUN to store an object,
        // with as title the value of the input element.
        todos.set({title: input1.val()})
        // Clear the input1 element, so the user is free to enter more todos.
        input1.val('')
        // Prevent default form submit handling.
        event.preventDefault()
      })

      // Listen to any changes made to the GUN todos list.
      // This will be triggered each time the list changes.
      // And because of how GUN works, sometimes even multiple times per change.
      todos.map().on(function (todo, id) {
        // Check if the todo element already exists.
        // This can happen because GUN sometimes sends mulitple change events for the same item.
        var li = $('#' + id)
        // Does is not yet exist?
        if (!li.get(0)) {
          // Create it.
          // Set the id to the GUN id of the item.
          // GUN automatically creates id's for all items.
          // Finally set the new todo element to the end of the list.
          li = $('<li>').attr('id', id).appendTo('ul')
        }
        // Does the GUN item contain any data?
        // (It sends null if it was removed from GUN.)
        if (todo) {
          // Create an element with the title of the GUN item in it.
          var html = todo.title
          // Set it to the element.
          li.html(html)
        }
      })
    </script>

    <!-- script for the second form below -->

<script>
    // Initialize GUN and tell it we will be storing all data under the key 'todos'.
    var todos = Gun().get('todos')

    // Get the form2 element.
    var form2 = $('form2')
    // Listen for submits of the form2.
    form2.on('submit', function (event) {
      // Get the input2 element.
      var input2 = form2.find('input2')
      // Tell GUN to store an object,
      // with as title the value of the input element.
      todos.set({title: input2.val()})
      // Clear the input2 element, so the user is free to enter more todos.
      input2.val('')
      // Prevent default form submit handling.
      event.preventDefault()
    })

    // Listen to any changes made to the GUN todos list.
    // This will be triggered each time the list changes.
    // And because of how GUN works, sometimes even multiple times per change.
    todos.map().on(function (todo, id) {
      // Check if the todo element already exists.
      // This can happen because GUN sometimes sends mulitple change events for the same item.
      var li = $('#' + id)
      // Does is not yet exist?
      if (!li.get(0)) {
        // Create it.
        // Set the id to the GUN id of the item.
        // GUN automatically creates id's for all items.
        // Finally set the new todo element to the end of the list.
        li = $('<li>').attr('id', id).appendTo('ul')
      }
      // Does the GUN item contain any data?
      // (It sends null if it was removed from GUN.)
      if (todo) {
        // Create an element with the title of the GUN item in it.
        var html = todo.title
        // Set it to the element.
        li.html(html)
      }
    })
  </script>

    <!-- Just some minimal styling. -->
    <style>
      ul { padding: 0; }
      li { display: flex; }
      li span { width: 150px; word-break: break-all; }
      img { height: 20px; margin-left: 8px; cursor: pointer; }
      input { width: 150px; margin-right: 8px; }
      input[type='checkbox'] { width: auto; }
      .div1{
            position: absolute;
            margin-left: 10px;
        }
        .div1{
            position: absolute;
            margin-left: 200px;
        }
    </style>
  </body>
</html>

Thanks for the help


Solution

  • Your code seems mostly fine, I think the problem was your selectors in jQuery. Here’s the working code: https://codesandbox.io/s/vigorous-field-pezjw?file=/index.html

    What I changed:

    • You want to append the todo items to lists in the page (.appendTo('ul')), but there is no ul in the markup. I changed div1 and div2 to <ul id=list1> and <ul id=list2> and added hashes to the selectors

    • Then the form selectors was not working right. Element IDs become globals in HTML documents but I don’t think you can select them with jQuery without the hash - so an element with an ID (<div id=watermelon>) would be selected by #watermelon in the same way you get an element by class name with a . e.g. $('.icecream').

    • I did the same with the form.find('input1') - it just needed the # to be added to the selector and it worked.

    Here’s the code:

        <h1>Todos</h1>
    
        <ul id="list1"><ul/>
        <ul id="list2"><ul/>
        
        <form id="form1"><input id="input1"><button>Add</button></form>   
        <form id="form2"><input id="input2"><button>Add</button></form>
    
        <!-- Load GUN itself. -->
        <script src="https://cdn.jsdelivr.net/npm/gun/gun.js"></script>
    
        <!-- Load jQuery to help make things a bit easier. -->
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
    
        <script>
          // Initialize GUN and tell it we will be storing all data under the key 'todos'.
          var todos = Gun().get('todos')
    
          // Get the form1 element.
          var form1 = $('#form1')
          // Listen for submits of the form1.
          form1.on('submit', function (event) {
            // Get the input1 element.
            var input1 = form1.find('#input1')
            // Tell GUN to store an object,
            // with as title the value of the input element.
            todos.set({title: input1.val()})
            // Clear the input1 element, so the user is free to enter more todos.
            input1.val('')
            // Prevent default form submit handling.
            event.preventDefault()
          })
    
          // Listen to any changes made to the GUN todos list.
          // This will be triggered each time the list changes.
          // And because of how GUN works, sometimes even multiple times per change.
          todos.map().on(function (todo, id) {
            console.log(todo, id)
            // Check if the todo element already exists.
            // This can happen because GUN sometimes sends mulitple change events for the same item.
            var li = $('#' + id)
            // Does is not yet exist?
            if (!li.get(0)) {
              // Create it.
              // Set the id to the GUN id of the item.
              // GUN automatically creates id's for all items.
              // Finally set the new todo element to the end of the list.
              li = $('<li>').attr('id', id).appendTo('#list1')
            }
            // Does the GUN item contain any data?
            // (It sends null if it was removed from GUN.)
            if (todo) {
              // Create an element with the title of the GUN item in it.
              var html = todo.title
              // Set it to the element.
              li.html(html)
            }
          })
        </script>
    
        <!-- script for the second form below -->
    
    <script>
        // Initialize GUN and tell it we will be storing all data under the key 'todos'.
        var todos = Gun().get('todos')
    
        // Get the form2 element.
        var form2 = $('#form2')
        // Listen for submits of the form2.
        form2.on('submit', function (event) {
          // Get the input2 element.
          var input2 = form2.find('#input2')
          // Tell GUN to store an object,
          // with as title the value of the input element.
          todos.set({title: input2.val()})
          // Clear the input2 element, so the user is free to enter more todos.
          input2.val('')
          // Prevent default form submit handling.
          event.preventDefault()
        })
    
        // Listen to any changes made to the GUN todos list.
        // This will be triggered each time the list changes.
        // And because of how GUN works, sometimes even multiple times per change.
        todos.map().on(function (todo, id) {
          // Check if the todo element already exists.
          // This can happen because GUN sometimes sends mulitple change events for the same item.
          var li = $('#' + id)
          // Does is not yet exist?
          if (!li.get(0)) {
            // Create it.
            // Set the id to the GUN id of the item.
            // GUN automatically creates id's for all items.
            // Finally set the new todo element to the end of the list.
            li = $('<li>').attr('id', id).appendTo('#list2')
          }
          // Does the GUN item contain any data?
          // (It sends null if it was removed from GUN.)
          if (todo) {
            // Create an element with the title of the GUN item in it.
            var html = todo.title
            // Set it to the element.
            li.html(html)
          }
        })
      </script>
    
        <!-- Just some minimal styling. -->
        <style>
          ul { padding: 0; }
          li { display: flex; }
          li span { width: 150px; word-break: break-all; }
          img { height: 20px; margin-left: 8px; cursor: pointer; }
          input { width: 150px; margin-right: 8px; }
          input[type='checkbox'] { width: auto; }
          .div1{
                position: absolute;
                margin-left: 10px;
            }
            .div1{
                position: absolute;
                margin-left: 200px;
            }
        </style>
    

    Hope this helps 👍