2

Here is the working demo of what I want to achieve. Just enter some value in input and you might get what I want to achieve. (Yes, I got it working but stay on..)
But it fails when multiple keys are pressed together.

What I am trying :
I have screen which contains few enabled and few disabled input elements. Whenever user updates any value in editable input element, I want to update disabled input which had same value with user updated value.

HTML :

<input value="foo" />   // When User updates this
<br/>
<input value="bar">
<br/>
<input value="Hello">
<br/>
<input value="World">
<br/>
<input value="foo" disabled>  // this should be updated
<br/>
<input value="bar" disabled>
<br/>
<input value="foo" disabled>  // and this also
<br/>
<input value="bar" disabled>
<br/>
<input value="Happy Ending!">
<br/>  

I tried this which I think will save me from multiple_clicks_at_a_time
JS:

$(":input:not(:disabled)").keyup(function () {
    // Get user entered value
    var val = this.value;

    // Find associated inputs which should be updated with new value
    siblings = $(this).data("siblings");
    $(siblings).each(function () {
         // Update each input with new value 
         this.value = val;
    });
});

$(function () {
    $(":input:not(:disabled)").each(function () {
        // Find inputs which should be updated with this change in this input
        siblings = $(":input:disabled[value=" + this.value + "]");

        //  add them to data attribute   
        $(this).data("siblings", siblings);
    });
});

But I am not able to pass the selectors to keyup function and invoke .each on it.


PS:

My previous completely different try, working with single_click_at_a_time but I felt that I am unnecessarily traversing the DOM again and again so dropped this

$(":input").keypress(function () {
    $(this).data("oldVal", this.value);
});

$(":input").keyup(function () {
    var oldVal = $(this).data("oldVal");
    $(this).data("newVal", this.value);
    var newVal = $(this).data("newVal");

    $("input:disabled").each(function () {
        if (this.value == oldVal) this.value = newVal;
    });
});
9
  • 2
    Why are you storing the siblings with .data() instead of selecting them when you're actually ready to use them? And why are you re-jQueryifying them in the keyup callback? Commented Mar 4, 2013 at 18:43
  • 3
    Why are you binding the keyup event outside of the DOMready function? Commented Mar 4, 2013 at 18:45
  • @Bergi probably because all of this code is running on window load in the fiddle. Not that that's an excuse... Commented Mar 4, 2013 at 18:48
  • @MattBall: Because in keyup I wont have old input value so thought its better to find the required input with required values on page load itself. Commented Mar 4, 2013 at 18:48
  • @Bergi: Not much into jQuery, I used to keep all custom functions outside the document.ready so just followed my bad habits..My bad Commented Mar 4, 2013 at 18:50

2 Answers 2

2

I would group those inputs first and bind a handler for enabled elements to apply to the group. See below,

var grpInp = {};

$(":input").each(function () {
    if (grpInp.hasOwnProperty(this.value)) {
        grpInp[this.value] = grpInp[this.value].add($(this));
    } else {
        grpInp[this.value] = $(this); 
    }
});

$.each(grpInp, function (i, el) {    
    el.filter(':enabled').keyup(function () {
        el.val(this.value);
    });
});

DEMO: http://jsfiddle.net/fjtFA/9/

The above approach basically groups input element with same value, then filters them based on :enabled and bind a handler to apply it to the group.

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

3 Comments

Oh gosh.Short and sweet but I just dont understand it. Will be great if you can add some light on it.
Group all input elements by value. After that first .each The grpInp object will look like {foo: [input1, input4, input6], ...} in which input1 is the first element with value foo, input4 is the fourth input element which has value foo. So basically it groups down input by value. The second iterate is used to iterate by group and bind a keyup handler to the enabled elements in the group. The handler simply updates the value to all elements in the group.
A lot better than mine. But will accept Bergis answer he points out my mistake and gave answer in my way. Thanks a lot though..
1
// Find associated inputs which should be updated with new value
siblings = $(this).data("siblings", siblings);

No. The .data method called with two arguments does not get, but set the data (and returns the current selection). Also, you should make your variables local:

var siblings = $(this).data("siblings");

Working demo

5 Comments

Oops, my copy paste blunder. Was not working with that also jsfiddle.net/Ajinkya_Parakh/fjtFA/10. Still +1 for pointing it out
cant we store jQuery objects (may be in data) and retrieve them and call any function on them like .each?
You can. See my working demo. In your version 10 fiddle you somehow stored the siblings value on the siblings' data properties.
Exactly what I trying. But if I try the same code in my way like defining it outside the DOM it doesnt work. What diff exactly it make if I dont define it as callback?
In v13 you did forgot the dot right before keyup(), check your error console for the syntax error. Btw, :input:disabled[value=Happy Ending!]" is no valid selector, leading to unexpected behaviour - better use an exact filter function

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.