Condensing a lengthy list by utilizing an array element

I require assistance,

Looking at the code below, it is evident that I will have a lengthy list of code to handle an onblur and on focus scenario for a div and an input field. Is there a more efficient way to achieve this without writing separate lines of code for each instance? With over 20 fields, the amount of code on the page will become excessively long.

document.getElementById('f1').onfocus = function() {
    document.getElementById('f1').style.border = '1px solid #0033CC'
    document.getElementById('div_rssims_prefix').style.color = '#0033CC'    
}
document.getElementById('f1').onblur = function() {
    document.getElementById('f1').style.border = '1px solid #ABADB3'
    document.getElementById('div_rssims_prefix').style.color = ''   
}
document.getElementById('f2').onfocus = function() {
    document.getElementById('f2').style.border = '1px solid #0033CC'
    document.getElementById('div_rssims_firstname').style.color = '#0033CC' 
}
document.getElementById('f2').onblur = function() {
    document.getElementById('f2').style.border = '1px solid #ABADB3'
    document.getElementById('div_rssims_firstname').style.color = ''    
}
document.getElementById('f3').onfocus = function() {
    document.getElementById('f3').style.border = '1px solid #0033CC'
    document.getElementById('div_rssims_middlename').style.color = '#0033CC'    
}
document.getElementById('f3').onblur = function() {
    document.getElementById('f3').style.border = '1px solid #ABADB3'
    document.getElementById('div_rssims_middlename').style.color = ''   
}

An optimal solution would involve:

f1,div_rssims_prefix
f2,div_rssims_firstname
f3,div_rssims_middlename

and so forth.

Answer №2

To simplify event assignment, you can utilize a JavaScript object to map the fields and then iterate through it to set the events accordingly.

Check out this working example: http://jsfiddle.net/jZCQV/1/

var fieldEventsMap = {
    "field1": "div_rssims_prefix",
    "field2": "div_rssims_firstname",
    "field3": "div_rssims_middlename"
}

for (var fieldID in fieldEventsMap) {
    document.getElementById(fieldID).onfocus = function(id){
        return function(){applyFocusStyle(id)};
    }(fieldID);
    document.getElementById(fieldID).onblur = function(id){
        return function(){applyBlurStyle(id)};
    }(fieldID);
}

function applyFocusStyle(id) {
    document.getElementById(id).style.backgroundColor = 'aliceblue';
    document.getElementById(fieldEventsMap[id]).style.color = 'mediumblue';
}

function applyBlurStyle(id) {
    document.getElementById(id).style.backgroundColor = '';
    document.getElementById(fieldEventsMap[id]).style.color = '';
}

Answer №3

If you desire the code to function in the same way with the current DOM structure, follow this approach:

setupFocusBlurList([
    'f1,div_rssims_prefix',
    'f2,div_rssims_firstname',
    'f3,div_rssims_middlename'
]);

function setupFocusBlurList( elements ) {
    for( var i = 0;  i < elements.length;  i++ ) {
        var ee = elements[i].split(),
            input = document.getElementById( ee[0] ),
            div = document.getElementById( ee[1] );
        setupFocusBlur( input, div );
    }
}

function setupFocusBlur( input, div ) {
    input.onfocus = function() {
        input.style.border = '1px solid #0033CC';
        div.style.color = '#0033CC';
    };
    input.onblur = function() {
        input.style.border = '1px solid #ABADB3';
        div.style.color = '';
    };
}

However, there are alternative methods that could simplify this process. Do you have the ability to modify the HTML structure? Can jQuery be utilized? Depending on the HTML structure and jQuery usage, this code can be streamlined significantly.

For instance, consider structuring the HTML like this:

<div id="input-list">

    <div>
        <input id="f1" class="input-hilite">
        <div class="div-hilite" id="div_rssims_prefix"></div>
    </div>

    <div>
        <input id="f2" class="input-hilite">
        <div class="div-hilite" id="div_rssims_firstname"></div>
    </div>

    <div>
        <input id="f3" class="input-hilite">
        <div class="div-hilite" id="div_rssims_middlename"></div>
    </div>

</div>

Incorporating jQuery, you could use this code:

setupFocusBlurList( '#input-list' );

function setupFocusBlurList( wrapper ) {
    setupStyle( 'focus', '1px solid #0033CC', '#0033CC' );
    setupStyle( 'blur', '1px solid #ABADB3', '' );

    function setupStyle( event, inputBorder, divStyle ) {
        $(wrapper).on( event, '.input-hilite', function() {
            $(this).css( 'border', inputBorder )
                .parent().find('.div-hilite')
                    .css( 'color', divColor );
        });
    }
}

The code provided above could be simplified further depending on the specific HTML structure. Additionally, if the HTML resembles the example in Xotic750's answer:

<div id="container">
    <div id="div_rssims_prefix">Prefix
        <input id="f1" type="text" value="Prefix">
    </div>
    <div id="div_rssims_firstname">First Name
        <input id="f2" type="text" value="First Name">
    </div>
    <div id="div_rssims_middlename">Middle Name
        <input id="f3" type="text" value="Middle Name">
    </div>
</div>

Simply adjust the selectors accordingly in the jQuery code to achieve the desired functionality. In either case, note that using jQuery's event delegation method results in a more efficient code structure compared to traditional JavaScript approaches, especially with a large number of input fields.

Answer №4

Why not consider a different approach? Do you really have to store an array or list of IDs within your script? This solution should function well on IE7, although I am unable to test it myself.

Here is a suggested HTML structure:

<div id="container">
    <div id="div_rssims_prefix">Prefix
        <input id="f1" type="text" value="Prefix"></input>
    </div>
    <div id="div_rssims_firstname">First Name
        <input id="f2" type="text" value="First Name"></input>
    </div>
    <div id="div_rssims_middlename">Middle Name
        <input id="f3" type="text" value="Middle Name"></input>
    </div>
</div>

And the corresponding Javascript code:

var container = document.getElementById("container"),
    length1 = container.childNodes.length,
    i = 0,
    node1,
    length2,
    node2,
    j;

while (i < length1) {
    node1 = container.childNodes[i];
    if (node1 && node1.nodeType === 1 && /^div_rssims_\S+$/.test(node1.id)) {
        length2 = node1.childNodes.length;
        j = 0;
        while (j < length1) {
            node2 = node1.childNodes[j];
            if (node2 && node2.nodeType === 1 && /^f\d+$/.test(node2.id)) {
                node2.onfocus = function () {
                    this.style.border = 'solid 1px #0033CC';
                    this.parentNode.style.color = '#0033CC'
                }

                node2.onblur = function () {
                    this.style.border = 'solid 1px #ABADB3';
                    this.parentNode.style.color = ''
                }
            }

            j += 1;
        }
    }

    i += 1;
}

You can also view it on jsfiddle.

Alternatively, here's a more generic approach based on guessed HTML:

Javascript

function getElementsById(node, regex) {
    var nodeList = arguments[2] || [];

    if (node.nodeType === 1) {
        if (regex.test(node.id)) {
            nodeList.push(node);
        }

        node = node.firstChild;
        while (node) {
            getElementsById(node, regex, nodeList);
            node = node.nextSibling;
        }
    }

    return nodeList;
}

var inputs = getElementsById(document.getElementById("container"), /^f\d+$/),
    length = inputs.length,
    i = 0,
    node;

while (i < length) {
    node = inputs[i];

    node.onfocus = function () {
        this.style.border = 'solid 1px #0033CC';
        this.parentNode.style.color = '#0033CC'
    }

    node.onblur = function () {
        this.style.border = 'solid 1px #ABADB3';
        this.parentNode.style.color = ''
    }

    i += 1;
}

You can find this version on jsfiddle.

If you have control over your markup, consider a layout like this instead:

CSS

label {
    float: left;
    margin-right: 5px;
}
input {
    display: block;
}

HTML

<div id="container">
    <label for="f1">Prefix</label>
    <input id="f1" type="text" value="Enter value"></input>
    <label for="f2">First Name</label>
    <input id="f2" type="text" value="Enter value"></input>
    <label for="f3">Middle Name</label>
    <input id="f3" type="text" value="Enter value"></input>
</div>

Corresponding Javascript:

function getElementsById(node, regex) {
    var nodeList = arguments[2] || [];

    if (node.nodeType === 1) {
        if (regex.test(node.id)) {
            nodeList.push(node);
        }

        node = node.firstChild;
        while (node) {
            getElementsById(node, regex, nodeList);
            node = node.nextSibling;
        }
    }

    return nodeList;
}

function getPreviousSibling(element) {
    var p = element;

    do {
        p = p.previousSibling;
    } while (p && p.nodeType !== 1);

    return p;
}

var inputs = getElementsById(document.getElementById("container"), /^f\d+$/),
    length = inputs.length,
    i = 0,
    node;

while (i < length) {
    node = inputs[i];

    node.onfocus = function () {
        if (this.value === "Enter value") {
            this.value = "";
        }

        this.style.border = 'solid 1px #0033CC';
        getPreviousSibling(this).style.color = '#0033CC'
    }

    node.onblur = function () {
        if (this.value === "") {
            this.value = "Enter value";
        }

        this.style.border = 'solid 1px #ABADB3';
        getPreviousSibling(this).style.color = ''
    }

    i += 1;
}

You can check out this version on jsfiddle.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What's the best way to add a jQuery event handler to several cached selectors at once?

Imagine having three buttons <button data-action="grow" class="resizeButton">Grow</button> <button data-action="shrink" class="resizeButton">Shrink</button> <button id="normalButton">Normal Button</button> All buttons ...

How can I make Requirejs and Threejs OrbitControls work together?

Having trouble implementing OrbitControls with requirejs. Here's my configuration: I attempted to follow guidance from this post on Stack Overflow RequireJS and THREE.js Orbit Controls, but it's not working. requirejs.config({ baseUrl: &ap ...

We encountered a problem while trying to create the route "/": Minification of HTML failed in Nuxt js

After successfully developing a Nuxt app that runs perfectly with "npm run dev," I encountered an error when generating the site using "npx nuxt generate." Despite my efforts, I cannot locate the source of the error. Any assistance would be greatly appre ...

What is the process of creating multiple entities in Three.js?

I am struggling to create a scenario where multiple objects fall from the top in my project. My attempt at duplicating the code has not been successful. Below is the code snippet I have been working on: var renderer = new THREE.WebGLRenderer({canvas: doc ...

Testing out a login form in Vue framework

Hi there! I recently put together a login form using the Vue.js framework, and now I'm looking to write some tests for my API calls. Although I'm still new to Vue.js, I'm eager to learn more about testing in this environment. Here's th ...

Managing extensive amounts of data with server-side scripting in a Datatable

I am exploring the use of the datatable plugin to effectively manage a large amount of data. Currently, I am interested in implementing "server side processing in datatables" with the help of server-side scripting. Since I have limited experience with AJA ...

Making the toggle button functional on the navbar

Trying to customize my navbar for tablet and mobile devices is proving to be a challenge. I am looking for a way to make the dropdown button take up the entire page when clicked on. It seems like JavaScript might be the solution, but I'm not quite sur ...

Is it possible to convert a string using object-to-object syntax?

After running a particular function, I received the following results: [ "users[0].name is invalid", "date is invalid", "address.ZIP is invalid" ] I am looking for a way to convert this output from object syntax i ...

Delete an entry in a singular mapping in a one-to-one connection [TypeORM]

Is there a way to remove an index from a one-to-one relationship in TypeORM? @OneToOne(() => Customer, { cascade: true }) @JoinColumn({ name: 'customer', referencedColumnName: 'uid' }) customer: Customer I searched the d ...

What is causing the role="status" attribute to malfunction?

I'm having an issue with the role="status" attribute in my code. When using a screen reader, the paragraph text doesn't get read once it's appended to the body. index.html: <!DOCTYPE html> <html> <head> <title> ...

Using an array of objects to set a background image in a Bootstrap carousel using jQuery: a step-by-step guide

I have an array of items, each containing a background property with a URL to an image. Here is my array: https://i.sstatic.net/jfrV0.png Here is the HTML structure: <div id="myCarousel" class="carousel slide" data-ride="carousel"> <ol ...

The noclose feature in Twitter Bootstrap is malfunctioning when placed within a div

I have a PHP page named a.php that contains the following code: <ul class="dropdown-menu noclose"> This code functions correctly, preventing the drop-down menu from closing until the user clicks outside the box. However, when I load the entire a.p ...

Move the divs within the overflow container by sliding them, then take out the initial element and append it to the end

Currently, when I utilize .appendTo(".wrapper") as shown in the code below, it eliminates the animation effect. My goal is to have the div on the far left slide out of view, triggering an overflow hidden effect, and then be placed at the end of the slide c ...

Cross-Origin Resource Sharing problem encountered with the webservice thumbnail.ws

I am attempting to create an HTML page that generates a snapshot of a URL using the free webservice provided by thumbnail.ws. Below is my code snippet: var myurl = "http://api.thumbnail.ws/api/API_KEY/thumbnail/get?url=http://maps.google.com/?q=36.82 ...

What seems to be the issue with my code for Javascript Math functions?

Welcome to the number game slider! If you roll above 50, you will get double the amount bet. Use the slider to choose your desired betting amount. Issue 1: After a win, the score does not update correctly. Instead of showing increments of 5, it displays s ...

Issue with Ajax POST request: encountering a 500 internal server error

I am facing an issue with my project when I try to run it. Whenever I attempt to run the project, I encounter a 500 internal server error. Here is a snippet of my code: Client.cs public class Client { public Client(string firstName, string id ...

Tips for extracting data from div tags that share the same id

Html <!DOCTYPE html> <html> <body> <div id="one"> welcome <div class="two"> hello world </div> <div class="two"> bye world </div> < ...

Exploring test suite pathways while utilizing ArcGIS JSAPI as an alternative loader within the Intern framework

I have been developing an application using the ArcGIS Javascript API and incorporating tests with Intern. While working on Windows 7 under IIS, I encountered some challenges but managed to overcome them by following the Intern tutorial and referring to so ...

What can be done to ensure smooth functionality of my nested navigation menu on mobile devices?

I'm utilizing the incredible features of Base Web for my website. One of the components I am using is a menu with a child menu, based on this example. The menu works perfectly fine on desktop - when I hover over an option, the child menu appears. Howe ...

Utilizing ObjectLoader for loading JSON featuring a BufferGeometry with multiple materials is not successful

I have successfully crafted a sphere using multiple materials in the following manner: const materials = [ new THREE.MeshPhongMaterial({}); new THREE.ShaderMaterial({ visible: false}); ] const geometry = new THREE.SphereBufferGeometry(2,100,100); ...