JSON Data - Set Text Input Based On Select Menu Value

I want to set the value of a text input with jquery based on a select menu value and json data

example json:

var company_data = [
    { company_id: '1', company_ref: 'ABC', company_rate: '300' },
    { company_id: '2', company_ref: 'DEF', company_rate: '400' },
    { company_id: '3', company_ref: 'XYZ', company_rate: '500' }
    ];

form example:

<form>
    Company info: <select>
    <option value="1">ABC</option>
    <option value="2">DEF</option>
    <option value="3">XYZ</option>
    </select><br><br>
    Company rate: <input type="text" value=""><br>

    </form>

So if select menu value = 1 then text input value would be set to 300 and so on …

Thanks in advance

Looks easy enough. What you do it to give the select element a change event handler. That handler then gets the value of the select element, and gets then company rate, and updates the text input.

  • give the select element
  • a change event handler
  • handler then gets the value of the select element
  • and gets then company rate
  • and updates the text input

give the select element a change event handler

When working with form elements, it’s best if the form has a unique identifier, and the elements within it have name attributes so that we can easily access them later on. Here. I’m giving the company info select and the company rate input names.

<form id="companyForm">
    Company info: <select name="companyInfo">
    <option value="1">ABC</option>
    <option value="2">DEF</option>
    <option value="3">XYZ</option>
    </select><br><br>
    Company rate: <input type="text" name="companyRate" value=""><br>
</form>

We can now easily give the select element a change handler.

const form = document.querySelector("#companyForm");
const companyInfo = form.elements.companyInfo;

function infoChangeHandler(evt) {
}
companyInfo.addEventListener("change", infoChangeHandler);

That infoChangeHandler is currently an empty function, but we’ll add more to it soon.

handler then gets the value of the select element

When you trigger the event, the browser gives the event info to the handler, letting us easily get things about the event, such as the element involved.

function infoChangeHandler(evt) {
    const selectInfo = evt.target;
    const infoValue = selectInfo.value;
}

and gets then company rate

We can then use that value to find the company rate

function getCompanyRate(infoValue) {
    const data = company_data.find(
        (data) => data.company_id === infoValue
    );
    return data.company_rate;
}
function infoChangeHandler(evt) {
    const selectInfo = evt.target;
    const infoValue = selectInfo.value;
    const companyRate = getCompanyRate(infoValue);
}

and updates the text input

function infoChangeHandler(evt) {
const selectInfo = evt.target;
const infoValue = selectInfo.value;
const companyRate = getCompanyRate(infoValue);
form.elements[“companyRate”].value = companyRate;
}

And, update on page load

It would be nice if we can simulate a change event when the page loads, to populate the company rate. We can create a change event and dispatch that to the select element.

const changeEvent = new MouseEvent('change', {
    view: window,
    bubbles: true,
    cancelable: true
});
companyInfo.dispatchEvent(changeEvent);

Summary

Here is the scripting code in full:

var company_data = [
    { company_id: '1', company_ref: 'ABC', company_rate: '300' },
    { company_id: '2', company_ref: 'DEF', company_rate: '400' },
    { company_id: '3', company_ref: 'XYZ', company_rate: '500' }
];

const form = document.querySelector("#companyForm");

function getCompanyRate(infoValue) {
    const data = company_data.find(
        (data) => data.company_id === infoValue
    );
    return data.company_rate;
}
function infoChangeHandler(evt) {
    const selectInfo = evt.target;
    const infoValue = selectInfo.value;
    const companyRate = getCompanyRate(infoValue);
    form.elements["companyRate"].value = companyRate;
}
const companyInfo = form.elements.companyInfo;
companyInfo.addEventListener("change", infoChangeHandler);

const changeEvent = new MouseEvent('change', {
    view: window,
    bubbles: true,
    cancelable: true
});
companyInfo.dispatchEvent(changeEvent);

and you can play with it at https://jsfiddle.net/arh13jvd/

2 Likes

Now that we’ve coded up a solution, how can we simplify this without committing serious sins?

We have a select source field, an input target field, and a data reference.

Move the trigger code to a separate function

That code to trigger a change event when the page loads is easier to understand when it’s in a separate function.

function triggerEvent(eventName, el) {
    const event = new MouseEvent(eventName, {
        view: window,
        bubbles: true,
        cancelable: true
    });
    el.dispatchEvent(event);
}
...
triggerEvent("change", companyInfo);

And we can now focus more easily on the rest.

Is it possible to give a function those important things, and have it connect everything together?

Ways that we can simplify

Let’s try it. One possible way is to use a data object:

updateField({
    source: "#companyForm [name=companyInfo]",
    valueCallback: getCompanyRate,
    target: "#companyForm [name=companyRate]"
});

However, a simpler way is to have the function take three arguments. It is possible to just send those selectors to the function instead, but functions tend to be more difficult to use when selectors are used instead of actual element references.

function updateField(source, target, callback) {

}
const form = document.querySelector("#companyForm");
const source = form.elements.companyInfo;
const target = form.elements.companyRate;
updateField(source, target, getCompanyRate);

That looks to be about the simplest we can make it.

The source field is where we get the value from. That value is fed to the callback function which gets the company rate, and the target is where that company rate is placed. It is standard for the callback to be the last argument of the function.

Move code into updateField function

We can now move the remaining code into the updateField function, renaming things like companyInfo to their appropriate counterparts, like source.

function updateField(source, target, callback) {
    // function infoChangeHandler(evt) {
    function infoChangeHandler() {
        // const selectInfo = evt.target;
        // const infoValue = selectInfo.value;
        // const companyRate = getCompanyRate(infoValue);
        // form.elements["companyRate"].value = companyRate;
        target.value = callback(source.value);
    }
    // const companyInfo = form.elements.companyInfo;
    // companyInfo.addEventListener("change", infoChangeHandler);
    source.addEventListener("change", infoChangeHandler);

    triggerEvent("change", source);
}
const form = document.querySelector("#companyForm");
const source = form.elements.companyInfo;
const target = form.elements.companyRate;
updateField(source, target, getCompanyRate);

Inline getCompanyRate

We can inline the getCompanyRate function, making it easier to understand how we use the info value to get the company rate:

updateField(source, target, function getCompanyRate(infoValue) {
    const dataRow = company_data.find(
        (data) => data.company_id === infoValue
    );
    return dataRow.company_rate;
});

The updated code

With the comments of previous code removed, that give us the following code in total:

function triggerEvent(eventName, el) {
    const event = new MouseEvent(eventName, {
        view: window,
        bubbles: true,
        cancelable: true
    });
    el.dispatchEvent(event);
}
function updateField(source, target, callback) {
    function infoChangeHandler(evt) {
        target.value = callback(source.value);
    }
    source.addEventListener("change", infoChangeHandler);
    triggerEvent("change", source);
}

const form = document.querySelector("#companyForm");
const source = form.elements.companyInfo;
const target = form.elements.companyRate;
updateField(source, target, function getCompanyRate(infoValue) {
    const dataRow = company_data.find(
        (data) => data.company_id === infoValue
    );
    return dataRow.company_rate;
});

The updated code is found at https://jsfiddle.net/pmw57/zxp9ytso/

thank you … very informative