I am attempting to query a database through an API which I don't fully understand. I have been sent an example of the API being used with a keyword search form. The form is an html file and uses jquery return JSON documents, format items into an array array, and display.
I tried to build the design of my application and manipulate the form to work within my pages. The file the uses the API requires that the a base link be used.
<base href="{{app_root}}">
If I remove this base link my functionality of the search is lost. If I use the base link all of presentation and CSS is lost.
I thought maybe I could change the base link dynamically when I needed to call the search file with:
<script type="text/javascript">
function setbasehref(basehref) {
var thebase = document.getElementsByTagName("base");
thebase[0].href = basehref;
}
//setbasehref("{{app_root}}");
setbasehref("{{app_root}}");
</script>
Then use setbasehref() to change it back to my original base link, but that didn't work.
I'm new to javascript and JSON, and I'm not entirely sure what app_root is doing. Any thoughts?
Related
I have a custom VisualForce page and would like via javascript to get the url to create a new account/contact.
I know I can do the following in the main apex code but I want to do something dynamically.
Create New Account
What is the easiest way to get the url to create a new object via javascript?
You can use this code in Javascript (if your script tag is inside a visualforce page):
var newAccountEndpoint = '{!URLFOR($Action.Account.New)}';
var newOpptyEndpoint = '{!URLFOR($Action.Opportunity.New)}';
Or as I stated before refer to pre made list of standard salesforce object prefixes
I've started to use scrapy for a project of mine to scrape data off a tennis website. Here is an example page that I want to scrape data off. As you can see, I want to scrape data for a tennis player. I need to recursively go through the entire page and gather 'Match Stats' (Theres a link titled 'Match Stats' next to every match) for a player's matches. I've already written code to parse data from the opened match stats popup. All I need to do now is open these match stats pages through the initial spider.
In all the examples I've read up on, we can write rules to navigate scrapy to the different urls that need scraping. In my case, I just want to write a rule to the different match stats links. However, if you saw the page I want to scrape, 'Match Stats' links are in the following format: javascript:makePopup('match_stats_popup.php?matchID=183704502'). As I've read online (I might be wrong!), scrapy can't deal with javascript and hence cant 'click' on that link. However, since the links are javascript popups, its possible to add the match_stats_popup.php?matchID=183704502 part of the link to the main url to get a standard html page:
http://www.tennisinsight.com/match_stats_popup.php?matchID=183704502
I am hoping I could modify the rules before scraping. In summary, I just want to find the links that are of the type: javascript:makePopup('match_stats_popup.php?matchID=183704502, and modify them so that they are now of the type http://www.tennisinsight.com/match_stats_popup.php?matchID=183704502
This is what I've written in the rules so far, which doesnt open any pages:
rules = (
Rule(SgmlLinkExtractor(allow='/match_stats_popup.php?matchID=\d+'),
'parse_match', follow=True,
),
)
parse_match is the method which parses data from the opened match stats popup.
Hope my problem is clear enough!
Using BaseSgmlLinkExtractor or SgmlLinkExtractor you can specify both the tag(s) from which to extract and process_value function used for extracting the link. There is nice example in the official documentation. Here is the code for your example:
class GetStatsSpider(CrawlSpider):
name = 'GetStats'
allowed_domains = ['tennisinsight.com']
start_urls = ['http://www.tennisinsight.com/player_activity.php?player_id=1']
def getPopLink(value):
m = re.search("javascript:makePopup\('(.+?)'\)", value)
if m:
return m.group(1)
rules = (
Rule(SgmlLinkExtractor(allow=r"match_stats_popup.php\?matchID=\d+",
restrict_xpaths='//td[#class="matchStyle"]',
tags='a', attrs='href', process_value=getPopLink), callback='parse_item', follow=True),
)
def parse_item(self, response):
sel = Selector(response)
i = TennisItem()
i['url_stats'] = response.url
return i
I'm working on an extension and one of the options available in the settings needs a custom javascript to be added to the document head when rendered. The problem I am having is with the parsing order. (There may also be a better way of doing the include too)
I am using the channel_entries_tagdata hook.
Inside this, once the settings are processed, I am doing the following:
// Add the required javascript
$jscript = "
<script type="text/javascript">
/*! etc......
</script></head>
";
// Add js
$tagdata = str_replace("</head>", $jscript, $tagdata);
I would like to be able to just keep my javascript in a separate file and include it somehow by reference, but I don't know how to do that at this stage.
The other issue I am running into is the parsing order of the EE variables. Inside the javascript, I am using the variables from the $tagdata. Something like this:
$.post("URL", { channel: "{channel}", entryId: "{entry_id}", urlTitle: "{url_title}", lastSegment: "{last_segment}", editDate: eo.editDate, field: eo.eleName }, function(data){...
How would I call/use the EE variables in this case?
Elaborated...
This extension is for the following:
In the Addons -> Extensions from the control panel, they will activate the extension. In the 'Settings' for that extension, they will be able to authorize, by Channel, the members or groups that can 'edit' entries in that channel.
The extension, after checking permissions, edits each custom field type before it is rendered and wraps it in a class element. The JavaScript file is for this functionality next. When that element is clicked, a modal is opened which will contain the custom field type as well as the channel/entry information, so it can save the field once edited.
Could you let the script in the <head> be a generic function and pass variables to it by calling it from inside your channel entries?
<head>
...
<script>
function W3bGuy_function(channel, entry_id, last_segment) {
...whatever...
}
</script>
</head>
<body>
...
{exp:channel:entries}
some action triggers: W3bGuy_function('{channel}', '{entry_id}', '{segment_3}');
{/exp:channel:entries}
...
channel_entries_tagdata contains the raw template code pulled from within each {exp:channel:entries} loop, and then has another variable ($row) which is an array of the actual data for that entry. (As per the docs.)
So first, you'll have to make sure your entire page template is within your Channel Entries loop if you want to add JS to the <head> in this manner - and that may not work if your <head> is inside an embed.
Second, I'd suggest dumping the $row data that's passed via that hook, to see if you can extract your data in your returned JS from there.
Hope that helps.
I am attempting to write a javascript heavy portion of my Asp.net MVC Web App (this portion of the website is a RIA using Extjs). However, I have come up to a standstill at the correct way to handle URLs in the javascript.
For example, right now I have an Ajax call to the List action in the ObjectsController, which resides in the Reading area. The List action takes a parameter of documentId (int). As of right now, this maps to /Reading/Objects/List since I have no changed routing yet (the site is too young at the moment to finalize routes). Normally in a view, to put this URL in a string I would do #Html.Action("List", "Objects", new { area = "Reading", documentId = 3).
However, this doesn't work when dealing with javascript, since javascript isn't parsed by a viewengine.
To get around this, I have a very small view that returns javascript constants, such as URLs, that is loaded prior to my main application's js files. The issue is that I can't call Html.Action for this action because at constant creation time I (obviously) do not know what documentId the ajax calls are going to be, and if you exclude documentId from the Html.Action call an exception occurs. The documentId could change during the normal workflow of the application.
How do I handle this? I don't want to hardcode the URL to /Reading/Objects/List because if I change my routing for this (for a more user friendly json API), or this web app isn't hosted on the root of the domain, the URL will no longer be valid.
How does everyone else handle MVC URLs in their javascript calls?
Here's a safe technique that I've been using. Even if your route changes, your JavaScript will automatically conform to the new route:
<script>
var url = '#Url.Action("List", "Objects", new { area = "Reading", documentId = "_documentId_")';
var id = 100;
var finalUrl = url.replace('_documentId_', id);
</script>
"_documentId_" is essentially a dummy placeholder. Then inside my JavaScript, I replace "_documentId_" with the proper id value once I know what it is. This way, regardless of how your route is configured, your URL will conform.
Update: Dec 20
I just saw this interesting blog post. The author built a library that allows you to build routes inside of your JavaScript file with intellisense support in VisualStudio.
http://weblogs.asp.net/zowens/archive/2010/12/20/asp-net-mvc-javascript-routing.aspx
Personally I use unobtrusive javascript and avoid mixing markup with javascript. AJAX calls are normally triggered by clicking on some buttons or links:
#Html.ActionLink("click me", "List", "Objects",
new { area = "Reading", documentId = 3 }, new { id = "foo" })
and then in a separate js file I would attach and handle the onclick event (example with jquery):
$(function() {
$('#foo').click(function() {
$('#resultDiv').load(this.href);
return false;
});
});
As you can I didn't need to use any hardcoded URL in my javascript file. URLs should always be handled by the routing engine and generated with html helpers.
If it was a <form> instead of a link I would simply handle the onsubmit event (the same way) and use the form's action attribute to get the URL.
UPDATE:
After pointing out in the comments section that the documentId is known only at client-side you could do this:
#Html.ActionLink("click me", "List", "Objects",
new { area = "Reading" }, new { id = "foo" })
And then:
$(function() {
$('#foo').click(function() {
$('#resultDiv').load(this.href, { documentId: '123' });
return false;
});
});
Turns out, this was all solved by using Url.Action() instead of Html.Action(). Url.Action() is (so far) allowing me to generate URLS without all of the parameters. I am assuming that this only works when the route does not specify the parameters in the target URL itself.
I wanted to develop a Django app and one of the functionalities I'd like to have is dynamic drop-down lists...specifically for vehicle makes and models...selecting a specific make will update the models list with only the models that fall under that make....I know this is possible in javascript or jQuery (this would be my best choice if anyone has an answer) but I don't know how to go about it.
Also, I'd want the make, model, year and series to be common then the other attributes like color, transmission etc to be variables so that one needs only enter the make, model, year, and series only for a new vehicle. Any ideas would be highly appreciated.
The 3 things you mention being common, make, model, year, would be the 3 input values. When given to the server, an object containing the details would be returned to the calling page. That page would parse the object details (using JavaScript), and update the UI to display them to the user.
From the Django side, there needs to be the facilities to take the 3 inputs, and return the output. From the client-side, there needs to be the facilities to pass the 3 inputs to the server, and then appropriately parse the server's response.
There is a REST api framework for Django that makes it rather easy to add the "api" mentioned above -- Piston. Using Piston, you'd simply need to make a URL for that resource, and then add a handler to process it. (you'll still need to skim the Piston documentation, but this should give you an idea of what it looks like)
urls.py:
vehicle_details = Resource(handler=VehicleDetails)
url(r'^vehicle/(?<make>.*)/(?<model>.*)/(?<year\d{2,4}/(?P<emitter_format>[a-z]{1,4}), vehicle_details, name='vehicle_details'),
handler.py:
class VehicleDetails(BaseHandler):
methods_allowed = ('GET',)
model = Vehicles #whatever your Django vehicle model is
def read(self, request, *args, **kwargs):
# code to query the DB and select the options
# self.model.objects.filter()...
# Build a custom object or something to return
return custom_object
This simply sets up the url www.yoursite.com/vehicle/[make]/[model]/[year]/json to return a custom data object in JSON for jquery to parse.
On the client side, you could use jquery to setup an event (bind) so that when all 3 drop downs have a value selected, it will execute a $.get() to the api URL. When it gets this result back, it passes it into the Jquery JSON parser, and gives the custom object, as a javascript object. That object could then be used to populate more drop down menus.
(Big warning, I just wrote the following off the top of my head, so it's not meant to be copy and pasted. It's just for the general idea.)
<script type="text/javascript">
// On document load
$(function() {
$('#dropdown_make').bind('change', checkForValues());
$('#dropdown_model').bind('change', checkForValues());
$('#dropdown_year').bind('change', checkForValues());
});
function checkForValues() {
if ($('#dropdown_make').val() && $('#dropdown_model').val() && $('#dropdown_year').val())
updateOptions();
}
function updateOptions() {
url = '/vehicle/';
url += $('#dropdown_make').val() + '/';
url += $('#dropdown_model').val() + '/';
url += $('#dropdown_year').val() + '/';
url += 'json/';
$.get(url, function(){
// Custom data object will be returned here
})
}
</script>
This is uncanny: Dynamic Filtered Drop-Down Choice Fields With Django
His question:
"Here is the situation: I have a database with car makes and models. When a user selects a make, I want to update the models drop-down with only the models associated with that make. ... Therefore I want to use Ajax to populate the data."
You're not the same guy? :)