I read here, that in the GSP we could write:
${params.action}
From the GSP, we could call a Javascript function with ${params.action} as parameter (see here).
Is there any other way to get the action name without passing parameters from the GSP view?
I understand the desire to reduce application code happening in the views, but to allow the proper components to handle what they handle (separation of concerns), it is the best way to have the controller pass the action name to the view via a model.
The client-side script otherwise has only the url and a loose sense of the route table compared to the server-side which must know exactly the route table.
If you still feel it best to use client-side script, window.location provides the url. To parse the url, javascript's string.split using '/' as the delimiter should suffice, the following snippet should help:
var url = window.location;
var urlParts = url.split('/');
var controller = urlParts[3];
var action = urlParts[4];
We've been working on a web application and we've just about got it finished up, but there's one thing that bothering us (although by no means is it going to stop production.)
When we call one of the pages (index.html), we sometimes have to pass it a variable in the URL (searchid). So we get a page like http://domain.com/index.html?searchid=string.
We'd ideally like to not show the ?searchid=string, but I'm not sure how we'd do that.
My group doesn't own the index.html page (but we are working with the group that does), so I don't know how much we'd be able to do with anything like .htaccess or similar.
I was thinking about POSTing the variable, but I don't know how to receive it with just HTML and jQuery. Another person in my group thought that after the page loaded we could remove it from the URL, but I assume we would need a page refresh which would then lose the data anyway.
I'm trying to avoid XY problem where the problem is X and I ask about Y, so what's the right way to remove the variable from the URL?
You can use the History API, but it does require a modern browser
history.replaceState({}, null, "/index.html");
That will cause your URL to appear as /index.html without reloading the page
More information here:
Manipulated the browser history
Your question seems to indicate that the target page is not and will not be powered by some server-side script. If that's the case, I'd suggest changing the querystring to a hash, which has the advantage of being directly editable without triggering a page-load:
http://yourdomain.com/page.html#search=value
<script type='text/javascript'>
// grab the raw "querystring"
var query = document.location.hash.substring(1);
// immediately change the hash
document.location.hash = '';
// parse it in some reasonable manner ...
var params = {};
var parts = query.split(/&/);
for (var i in parts) {
var t = part[i].split(/=/);
params[decodeURIComponent(t[0])] = decodeURIComponent(t[1]);
}
// and do whatever you need to with the parsed params
doSearch(params.search);
</script>
Though, it would be better to get some server-side scripting involved here.
It's possible to rewrite the URL using JavaScript's history API. History.js is a library that does this very well.
That being said, I don't think there's any need for removing the query-string from the URL, unless you're dynamically changing the contents of the page to make the current query-string irrelevant.
You could post the data, then let the server include the posted data in the page, e.g.:
echo "<script> post_data = ".json_encode($_POST)." </script>";
This works cross-browser.
Is it possible to get information from URL without using the XmlHttpRequest .
I am trying to get document from my noSqlDatabase from URL
by the XHR object and It did not work . but If I type the URL in the browser I get the data.
If by 'get information' you mean load data from a 3rd party url without using XHR requests, the answer is yes, but with caveats.
One commonly used method to load json data cross-domain is called jsonp. Essentially, you define a function on your page:
var x = function(data){ //do something with data }
Then you create a script tag and append it to you page where the src attribute points to some other url that returns a js file like this:
x({ param: 'some data' });
The x function then executes on your page and has access to the 'param' data in the object. You can also pass a string or number using this method.
There is another method involving iframes and the window.name property of the iframe. This technique is a bit older but still works, but I won't go into a lot of detail about it here. You can read more about it here, http://skysanders.net/subtext/archive/2010/10/11/leveraging-window.name-transport-for-secure-and-efficient-cross-domain-communications.aspx, and other places.
In my JSP Page i have one tag .the URL of this tag i am setting in java script which calls servlet.so basically all the parameters are passing by GET request.
The above wroks fine as it generates pdf of current form data so in URL user can see all parameters.
Now the problem is that i have added one more parameter for sending to servlet get request which is quite a long.so it gives error."TOO LONG URI REQUEST".the data which i am seding is javascript variable.
I can not change it to post as i want some data also to be passed in URL.and the parameter which i am adding(the large one) can be by hidden variable or so..???
so can you suggest what should i do??
<div class="pdflink">
<a id="pdfLinkForGroup" href="" onclick="getPDF('<%=reportID%>','',reportTitle)"> <img src="/images/PdfIcon.jpg" class="pdflink"></img></a></div>
getPDFfunction:
aTag=document.getElementById("pdfLinkForSingle");
var queryString = "?"+qry+qString+"&offset=" + offset + "&limit=1000"+"&imgwidth="+imgWidth+"&imgheight="+imgHeight+lastorderby+lastordertype+"&path=/tmp/pdf.xml&svgData="+encodeURIComponent(svgData);
var url = conPath+"/pdf/"+encodeURIComponent(reportName)+".pdf" + queryString + searchQuery;
aTag.target="blank";
aTag.href=url;
It is because DOS is enabled on the sever. Try increasing the MAX URI REQUEST SIZE value in server DOS configuration.
I think you could found an answer in the following URL which is talking about the max URL length you can put in your browser.
The issue seems that you put a long URL, and there are 2 solutions:
- modify you parameters in the url, minify them!
- Use POST to send the parameters to your server
What is the maximum length of a URL in different browsers?
Enjoy :)
I'm using Django on Appengine. I'm using the django reverse() function everywhere, keeping everything as DRY as possible.
However, I'm having trouble applying this to my client-side javascript. There is a JS class that loads some data depending on a passed-in ID. Is there a standard way to not-hardcode the URL that this data should come from?
var rq = new Request.HTML({
'update':this.element,
}).get('/template/'+template_id+'/preview'); //The part that bothers me.
There is another method, which doesn't require exposing the entire url structure or ajax requests for resolving each url. While it's not really beautiful, it beats the others with simplicity:
var url = '{% url blog_view_post 999 %}'.replace (999, post_id);
(blog_view_post urls must not contain the magic 999 number themselves of course.)
Having just struggled with this, I came up with a slightly different solution.
In my case, I wanted an external JS script to invoke an AJAX call on a button click (after doing some other processing).
In the HTML, I used an HTML-5 custom attribute thus
<button ... id="test-button" data-ajax-target="{% url 'named-url' %}">
Then, in the javascript, simply did
$.post($("#test-button").attr("data-ajax-target"), ... );
Which meant Django's template system did all the reverse() logic for me.
The most reasonable solution seems to be passing a list of URLs in a JavaScript file, and having a JavaScript equivalent of reverse() available on the client. The only objection might be that the entire URL structure is exposed.
Here is such a function (from this question).
Good thing is to assume that all parameters from JavaScript to Django will be passed as request.GET or request.POST. You can do that in most cases, because you don't need nice formatted urls for JavaScript queries.
Then only problem is to pass url from Django to JavaScript. I have published library for that. Example code:
urls.py
def javascript_settings():
return {
'template_preview_url': reverse('template-preview'),
}
javascript
$.ajax({
type: 'POST',
url: configuration['my_rendering_app']['template_preview_url'],
data: { template: 'foo.html' },
});
Similar to Anatoly's answer, but a little more flexible. Put at the top of the page:
<script type="text/javascript">
window.myviewURL = '{% url myview foobar %}';
</script>
Then you can do something like
url = window.myviewURL.replace('foobar','my_id');
or whatever. If your url contains multiple variables just run the replace method multiple times.
I like Anatoly's idea, but I think using a specific integer is dangerous. I typically want to specify an say an object id, which are always required to be positive, so I just use negative integers as placeholders. This means adding -? to the the url definition, like so:
url(r'^events/(?P<event_id>-?\d+)/$', events.views.event_details),
Then I can get the reverse url in a template by writing
{% url 'events.views.event_details' event_id=-1 %}
And use replace in javascript to replace the placeholder -1, so that in the template I would write something like
<script type="text/javascript">
var actual_event_id = 123;
var url = "{% url 'events.views.event_details' event_id=-1 %}".replace('-1', actual_event_id);
</script>
This easily extends to multiple arguments too, and the mapping for a particular argument is visible directly in the template.
I've found a simple trick for this. If your url is a pattern like:
"xyz/(?P<stuff>.*)$"
and you want to reverse in the JS without actually providing stuff (deferring to the JS run time to provide this) - you can do the following:
Alter the view to give the parameter a default value - of none, and handle that by responding with an error if its not set:
views.py
def xzy(stuff=None):
if not stuff:
raise Http404
... < rest of the view code> ...
Alter the URL match to make the parameter optional: "xyz/(?P<stuff>.*)?$"
And in the template js code:
.ajax({
url: "{{ url views.xyz }}" + js_stuff,
... ...
})
The generated template should then have the URL without the parameter in the JS, and in the JS you can simply concatenate on the parameter(s).
Use this package: https://github.com/ierror/django-js-reverse
You'll have an object in your JS with all the urls defined in django. It's the best approach I found so far.
The only thing you need to do is add the generated js in the head of your base template and run a management command to update the generated js everytime you add a url
One of the solutions I came with is to generate urls on backend and pass them to browser somehow.
It may not be suitable in every case, but I have a table (populated with AJAX) and clicking on a row should take the user to the single entry from this table.
(I am using django-restframework and Datatables).
Each entry from AJAX has the url attached:
class MyObjectSerializer(serializers.ModelSerializer):
url = SerializerMethodField()
# other elements
def get_url(self, obj):
return reverse("get_my_object", args=(obj.id,))
on loading ajax each url is attached as data attribute to row:
var table = $('#my-table').DataTable({
createdRow: function ( row, data, index ) {
$(row).data("url", data["url"])
}
});
and on click we use this data attribute for url:
table.on( 'click', 'tbody tr', function () {
window.location.href = $(this).data("url");
} );
I always use strings as opposed to integers in configuring urls, i.e.
instead of something like
... r'^something/(?P<first_integer_parameter>\d+)/something_else/(?P<second_integer_parameter>\d+)/' ...
e.g: something/911/something_else/8/
I would replace 'd' for integers with 'w' for strings like so ...
... r'^something/(?P<first_integer_parameter>\w+)/something_else/(?P<second_integer_parameter>\w+)/' ...
Then, in javascript I can put strings as placeholders and the django template engine will not complain either:
...
var url = `{% url 'myapiname:urlname' 'xxz' 'xxy' %}?first_kwarg=${first_kwarg_value}&second_kwarg=${second_kwarg_value}`.replace('xxz',first_integer_paramater_value).replace('xxy', second_integer_parameter_value);
var x = new L.GeoJSON.AJAX(url, {
style: function(feature){
...
and the url will remain the same, i.e something/911/something_else/8/.
This way you avoid the integer parameters replacement issue as string placeholders (a,b,c,d,...z) are not expected in as parameters