I am developing web application in smartAdmin Template, which is fully ajax based template you can check demo here. i am facing some difficulties in this template. when i write one javascript function on some page it works on all pages.
for example
$(document).on('click', '#elementA', function(){
alert('Hello World');
});
works on other pages's element which also have same id, it is difficult to give different ids to all element as it is very large project and i am working on it since 6 months, so i thought about it and find out solution to give unique id to each pages and write script like this.
$(document).on('click', '#pageA #elementA', function(){
alert('Hello World');
});
i thought i solved the issue but, isn't function stopped working on other page's element. but when i visit #PageA 2nd time the function runs twice. actually template stores all the user defined function in local memory storage (i think, i am not sure about this) and keeps storing, until we do not refresh whole template.
ok, after long R&D i solved this my self..
i used loadscript() function to prevent loading scripts twice unnecessarily..
i wrote all the script into one file (now i will have two view pages for one page.)
earlier it was like..
A.php -> JScript + PHP & HTML
now it is like A.php -> PHP & HTML, script/A.php -> OnlyJS
as i am using codeginiter framework, and dont want others too see js by accessing it through url, i used this process.
code on my view file
loadScript("<?php echo site_url('processor/load_script/path_to_folder/script/add'); ?>");
function on Processor controller
public function load_script($path)
{
$last_segment = count($this->uri->segment_array());
$path = '';
for($i=3;$i<=$last_segment;$i++)
{
$path .= '/'.$this->uri->segment($i);
}
$this->load->view('core/ajax'.$path);
}
Related
I just finished localizing my web application using spring boot configuration as a base.
#Bean
public LocaleResolver localeResolver() {
return new CookieLocaleResolver();
}
Due to a requirement one is supposed to be able to change locale/language of the website by pressing a button. Said function is implemented with a little bit of JS and a cookie.
<script>
function updateCookie(lang) {
let name = "org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE"
document.cookie = name+"="+lang
location.reload()
}
</script>
<a onclick="updateCookie('de')" class="flag-icon flag-icon-de mr-2"></a>
The idea is to update said cookie on click of a button and use it throughout the whole application. This works fine until I am trying to call a specific endpoint in my application.
In order to debug my application I use:
window.onload = function () {
alert(document.cookie)
}
Now to my problem:
When User-Testing the application this is the alert-feedback:
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=de
Switching to other pages, refreshing, changing language etc. properly resets the cookie with a different value.
When calling a specific endpoint though, I get the following alert:
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=de;
org.springframework.web.servlet.i18n.CookieLocaleResolver.LOCALE=fr
Instead of resetting/changing the existing cookie, a new one is added with the value 'de;'. A seemingly random semicolon is added.
This doesn't happen with endpoints using similar logic and almost identical implementation.
There is no further logic outside the little bit of JS code I've posted and I'm not touching the cookie in the backend.
Unfortunately I'm out of ideas. Any tips/help would be appreciated.
Mid development I decided to switch to server-side rendering for a better control amongst other benefits. My web application is completely AJAX based, no url redirecting, so the idea here is a website that builds itself up
I just couldn't figure out the proper way to send javascript events/functions along with the html string, or should all the necessary javascript always be preloaded in the static files?
Let's say client clicks a pre-rendered button 'open table'
The server will make a query, build the html table and send it back, but this table also needs javascript triggers and functions to work properly, how are these sent, received and executed?
There are a couple of articles that mention to not use eval() in Javascript, is there any way around this? I don't want to have to preload unnecessary events for elements that don't yet exist
The server is Python and the Client is Javascript/JQuery
Theoretical example :
Client Base Javascript :
$("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')
Worth noting my question comes from an experimental/learning perspective
Update:
You can use jQuery.getScript() to lazy load JS. I think this solution is as close as you can get to run 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" could be a string returned from $.getJOSN response.
Also, the documentation for getScrippt() has examples on how to handle errors and cache files.
Old Answer:
Using .on() attaches events to current and future DOM elements.
You can either attache events prior to DOM insertion or attache event after DOM insertion.
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 did not test the code but I think it should work.
Assuming you can't just set up an event-binding function and then call it from the main script (the JavaScript you need can't be guessed ahead of time, for example) then one really easy way is just to append the JavaScript to the bottom of the returned HTML content within script tags. When it's appended along with the HTML, the script should simply execute, with no eval() required.
I can't swear that this would work in old browsers, but it's a trick I've used a couple of times, and I've had no problems with it in Firefox, Chrome, or any of the later IE versions.
I think I see what you're asking here, from my understanding you want to send the new "page" asynchorously, and render the new javascript and html. It looks like you already got your request/response down, so i'm not gonna go and talk about sending JSON objects, and the whole "how-to" of sending html and javascript because it looks like you got that part. To do what you want and to dynamically add your javascript in, this stackoverflow question looks like it has what you need
Is there a way to create a function from a string with javascript?
So pertaining to your example, here is how it would look when you recieve 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 would be the string: response.javascript['function']
*Your parameter names if any would be in separate strings ex: response.javascript['param_1']
That is almost a direct copy of the "String to function" code that you can see in the linked question, just replaced it with your relevant code. This code is also assuming that your object is sent with the response.javascript object containing an array with your actual function content and parameter names. I'm sure you could change the actual name of the var too, or maybe put it in an associative array or something that you can keep track of and rename. All just suggestions, but hopefully this works for you, and helps you with your problem.
I am also doing similar work in my project where I had to load partial html using ajax calls and then this partial HTML has elements which requires events to be attached. So my solution is to create a common method to make ajax calls and keep a js method name to be executed post ajax call in 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 common method, look for input[type='hidden'][data-act='onPartialLoad'] and for each run the method name provided in value attribute (value="createTableEvents")
Dont Use Eval() method as it is not recommended due to security
issues. Check here.
you can run js method using window["method name"]...so here is a part of code that I use.
$.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 load the required js files first.
Please I have few html pages that i include some js scripts after the body . My script are working fine and successful. However, it gets messy putting the two together as the project grow. I then took the js in to an individual files . The problem is, now i reference all the files and the js codes became available for each and every html page.
I have events where I check each page load , because i want to execute or start my file on the page load . Now this page loads fire on every page load . Example below,
(function() {
$(this).on('load', function(){
console.log("the init is");
var g = true;
if(g === false)
window.location = '/';
init();
});
var init = function(){
$('#btnAdd').on('click',function(e){
e.preventDefault();
e.stopPropagation();
alert("Butoon click");
});
};
})();
Before when I embed a similar code above, it fires when my page is executed and my load became the entry point as I wanted . But now I moved them to separate html file and reference them which most have the same or similar functions. Now when i visit very html page, the onload method fires regardless , because they are all reference and available for each page.
Please is there any way I can refactor my code to separate every js file for a separate html page/url. How do I make jQuery or ajax load call with reference to the url? How do I make each file fires when its respective html/url is requested from server or loading? Any help would be appreciated
There are a couple common approaches to executing different page initialization code on different pages.
You can break the page-specific initialization code and supporting code into separate script files and only include them in <script> tags on the actual pages where they are needed.
You can use a common script file that is loaded across many pages and then within the page initialization code, you can check which page is loaded and then decide in your code which code is appropriate to run.
You can use a single common script file that includes a separate function for each separate page that needs unique initialization, but no code that calls those functions and then add one unique initialization function call to each individual page in the body of the page. This allows for the most efficient browser caching of script files and loading of fewer script files (it lets you combine and minimize most of your scripts).
For the second option, you can detect which page is loaded in your Javascript a number of different ways.
You can detect a class name on a known tag (like the body tag).
You can set a unique JS variable in each page that the initialization code can test.
You can look for the existence of certain HTML tags in the page that uniquely indicate which type of page it is. This works well when you want a particular initialization function to run on a bunch of pages that all have a certain common element.
Here's an example of option 1 (detect class name on body tag).
var m = document.body.className.match(/pageType_([^\s]+)/);
if (m) {
switch(m[1]) {
case "home":
// code here
break;
case "category":
// code here
break;
case "product":
// code here
break;
default:
// code here
break;
}
}
Here's an example of option 2 (set unique JS variable in each page):
<script>
// somewhere in each unique page
var pageType = "home";
</script>
<script>
// common script file
switch(pageType) {
case "home":
// code here
break;
case "category":
// code here
break;
case "product":
// code here
break;
default:
// code here
break;
}
</script>
Here's a scheme for detecting which unique tag exists and calling the appropriate initialization function:
if (document.getElementById("home")) {
initHome();
} else if (document.getElementById("category") {
initCategory();
}
First of all: 'Locally' neither means "localhost", nor "local folder". It means a code area or a code space or a code region.
I have two JS (*.js) files for my site. One is to show a news ticker and other is to load something on hover. They are conflicting, and I can't remove any one of 'em because I need 'em.
So a thing comes up to my mind is: as I can make many things locally, why not I load a js file locally? Suppose:
<?php
if('condition') {
DO IT ONCE;
}
?>
<?php
if('other_condition') {
DO STH ELSE ONCE;
}
?>
In such case, the first condition doesn't bother the second condition. Even though the first one is doing, the second one is also doing well. No conflict, nothing.
If I can load a JS locally for a specific purpose and then break the JS loading further, then if I load other JS, she won't find any JS before, because that's for a specific purpose for the specific region only.
I think I'm clear with my idea. I'm here with a WordPress site, loading code specifically for home page using is_home() function. I want such a way to load a JS file for a region, and then break it to let the other JS function properly.
If you've designed your Javascript well, you can have two scripts that don't interfere. Without seeing the actual scripts, it's hard to recommend improvement. You could introduce new scopes for each of the scripts:
script1.js
(function() {
var script_variable = document.getElementById("my_form");
script_variable.onchange = function() { /* ... */ };
})();
script2.js
(function() {
// Same name!
var script_variable = document.getElementById("other_element");
script_variable.onclick = function() { /* ... */ };
});
Load each in a separate iframe.
Here is my question, I am using jsp script, trying to match a key word in requesting url and do something:
<script>
$url = '${pageContext.request.requestURL}';
if("${fn:contains(url, 'key')}" == true){
...
}
....
But this doest work... I am not sure where the problem is but I want it to be like when url contains this string, go in to the if condition.
Thank you
You are mixing JSP/EL and JavaScript as if they run in sync. This is wrong. JSP/EL runs in webserver and produces HTML code which get executed in webbrowser. JavaScript (JS) is part of the generated HTML code and runs in webbrowser only.
You need to do it either fully in JSP/EL, or fully in JavaScript. You can use JSP/EL to dynamically generate JS code which get later executed when the page arrives at browser. Rightclick page in browser, do View Source to see what JSP/EL has generated. You should not see any line of JSP/EL. You should only see HTML/JS code. It's exactly that JS code which get executed then.
You're using a JSP EL function to test a JS variable which isn't in the variable scope at that moment at all. This is not going to work. It can only test JSP/EL variables.
Here's how you could do it in pure JS:
<script>
var url = window.location.href;
if (url.indexOf('key') > -1) {
// ...
}
</script>
If you really insist in doing it using JSP/EL, you could do as follows:
<script>
var url = '${pageContext.request.requestURI}';
if (${fn:contains(pageContext.request.requestURI, 'key')}) {
// ...
}
</script>
This will then generate the following JS code (rightclick page in browser and View Source to see it):
<script>
var url = '/some/uri';
if (true) {
// ...
}
</script>
But this makes no sense. Whatever functional requirement you need to solve, you need to think twice about the right approach. Feel free to ask a new question about solving the concrete functional requirement the proper way.
If you want a parameter that the page was requested with, use ${param.paramName}. So in this case ${param.key}. See implicit objects in the docs. And if you just want to check it has a value try ${not empty param.key}.