how to get $formBuilder->getForm() for a webform - drupal-8

I am trying to display my webform in a modal (including error/validation messages inside the modal). I am following this approach for a custom drupal form which is not a webform. I am wondering whether this is possible at all with webforms and in case it is, what I need to take into account to make it run?
The first problem I am having is the following code line from the example's TeacherContactController.php
$modal_form = $this->formBuilder->getForm('Drupal\tl_session\Form\TeacherForm');
When I try to use this in my own controller, I cannot get the webform's proper namespace + id. When I check my webform with devel it says:
[__CLASS__] => Drupal\webform\Entity\Webform
[id] => add_news_webform
But I get a "The form argument Drupal\webform\Entity\Webform\webform-submission-add_news_webform-form is not a valid form" error. I tried many things, but did not succeed.
How can I get the webform with formBuilder and what else am I missing here (like webform specific ajax settings etc.)?

You're trying to hard-code the namespace + ID in a string?
That'd be my first guess as to your problem
try
$modal_form = $this->formBuilder->getForm(Drupal\tl_session\Form\TeacherForm::class);
Or possibly
$modal_form = $this->formBuilder->getForm(\Drupal\tl_session\Form\TeacherForm::class);

If you enable the webform_devel.module you can use the API tab which provides some example code. (/webform/contact/api)
#see \Drupal\webform\WebformSubmissionForm::submitWebformSubmission

Related

How to get data by selecting a value from a drop-down option without using selenium

I need to fetch all URLs from this page -
http://www.questdiagnostics.com/testcenter/BUSearch.action?submitValue=BUSearch&keyword=Toxoplasma+Abs+IgG+%2F+IgM
whenever I am selecting a value from a drop down and click on go button.
I selected a value from dropdown option by using xpath. But i can't able to click on go button.
My code is:
import requests
from lxml.html import fromstring
req = requests.get('http://www.questdiagnostics.com/testcenter/BUSearch.action?submitValue=BUSearch&keyword=Toxoplasma+Abs+IgG+%2F+IgM')
hdoc = lxml.html.fromstring(req.content)
hdoc.xpath('//select[#id="labs"]/option/text()')
How to get all links without using selenium?
Normal Use Case
lxml is a great library, and it has decent support for filling out and submitting forms, as documented here. The real challenge for this particular use case is rooted in the way the form works.
The regional laboratory select box is not part of the form; its value is submitted with a cookie instead. This makes things a little more difficult.
If this wasn't the case, you could just issue your GET, pull the form out of it, change the values you're interested in, submit it, and examine the links that come back. That script might look something like this:
req = requests.get('http://www.questdiagnostics.com/testcenter/BUSearch.action?submitValue=BUSearch&keyword=Toxoplasma+Abs+IgG+%2F+IgM')
hdoc = lxml.html.fromstring(req.content)
form = hdoc.forms[1]
# Set form inputs using `form.fields = dict(...)`
form.action = "http://www.questdiagnostics.com" + form.action
submitResult = lxml.html.parse(lxml.html.submit_form(form)).getroot()
links = submitResult.xpath('//*[#id="maincolumn"]/ol/li/a[#class="title"]/#href')
While you can add arbitrary request parameters when calling lxml.html.submit_form(), I don't see a way to add arbitrary cookies.
This Use Case
That said, since this form essentially works by redirecting back to itself (with an additional cookie to identify the lab), you could simulate this behavior by just adding the cookie to your initial GET. You might not need to mess around with a form submission at all. This script will show the first ten links for the SKB lab:
cookies = dict(TC11SelectedLabCode='SKB')
req = requests.get('http://www.questdiagnostics.com/testcenter/BUSearch.action?submitValue=BUSearch&keyword=Toxoplasma+Abs+IgG+%2F+IgM', cookies=cookies)
hdoc = lxml.html.fromstring(req.content)
links = hdoc.xpath('//*[#id="maincolumn"]/ol/li/a[#class="title"]/#href')
print(links)
You could take this a step further, and issue a GET with no cookies to obtain the list of labs, and then iterate over that list, calling requests.get() on each one, sending the appropriate TC11SelectedLabCode cookie to simulate the form submission.
Notes
Note that while lxml has decent form submission support, you're not actually clicking anything. There is nothing "breathing life into" the DOM.
None of the javascript on the page is running.
To illustrate why this is important, consider this example. If you wanted to verify the links on page 2 of the results, I can't say how you'd accomplish that. If your tests need to exercise javascript on the page, I think you'll need more than requests and lxml.

Test both pages using split gem

I am using the split gem for A/B testing. I have 2 versions of a page for the test. How can our tester test both of these pages without changing the code?
I tested it simply by changing show to show_b in
- if #experiment == 'b'
= render "show_b"
- else
= render "show"
But how can the tester do this?
If you want a tester to be able to force a certain alternative to render a particular template, you can pass a URL parameter to override the normal behavior.
In your controller, you should have something like this to assign the test:
#experiment = ab_test("experiment_name", "a", "b")
For a tester to access a specific version (and not have the test alternative randomly assigned), you can format the URL like so:
http://myawesomesite.com?experiment_name=b
This will always assign the b test alternative, and render the show_b template.
See this section of the Split documentation for more information.
Where you assign #experiment variable? If it from DB you can simple change it via admin panel, before visit page.

Rails4: How do I change the way particular URL helpers works?

The goal
No log in screens!
A visitor to the site should be able to create a widget without logging in.
This widget is publically accessible and can be shared via a short URL.
To edit this widget, you need to know the longer, administration URL.
The show action should have a URL with a short token instead of an id:
widget_path(widget) # => /widget/abc123
The edit action should have a URL with a long token instead of an id:
widget_path(widget) # => /widget/abcdefghijklmnop123/edit
What I have so far:
Generating tokens
I'm using a before_create callback to generate two tokens, a token and an admin_token with SecureRandom.urlsafe_base64.
Then, to change the URL helpers from generating URLs with the id, I override the to_param method in the model to return the token:
def to_param
token
end
Now when I save a new record, a token gets generated and the url helpers return these:
widget_path(widget) # => /widget/abc123
edit_widget_path(widget) # => /widget/abc123/edit
The problem
I need the edit_widget_path helper to use the admin_token field.
I can't seem to find a way of doing this.
In an ideal solution, I would want the _url versions of these to also work and they should be available in the usual places (controllers and views).
The closest I have found is to create custom _path and _url methods in ApplicationController, but this doesn't seem right.
Open to suggestions for how to achieve this.
Is there a way to use Rails' existing mechanism for generating URL helpers?
I hope that makes sense, feel free to ask for clarification.
Thank you!
I don't know of any rails mechanism that could handle that except inheritance. You could implement a subclass and override the to_param method there. I don't think that this is worth doing so, since you just want to handle 1 route here. I think I would just create a helper method to handle that case.
Another hint here: You could use the same mechanism that GIT uses. Create a UUID (long version) and use the first X digits to make the public url, just the full UUID is secret. This works in GIT 99,9% of the time without collisions, so it should work for you as well.

Getting error while reading salesforce custom field type Rich Textarea

I am using salesforce.cfc (downloded from Riaforge) to integrate coldfusion with salesforce.
<cfset latestProductList = salesforce.queryObject("SELECT Id, Name, Description__c, Price__c, ProductImage__c FROM Product__c") />
I have created one custom object named "Product__c". This object have one custom field "ProductImage__c" type "Rich TextArea". When i an trying to get product without this custom field it is run, but when i am trying to get product with this field i am getting below error:
"INVALID_FIELD: Name, Description__c, Price__c, ProductImage__c FROM Product__c ^ ERROR at Row:1:Column:44 No such column 'ProductImage__c' on entity 'Product__c'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names. "
But i have this field. attached screen image of salesforce below.
Thanks,
Arun
A quick look at Salesforce CFC shows that it hasn't been updated in a while. The file SalesForce.cfc is pointing at:
https://www.salesforce.com/services/Soap/u/11.1
That's version 11.1 of the API, which is quite old and is long before rich text fields came into existence.
You might be able to fix this issue by simply updating the reference in SalesForce.cfc to the latest version of the API by changing
https://www.salesforce.com/services/Soap/u/11.1
to
https://www.salesforce.com/services/Soap/u/28.0
in that file, although there's a pretty good likelihood that that will break something else, since version 28.0 will have lots of new stuff that SalesForce.cfc is not coded to handle.
In any case, your problem is in fact the API version that you're using. In cases like this, when a field type did not exist as of a certain API version, then that field is invisible for that version. In your case, your rich text field is invisible for your API version, 11.1.

SharePoint Web Services - Updating ContentType field Required property?

I've been trying to programmatically reproduce the behavior of editing a Content Type's field properties in the SharePoint site management screen and selecting the "Required" radio button with no sucess using the WSS 3.0 web service's Webs.asmx "UpdateContentType" method.
The first difficulty was the issue with the MSDN documentation that said fields should be of a FieldRef type when in fact they need to be of a Field type (reference). Adding fields and deleting fields works fine after the fix, but updating fields seems to not function at all. (It should also be noted that I followed the recommendation on the previous link to use Method="2" for updating fields but it changes nothing, and using Method values other than 1 for adding or other than 3 for deleting also function correctly).
Here's the web service call (slightly modified with strings instead of XmlNode objects for readability):
SharePointWebServices.Webs webService = new SharePointWebServices.Webs();
webService.Url = "http://mysharepointserver/site";
webService.UseDefaultCredentials = true;
webService.UpdateContentType(
#"0x01005A089D9EC8A382458FB1F6C72096D52A",
#"<ContentType />",
#"<Fields />",
#"<Fields><Method ID=""1""><Field Name=""SomeField"" ID=""{8a4803c4-6545-4a7a-804d-237eebff0ce3}"" Required=""TRUE"" Hidden=""FALSE"" ReadOnly=""FALSE"" PITarget="""" PIAttribute="""" PrimaryPIAttribute="""" Aggregation="""" Node="""" /></Method></Fields>",
#"<Fields />");
After the call, the field is still Required="FALSE".
A quick look into the stssoap.dll assembly indicates that the "Required" property is apparently ignored during the update process. Is this normal behavior? If so, what is the recommended method for programmatically changing the "Required" field from client code (not executing on the SharePoint server)?
Any help would be greatly appreciated.
I've investigated this and found the same thing. I also tried adding the attribute Cmd="Update" to the Method element without success. This example of how to use UpdateContentType was helpful too.
I don't believe you will be able to do this with the out-of-the-box SharePoint services. You've verified from looking at stssoap.dll that this doesn't appear to work correctly. Another 'client'-style option is to use RPC methods but none appear to provide functionality for content types at all.
The web services are particularly frustrating because this type of not-so-edge case regularly comes up. It is very rare that I consider using them because of the time wasting involved with their limitations.
Do you have any option of deploying custom code to the server? You could develop this functionality using the object model and wrap it in your own custom web service (there is a walkthrough here) quite easily.
Here is an example adapted from Gabe Wishnie that does what you require:
SPContentType myContentType = myWeb.ContentTypes["myContentType"];
string internalName = myContentType.Fields["fieldToUpdate"].InternalName;
myContentType.FieldLinks[internalName].Required = false;
myContentType.Update(true);
Sorry this isn't more helpful but it's a common story when using the WSS 3.0 / SharePoint 2007 web services.