What is the correct way to send Javascript code along with a rendered HTTP client?

In the middle of development, I decided to switch to server-side rendering for better control, among other benefits . My web application is completely AJAX-based, doesn't redirect URLs, so the idea here is a website that builds itself

I just couldn't figure out how to properly send javascript events / functions along with the html string, or would all the necessary javascript always be preloaded into static files?

Suppose a customer clicks the open table preview button

The server will fulfill the request, build the html table and send it back, but this table also needs triggers and javascript functions to work correctly, how are they sent, received and executed?

There are several articles that mention that not using eval () in Javascript, is there a way around this? I do not want to preload unnecessary events for elements that do not yet exist.

Python server and client - Javascript / JQuery

Theoretical example:

Javascript client base:

$("body").on("click", "#open_table", function() { $.getJSON('/get_table', function(response){ $("#table_div").append(response.html); eval(response.javascript()); //?? } }); 

Python server (views.py):

 def get_table(request): data = {} #String containing rendered html data['html'] = get_render_table() #String containing Javascript code? data['javascript'] = TABLE_EVENTS_JAVASCRIPT return HttpResponse(json.dumps(data),content_type='json') 

It is worth noting that my question comes from an experimental / educational perspective

+5
source share
4 answers

Update:

You can use jQuery.getScript () to lazily load JS. I think this solution is as close as you can start JS without using eval ().

See this example:

 jQuery.getScript("/path/to/script.js", function(data, textStatus, jqxhr) { /* Code has been loaded and executed. */ console.log( data ); // Data returned console.log( textStatus ); // Success console.log( jqxhr.status ); // 200 console.log( "Load was performed." ); }); 

and "/ path / to / script.js" may be the string returned from the $ .getJOSN response.

In addition, the documentation for getScrippt () contains examples of how to handle errors and cache files.

Old answer:

Using . on () attaches events to current and future DOM elements. You can either do certificates before entering the DOM, or after after inserting the DOM.

So in your example you can do something like:

 $("body").on("click", "#open_table", function() { $.getJSON('/get_table', function(response){ var code = $(response.html); code.find(".elementToFind").on("click", function (){ // Code to be executed on click event }); $("#table_div").append(code); } }); 

I have not tested the code, but I think it should work.

+6
source

Assuming that you cannot just configure the event binding function and then call it from the main script (e.g. JavaScript, which you don't need to guess ahead of time), then one very simple way is to simply add JavaScript to the bottom of the returned HTML content in script tags. When it is added along with HTML, the script should just execute, without the need for eval ().

I cannot swear that this will work in older browsers, but this is a trick that I used a couple of times and I did not have any problems with it in Firefox, Chrome or any of the later versions of IE.

+1
source

I think I see what you are asking here, from my understanding you want to asynchronously send a new "page" and render new javascript and html. It looks like you already have your request / response, so I'm not going to talk about sending JSON objects and how you send html and javascript, because it looks like you got this part. To do what you want and dynamically add your javascript, this stackoverflow question looks like you have what you need Is there a way to create a function from a string with javascript?

So, as for your example, here is what it will look like when you get the JSON string from your python script:

 $("body").on("click", "#open_table", function() { $.getJSON('/get_table', function(response){ $("#table_div").append(response.html); /* Create function from string */ var newFunction = Function(response.javascript['param_1'], response.javascript['param_2'], response.javascript['function']); /* Execute our new function to test it */ newFunction(); } }); 

* Your actual function contents will be a string: response.javascript['function']
* Your parameter names, if they were on separate lines ex: response.javascript['param_1']

This is an almost direct copy of the "String to function" code that you see in the related question, just replaced it with the appropriate code. This code also assumes that your object is dispatched with a response.javascript object containing an array with your actual function contents and parameter names. I'm sure you could change the actual var name too, or maybe put it in an associative array or something that you can track and rename. All are just suggestions, but I hope this works for you and helps you solve your problem.

+1
source

I also do a similar job in my project where I had to load partial html using ajax calls, and then this partial HTML has elements that require event binding. So my solution is to create a generic method for making ajax calls and save the name of the js method for making the post ajax call in the html response itself. For example, my server returns below html

 <input type="hidden" data-act="onPartialLoad" value="createTableEvents" /> <div>.........rest of html response.....<div> 

Now in the general method, find input [type = 'hidden'] [data-act = 'onPartialLoad'] and for each run the method name specified in the value attribute (value = "createTableEvents")

Do not use the Eval () method as it is not recommended due to security issues. Check here .

you can run the js method using window ["method name"] ... so here is the part of the code I'm using.

 $.ajax(options).done(function (data) { var $target = $("#table_div"); $target.fadeOut(function () { $target.html(data); $target.fadeIn(function () { try { $('input[data-act="onPartialLoad"]', $target).each(function () { try { //you can pass parameters in json format from server to be passed into your js method var params = $(this).attr('params'); if (params == undefined) { window[$(this).val()](); } else { window[$(this).val()]($.parseJSON(htmlutil.htmlDecode(params))); } } catch (e) { if (console && console.log) { console.log(e.stack); console.log($(this).val()); } } }); } catch (e) { console.log(e.stack); } }); }); }); 

use jQuery.getScript () (as suggested by Kalimah Apps) to download the necessary js files first.

+1
source

Source: https://habr.com/ru/post/1261059/


All Articles