AngularJS doesn't detect value in input from address lookup - javascript

I have a web form using AngularJS form validation, however when I use the address lookup (using api/script from loqate.com) the inputs are filled in from selecting an address but the AngularJS can't see the values. The form responds as if the inputs are empty.
The form validation all works fine, but when the inputs have values set via the address lookup the ng-model sees nothing, ng-change isn't triggered etc.
I've tried calling $scope.$apply() but whenever I do I get $rootScope:inprog console error.
The script the address lookup calls appears to be this, but I can't make head nor tail of it
Here is the form in action. Address is on page 2, start entereing a postcode eg. 'PE' for address options.

According to the Loqate documentation you can use event listeners so you could update your model by adapting this code:
control.listen("populate", function(address, variations) {
// I don't know what fields the received address variable has but
// you just have to check it and apply the necessary changes.
$scope.Contact.address1_postalcode = address.PostalCode;
$scope.Contact.address1_line1 = address.Street;
$scope.Contact.address1_city = address.City;
$scope.Contact.address1_country = address.Country;
});

Related

Submitting Coldbox RC scope on form input change via AJAX and returning string to display on page

I need to pass in form variables via AJAX every time a select box value is changed, and get a returned string from the AJAX call to display on the page. Here's the situation:
I built a form which is dynamically built by the user for a set of compliance rules. This allows the user to have multiple select boxes to generate a logic statement such as the following:
(
( 6779 AND 10852 AND 10845 )
AND
(
( 8260 AND 8258 )
)
)
OR
( 6780 OR 10845 OR 8258 OR 12893 )
I've written a function that returns this logic statement as a string after submission of the form, but would like to dynamically populate a div (#logicblock) on the form page BEFORE submitting, so that the user can verify the logic before submission of the information into our database.
I tried to use the following:
('##logicblock').load("#getmodel('model.compliance').BuildLogic(rc)#", function(response){
$('##logicblock').html(response);
})
... but this does not properly pass in the RC scope into my model. I've searched and can't find a way that makes sense to me to send the entire form scope into a method that returns a value for display on the page.
I got it figured out. Because the form fields are dynamically generated, I found that I couldn't use a $('select').change() event to call the method, so I wrote a handler method to generate the data and serialized the form to pass in to the handler. I was able to use the following to get the desired response:
function updateLogicBlock(){
var serialform = $('form').serialize();
$.get("#event.buildLink('handler.buildComplianceLogic')#?" + serialform,
function(data) {
$('##logicblock').html(data);
});
};
Then I simply added onChange="updateLogicBlock();" to every select box on the form.

Fire Event on Background Change

Just the background:
(not really related to the question)
I am using SharePoint and creating a Sharepoint Hosted App.
I have some fields which provide a peoplepicker with which I can select Users out of a user pool. The functioninality is provide by the SharePoint internal scripts.
If I input a name of a user via jquery nothing happens. It has no built-in change handler I guess.
What I have done is a separat script which just resolve the user names on my jquery input via trigger("change") and then the SharePoint internal Scripts doing the job. This "job" is asynchronous and then if the data arrives from the backend the SharePoint Scripts apply the data to the Peoplepicker fields.
But this functions also doesn't support jQuery's trigger because I cannot alter the functions as they're pre-defined...
So want I want to do is to monitor when the text inside the Peoplepicker fields has been changed but I am a little bit lost now.
Question:
I have tried it with the following code (which doesn't work):
$('.peoplePickerDiv').bind("DOMSubtreeModified", function () {
alert("HAS BEEN CHANGED!");
});
Is there another way to react on lets say background editing of input fields in my DOM?
For People Picker control manipulation SPClientPeoplePicker object (clientpeoplepicker.js) is intended, which provides methods for getting information from the picker or to perform other operation.
SPClientPeoplePicker class exposes the following events:
OnControlValidateClientScript - triggers after a server error is set or cleared
OnUserResolvedClientScript - triggers once the resolved user is added or removed in client
OnValueChangedClientScript - triggers after text input or users change in client
OnValueChangedClientScript event probably suits your scenario, here is an example on how to attach it:
var picker = SPClientPeoplePicker.SPClientPeoplePickerDict[peoplePickerId];
picker.OnValueChangedClientScript = function (elementId, userInfo) {
if(userInfo.length > 0){ // once the value is resolved it could be retrieved via `userInfo` object
console.log(userInfo[0]);
}
console.log('value changed');
};
References
Use the client-side People Picker control in SharePoint-hosted SharePoint Add-ins

Undo form changes when an exception occurs

In Dynamics CRM 2013 is it possible to revert a field changed on a form when a business process error occurs?
For example:
1. User changes a text field on a form from 'abc' to 'xyz'
2. User clicks save
3. CRM pre-operation plugin validates field, 'xyz' not allowed, exception thrown
4. CRM displays business process error to user, 'xyz' is not allowed
5. The value 'xyz' is still shown in the form
The desired behavior we want is 'xyz' to revert to 'abc' in step 5.
You will need to cache the data first. You can do this OnLoad, e.g. by memorizing the entity's attribute values:
function GetInitialAttributeState() {
var preImage = {};
Xrm.Page.data.entity.attributes.forEach(function(field) {
// TODO: for lookup attributes you need to do extra work in order to avoid making merely a copy of an object reference.
preImage[field.getName()] = field.getValue();
});
return preImage;
}
window.preImage = GetInitialAttributeState();
Then you need to perform the save operation through the Xrm.Page.data.save method. Pass a callback function handling errors and resetting the fields, e.g.
Xrm.Page.data.save().then(
function() {
/* Handle success here. */
window.preImage = getInitialAttributeState();
},
function() {
/* Handle errors here. */
Xrm.Page.data.entity.attributes.forEach(function(field) {
if (field.getIsDirty()) {
field.setValue(preImage[field.getName()]);
}
});
});
It is not possible to reset the form's fields this way using the save event, because it kicks in before the actual save operation, never after it.
Why let the user save the record at all?
You could use a Business Ruel to validate the field, and set an error condition against the field for values you don't "like". The error condition will persist and prevent them saving the record until they change the value. The error message can give them some explanation as to why their value is not valid.
Obviously the validation you can do in a Business Rule is limited, but your example does not make it clear on what basis we match "xyz" as a "bad" value.

Refresh form (Ctrl+F5) doesn't fire Retrieve Plugin in CRM 2011

I need to update entity1 based on creation of entity2 (math calculation)
while the form of entity1 is open.
When I refresh the entity1 form, the field has the old value until I close and open the entity1 form (the caching issue).
I found out that it doesn't fire the Retrieve Plugin. Is there a way to overcome this issue just by refreshing the form?
First and foremost: latest CRM has Xrm.Page.data.refresh() to update form data "automagically" (not to mention the fact that fields self-refresh when changed via plugins).
If upgrading is not an option, I'd setup a "watcher" function like this:
// attach to Form Load event
function keepYourFieldInSync() {
setInterval(function(){
var current = Xrm.Page.getAttribute("yourField");
// Not shown here, basically get the updated value from server
var fetched = fetch_yourField_value_from_OData_or_SOAP();
if(fetched != current){
Xrm.Page.getAttribute("yourField").setValue(fetched);
// if users aren't allowed to set the field by hand, I'd also include this
// and customize the field to be readonly
Xrm.Page.getAttribute("yourField").setSubmitMode("never");
}
}, 1000); // keep it above 500 to avoid killing the browser
}
I use a "trick" like this to recognize status changes in Quotes (another user would activate it while this user was working on the draft) and it works quite well.

Task "Regarding" field not populating from subgrid in CRM 2013

I am using CRM 2013 on-premise with UR1 installed
I have a custom entity with a subgrid on it looking at related "tasks" which looks like this:
Whenever I create a task from the subgrid using the "+" button in the top right hand corner of the subgrid; the "Regarding" field of the newly created task remains blank. When it should be populated by a lookup to the record it was created from.
I have javascript on the task entity which checks the "Regarding" field to check what kind of entity it was created from (if it was created from one) and gets certain field values from the calling entity to populate fields on the task.
Since the "Regarding" field is never filled the Javascript never fires - and the fields do not populate.
When the record is saved, if the regarding field is blank (I have not manually filled it in) - it will eventually be populated by the correct record about 10 - 15 seconds later if you refresh the page. Then the correct fields will be populated and the user is able to edit the option set values and save again. This is not ideal for the user as they would like it to be one fluid action.
Is there any way around this problem?
EDIT for future browsers of this question:
Found a partial work around. If you use an "Activity" subgrid rather than a "Task" subgrid the field will populate. This has a drawback though as you cannot edit the "Activity" subgrid's view to show "Task" specific fields.
Ran into this same issue. The way I got around it was to add a look-up to the custom entity on the form (we put this on a hidden tab). When the Task gets created from the custom entity the look-up will be populated. You can then use that look-up to grab the values that you need to populate, including the regarding field. Not the most elegant, but it works.
I also ran into this problem and went with a pure JS approach to resolving. On load of the task form, call populateRegarding().
This works because even though the regarding lookup doesn't populate by default, the query string parameters include _CreateFromType and _CreateFromId values.
This works in 2015, didn't test on earlier versions. Note that it is unsupported.
function populateRegarding() {
var regarding = Xrm.Page.getAttribute("regardingobjectid"),
createFromType = Xrm.Page.context.getQueryStringParameters()._CreateFromType,
createFromId = Xrm.Page.context.getQueryStringParameters()._CreateFromId;
if (!createFromId || !createFromType ||
!regarding || regarding.getValue() !== null) {
return;
}
var entityLogicalName = getEntityLogicalNameFromObjectTypeCode(createFromType);
regarding.setValue([{
id: createFromId,
entityType: entityLogicalName,
name: "Hardcoded Name" // TODO: retrieve name dynamically
}]);
}
// This method uses an undocumented object and is therefore unsupported.
// You could implement a supported version of this function by querying for
// metadata, but that would be very expensive.
function getEntityLogicalNameFromObjectTypeCode(otc) {
var map = Mscrm.EntityPropUtil.EntityTypeName2CodeMap,
logicalName;
otc = Number(otc); // convert string to number
for (logicalName in map) {
if (!map.hasOwnProperty(logicalName)) { continue; }
if (map[logicalName] === otc) {
return logicalName;
}
}
}

Categories