Rich-text Reply

Re-binding event callbacks to DOM elements replaced by Optimizely

pchung 04-04-16
Accepted Solution

Re-binding event callbacks to DOM elements replaced by Optimizely

I'm using optimizely to change the color of an input label on my site. I'm using React.js on my site. The input label is rendered with React, which then binds an event to the input (id=fileupload), like so:

 

<label className="file-upload-label">
<input className="file-upload-input" id="fileupload" name="file" type="file" data-url="/my/api/upload"></input>
<span>Upload File</span>
</label>

 

function bindEventCallbacks() {
var oneMegabyte = 1000000;
$('#fileupload').fileupload({
acceptFileTypes: /(\.|\/)(pdf|doc|docx)$/i,
maxFileSize: oneMegabyte,
})
.bind('fileuploadprocessfail', function(e, data) {
UploadFormActionCreators.validationError(data);
})
}

However, pressing the button with the new color does not seem to trigger the event. I did a stack trace and found that Optimizely is actually doing a complete replacement of the label element (along with the input and span inside it), rather than changing the color of the existing label:

 

Optimizely does this:

 

"$(".file-upload-label").replaceWith("
<label class=\"file-upload-button\"
data-reactid=\".0.1.$=1$upload.0.3.0\"
style=\"background-color:#c00e00\">
<input class=\"file-upload-input\"
id=\"fileupload\"
name=\"file\"
type=\"file\"
data-url=\"/my/api/upload\"
data-reactid=\".0.1.$=1$upload.0.3.0.0\">
<span data-reactid=\".0.1.$=1$upload.0.3.0.1\">
Upload File
</span>
</label>");"

So the problem seems to be that by totally replacing the <input> element that I originally had with a new one from Optimizely, I lose the event callbacks that were bound to my original <input> element.

 

Is there an easy way to re-bind my events to the new <input> element?

 

The Optimizely snippet is placed above my script tag, but they seem to be running in async, so React renders my view before Optimizely replaces it. I want to try and use the experiment javascript feature in Optimizely to just re-bind the event by calling my original bindEventCallbacks() function again, but it is out of scope. Also, since my site is built using React, I'm not sure if I can just rebind those events without re-rendering the entire view again (if I re-render the view again, then I'll just get the original color, not the modified color by Optimizely)

 

Any thoughts on how to re-bind this event?

 

Level 2

pchung 04-04-16
 

Re: Re-binding event callbacks to DOM elements replaced by Optimizely

[ Edited ]

I solved this using event delegation to delegate the event to the parent DOM element. See: http://stackoverflow.com/questions/34857109/how-to-rebind-jquery-event-handlers-after-replacewith-e-...

Level 2
JesseB 04-07-16
 

Re: Re-binding event callbacks to DOM elements replaced by Optimizely

Do you mind to share the code that you used? I think that will help a few people.
Level 1