I have two Visualforce pages, and for several reasons I've decided it is best to pass a datetime value between them as a string. However, after my implementation my date always appear to be null even though my code seems to compile.
I have researched quite a few formatting topics but unfortunately each variation of the format() on date time seems to not produce different results.
The controller on page 1 declares two public variables
public datetime qcdate;
public String fdt;
qcdate is generated from a SOQL query.
wo = [SELECT id, WorkOrderNumber, Quality_Control_Timestamp__c FROM WorkOrder WHERE id=:woid];
qcdate = wo.Quality_Control_Timestamp__c;
fdt is then generated from a method
fdt = getMyFormattedDate(qcdate);
which looks like this
public String getMyFormattedDate(datetime dt){
return dt.format(); }
fdt is then passed in the URL to my next VF page.
String url = '/apex/workordermaintenanceinvoice?tenlan='+tenlan +'&woid=' + woid + '&invnum=' + invnum + '&addr1=' + addr1 + 'fdt=' + fdt;
PageReference pr = new PageReference(url);
I expected when calling {!fdt} on my next page to get a proper string. But I do not.
UPDATE:
Sorry I guess I should not have assumed that it was taken for granted that the passed variable was called correctly. Once the variable is passed the following happens:
The new page controller creates the variable:
public String fdt
The variable is captured with a getparameters().
fdt = apexpages.currentPage().getparameters().get('fdt');
The getfdt() method is created
public String getfdt(){
return fdt;
}
Which is then called on the VF page
{!fdt}
This all of course still yields a 'blank' date which is the mystery I'm still trying to solve.
You passed it via URL, cool. But... so what? Page params don't get magically parsed into class variables on the target page. Like if you have a record-specific page and you know in the url there's /apex/SomePage?id=001.... - that doesn't automatically mean your VF page will have anything in {!id} or that your apex controller (if there's any) will have id class variable. The only "magic" thing you get in apex is the standard controller and hopefully it'll have something in sc.getId() but that's it.
In fact it'd be very stupid and dangerous. Imagine code like Integer integer = 5, that'd be fun to debug, in next line you type "integer" and what would that be, the type or variable? Having a variable named "id" would be bad idea too.
If you want to access the fdt URL param in target page in pure Visualforce, something like {!$CurrentPage.parameters.fdt} should work OK. If you need it in Apex - you'll have to parse it out of the URL. Similar thing, ApexPages.currentPage() and then call getParameters() on it.
(Similarly it's cleaner to set parameters that way too, not hand-crafting the URL and "&" signs manually. If you do it manual you theoretically should escape special characters... Let apex do it for you.
Related
I'm new to writing jasper reports (and SQL in general). We are trying to load an RTF or HTML file as a disclosure at the end of a report. The way we are doing this is by selecting the name of the file ("Disclosure") in part of the SQL:
SELECT
....
'Disclosure' as Disclosure
FROM
...
And then, obviously, there is a field for this:
<field name="Disclosure" class="java.lang.String"/>
At the end, in the summary section of the report, we use the loadfile utility:
<textFieldExpression class="java.lang.String"><![CDATA[JasperFileRuntimeUtility.loadFile($F{Disclosure}, $P{REPORT_PARAMETERS_MAP})]]></textFieldExpression>
If the report returns data, this works beautifully. But if the result of the original query does not return any records, then the disclosure is not included in the report (since the result of the query is nothing, obviously).
I thought we could easily work around this by providing the "Disclosure" as a Parameter, but when I change that to $P instead of $F. I get an error about invalid io file type.
I also tried creating a Variable and setting that $V to the value of the $P we are passing in, but no luck there either.
Is there a load file type of utility that will load a parameter like we are doing with the field? Any other suggestions?
Appreciate the help!!!
I have understood you question better now so I edit the answer, you are calling
JasperFileRuntimeUtility.loadFile($F{Disclosure}, $P{REPORT_PARAMETERS_MAP})
you have no clue what function is this but you know that if you pass the String "Disclosure" it works.
The class JasperFileRuntimeUtility is within your library (its not an official jasper report function), try to search your project or your libraries.
It has a static method public static String loadFile(String value, Map<?,?> map)
Calling the metod with where $F{Disclosure} = "Disclosure"
JasperFileRuntimeUtility.loadFile($F{Disclosure}, $P{REPORT_PARAMETERS_MAP})
or
JasperFileRuntimeUtility.loadFile("Disclosure", $P{REPORT_PARAMETERS_MAP})
will not make any different the result will be the same (since the method have no other idea then with what parameters you call it).
Normally also calling with a $P{Disclosure} = "Disclosure"
JasperFileRuntimeUtility.loadFile($P{Disclosure}, $P{REPORT_PARAMETERS_MAP})
would be the same, but since the the parameter map is passed the function can see this parameter and maybe do something else...
More likely however since the parameter map is passed to function, you may have scriptlet or other calls that set static fields, and when you have no result the call to loadFile is not working since these static fields have not been set.
So if it is not working passing "Disclosure" this is most certainly the case..
Have fun!
I am going back and working through old coursework from my intro to comp sci class, and on one of the labs I'm supposed to use the flickrapi module to scrape flickr for a set of pictures to use for the rest of the lab. The project was assigned with some code to scrape flickr that I know should work, but whenever I run the code it throws a TypeError. The function that is returning an error is:
def getphotos(apicode, query, num_images):
''' Return a list of URLs that have a tag that
matches the query code. '''
# Form the object that will interact with the Flickr website
flickr = flickrapi.FlickrAPI(apicode, format='etree')
# Get each matching photo and store in a list, stopping when we
# reach the target number of images
photos = []
for photo in flickr.walk(tags = query, tag_mode = 'all', safe_search = '0', sort = 'interestingness-desc'):
url = "http://farm" + photo.get('farm') + ".staticflickr.com/" + \
photo.get('server') + "/" + photo.get('id') + "_" + \
photo.get('secret') + ".jpg"
print url
photos.append(url)
if len(photos) >= num_images:
break
return photos
The line that throws the error is flickr = flickrapi.FlickrAPI(apicode, format='etree') where apicode represents an apicode key given to me by flickr and I'm not quite sure what the format ='etree' does. When I go look at the flickrapi module and go into core.py, I get to the FlickrAPI class. The part of the class that seems to be of interest is given as:
class FlickrAPI(object):
"""Encapsulates Flickr functionality.
Example usage::
flickr = flickrapi.FlickrAPI(api_key)
photos = flickr.photos_search(user_id='73509078#N00', per_page='10')
sets = flickr.photosets_getList(user_id='73509078#N00')
"""
REST_URL = 'https://api.flickr.com/services/rest/'
UPLOAD_URL = 'https://up.flickr.com/services/upload/'
REPLACE_URL = 'https://up.flickr.com/services/replace/'
def __init__(self, api_key, secret, username=None,
token=None, format='etree', store_token=True,
cache=False):
...(followed by logic statements involving the inputs for __init__ and class methods)
When flickr gives me an apicode key, it also gives me a secret key which I have stored in a .txt file in the same directory as the program I'm working on.
Now obviously the call on the FlickrAPI class is being passed 3 arguments, 2 of which are the apicode key and the format ='etree', but I'm a little bit unsure as to what the third one is. Is the class somehow calling on the secret key through flickr, or is it one of the other inputs for init? How do I got about fixing the type error that the code is giving me?
The three required arguments are self, api_key and secret (arguments that have no default value), the example given in the docstring of the FlickrAPI does not work.
Here, the first argument, self, is implicit (it's the instance of the FlickrAPI being constructed itself), you are giving the second argument, api_key, with apicode, but the third required argument, secret, is missing. format is the third argument you give, but it doesn't count in the three required arguments, as it has a default value.
The problem is that you don't pass anything for secret.
Take a look at this example
class Test():
def __init__(self, one, two, three=3):
print one, two, three
Test(1, three=3)
Test.__init__ takes four arguments, of which one (three) has a default value, so it needs at least self, one and two passed to it. self is passed automatically because it is a class method, so that's the first. Then you pass something for one and something for three. You do pass three arguments, which is the minimum, but you pass nothing for two, which doesn't have any default value. That's where the error comes from. You could call Test(1, 2) which has the same number of arguments because then all arguments without a default value are provided.
In your code, you are passing an argument for api_key and an argument for format, but nothing for secret, which doesn't have a default value.
I have a varient that finds the current url and splits it as follows:
var ehref = window.location.href.split('?',1);
This is then used to match the url with a navigation link href and give an ID to the page. My issue is that when our cookie pop up is closed, # is added to the url. Subsequently the page links are passed around between users with the # and the page ids do not work.
What is a simple way of splitting the url at a # as well? I am new to jquery, thus I understand the gist of what I'm 'reading,' but anything I've tried from researching the net has broken the page. I can replace the '?' With '#' but that doesn't really solve the issue.
Thanks!
If you want to get string after '#' you can write like this:
window.location.hash
in javascript ,see here
I have been searching for a way to split up a URL and replace with a new URL. as example, YouTube.com/ "user/video" and change it to YouTube.com/v/"video" so I would not have to sign in to watch a video that got restricted. But then needed to use the same code that would grab whatever string I want between two marks. So here we go!
Our goal: To isolate a part of a URL and use it within another URL!
The line of code will be broken up in sections for easy reading
The line of code will be for a web-link, clicked from the browser’s bookmark
Example URL
https: //duckduckgo.com/?q=School&t=h_&atb=v102-5_f&ia=web
The code:
javascript:var DDG=(window.location.href.split('?q=')[1]);DDG2=DDG.split('&t')[0];DD2G="https://www.google.com/search?q="+DDG2;window.location.assign(DD2G);
Variable name;
DDG = duckduckgo
DDG2 = duckduckgo2
DD2G = duckduckgo 2 google
The code break down:
javascript:var DDG=(window.location.href.split('?q=')[1]);
DDG2 = DDG.split('&t')[0];
DD2G="https://www.google.com/search?q="+DDG2;
window.location.assign(DD2G);
The first part of the code defines it as a JavaScript, we create a variable (var) with the name DDG
Var DDG
The next part we want the value to be what the current URL of the users browser and split that into sections
window.location.href.split
We want to find within the URL this string ‘?p=’ which indicates the search inquiry/s in duckduckgo
But I only want what comes after ‘?p=’ represented by [1], which will give our variable name DDG the value of this: School&t=h_&atb=v102-5_f&ia=web
We now want to split the new value we just gave to our DDG variable, so we do a split on that
DDG.split, and this time we only want everything before the ‘&=’ so we put [0] and assigned that result to a new variable we called DDG2
DDG2 = DDG.split(‘&t’)[0]
We now have a new variable with the value we wanted and we will use DDG2 to replace whatever we want in another URL!
DDG2 = School (this updates every time there is a new search.)
Now we want to replace the URL with our new URL + our variable name.
We make our final variable name DD2G with the value of: https:// www.google .com/search?q= but we want to add our value from DDG2
DD2G="https: //www.google.com/search?q="+DDG2;
Which would look like this (https: //www.google.com/search?q=School).
We now want to assign that to the browser and it will redirect to the new URL with the search term.
window.location.assign(DD2G);
= window.location.assign(“https: //www.google.com/search?q=” + (DDG2))
= window.location.assign(“https: //www.google.com/search?q=School”)
= https: //www.google.com/search?q=School //our new URL with our search term we started with from duckduckgo, without having to retype the inquiry.
So for your question, just replace the string between '' '?q=' with the first string you want the script to look for, then from that result, change the second string between'' '&t' with the second string you want it to look for.
I hope this helps!
if you want to test it out select all of this:
javascript:var DDG=(window.location.href.split('?q=')[1]);DDG2=DDG.split('&t')[0];DD2G="https://www.google.com/search?q="+DDG2;window.location.assign(DD2G);
and drag it to an empty space in your toolbar/bookmarks, in Firefox, I do not know if this works with other browsers, but if they support JavaScripts, it should work. Now navigate to DuckDuckgo.com and search for something, then click on that bookmarked with that code.
I'm using a plugin and want to perform an action based on the records statuscode value. I've seen online that you can use entity.FormattedValues["statuscode"] to get values from option sets but when try it I get an error saying "The given key was not present in the dictionary".
I know this can happen when the plugin cant find the change for the field you're looking for, but i've already checked that this does exist using entity.Contains("statuscode") and it passes by that fine but still hits this error.
Can anyone help me figure out why its failing?
Thanks
I've not seen the entity.FormattedValues before.
I usually use the entity.Attributes, e.g. entity.Attributes["statuscode"].
MSDN
Edit
Crm wraps many of the values in objects which hold additional information, in this case statuscode uses the OptionSetValue, so to get the value you need to:
((OptionSetValue)entity.Attributes["statuscode"]).Value
This will return a number, as this is the underlying value in Crm.
If you open up the customisation options in Crm, you will usually (some system fields are locked down) be able to see the label and value for each option.
If you need the label, you could either do some hardcoding based on the information in Crm.
Or you could retrieve it from the metadata services as described here.
To avoid your error, you need to check the collection you wish to use (rather than the Attributes collection):
if (entity.FormattedValues.Contains("statuscode")){
var myStatusCode = entity.FormattedValues["statuscode"];
}
However although the SDK fails to confirm this, I suspect that FormattedValues are only ever present for numeric or currency attributes. (Part-speculation on my part though).
entity.FormattedValues work only for string display value.
For example you have an optionset with display names as 1, 2, 3,
The above statement do not recognize these values because those are integers. If You have seen the exact defintion of formatted values in the below link
http://msdn.microsoft.com/en-in/library/microsoft.xrm.sdk.formattedvaluecollection.aspx
you will find this statement is valid for only string display values. If you try to use this statement with Integer values it will throw key not found in dictionary exception.
So try to avoid this statement for retrieving integer display name optionset in your code.
Try this
string Title = (bool)entity.Attributes.Contains("title") ? entity.FormattedValues["title"].ToString() : "";
When you are talking about Option set, you have value and label. What this will give you is the label. '?' will make sure that the null value is never passed.
I have a SSRS "statement" type report that has general layout of text boxes and tables. For the main text box I want to let the user supply the value as a parameter so the text can be customized, i.e.
Parameters!MainText.Value = "Dear Mr.Doe, Here is your statement."
then I can set the text box value to be the value of the parameter:
=Parameters!MainText.Value
However, I need to be able to allow the incoming parameter value to include a dataset field, like so:
Parameters!MainText.Value = "Dear Mr.Doe, Here is your [Fields!RunDate.Value] statement"
so that my report output would look like:
"Dear Mr.Doe, Here is your November statement."
I know that you can define it to do this in the text box by supplying the static text and the field request, but I need SSRS to recognize that inside the parameter string there is a field request that needs to be escaped and bound.
Does anyone have any ideas for this? I am using SSRS 2008R2
Have you tried concatenating?
Parameters!MainText.Value = "Dear Mr.Doe, Here is your" & [Fields!RunDate.Value] & "statement"
There are a few dramatically different approaches. To know which is best for you will require more information:
Embedded code in the report. Probably the quickest to
implement would be embedded code in the report that returned the
parameter, but called String.Replace() appropriately to substitute
in dynamic values. You'll need to establish some code for the user for which strings will be replaced. Embedded code will get you access to many objects in the report. For example:
Public Function TestGlobals(ByVal s As String) As String
Return Report.Globals.ExecutionTime.ToString
End Function
will return the execution time. Other methods of accessing parameters for the report are shown here.
1.5 If this function is getting very large, look at using a custom assembly. Then you can have a better authoring experience with Visual Studio
Modify the XML. Depending on where you use
this, you could directly modify the .rdl/.rdlc XML.
Consider other tools, such as ReportBuilder. IF you need to give the user
more flexibility over report authoring, there are many tools built
specifically for this purpose, such as SSRS's Report Builder.
Here's another approach: Display the parameter string with the dataset value already filled in.
To do so: create a parameter named RunDate for example and set Default value to "get values from a query" and select the first dataset and value field (RunDate). Now the parameter will hold the RunDate field and you can use it elsewhere. Make this parameter hidden or internal and set the correct data type. e.g. Date/Time so you can format its value later.
Now create the second parameter which will hold the default text you want:
Parameters!MainText.Value = "Dear Mr.Doe, Here is your [Parameters!RunDate.Value] statement"
Not sure if this syntax works but you get the idea. You can also do formatting here e.g. only the month of a Datetime:
="Dear Mr.Doe, Here is your " & Format(Parameters!RunDate.Value, "MMMM") & " statement"
This approach uses only built-in methods and avoids the need for a parser so the user doesn't have to learn the syntax for it.
There is of course one drawback: the user has complete control over the parameter contents and can supply a value that doesn't match the report content - but that is also the case with the String Replace method.
And just for the sake of completeness there's also the simplistic option: append multiple parameters: create 2 parameters named MainTextBeforeRunDate and MainTextAfterRunDate.
The Textbox value expression becomes:
=Parameters!MainTextBeforeRunDate.Value & Fields!RunDate.Value & Parameters!MainTextAfterRunDate.Value.
This should explain itself. The simplest solution is often the best, but in this case I have my doubts. At least this makes sure your RunDate ends up in the final report text.