Marketo Hidden Field update - javascript

How should I update the value of a hidden field of Marketo?
What I have tried
form.setValues({"Results_PDF_URL__c":"assignedCampaignID"});
form.vals({"Results_PDF_URL__c":"assignedCampaignID"});
Both of the above options don't work.
So I checked the id, if I am using the right id, when I tried to get the id it retured blank (nothing) for hidden marketo fields.
While I can get the id for input text Marketo fileds (like FirstName, Comapany..) - I am not able to get the id of any hidden Marketo fields.
Any idea what I should set to get this to work?

Either of those, as long as they're used in the right scope, should work. The form object is not global.
MktoForms2.whenReady( function (form) {
form.vals({"Results_PDF_URL__c":"assignedCampaignID"});
});
You'll first want to make sure the MktoForms2 API is available so you don't get an error.
if( typeof MktoForms2 != "undefined" ) {
MktoForms2.whenReady( function (form) {
form.vals({"Results_PDF_URL__c":"assignedCampaignID"});
});
}
In Marketo, you can get the field names under Admin > Field Management > Export Field Names. (Requires Marketo admin access.) This will download a CSV of all the field names. You will want to use the field names shown in the REST API column.
For a quick check, I usually just add the fields I want to a form and inspect them to get the correct field IDs.
Also, you can use .addHiddenFields() instead of .vals() to ensure that the fields are a) on the form b) as hidden fields and c) have the correct values that you want to pass into Marketo. If the fields already exist, this function will detect the fields and only set the values. Very handy.
if( typeof MktoForms2 != "undefined" ) {
MktoForms2.whenReady( function (form) {
form.addHiddenFields({"Results_PDF_URL__c":"assignedCampaignID"});
});
}
Finally, you may want to add a brief delay to ensure that the Marketo forms library has ample time to load and that the form will be available on the page when you look for it. It's unlikely that someone will submit the form in the first two seconds on the page, so it is probably okay to delay for two seconds before adding the field/value to the form.
setTimeout( function(){
if( typeof MktoForms2 != "undefined" ) {
MktoForms2.whenReady( function (form) {
form.addHiddenFields({"Results_PDF_URL__c":"assignedCampaignID"});
});
}
}, 2000 ); // two-second delay
Resources:
Marketo forms API Reference
Marketo forms API Examples

Related

How to detect Event Listeners and their actions on input fields

I have purchased a booking plugin (wordpress) to add to a site.
https://wpamelia.com/
I cannot show the site I am working on, but here a demo from plugin developers
https://sports.wpamelia.com/#book
Once you have chosen your date and time, you end up on a form with input fields.
I was able to pre-fill this form with data that I could pass via the URL.
My URL would look something like this: https://sports.wpamelia.com/?first=Jim&last=Tester&email=something%40something.com&phone=0222222222#book
But here is the problem:
Even though I managed to use jQuery to pre-fill the input fields of the form, as soon as I click confirm the fields' content is erased and the error "Please enter... " appears for each of them.
So again:
STEP 1: I open the booking page with an URL containing data in the query string
STEP 2: Using jQuery, I manage to pre-fill the form that appears after having chosen date and time (first name, last name ...)
STEP 3: I click "Confirm"
RESULT: all the fields are empty and for each one the error message "Please enter first name" (etc..) appears
I've messaged the plugin developers. Only answer was that there is indeed no functionality to take the data from the Query String into the form fields yet.
MY QUESTIONS:
1) How could I find out, with chrome inspector or other tools, why exactly the content I pre-fill into the form is ignored?
---> I've tried things like getEventListeners in the chrome inpector's console, but I don't really see how to get information out of that
2) Would anyone know what the issue is and/or how I could bypass it?
---> there is a lot of javascript from the plugin developers behind that and something is expecting manual entering of the data into the fields...
---> but even when trying to fake manual entering with things like $(this).trigger("change").val(function(i,val){return 'aaaa';}); this didn't solve the problem....
(If anyone is interested, I can post later my javascript/jQuery functionality to get the form fields pre-filled with data from Query String... interesting code as you have to wait until the fields appear for jQuery to recognise them..)
Thanks so much for any help!
cheers
Admino
#Admino - this may not be the best solution and I know this is an old question so you may not need it now but after not finding a better one it at least worked for me.
function getUrlVars() {
var vars = {};
var parts = window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) {
vars[key] = value;
});
return vars;
}
function valueOutput(element) {
element.dispatchEvent(new Event('input'));
}
jQuery(function() {
jQuery(document).on('change', 'input', function(e) {
valueOutput(e.target);
});
// you may want to perform more validations here if needed
// just checking here if email is present (but not checking for valid email address)
var fname = getUrlVars()["first"];
var lname = getUrlVars()["last"];
var email = getUrlVars()["email"];
var phone = getUrlVars()["phone"];
var custom1 = getUrlVars()["custom1"]; // you know this field label is Order Number
if (email.length > 0) {
// run an interval until the elements are present on the page (form displayed)
var checkInputs = setInterval(function() {
if (jQuery('.amelia-app-booking label[for="customer.email"]').length > 0) {
var em = jQuery('.amelia-app-booking label[for="customer.email"]').closest('.el-form-item').find('.el-input__inner');
// this checks to see if an Amelia customer is already present
if (em.val() == '') {
em.prop('value', email).val(email).trigger('change');
jQuery('.amelia-app-booking label[for="customer.firstName"]').closest('.el-form-item').find('.el-input__inner').prop('value', fname).val(fname).trigger('change');
jQuery('.amelia-app-booking label[for="customer.lastName"]').closest('.el-form-item').find('.el-input__inner').prop('value', lame).val(lame).trigger('change');
jQuery('.amelia-app-booking label[for="customer.phone"]').closest('.el-form-item').find('.el-input-group__prepend').siblings('.el-input__inner').prop('value', phone).val(phone).trigger('change');
}
// for custom fields I check the label text to find the correct input
if (custom1 != '') {
jQuery('.amelia-app-booking label:contains("Order Number")').closest('.el-form-item').find('.el-input__inner').prop('value', custom1).val(custom1).trigger('change');
}
// form info is updated so clear the interval
clearInterval(checkInputs);
}
}, 500);
}
});
You may want to try a different method than url params to sync this info so it's not so public in the url string. This code may not need both the prop and val jquery setters but I just left them for you to try. Hope it helps (and to others I'm open to a better solution)!

Angular JS form running only first time

I am at the very beginning with my Angular learning and I implemented this form:
http://codepen.io/jgrecule/pen/WxgqqO
What it is supposed to do is very basic: it consumes Flickr public JSONP feed as per Flicker specs https://www.flickr.com/services/feeds/docs/photos_public/ and renders the retrieved pictures thumbnails
The form I implemented has a submit button as well as a reset one. My problems I am trying too find solutions in the order of their importance are:
The very first time when you typing tags everything works but when u try to submit the request again by either adding a new tag or an user Id or anything it no longer works. I can see this warning in the logs but I have no idea what is causing it WARNING: Tried to load angular more than once.
The reset only works for the thumbnails but not for the other controls in my page
I would like to find a way to show an error message when the user pushes on the search flicker button and both tags and user ids input fields are empty. I tried to implement a custom directive but it was no way to get it working.
Thank you in advance for your inputs.
You are loading Angular more than once.
Your resetForm function doesn't reset the form at all. It just calls $setValidity on two of the form elements. It looks like it does try and reset the form in another part of your code with
document.getElementById("searchCriteriaTags").innerHTML = "";
document.getElementById("searchCriteriaIds").innerHTML = "";
document.getElementById("images").innerHTML = "";
which means you are modifying the DOM directly, about which see point 4.
You can add a simple check as to whether $scope.form.tags === '' and so the same for the other fields in your form.
Having addressed your 3 points, I'm afraid to say your code has bigger problems. You are modifying the DOM directly all over the place and you have a lot of duplicate code, plus lots of very complex conditionals.
EDIT 1 in response to OP's comment:
The Angular way of clearing form fields would be to simply clear the scope objects that the form fields are bound to. In other words it is as simple as doing something like:
$scope.tags = [] // for arrays
$scope.name = '' // for strings
Because the form fields are bound to these scope variables through the ng-model directive, changing the variables will also change the form fields.
Setting an error message when two fields are empty you can do like this:
$scope.checkFields = function(field1, field2) {
var oneEmpty = field1 === '';
var twoEmpty = field2 === '';
if (oneEmpty && twoEmpty) {
// call the failure message here
}
}
EDIT 2 in response comments:
Firstly good to see that your code is looking a lot cleaner. Secondly, the reason it fails is because in your search function you set the search fields to null, eg searchCriteria.tags = null;. You should set them to empty strings instead: searchCriteria.tags = '';.
I don't know what the purpose of checkFields is so I don't know where you want to place it. If you want to show an error message if the fields are empty then I'd say have checkFields() return a boolean and use ng-show to display the error div if checkFields() === false.
HTML:
<div ng-show="checkFields() === false">Fields can't be empty</div>
JS:
$scope.checkFields = function(field1, field2) {
var oneEmpty = field1 === '';
var twoEmpty = field2 === '';
return (oneEmpty || twoEmpty);
}

ServiceNow show button if condition is true

I am trying to build a Client Script in ServiceNow - Geneva (function onChange), that does the following:
-> If the user writes something in an empty field a button should appear after change;
This is my code now, it doesn't work -> gives me an X on the form :):
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
//Define the variable and the name of the button
if (g_form.getValue('work_around') != ''){
var items = $$('BUTTON').each(function(item){
if(item.innerHTML.indexOf('Publish Known Error')=== -1){
item.show();
}
});
}
}
Instead of a Client Script, I would recommend using an onChange(<your field>) UI Policy. This can be accomplished by setting a Condition of your field not being NULL or some other value check.
Your UI Policy can then use the .append function to bind your button to an element of your choice.

CRM 2015 read "dirty" value from unsaved form

I'm creating new account record. The easiest way is to fill account id (vat number or something similar) and push button. Button run some javascript. Javascript read value of account id and fill the rest (call some external ws and fill account name, address and so on).
But I need to read this unsaved account id. Standard
Xrm.Page.getAttribute("accId").getValue();
can read only saved values.
Via debugger I found the right value, so I wrote simple function, which returns it.
Here it is:
function getDirtyValue(attName) {
var control = Xrm.Page.ui.controls.get(attlName);
if (control != null && control.$1G_1 != null) {
return control.$1G_1.$3V_0;
}
else {
return null;
}
}
It works but is there some official way to get this value?
(language correction welcome)
You could avoid this trick by adding a function, called when the form loads, and sets the value of the field into a global variable. You can access that variable in the on change event of that field.
Keep in mind that Microsoft does not support methods that are not present in the SDK and they might change. So if they change the property you are using, and your code is already in production, you'll end up having some problems.
Hope it helps,
Cheers

Specifying form for 'on form submit' trigger

I have two google forms, which send data to two tabs in a single spreadsheet.
I have set up a script with two functions. I would like the first function to run on submission of the first form. And, the second function to run on submission of the second form.
Problem is: when setting up a trigger onformsubmit, it does not allow you to specify which form.
Therefore, whenever completing the first form, it runs both functions.
Question: how can I restrict the functions from running only when the specific form is submitted?
As I suggested in the comments, you can determine the origin of the form submission by analyzing the response object's content.
Here is a basic example to illustrate : it will send you an email to tell which form has been submitted but you can of course use the same condition test to select the action you want to run.
function formSubmitOriginTest(e){
// Logger.log(JSON.stringify(e));
// example value : {"namedValues":{"Untitled Question 2":["test"],"Timestamp":["8/17/2014 11:22:47"]},"values":["8/17/2014 11:22:47","test"],"source":{},"range":{"rowStart":3,"rowEnd":3,"columnEnd":2,"columnStart":1},"authMode":{}}
if(e.namedValues["Untitled Question 2"]!=undefined){// only form B has one question with this exact title, that's enough to identify it.
MailApp.sendEmail(Session.getActiveUser().getEmail(),'form B has been submitted','');// optionally include the answers in the email body if you want
}else{
MailApp.sendEmail(Session.getActiveUser().getEmail(),'form A has been submitted','');// optionally include the answers in the email body if you want
}
}
Another way this can be done is by looking at the sheet name that comes in the response's event object via the range property. Here's an example of how I determined the form that triggered the submission:
// set the sheet name that stores the form responses you care about here:
function getSourceSheetName() { return 'Form Responses 1'; }
function submit(eventObj) {
var range = eventObj.range;
var eventSourceSheetName = range.getSheet().getName();
var givenSourceSheetName = getSourceSheetName();
// if the source sheet (from form response sheet) is not the same as the specified form response sheet, quit (return) so extra forms don't trigger the code
if (eventSourceSheetName.toUpperCase() !== givenSourceSheetName.toUpperCase() ) {
Logger.log('A different form just submitted data - quit code');
return;
}
// you now know which form submitted the response, so do whatever you want!
// ... your code goes here
}
Basically, this code grabs the name of the sheet that the Form response comes from via range.getSheet().getName(). Next, it checks if that name is a specified name we're looking for (specified in the function getSourceSheetName().
I think it's also possible to get the active sheet name via:
eventObj.source.getActiveSheet().getName();
In case you don't want to use "Range".
I hope this helps!
I was just looking at some documentation and found this:
Documentation forForm
It states:
Creates and returns a FormTriggerBuilder tied to the given form.
Also:
var form = FormApp.openById('1234567890abcdefghijklmnopqrstuvwxyz');
ScriptApp.newTrigger('myFunction')
.forForm(form)
.onFormSubmit()
.create();
onFormSubmit
That code seems to be tied to a specific form.

Categories

Resources