0

I am generating a form that is constructed from JSON. I've successfully created the form, but I am now trying to figure out how to update the specific item in JSON from the user input. I've seen this question asked using node and underscore, etc but I would like to accomplish this with vanilla JS or jQuery.

I am trying to avoid modifying the JSON other than the values as it will need to be sent back in the same format, and I am able to find an item by its key or value, however the problem I have is that there are multiple k/v pairs in each object that I am using. Here is an example object:

var list = {
"parent": {
   "item" : {
      "id" : "a1b295",
      "name" : "sample name",
      "value" : "this is a sample value"
   }
}

My form elements come out as <input type="text" name="a1b295" value="this is a sample value" />

What I am trying to do is on submit, iterate through the form elements and update each object in the JSON. I am struggling to figure out how to look up the item by its id and then update the value key value pair for that object.

To be clear the data can have any number of nested children, and I need to go after the ones with specific IDs which I am already turning into form inputs.

Thank you.

This is what I have attempted but it returns a "can't access id of undefined" error.

function traverseData(data, obj)
  {
      for (var k in data)
      {
          if (typeof data[k] == "object" && data[k] !== null) {
              traverseData(obj[k], obj);
          } else if (!data.hasOwnProperty(k)) {
            continue;
          } else if (k = obj) {
            console.log(obj);
          }
      }
  }

  traverseData(data, $(this).attr('id'));
2
  • Am I understanding that you want to update a JSON array (of objects in the format given above) with updated values based on the form changes when you submit the form? Commented Jan 13, 2020 at 18:32
  • Could you please provide a more detailed version of your JSON? Perhaps include more than one form input object. Are there any arrays in there? Commented Jan 14, 2020 at 16:16

4 Answers 4

2

If I understand your question correctly, you have your form which was generated from a JSON array in the format described above, and want to update the values in that JSON array with new values that may have changed on submission.

The following code assumes your forms have been set up properly, and the text values have been updated with the values in the HTML section.

jQuery solution

const json = [
  {
    "item": {
      "id": "a1b295",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b296",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b297",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b298",
      "name": "sample name",
      "value": "this is a sample value"
    }
  }
]

for (const item in json) {
  json[item].item.value = $('input[name="' + json[item].item.id + '"]').val()
}
console.log(json)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="text" name="a1b295" value="this is a sample value" />
<input type="text" name="a1b296" value="New sample value1" />
<input type="text" name="a1b297" value="New sample value2" />
<input type="text" name="a1b298" value="New sample value3" />

Vanilla Javascript solution

const json = [
  {
    "item": {
      "id": "a1b295",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b296",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b297",
      "name": "sample name",
      "value": "this is a sample value"
    }
  },
  {
    "item": {
      "id": "a1b298",
      "name": "sample name",
      "value": "this is a sample value"
    }
  }
]

for (const item in json) {
  json[item].item.value = document.querySelector('input[name="' + json[item].item.id + '"]').value
}
console.log(json)
<input type="text" name="a1b295" value="this is a sample value" />
<input type="text" name="a1b296" value="New sample value1" />
<input type="text" name="a1b297" value="New sample value2" />
<input type="text" name="a1b298" value="New sample value3" />

These examples overwrite the value in the json variable that you can submit with your form. You should see that the json values have been updated to those in the HTML.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for this detailed response, I've updated the question to try to remove any confusion. The problem is the JSON can be nested any number of times so I need to be able to target the ones with IDs. I'm also trying to do this on blur of an input so should I be concerned about performance here?
0

Javascript now supports for..in where you can loop through object keys:

let data = {
  "item" : {
     "id" : "a1b295",
     "name" : "sample name",
     "value" : "this is a sample value"
  }
};


function traverseData(data, obj, newValue)
  {
      for (var k in data)
      {
          if (data.hasOwnProperty(k) && typeof data[k] == "object") {
              data[k] = traverseData(data[k], obj, newValue);
          } else if (k == obj) {
            console.log(obj);
            data[k] = newValue;
          }
      }
      return data
  }

//single element
$('input').blur(function(event){
   data = traverseData(data, 'value', $(this).attr('value'));
   console.log(data);
});

//multiple elements
$('input').each(function (index) {
   let self = $(this); //to differenciate between elements
   self.blur(function(event){
      data = traverseData(data, 'value', $(this).attr('value'));
      console.log(data);
   });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input type="text" name="a1b295" value="this is a sample value 2" />

9 Comments

Thanks for the answer, I've updated the question to be more clear as I am trying to traverse a JSON object of unknown depth. I've created a bit of a recursive function (added to the question) but am getting errors, your help would be appreciated
I've updated my answer. Please, check it and let me know.
@nghs Sorry, I forgot to mention you.
that seems to work, though i changed 'input' to $(this) so I got the name for the specific form field I am working with, let me see if I can replace the console.log so it updates the json and I'll mark it right, thank you! If you have a quick solution for that ready just let me know, we should probably have that in the answer for future viewers
@nghs Done. As I understand. you need to update the json object from the html and that's what i did.
|
0

If I understand correctly, you could before submitting to json alter the input string and change values accordingly.

If u need to compare to another JSON u could just compare values via function.

JSON is just a formated string.

Comments

0

I assume you have an array of objects. So you basically can filter this array to find the object of which the id matches the corresponding input's name. And then update this object's value property with the input value.

  const targetInput = document.getElementById('inputId')
  let newValue = targetInput.value
  let inputName = targetInput.name
  // We filter objects to find the one where id matches input's name
  let targetObject = objects.filter(i => i.item.id === inputName)
  targetObject[0].item.value = newValue
  console.log(targetObject)

2 Comments

Thank you, I do not have an array but perhaps it might be easier to just convert it to an array? I just don't want to lose the integrity of the JSON which is why I preferred to update it. I have updated the question for clarification.
You can use JSON.parse() method to convert JSON to a javascript object. Then update it in any way you need and convert back to a JSON with JSON.stringify

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.