ItemUpdated List Item Comparison - sharepoint

Is it possible to compare the properties listItemId with a field in a new list? I have an event receiver, I want to update a new list once an item in updated. I don't want to use GetItemById, I want to compare the first list auto generated ID with a field in the new list.
foreach(ListItem UpdateItem in destListItems) {
if (properties.ListItem["ID"] == UpdateItem["NewId"]); {
//Do something
}
}
The script does not update the item in the destination list. Any suggestions?

Try this:
if (properties.ListItem["ID"].ToString() == UpdateItem["NewId"].ToString()); {
UpdateItem["Field"]="123";
UpdateItem.Update();
}

Related

Using recalc function to change a field if item has weight

I currently have a recalc function that resets the shipping cost field if a line item has changed, but I really only need to do that if the item has a weight. How do I retrieve the weight of the changed line item?
Here's what I currently have:
function recalc(){
nlapiSetFieldValue('shippingcost', '0.00');
}
recalc is fired only when a change to a line item affects the Total of the transaction, and as such, may not be a reliable event for what you want to accomplish.
I would recommend against using validateLine as that event should be used to determine whether the new value for a field is valid.
I would advise you to use fieldChanged for responding to a field value that has changed. Something like:
function fieldChanged(type, name, linenum) {
if (type == 'item') {
if (name == 'item') {
handleItemChange(linenum);
}
}
}
function handleItemChange(linenum) {
var itemWeight = parseFloat(nlapiGetFieldValue('item', 'weight', linenum)) || 0;
if (itemWeight > 0) {
nlapiSetFieldValue('shippingcost', 0);
}
}
You may also want to consider the postSourcing event instead of fieldChanged, depending on which fields should actually trigger this logic.
Small segue, recalc doesn't give you a way to get the current line of the sublist, you'd need to loop through the whole sublist anytime a single line was changed.
Try validateLine, something like:
function validateLine(listType){
//To get the item weight, you could create a
//custom transaction column field that sourced the item weight.
if(nlapiGetCurrentLineItemValue(listType,'custcolitemWeight') > 0){
nlapiSetFieldValue('shippingcost','0.00')
}
//or you could source directly from the item record using nlapiLookupField
// Depending on your use case either could be appropriate
if(nlapiLookupField('item',nlapiGetCurrentLineItemValue(listType,'item'),'weight')){
nlapiSetFieldValue('shippingcost','0.00')
}
//you *need* to return true with the validate* event functions.
return true;
}
This (untested) example only handles line additions. If users are allowed to remove items, you'll need to implement a similar validateDelete that also reverts your changes.

How to create a Custom Select List for a netsuite field?

I have a field on a custom record. The name of the field is reference_code.
I want to populate "reference_code" with my own dynamic list which would be presented as a drop down to the user.
How do I do this? I defined my field as Free-Text. Do I need to keep it hidden but then show it as a drop down before I load the form?
I thought this might do something:
nlapiInsertSelectOption('custrecord_rulereferencecode', code, code, false)
But I would need to convert the field to a select?
Typically, instead of creating the field as Free-Text, you would first create a Custom List (Customization > Lists/Records/Fields > Lists > New) with all of your dropdown options.
Then you would create your field as a List/Record field and select your new Custom List as the "List/Record Type", as depicted below.
This can be done by giving a source to your drop-down menu. The source field accepts an internal id of a list. This internal id can be an in-built(provided by netSuite) or a custom list created by a user. For Eg: I have a custom list with an internal id '23' which has some list items in it, these can be populated in the drop down menu by the following syntax.
var start = function(request, response)
{
var form = nlapiCreateForm('Custom Form');
form.addField('custpage_selectfield', 'select', 'select a color', '23');//here 23 is the internal id of my list
respnose.writePage(form);
}
or you could generate you own field's dynamically using the addSelectOption() function.
var start = function(request, response)
{
var form = nlapiCreateForm('Custom Form');
var myselectfield = form.addField('custpage_selectfield', 'select', 'select a color');
myselectfield.addSelectOption('1', 'Red');//Here 1, 2 and 3 are the id's
myselectfield.addSelectOption('2', 'Green');//which are returned when the
myselectfield.addSelectOption('3', 'Blue');//form is submitted
respnose.writePage(form);
}
I solved this by creating two fields. One is created in the RecordType and will store the info. I set this as hidden. The next field, with the custom dropdown is added in user event. I then process data for my custom dynamic select list and add that to my added user event field.
Then in my change event, I set the record type field to the value selected in my dynamically added field.
Userevent
function userEventBeforeLoad(type, form, request){
if(type == "edit"){
form.addField('custpage_referencecode','select','Reference Code',null, null)
}
}
In my Client Script:
function clientFieldChanged(type, name, linenum){
if(name == 'custpage_referencecode'){
//obtain the upper case value
var codetext = nlapiGetFieldValue(name)
//make sure it hasn't been set
if (codetext != nlapiGetFieldValue('custrecord_rulereferencecode'))
{
nlapiSetFieldValue('custrecord_rulereferencecode', codetext );
}
}
return true
}

in a civicrm webform, create multiple 'groups' fields

In CiviCRM webform, you can 'enable tag and groups'. Configuring those allows you to create option elements in the webform.
This creates one 'widget', one dropdown or set of checkboxes. I have two field instances where I want the user to select a group - say for example
which mailing lists do you want to receive (a,b,c)
what food are you interested in (d,e,f)
a,b,c,d,e and f are all groups. I can not change that.
How could I do that ?
A technical suggestion below, but first, I'd suggest that your real solution is to not use groups for the second question. Groups are set up nicely to handle mailing lists, but if it's to track interests, you'd be better off setting those up as custom fields. It'll solve this immediate issue, and it'll make it easier to deal with tandem searches and so forth (on list b and likes food d).
Now if you must have them as groups, you can create a fake field and move checkboxes into it using jQuery. Create the fake field with one option that you don't care about, but label it "What food are you interested in", or equivalent. Then, edit the Groups field that CiviCRM generated: label it more specifically as "which mailing lists...", and choose Static Options so it doesn't start offering up just any group for someone to choose.
Now, add the following javascript:
// first remove the dummy checkboxes in your fake field
$('#yourdummyfield .form-item').each( function() { $(this).remove(); });
// now move things into the dummy field
$('#yourdummyfield').append( $('#groupsfield .form-item-d');
$('#yourdummyfield').append( $('#groupsfield .form-item-e');
$('#yourdummyfield').append( $('#groupsfield .form-item-f');
From the form processing perspective, they'll all be evaluated as the "groups" field. However, they'll look separate. For better or worse, this will have to be adjusted as you add new groups fields.
After using Andrew Hunts suggestion for a while, I finally solved this on the server side, in a custom module, using webform logic as described here
http://www.webomelette.com/drupal-webform-submission-presave-hook
Basicly, on presave, I look for 2 custom fields containing group ids (mailing and food in the example). Then I add these to the CiviCRM groups field.
I'll add the code below, which has some more logic:
to make it flexible, I use one hidden field to contain the fieldkey
of the civicrm groups selector to add the other fields in. that
field is called 'the_groups_element' (but its not the groups element, it contains the key of the groups element)
there is only one foods group allowed, so before it adds you to a food group, it removes all other food groups from the groups selector.
You could probably make it even more generic, but since I had different logic for the different groups, this was suitable for me.
function getFoodGroups() {
// return foodgroups
}
function getMailGroups() {
// return mailgroups
}
function MYMODULE_webform_submission_presave($node, &$submission) {
$groupselm = '';
$groups_cid = false;
$foods_cid = false;
$mailings_cid = false;
// http://www.webomelette.com/drupal-webform-submission-presave-hook
foreach($node->webform['components'] as $cid=>$comp) {
if ($comp['form_key']=='the_groups_element') {
$groupselm = $comp['value'];
break;
}
}
if ($groupselm) {
foreach($node->webform['components'] as $cid=>$comp) {
if ($comp['form_key']==$groupselm) $groups_cid = $comp['cid'];
if ($comp['form_key']=='the_foods') $foods_cid = $comp['cid'];
if ($comp['form_key']=='the_mailings') $mailings_cid = $comp['cid'];
}
$group_gids = $submission->data[$groups_cid];
if (!$group_gids) $group_gids=array();
if ($foods_cid!==false && $submission->data[$foods_cid]) {
// remove all current foods
foreach ($group_gids as $gidx=>$group_gid) {
foreach (getFoodGroups() as $foodgroup) {
if ($group_gid==$foodgroup['gid']) {
if ($debug) drupal_set_message('removing foodgroup '.$foodgroup['gid']);
unset($group_gids[$gidx]);
}
}
}
// validate and add submitted regions
$foodsgids = $submission->data[$foods_cid];
if (!is_array($foodsgids)) $foodsgids = array($foodsgids);
foreach ($foodsgids as $foodsgid) {
foreach (getFoodGroups() as $foodgroup) {
if ($foodsgid==$foodgroup['gid']) {
$group_gids[]=$foodsgid;
break; // only one food allowed
}
}
}
}
if ($mailings_cid!==false && $submission->data[$mailings_cid]) {
// just add submitted mailings, dont remove any
$mailinggids = $submission->data[$mailings_cid];
if (!is_array($mailinggids)) $mailinggids = array($mailinggids);
foreach ($mailinggids as $mailinggid) {
foreach (getMailGroups() as $mailing) {
if ($mailinggid==$mailing['gid']) {
if ($debug) drupal_set_message('adding mailing '.$mailing['gid']);
$group_gids[]=$mailinggid;
}
}
}
}
$submission->data[$groups_cid] = array_unique($group_gids);
}

How to prevent computed() from firing when its array value doesn't change

This seems like a question that should have been answered already, but I haven't been able to find any discussion of this.
I have an array of items, some of which may be selected:
function Item(name) {
this.name = name;
this.selected = ko.observable(false);
}
function ViewModel() {
var self = this;
this.items = ko.observableArray([]);
this.selected = ko.computed(function() {
return ko.utils.arrayFilter(self.items(), function (item) {
return item.selected();
});
}, this);
}
Since viewmodel.selected() depends on viewmodel.items(), whenever I add a new object to items the selected observable also changes, even if the added item is not selected. How do I prevent this.selected() from updating if no new items are actually selected?
I am not sure you can achieve this with a pure ko.computed solution.
Maybe you could subscribe to your "items" changes. When one item is added, you check if it is selected and push it to another observableArray if it is.
See the first answer to this question : Determine which element was added or removed with a Knockoutjs ObservableArray
It would allow you to subscribe to specific changes on your "items" (item added or deleted).

foreach inside xdocument.add

I have a class that has a dictionary field. I want to loop through every item of this class and create an xml document but inside this loop I want to loop through this dictionary properties and add the key values pairs.
I am looking for something that will do the following
foreach(Book bk in query)
{
ReturnData.Descendants("Books")
.FirstOrDefault().Add(new XElement("Book",
new XElement("Name", bk.BookName),
new XElement("Measure", bk.Measure,
.foreach(KeyValuePair<string, double> measure in bk.NewMeasures)
{
new XElement(measure.Key,measure.Value)
},
new XElement("Value", bk.PreviousValue))));
}
Return data already contains some XML, this is why I am adding to the Books descendants. It may already have other roots such as videos, games etc.
Appreciate any thoughts on this.
First of all, I would query for the first book outside the loop:
var book = ReturnData.Descendants("Books").FirstOrDefault();
And then use it within the loop:
foreach(var b in query)
{
book.Add(new XElement("Book",
new XElement("Name", b.Name),
new XElement("Measure", b.Measure,
from m in b.NewMeasures select new XElement(m.Key, m.Value)),
new XElement("Value", b.Value)));
}

Resources