0

I have a front-end where I track what element has been clicked and send it back to the server to do some work on the backend depending on what that element is. The code is setup like so...

$('body').on('click', function(e) {
    $.post( '/edit', {el: $( e.target ).serialize()}, function(response) {
        console.log( response );
    });
});

But I get el as an empty string on the server. What else can I do to get the e.target info to my server?

Update:

I think my question could benefit from some context.

The basic function of the app is to enable in-page editing. A node server loads the HTML page I want to edit. Clicking on any element on this page lets me change the text in that element, which is then POSTed back to the node server, where I use the cheerio module to change the DOM representation and overwrite the original HTML file. Reloading the page now gives me the new version of the page with the edits I had made.

But to apply the edits I have made on the front-end, cheerio needs the e.target to find the right element in its DOM representation and then change the text, since many of the elements on the page don't have ids.

This is the whole app...

var
    express  = require( 'express' )
,   fs       = require( 'fs' )
,   cheerio  = require( 'cheerio' )
,   $        = ''
,   app      = express()
,   html     = ''
,   injected = "<script> \
                    $( 'body').on( 'click', function(e) {  \
                        $( e.target ).text( prompt('Enter new value:') );  \
                        $.post( '/edit', {el: $(e.target).serialize(), newVal: $(e.target).text()}, function(response) {  \
                            alert( response );  \
                        });  \
                    });  \
                </script>";

app.use( express.static(__dirname) )
app.use( express.bodyParser() )


app.get( '/', function( req, res ) {
    fs.readFile( process.argv[2], 'utf8', function(err, data) {
        $ = cheerio.load( data )
        err? console.log( err ): res.send( data.replace('</body>', injected + '</body>') )
    })
})

app.post( '/edit', function(req,res) {
    $( req.body.el ).text( req.body.newVal )
    fs.writeFile( process.argv[2], $.html(), function(err) {
        err? res.send( err ): res.send( 'file saved with changes!' )
    })
})

app.listen( 8080 )

I then run the app:

node cms.js "E:\Dropbox\sites\index.html"

Theoretically, this should let me edit index.html "in-page" and without a code editor. But getting the e.target back to the server intact remains the hurdle.

Workaround:

My current workaround is to just POST the entire HTML of the page using $( 'html' ).html() so regardless of which element is clicked, I can get the new state of the page in it's entirety and overwrite the existing file with this new state. But I have browser extensions that inject their own HTML/JS and I want to avoid the painful process of stripping those away before saving to file. For that, I need to tell cheerio exactly which element has been clicked.

vjk2005
  • 678
  • 1
  • 12
  • 23
  • it depends on what you expect to receive at the server side – amakhrov Aug 10 '13 at 14:18
  • what is you are looking for? what kind of data has to be sent – Arun P Johny Aug 10 '13 at 14:19
  • 8
    `serialize` is for converting **form** control elements to a string (name + value). `e.target` is a DOM node, which is an object. Since you cannot simply send such objects between servers, what exactly do you need from the node? How would a "serialized" DOM element look like for you? – Felix Kling Aug 10 '13 at 14:20
  • JSON.stringify the props after extracting the ones you want – mplungjan Aug 10 '13 at 14:27
  • 2
    @FelixKling Surely you meant to say "One cannot simply _send DOM Objects_ into _a Server_" – Paul S. Aug 10 '13 at 14:37
  • @PaulS.: Does it matter? Server, clients are all just computers anyway ;) And all objects have to be serialized first somehow before they can be sent. But yeah, I basically meant that. – Felix Kling Aug 10 '13 at 14:42
  • I've added some more context to help clear things up a bit. I got the point about `serialize()` being the wrong way to go, but the problem of getting `e.target` back to the server still remains. – vjk2005 Aug 10 '13 at 14:55

1 Answers1

0

Serialize works on forms and generates output similar to what your query string would be, single=Single&multiple=Multiple&multiple=Multiple3&check=check2&radio=radio1

You may want to check this answer, I use it here to get the html of the button when it's clicked:

HTML

<input id="b" type="button" value="click" /> 

JS

$("#b").click (function (e) {
    window.alert($(e.target).outerHTML());
});

jQuery.fn.outerHTML = function(s) {
    return s
        ? this.before(s).remove()
        : jQuery("<p>").append(this.eq(0).clone()).html();
};
Community
  • 1
  • 1
Nabil Kadimi
  • 10,078
  • 2
  • 51
  • 58
  • *"The reason why it's empty is because the element you clicked has no innerHTML"*: How do you know that? It's incorrect anyways. If the result is empty, then the target element is neither a `form` element nor a form control element (such as `input` or `select`). – Felix Kling Aug 10 '13 at 14:39
  • Thanks, I was editing by the time you were writing your comment )) – Nabil Kadimi Aug 10 '13 at 14:39