django modify request parameters in templates - javascript

So I wrote an app that returns an the query results. Let's assume the query URL is /query/?A=a&B=b
And now I want to add a "sort by" button to my results page to allow the users to sort the results by time, or type. Essentially just allow user to visit /query/?A=a&B=b&sorted=time or /query/?A=a&B=b&sorted=type
The easiest way is to append sorted= after the current URL. For example <a href = "{{ request.get_full_path }}&sorted=time"> But the problem is that if user first sorts by time, then sorts by type, you will have /query/?A=a&B=b&sorted=type&sorted=time
I suppose I can do some fancy string operations, but I don't know if I can do that in django template language, and I suppose there is a better way of doing it. There should be somewhere I can just modify the GET request and let the page refresh.
Thanks a lot!

You might want to look at django-tables2's solution (you might just want to look at django-tables2 in general if you're displaying this data in a table).

Two GET variables with the same name is ambigious. You can define different varaibles for the different types of sorting. Sorting has two options either ascending or descending depending on the context, you also need those values so that user can go back to the default sorting.
/query/?A=a&B=b&sort_type=asc&sort_time=desc
Then in view:
sort_type = request.GET.get('sort_type', '')
sort_time = request.GET.get('sort_time', '')
qs = MyModel.objects.all()
if sort_type:
if sort_type == 'asc':
qs = qs.order_by('type')
elif sort_type == 'desc':
qs = qs.order_by('-type')
# same goes with sort_time
# ...
# pass sort_type and sort_type or all get variables in the context to generate url in template
Now in template:
<a href = "{{ request.get_full_path }}?&sort_time={{sort_time}}&sort_type={{sort_type}}">

Related

How do I save the first users selections, then generate a unique code/link, and finally display the first users selections for a subsequent user?

I want to create a web page with selections then when a user inputs their selections I would like an output of a code (or even better a unique url) which can be copy-pasted to forums, e-mailed etc... Allowing their friends to click the link and retrieve the input selections associated with that link.
A code would be fine where a link + a code that is copy/pasted into a text box then generated the shared entries.
So for instance I have several drop down boxes:
A drop down with 50 states, a drop down with gender, a drop down with
ages 1-100, a drop down with number of kids.
An end-user comes and selects whatever choices they want and the page
produces the link or code allowing future end-users to either click
the link (preferable) or paste the code into a text box which then
selects all the appropriate selections wishing to be shared. This
allows the second user to view exactly what the first user wanted to
share with a simple short link/code.
I am stuck and I know I don't have to create a unique webpage for each possibility but I'm not sure how to approach.
How do I save the first users selections, then generate a unique code/link, and finally display the first users selections for a subsequent user?
What you probably want are url parameters..
Here's a function that uses regex to grab a param from the url
function gup( name ){
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null ) return "";
else return results[1];
}
I wouldn't sweat what's going on in there.. but to use it you'ld have a url (mysite.com/coolPage) if they go there with a parameter (mysite.com/coolPage?whosCool=ImCool)
you can, in your javascript call gup("whosCool") and it'll return "ImCool"
in your example, you'ld have mySite.com?state=oklahoma&gender=male
in your javascript you can, on load:
document.getElementById('state').value = gup('state');​​​​​​​​​​
document.getElementById('gender').value = gup('gender');​​​​​​​​​​
to build the url, when they make all of their selections you'll build the url with the parameters.
var url = "mycoolSite.com/mypage?";
url += "state=" + document.getElementById('state').value;
url += "gender=" + document.getElementById('gender').value;
document.getElementById('outputURL').innerHTML = "<a href='"+url+"'>Your url</a>";
That's the pieces, you'll have to build it all together though
I can think of two ways to do this:
Unique database id which stores all the information for that user and is generated when they generate the link.
A much longer url with all the options stored as parameters on the end.
Database solution
When the user clicks to generate the link I'd take all the information gathered from the page, and push it through in a form for processing. I'd then store all the information in a database with a unique id and pass that id back to the user, storing it as a parameter in the url that is in the generated link.
When the user clicks the link the first thing you could do on page load is to query the id parameter and display all the database fields that have been previously stored.
Depending on whether you have any PHP knowledge, you might find these links useful:
https://gist.github.com/webaware/4048580
http://www.dynamicdrive.com/forums/showthread.php?45895-How-to-populate-php-html-form-with-MySQL-data
URL parameters solution
I'd again gather all the information from the page and push it through in a form before building a link with the parameters listed out. So www.tester.com?gender=female etc.
When the user clicks the link the first thing you could do on page load is to pull the parameters from the link and display them against the appropriate inputs.
This might get you off the ground with the basics for doing this with javascript.
Pre-fill form field via URL in html
Get the info from the form: How to save data from a form with HTML5 Local Storage?
This one will be particularly helpful to you: How can I pre-populate html form input fields from url parameters?
This second option is definitely messier and I'd probably go with the first option myself.
Hopefully they both make sense - any questions then just ask!

Breeze - Getting All Navigation Properties For Array of Entities

I'm trying to figure out with Breeze how to expand a specific navigation property for all items in an array of entities with a single request.
On this page of the Breeze documentation it shows the following way of achieving this:
var orderEntityType = selectedOrders[0].entityType;
var navProp = orderEntityType.getNavigationProperty("OrderDetails");
var navQuery = EntityQuery
.fromEntityNavigation(selectedOrders, navProp)
.expand("Product");
manager.executeQuery(navQuery).fail(handleFail);
However, when I tried this I get the error
The 'entity' parameter must be an entity
So I looked up in the documentation specifically for the EntityQuery.fromEntityNavigation method and it shows:
// 'employee' is a previously queried employee
var ordersNavProp = employee.entityType.getProperty("Orders");
var query = EntityQuery.fromEntityNavigation(employee, ordersNavProp);
The documentation indicates that it is for a specific entity, not multiple. Which is consistent with the error I'm getting.
Is it possible to get all the navigation properties in a single request, or is the preferred way to iterate over an array making a request for each entity?
Basically, I'm working on filtering a list of items. My goal is that when a user selects a filter it then expands the needed navigation property at that time instead of loading all the data up front.
Thanks for the help.
I think this might be a typo or some out of date information on the navigation properties documentation page. According to the API documentation for EntityQuery.fromEntityNavigation, the first parameter should be a single entity, not an array. Took a look at the breeze code, didn't see any evidence that an array of entities could be passed.
As a workaround, you could construct the query a bit differently. Continuing with the Order/OrderDetails scenario, you could do something like this:
var subsetOfOrders = ..., // array containing the subset of orders whose OrderDetails we need to load
predicates = subsetOfOrders.map(function(order) { return new breeze.Predicate('OrderId', '==', order.OrderId()); }),
predicate = breeze.Predicate.or(predicates),
query = new breeze.EntityQuery('Orders').expand('OrderDetails').where(predicate);
manager.executeQuery(query)...
If you're able to query the order details directly you don't even need expand. Breeze will wire up the freshly loaded OrderDetails to the respective orders entities that are already cached in the entity manager:
var subsetOfOrders = ..., // array containing the subset of orders whose OrderDetails we need to load
predicates = subsetOfOrders.map(function(order) { return new breeze.Predicate('OrderId', '==', order.OrderId()); }),
predicate = breeze.Predicate.or(predicates),
query = new breeze.EntityQuery('OrderDetails').where(predicate);
manager.executeQuery(query)...
This predicate based workaround may or may not be feasible depending on the number of orders you're dealing with. Could end up with a long query string. You could then consider using a dedicated controller action (ie "OrderDetailsByOrderId(int[] orderIds)" and use the withParameters EntityQuery method to load the order details using the new action.
The documentation was in error. I just corrected it.
#Jeremy Danyow offered a superb explanation and a solution. I probably would use his approach to solve a specific use case.
The documentation now discusses the problem and describes yet another approach that might be more appropriate if you were trying to write a general utility.
// create an array of filter criteria (`wherePredicate`) for each order
var predicates = orders.map(function (order) {
return EntityQuery.fromEntityNavigation(order,'OrderDetails')
.wherePredicate;
});
// OR the predicates together
var filter = breeze.Predicate.or(predicates);
EntityQuery.from('OrderDetails')
.where(filter)
.expand('Product')
.using(em).execute().catch(handleFail);
Thanks to you both for identifying the problem and working through it.

SuiteScript: How does the dynamic mode of nlobjColumn.setURL work?

In NetSuite, I have a scripted search of transactions that is expected to return results of several different transaction types. The results are then rendered in an nlobjList. I would like one of the columns of said list to be a link to the transaction that the list row represents.
In all NetSuite examples, this is accomplished something like:
var column = list.addColumn('number', 'text', 'Number', 'left');
column.setURL(nlapiResolveURL('RECORD','salesorder'));
column.addParamToURL('id','id', true);
Unfortunately, transaction is not an acceptable record type to pass to nlapiResolveURL, so I would need to dynamically detect the record type for each row. The setURL function does accept a second Boolean parameter that makes it dynamic per row, but I am not sure how this actually works. There are no examples, and the JSDocs do not explain its usage.
Does anyone have any guidance on generating a list with dynamic URLs in NetSuite?
If you set the dynamic argument to true, then the first argument should be a column listed in the data source that will contain the base URL.
column.setURL('base_url', true);
column.addParamToURL('id','id', true);
Then, on each record of your results, make sure you have a base_url that is set to the url you are looking for.
Note, the following example assumes a regular javascript object instead of the search result object.
rec.base_url = nlapiResolveURL('RECORD', rec.type)
Transaction field is just an abstraction for all transaction types. You can search them but can't load them.
The field you need to retrieve is recordtype. Sample code is below.
var recs = nlapiSearchRecord('transaction',null,null,new nlobjSearchColumn('recordtype'));
for(var i in recs)
url = nlapiResolveURL('RECORD',recs[i].getValue('recordtype'));

Pass a list of string from Django to Javascript

My Django objects have an attribute "City". I'm trying to get a list of cities and catch it in the template with Jquery (to use in a chart on the X axis).
My problem is that I can't get rid of the unicode and quote for a list.
(I manage to do it for one single value). Instead I'm stucked with this:
["[[u'Paris'], [u'Lyon']]"]
I've tried tons of things, included JSON. No success.
My view:
(actually, one of many try..)
def barchart1(request):
city_array =[]
for i in [1,MyObject.objects.count()]:
objet = get_object_or_404(MyObject, pk=i)
cities = [objet.city.city_name]
city_array.append(cities)
return render (request, 'plot3/plot_page.html', {"city_array" : city_array})
My JS:
<script type="text/javascript">
var cities = ["{{ city_array }}"];
</script>
Here is how JS read the context sent by the view
["[[u'Paris'], [u'Lyon']]"]
Here is what I would like to get
['Paris', 'Lyon']
It MUST be something simple but I just couldn't figure out how to do it.
Others posts don't deal with a list of string.
Any idea of what should I do?
When you do {{ city_array }} in your template, your list is converted to a string. This is done by calling repr() on the list, which recursively calls repr() on its contents. Because your strings are unicode, you see those unicode literals, u'Paris'.
The "correct" way to do this is to encode your data to json, for example in your view:
import json
# ...
json_cities = json.dumps(city_array)
# ...
return render (request, 'plot3/plot_page.html', {"city_array" : json_cities})
and then do
var cities = {{ city_array|safe }};
in the template.
Please note: don't use this for user-controller data! See the XSS Cheat Sheet by OSWASP and the discussion on Django ticket 17419 for further information. To prevent XSS, you could use something like the SafeJSONEncoder from the django-cms project.

Populating data in the text fields using java scripts

I have two html pages. from one html if I am clicking the id which i have made as a link I want the data associated with that to be populated into the other html page.Its like the id of an employee is being cliked and all te values associate dwith it like his name, address and gender should get populated in the text fields in the previous html table. Currently I am not using any DB. I have entered everything manually through html. I want to use only Java script.
If I understand your question: Yes, it can be done. (I don't know why you would want to do this without a database, but it is possible.) When you're making the links on your first page, make sure they contain the information you want in query string format like this:
Bob Smith
Then on your second page, you can use JavaScript to parse window.location.search which is the query string that you passed from your first page. You can do this in many ways. Here is an example function that will let you extract variables from the query string. You could use it like this on the second page:
<script type="text/javascript">
var firstName = getParameterByName('firstName');
var lastName = getParameterByName('lastName');
var gender = getParameterByName('gender');
// now do something with those variables.
</script>

Categories

Resources