0

I'm currently designing a website and I am in the process of creating Javascript objects that will then be sent to the servers via fetch() API. So currently in my code I'm using input groups to let the user input some parameters. For efficiency reasons, I decided that every input that the user inputs will be a parameter of my Javascript object, but I was wondering if it is possible to create some sort of "globally accessible" (or something along those lines) object that will let me essentially put each input into a certain object parameter.

<div class="col-xs-2">
    <div class="input-group mb-3">
        <input type="text" class="form-control" 
                 placeholder="Feed Flow" aria-label="Feed Flow" 
                 aria-describedby="basic-addon2">
        <div class="input-group-append">
            <span class="input-group-text" id="basic- 
                         addon3">m<sup>3</sup>/d</span>
        </div>
    </div>
</div>

So that's the code. This would be asking the user to input a number for the feed flow of the water in a desalination process. I want to scan whatever is in the input box and pass it to a parameter of an Object called ReverseOsmosis. So what in another language would look like: ReverseOsmosis.feed_flow=input (assuming input is what the user inputs)

alvaroszi
  • 3
  • 1
  • I have to admin, I have no idea what you're asking here. What are you trying to _do_ that made you think you needed this approach? Because it feels very much like what you came up with is a very unusual solution to a problem with a very normal solution available already. – Mike 'Pomax' Kamermans Apr 26 '19 at 21:31
  • So my website displays a bunch of different input boxes. The user inputs certain numbers on them, and then I am supposed to get those inputs and put them in an object that I have to create – alvaroszi Apr 26 '19 at 21:34
  • 1
    No, that's an implementation detail of what you're doing, What are you actually _doing_ here? A website with "a bunch of different input boxes" is a useless website, so what are you doing? You're making users type things: what are those things? Why are you gathering them, etc. – Mike 'Pomax' Kamermans Apr 26 '19 at 21:46
  • 1
    Okay, maybe I'm not being very clear. In this HTML file I display blank input boxes with parameters related to water attributes in a process called reverse Osmosis. I want the users to fill those blank boxes out, then I want to retrieve that data and assign it to a javascript object so that I can send the user-inputted info to a server that will process it. – alvaroszi Apr 26 '19 at 22:01
  • 1
    Kind of sounds to me like you should be using a UI framework. It's not essential, but you're binding your UI to a whole data structure, which is the main purpose of a UI framework. If you're using one, the question of "how do I bind data to my UI" is going to be answered directly by the framework's documentation and tutorials. – Andrew Koster Apr 26 '19 at 22:07
  • Yeah I'm using Bootstrap. Sorry I'm a newbie in web design. I've only taken regular programming courses (Java and C) in class and Udemy (Python) and I've never done anything similar to web design before, so if my expressions are not the most accurate I apologize. – alvaroszi Apr 26 '19 at 22:13
  • Based on your description (which you _really_ need to put in your post, because [all the details should be in the post itself](/help/how-to-ask) then there's nothing special you need to do. Put everything inside a `
    `, add an eventlistener for `submit` on that form that _turns off default form processing_ (using `event.preventDefault()`) and then simply create a FormData object off of that form and send it to your server, without the page ever hard reloading. Trincott shows your the correct answer for this - the answer you've accepted is not quite the right answer.
    – Mike 'Pomax' Kamermans Apr 27 '19 at 16:17

2 Answers2

4

When you put your input controls in a form tag, you can use the FormData constructor to get the key/value pairs. Those are represented as pairs (arrays with 2 elements), but can be easily converted to a plain object, for instance with Object.fromEntries:

document.querySelector('form').addEventListener("change", function () {
  var data = new FormData(this);
  console.log(Object.fromEntries(data.entries()));
});
<form onsubmit="return false;">
  name: <input name="name"><br>
  address: <input name="address"><br>
</form>

The above used onsubmit attribute will prevent the form from submitting when clicking button elements (as they are by default of the type "submit"). See "Can I make a button not submit a form?" for more info and alternatives on that aspect.

trincot
  • 317,000
  • 35
  • 244
  • 286
  • Although just for cleanliness, it'd be better to turn that into an `addEventListener` with an `evt.preventDefault()` instead of using the legacy `onchange` handler. – Mike 'Pomax' Kamermans Apr 27 '19 at 16:18
  • @Mike'Pomax'Kamermans, indeed, changed to `addEventListener`. Thanks! I don't feel that calling `preventDefault` is needed in this demo, as I did not intend to bypass any standard behaviour. I just wanted to plug into the `change` event bubbling up from the input controls. If however someone wants to *replace* some standard behaviour, then I fully agree this would be an appropriate action. – trincot Apr 27 '19 at 16:56
  • Fair - although as the question was about doing this without reloads, I would still advocate showing how to "turn off" the form with a `preventDefault()` on the containing form submit event, as that'll guaranteed trigger a page navigation action in every browser in absence of an override. – Mike 'Pomax' Kamermans Apr 27 '19 at 17:03
  • 1
    True; I added a paragraph about that, and went for the `onsubmit` attribute, so to keep the focus in the JS code on the question. – trincot Apr 27 '19 at 17:58
0

If I understand right, you need to attach event listeners to every input. For example:

var inputs = document.querySelectorAll(".form-control");
for (var i = 0; i < inputs.length; i++){
    inputs[i].addEventListener("keyup", addDataToObject);
}

You also need to create an object, for example:

var objectContainingAllParams = {};

And finally your function:

function addDataToObject(){
  var key = this.getAttribute("aria-label");
  objectContainingAllParams[key] = this.value;
}

And then I suppose you have some button sending this object via fetch API.

Or you can just read all inputs once before sending request. You need to slightly refactor the code above to do it.

Alonad
  • 1,986
  • 19
  • 17