3

I'm trying to append a transparent layer to some elements with an edit button within. The edit button has an onclick function. The value transfered with the onclick is an ID from the parent element (whom the transparent layer is appended upon)

My problem is, that all the edit buttons unfortunately carry the same value: cms-block-3.

What am I doing wrong?

I hope I explained myself properly. Thanks in advance!

Example of HTML:

<div class="editable cms-block-1">Some</div>
<div class="editable cms-block-2">Someting else!</div>
<div class="editable cms-block-3">Something else else! :)</div>

$(document).ready(function() {
    $('.editable').each(function(index) {

        $($(this).attr('class').split(' ')).each(function() { 
            if (this !== '' && this.substring(0, 3) == "cms") {
                element = this.toString();
            }
        });

        var $t = $(this);
        var offset = $t.offset();
        var dim = {
            left:    offset.left, 
            top:    offset.top, 
            width:    $t.outerWidth(), 
            height:    $t.outerHeight()
        };

        $('<div class="editable-focus"></div>').css({
            position:    'absolute', 
            left:        dim.left + 'px', 
            top:        dim.top + 'px',
            width:        dim.width + 'px',
            height:        dim.height + 'px'
        }).appendTo(document.body).append('<input type="button" value="Edit" class="edit-btn" onclick="edit_area(element)" />');
    });
});
2
  • 1
    Why are all the quotes escaped? Commented Jan 12, 2012 at 14:08
  • $($(this).attr('class').split(' ')) This seems crazy... Commented Jan 12, 2012 at 14:24

6 Answers 6

3

With this code, your button HTML ends up being literally

<input type="button" value="Edit" class="edit-btn" onclick="edit_area(element)" />

Based on your description, it should rather be something like

<input type="button" value="Edit" class="edit-btn" onclick="edit_area('some_id')" />

But then again, your editable divs do not have an id so with the current HTML this would not work either.

Apart from this, your problem is that by writing element you are actually referencing window.element, which returns the last value assigned to it.

Here's a fix:

$('.editable').each(function(index) { 
    var element; // ADD THIS TO MAKE element A LOCAL VARIABLE

    // [...]

    var $button = $('<input type="button" value="Edit" class="edit-btn" />');
    $('<div class="editable-focus"></div>').css({
        position:    'absolute',
        left:        dim.left + 'px',
        top:        dim.top + 'px',
        width:        dim.width + 'px',
        height:        dim.height + 'px'
    }).appendTo(document.body).append($button);

    // And now you can write your event handler without fuss like this:
    $button.click(function() { alert(element); });

See it in action.

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

1 Comment

I appreciate your effert Jon. It's working nicely. I'll read up about global / local variables.
0

You need to insert the value of "element" not the variable itself, which changes. This is why you see the final value "cms-block-3" every time.

Change:

onclick="edit_area(element)"

To:

onclick="edit_area(\"'+element+'\")"

2 Comments

This defintely transfers the element values. However it gives me an error: cms* is not defined when clicking.
Post the new HTML output if you can here or on jsfiddle.net. It may just be a quote issue,
0

You have to add the content of the element variable instead of the variable itself to the input:

}).appendTo(document.body).append('<input type="button" value="Edit" class="edit-btn" onclick="edit_area(\''+element+'\')" />');

Because the element variable will always the value of the last element in the loop. (You shouldn't define it as a global variable by leaving out the var in front of its declaration by the way)

Comments

0

In your code.

element is a global object. Then, you created your button with onclick="edit_area(element)".

So, whenever you click the button, the browser pass the global object element to the function. But the element got the last value you assigned it in the iteration.

Comments

0

Well first of all, you are not declaring element so it's a global variable.

Secondly:

'<input type="button" value="Edit" class="edit-btn" onclick="edit_area(element)" />'

Is just a string, it has no idea of the context you are creating it in, so edit_area(element) will be called in global context. This conveniently doesn't throw an error because you forgot to declare element and it's a global variable so it uses that.

Replace with:

.append($('<input>', {
    type: "button",
    val: "Edit",
    'class': "edit-btn",
    click: function () {
        edit_area(element);
    }
}));

And declare element

$('.editable').each(function(index) {
    var element;
....

Comments

0

The problem here is that for each of your input the onlick handler equals "edit_area(element)"

element is a variable so it will have only one value (ie: the last value it was given)

What you wanna do here is pass the value of element and not the reference to the variable.

$('<div class="editable-focus"></div>').css({
            position:    'absolute', 
            left:        dim.left + 'px', 
            top:        dim.top + 'px',
            width:        dim.width + 'px',
            height:        dim.height + 'px'
        }).appendTo(document.body).append('<input type="button" value="Edit"   class="edit-btn" onclick="edit_area(\'' + element +'\')" />');

This corrected code should do the trick.

As to your comment above my guess is that your function edit_area doesn't expect a string as an input but expects a DOM element or a jQuery object maybe?

There are several fixes depending on where you want to modify your code. The easiest way to fix that would be to retrieve the dom element based on the css class we give to the function as a parameter.

So at the beginning of your edit_area function just add :

var myElement = $('.' + element);

Comments

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.