Michael
Michael

Reputation: 4390

Replace hyperlink with inline textbox upon click

I would like to create a textbox upon clicking a hyperlink within the body of a webpage.

Scenario:

The user visits the page and is asked a number of questions, they can choose to answer any number of them. To do so, they click on the question (which is formatted as a link so it is clear that you click on it) then a textbox appears. Upon entering the desired answer and hitting enter/on focusout etc the hyperlink is replaced with the resulting text.

I have seen this JSFiddle which was from this question but it doesn't accomplish the desired effect. (code below - not mine)

HTML

<div class="control-group">
    <label for="name" class="control-label">
        <p class="text-info">Saghir<i class="icon-star"></i></p>
    </label>
    <input type="text" class="edit-input" />
    <div class="controls">
        <a class="edit" href="#">Edit</a>
    </div>
</div>

JavaScript

$(document).ready(function() {
    $('a.edit').click(function () {
        var dad = $(this).parent().parent();
        dad.find('label').hide();
        dad.find('input[type="text"]').show().focus();
    });

    $('input[type=text]').focusout(function() {
        var dad = $(this).parent();
        $(this).hide();
        dad.find('label').show();
    });
});

CSS

.edit-input {
    display:none;
}

Upvotes: 0

Views: 1030

Answers (2)

Michael
Michael

Reputation: 4390

So I have decided to answer my own question...

Even though I have accepted the answer Flo gave me earlier, I have since edited my original JSFiddle with his suggestions and my own tinkering around to get my original desired effect.

This will in fact replace the link with a textbox upon clicking (ready for editing) and then revert back to a link with the updated text when you hit the enter key or focus-out of the textbox.

HTML

<div class="control-group">
    <input type="text" class="edit-input" id="tag"/>
    <div class="controls">
        <a class="edit-link" href="#" id="qa">Where does this song remind you of?</a>
    </div>
</div>

JavaScript

$(document).ready(function() {
    $('#qa').click(function () {
//        var dad = $(this).parent().parent();
//        dad.find('#tag').val($(this).text()).show().focus().select();
        $('#tag').val($(this).text()).show().focus().select();
        $('#qa').hide();
    });

    $('#tag').keyup(function(e) {
    var code = (e.keyCode ? e.keyCode : e.which);
    if (code == 13) {

        $(this).hide();
        $('#qa').text($(this).val()).show();
        e.preventDefault();
    }
}).focusout(function() {

        $(this).hide();
        $('#qa').text($(this).val()).show();
});
});

CSS

body {
   font-family: "HelveticaNeue-Light", "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; 
   font-weight: 300;
    font-size: 16px;
}

.edit-input {
    display:none;
    color: #333;
    font-size: 16px;
    font-weight: 300;
    line-height: 16px;
    vertical-align: middle;
    height: 18px;
    border: 1px solid #333;
    width: 400px;
}

a.edit-link {
    text-decoration: none;
    color: #333;
    font-size: 16px;
    font-weight: 300;
    line-height: 16px;
    vertical-align: middle;
    height: 18px;
    width: 400px;
}

Upvotes: 0

Florian Motteau
Florian Motteau

Reputation: 3714

You need to update your label tag content before showing it using .text($(this).val()) on the focusout event :

$(document).ready(function() {
    $('a.edit').click(function () {
        var dad = $(this).parent().parent();
        dad.find('label').hide();
        dad.find('input[type="text"]').show().focus();
    });

    $('input[type=text]').focusout(function() {
        var dad = $(this).parent();
        $(this).hide();
        dad.find('label').text($(this).val()).show();
    });
});

To get it working on the enter keyup you need :

$('input[type=text]').keyup(function(e) {
    var code = (e.keyCode ? e.keyCode : e.which);
    if (code == 13) {
        var dad = $(this).parent();
        $(this).hide();
        dad.find('label').text($(this).val()).show();
        e.preventDefault();
    }
});

You can chain all this :

$('input[type=text]').keyup(function(e) {
    var code = (e.keyCode ? e.keyCode : e.which);
    if (code == 13) {
        var dad = $(this).parent();
        $(this).hide();
        dad.find('label').text($(this).val()).show();
        e.preventDefault();
    }
}).focusout(function() {
    var dad = $(this).parent();
    $(this).hide();
    dad.find('label').text($(this).val()).show();
});

In order to stay DRY (Don't Repeat Yourself) you'd better wrap yout behavior in a function (which has to detect the kind of event to get something like (didn't test) :

$('#youdbettergiveyourinputanidtoo').keyup(your_function).focusout(yourfunction);

...and finally if you're using a recent jQuery version you can do (with on() function) :

$('#youdbettergiveyourinputanidtoo').on('focusout keyup', function(e) {...});

(didn't test too, but you get the idea)

Maybe you could just trigger a focusout event (see trigger() function) on the enter keyup event...lots of solutions.

Good luck with that

Upvotes: 2

Related Questions