react-bootstrap-typeahead: How to get attribute value on "OnChange" , I am using Typeahead in table cell - react-bootstrap-typeahead

I am using react-bootstrap-typeahead in table row for invoice items.
my json is like [{record_id:1,value="value1"},{record_id:2,value="value2"}]
on this basis I am creating bootstrap table.
in table cell I am adding typeahead select box to change the value and update my json,
when I change the value I want to update my json array with latest value in related record.
But as in onChange we only get selected array not an event object so, I am not able to find record id.

I have create one solution , I know it is not best but it works for me.
I have set state called currentLineItem and I am updating this value on "onFocus" event of react-bootstrap-typeahead. in this event I am getting an event object.
const [currentLineItem, setCurrentLineItem] = useState(null);
const selectBoxOnFocus = (event) => {
const rowId = event.target.parentNode.parentNode.parentNode.parentNode.getAttribute("data-id");
setCurrentLineItem(rowId);
};
const taxCalcChangeInRow = async (option) => {
const rowId = currentLineItem;
// my other code
};
<SelectBox {/*(this is wrapper componat of typeahead)*/}
data-id={row.id}
name="inputTaxCalc"
options={taxCalcOptions}
OnChange={taxCalcChangeInRow}
onFocus={selectBoxOnFocus}
/>

Related

Set ag grid readonly fields

I am using a method per ag-grid example setting
gridOptions = {
columnDefs: [],....etc.
and reading a json file from the server that populates the fields (and columns).
// Get data from server //https://ag-grid.com/javascript-data-grid/getting-started/
fetch ('https://dev.perfectiononwheels.com/pricedataJSON/pricelistJson.json')
.then(function (response) {
return response.json();
}).then(function (data) {
// set the column headers from the data
const colDefs = gridOptions.api.getColumnDefs();
colDefs.length=0;
const keys = Object.keys(data[0])
keys.forEach(key => colDefs.push({field : key}));
gridOptions.api.setColumnDefs(colDefs);
// add the data to the grid
gridOptions.api.setRowData(data);
});
The document states that using this technique you can then set editable:true to be able to edit fields on the grid. However, I would like to set some columns (fields) as read-only, and change another to a checkbox.
I am not able to find an refernce on how to access a column to change to read-only or a checkbox.
(I was able to set these params when I defined each field in the columnDefs)
There is no direct api for this.
To change whether a column is editable, you'll have to change the editable property for the column in the columnDefs, and then call the grid api's setColumnDefs() method, passing it the updated columnDefs.
Same thing with the checkboxSelection property, to show a checkbox or not.

DynamoDB - How to upsert nested objects with updateItem

Hi I am newbie to dynamoDB. Below is the schema of the dynamo table
{
"user_id":1, // partition key
"dob":"1991-09-12", // sort key
"movies_watched":{
"1":{
"movie_name":"twilight",
"movie_released_year":"1990",
"movie_genre":"action"
},
"2":{
"movie_name":"harry potter",
"movie_released_year":"1996",
"movie_genre":"action"
},
"3":{
"movie_name":"lalaland",
"movie_released_year":"1998",
"movie_genre":"action"
},
"4":{
"movie_name":"serendipity",
"movie_released_year":"1999",
"movie_genre":"action"
}
}
..... 6 more attributes
}
I want to insert a new item if the item(that user id with dob) did not exist, otherwise add the movies to existing movies_watched map by checking if the movie is not already available the movies_watched map .
Currently, I am trying to use update(params) method.
Below is my approach:
function getInsertQuery (item) {
const exp = {
UpdateExpression: 'set',
ExpressionAttributeNames: {},
ExpressionAttributeValues: {}
}
Object.entries(item).forEach(([key, item]) => {
if (key !== 'user_id' && key !== 'dob' && key !== 'movies_watched') {
exp.UpdateExpression += ` #${key} = :${key},`
exp.ExpressionAttributeNames[`#${key}`] = key
exp.ExpressionAttributeValues[`:${key}`] = item
}
})
let i = 0
Object.entries(item. movies_watched).forEach(([key, item]) => {
exp.UpdateExpression += ` movies_watched.#uniqueID${i} = :uniqueID${i},`
exp.ExpressionAttributeNames[`#uniqueID${i}`] = key
exp.ExpressionAttributeValues[`:uniqueID${i}`] = item
i++
})
exp.UpdateExpression = exp.UpdateExpression.slice(0, -1)
return exp
}
The above method just creates update expression with expression names and values for all top level attributes as well as nested attributes (with document path).
It works well if the item is already available by updating movies_watched map. But throws exception if the item is not available and while inserting. Below is exception:
The document path provided in the update expression is invalid for update
However, I am still not sure how to check for duplicate movies in movies_watched map
Could someone guide me in right direction, any help is highly appreciated!
Thanks in advance
There is no way to do this, given your model, without reading an item from DDB before an update (at that point the process is trivial). If you don't want to impose this additional read capacity on your table for update, then you would need to re-design your data model:
You can change movies_watched to be a Set and hold references to movies. Caveat is that Set can contain only Numbers or Strings, thus you would have movie id or name or keep the data but as JSON Strings in your Set and then parse it back into JSON on read. With SET you can perform ADD operation on the movies_watched attribute. https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html#Expressions.UpdateExpressions.ADD
You can go with single table design approach and have these movies watched as separate items with (PK:userId and SK:movie_id). To get a user you would perform a query and specify only PK=userId -> you will get a collection where one item is your user record and others are movies_watched. If you are new to DynamoDB and are learning the ropes, then I would suggest go with this approach. https://www.alexdebrie.com/posts/dynamodb-single-table/

APEX Trigger when a textfield gets updated

I am trying to create a trigger in APEX, when an custom textfield of an custom sObject gets updated with products (means, when new products get insert or existing one get deleted).
How can I compare in APEX the Trigger.Old values with the Trigger? New values of this field in order to start the Trigger.
It would look something like this:
Trigger NameOfTrigger on CustomSObject__c (after update){
/*there is already an existing list of products that get insert into the custom textfield (probably as Strings)
*/
List <String> textList = new List <String> ();
/*PseudoCode: if the textfield got updated/has changed, copy from every entry of this textfield (entry = product name as a string) and copy fieldX into another sObject
*/
if(CustomSObject.field(OldValues) != CustomSObject.field(NewValues)){
for (String product : textList){
//Trigger e.g. copy the values of a certain field of p and paste them in another sObject
}
Could somebody help me with the syntax?
You can utilize inbuilt Trigger.new and Trigger.old to get the latest and old values of any record. These lists can be used to achieve what you're looking for.
Sample example would be:
Trigger NameOfTrigger on CustomSObject__c (after update){
for(CustomSObject__c customObject : Trigger.new) {
// get old record
CustomSObject__c oldCustomObject = Trigger.oldMap.get(customObject.Id);
// compare old and new values of a particular field
if(customObject.fieldName != oldCustomObject.fieldName){
//Trigger e.g. copy the values of a certain field of p and paste them in another sObject
}
}
}
See documentation of Trigger.new & Trigger.old

How to insert a table inside a contentControl using Word javascript api

I am developing a word add-in using word JavaScript api, I need to insert some data in table format inside the content Control and placed that content control on top of document.
Please advice.
Thanks.
This should be quite a simple operation. I am assuming that by "On top" of the document you mean inserting a table where the document starts. First line.
All the insertion methods have an insertionLocation parameter that you can use for that purpose. On this case you want to do a body.isnertTable, the 3rd parameter is the insertionLocation ("start" is sent to insert at the beginning of the body of the document).
Once its inserted you can actually wrap it with a content control. Check sample below for details. I included other details, such as applying a built-in style to the inserted table.
hope this unblocks you. thx!
function insertTableAndWrapWithCC() {
Word.run(function (context) {
// We need a 2D array to hold the initial table values
var data = [["Apple", "Orange", "Pineapple"],["Tokyo","Beijing", "Seattle"]];
var table = context.document.body.insertTable(3, 3, "start", data);
table.styleBuiltIn = Word.Style.gridTable5Dark_Accent2;
//now we insert the content control on the table.
var myContentControl = table.insertContentControl();
myContentControl.title = "CC Title";
return context.sync()
})
.catch(function (e) {
console.log(e.message);
})
}

link multiple models on same row of sap.m.table

This may be a basic question, but it's my first, so please be kind :-).
I have a sap.m.table with two models, one model with transaction data (trxModel) and another model that is used to display a sap.m.select list (reasonCodeModel). The table model is set to trxModel.
The selected value key from the dropdown needs to update a value (ReasonCodeID) in the trxModel when a value from the reason code list is selected.
I can retrieve the selected key in the change event as so
var selKey = evt.getParameter("selectedItem").getKey();
Is there a simple way to find the trxModel relevant model path from the table row Select list value I've just modified? Or is it possible to bind the ReasonCodeID from the trxModel to the ReasonCodeID field in the reasonCodeModel?
Just an extra piece of info, The current row is selected and is accessible
var selItem = dtlTable.getSelectedItem();
2nd question and I guess could be kind of related, is there a way of getting the table model path based on the selected item (highlighted row) of the table? And vice a versa?
More details on Select & Table binding.
var tabTemplate = new sap.m.ColumnListItem(
{
::
new sap.m.Select(
"idReasonCodeSelect",
{
enabled : false,
change : function(evt) {
oS4View.getController().changeReasonCodeSel(evt);
}
}
),
Bind the resource code Select to the Table
// bind the reason codes to the reason code model
sap.ui.getCore().byId("idReasonCodeSelect").setModel(
oReasonCodeModel);
sap.ui.getCore().byId("idReasonCodeSelect").bindAggregation("items", "/results",
new sap.ui.core.Item({
key : "{ReasCodeID}",
text : "{ReasCodeDesc}"
}));
Per Qualiture comment, how do I bind the Select key to the table model ReasonCodeID value?
I found an approach to tackle the first part of my question above
From the change function on the Select, I can find the path of the table model using the following.
var path = evt.getSource().getParent().getBindingContext().sPath;
2nd Update:
On the selectionChange event on the table, there's a couple of options to find the associated model path or model content.
// find the model path
oModelPath = selItem.getBindingContext().getPath();
// model values
oItem = oEvent.getParameter("listItem").getBindingContext().getObject();
So my only remaining issue, While I loop through the table model results (trxModel) and I want the Select List (using setSelectedKey) to reflect the ReasonCodeID value in the trxModel.