lit-element v2 clearing text fields with null properties - lit-element

I have lit-element based forms that are reused for editing entities.
As an example consider a name form with the following fields
<mwc-textfield id="first-name" label="First name" value="${this.firstName ?? ''}"></mwc-textfield>
<mwc-textfield id="middle-name" label="Middle name" value="${this.middleName ?? ''}"></mwc-textfield>
<mwc-textfield id="last-name" label="Last name" value="${this.lastName ?? ''}"></mwc-textfield>
The user selects an entity from some list and I fill the properties firstName, middleName, lastName
with the corresponding values. The user then may edit the values and press a save button which reads
the values of the text fields with something like
this.firstName = this.shadowRoot.getElementById("first-name").value;
and writes them back to the database. This all works well except for one case:
when the user edited the fields but then decides to not save the changes and instead
load another entity, the data binding seems to be somehow broken for empty properties.
So, f.e. assume the user selected 'Fred Krueger' (firstName=Fred, middleName=null, lastName=Krueger),
then typed a middle name 'Jacob' into the field but then decides to not save it and load
'Sarah Mueller' instead. Since her middle name is null, the text field should be cleared.
What happens instead is that 'Jacob' remains in the field!
It seems as if a null value will not clear a text field that was edited by the user and not synchronized
to the bound property. Note that properties that are not null do always update the fields!
The problem can be resolved by adding a change and keyup handler to each and every textfield in my form
to synchronize the corresponding properties.
Question:
Is this really the only way to do it?
Why does a property with value null not update the field when it has been edited before?
(Edit: changing the binding from value to .value does not fix this!)

This is due to the value property on the DOM being changed by the user input and Lit can't tell the DOM element needs to change. As you've noticed, using an event listener to keep the DOM value and Lit property always in sync is one way to avoid this, and this is often preferable since the Lit components will always have the latest value without needing to look it up from the DOM node.
Alternatively, using the live directive can force Lit to check against the current live value on the DOM node and properly update it.
import {live} from 'lit/directives/live.js';
<mwc-textfield id="first-name" label="First name" value="${live(this.firstName ?? '')}"></mwc-textfield>
<mwc-textfield id="middle-name" label="Middle name" value="${live(this.middleName ?? '')}"></mwc-textfield>
<mwc-textfield id="last-name" label="Last name" value="${live(this.lastName ?? '')}"></mwc-textfield>

Related

Is there a way to have a new PXDBDecimal field show null

I have added PXDBDecimal user fields to an existing screen in the form section. When creating a new record, these immediately show as '0.00' - I'd like to know if there's a way for it to just show empty / null. I have no PXDefault attribute, so it's not set to default to 0.00.
See the answer here: (Presumably this is the same case with PXDBInt and PXDBDecimal)
Default [PXDBInt] data field to Null value?

Null value submitted for a conditionally disabled field in a reusable JSF popup

I have a popup dialog developed in IceFaces 1.8.x (JSF 1.2).
The dialog is reusable (used for account creation as well as modification) and has a cancel button with immediate = true (to avoid validations). This dialog suffered a problem in the past ,where old values were rendered on re-opening the dialog, but that problem is now fixed as directed here (by setting submittedValue to null etc.).
The problem that I am facing now is specific to a conditionally disabled input field (<ice:inputText>) and here is what happens:
The popup is first opened (say for account creation) and this field
is NOT disabled.
User then cancels this dialog and, as we have incorporated the fix mentioned above (setSubmittedValue(null)), the submittedValue for this field is set to null (along with other fields).
Now the user opens "modify account" dialog, where in this field IS disabled. Everything seems to be rendered fine until user makes any changes to the form.
When user changes some field (say name) in the form, a partial submit happens for the name field as expected, but along with it null value is submitted for this disabled field.
This problem can be worked around by adding a null check in the setter method for the field in question, but this is not the desired solution for the project - as there are multiple places where this could be needed and doesn't seem like a very intuitive thing to do.
So I need to understand:
Why is the setter for this disabled field getting called in the
first place? and that too with a null value. The setter is not
called for any other enabled fields.
More importantly, is there any way to fix this (other than adding null check in the setter)?
You must be using rendered attribute to show/hide the dialog
<ice:panelPopup modal="true" rendered="#{bean.enabled}">
When dialog is reopened, it is coming up with some residual values from previous instance
The solution (or workaround) is to use <c:if> instead of rendered attribute, this way the DOM is completely destroyed when dialog closes and created from scratch when dialog opens
<c:if test="#{bean.enabled}">
<ice:panelPopup modal="true">
...
</ice:panelPopup>
</c:if>
This way you even would not need the fix to set submittedValue to null

In crm 2013 the AttributeInfo.GetValue returns wrong value

We are experiencing a strange issue, which can be reproduced by following below steps:
Open New Task (Or any other entity)
Enter text “Test Subject” in “Subject” field (or use any other field).
Use this Xrm.Page.getAttribute("subject").getValue(); statement to
get the value of subject’s field, it will return “Test Subject”.
Now clear the subject field.
Use this Xrm.Page.getAttribute("subject").getValue(); statement to
get the value of subject’s field, it will return “Test Subject”,
which is wrong value, the subject field is empty.
The Xrm.Page.getAttribute("subject").getValue() returns wrong value. We checked this issue in CRM 2011 and its ok the issue is specific to CRM 2013.
EDIT:
This code is fired from Custom Ribbon Button.
We tried to change the focus to another control and then we checked the value, it not works.
EDIT:
This issue occurs only if the field is a required field.
The logic of CRM page is that it changes data inside of the Xrm.Page.data object only if the edited field lost focus (this event tells CRM that the data entry is done), so it could be that after step 4 you don't lose focus to other field. This behavior is the same as in CRM 2011.
I think you have two problems here although they maybe cause by the same thing. This is unfortunately not an answer to these problems but an attempt to clarify the above.
Problem 1: JavaScript reads previous value when an empty value is entered.
I think this is the same as the original problem of this post.
This is also posted at: http://partnersupport.microsoft.com/en-us/mpndynamics/forum/mpndyncrm/javascript-reads-previous-value-when-an-empty/f7b8dffd-3a21-48ae-8dca-4c5467ea8272
On the Competitor form.
Enter “Oliver” in the name field.
Then read it in JavaScript as below.
function ClickHandler()
{
var nameValue = "";
nameValue = locationValue = parent.Xrm.Page.getAttribute("name").getValue();
var test1 = "";
}
You should get “Oliver” as expected.
Then go back to the Competitor form and manually delete the text with the backspace key.
Now read what is in the name field with JavaScript as was done earlier.
You would expect to get nothing but you get “Oliver”.
Now enter Mark in the name field.
Read the field with JavaScript and you get “Mark” as you should.
So it seems when an empty value is entered following a previous value the JavaScript reads the previous value.
To put it a different way. It seems that there is a problem if the Name field had a value and the text then gets manually deleted. The Xrm.Page object will not update to the empty string. The Xrm.Page object will however update to a non-empty value.
Problem 2: Javascript cannot read the value in the text field if the field has not lost focus.
This is also posted at http://partnersupport.microsoft.com/en-us/mpndynamics/forum/mpndyncrm/javascript-cannot-read-the-value-in-the-text-field/ecc2c9e0-fba0-44f2-93cd-320d042896f0?tm=1389885238744
Javascript cannot read the value in the text field if the field has not lost focus.
On the "Recurring Appointment" form I have an IFRAME that runs Javascript. It reads the value in the location field when a button is pressed. If I change the value in the location field to say "Brunswick Street" and press the button I get nothing read (i.e. in the code below locationValue is null).
However if I change the value in the location field to say "Brunswick Street". I then then click away to somewhere on the form other than the IFRAME so the location field has lost its focus (this can also be achieved by pressing enter/tab after entering the text in the location field). If I then press the button on the IFRAME the Javascript will read the text in the location field correctly.
I gather that this is because parent.Xrm.Page is only updated when focus is lost in a field.
function ClickHandler()
{
var locationValue = parent.Xrm.Page.getAttribute("location").getValue();
}
I tried changing the focus in the JavaScript by setting it to requiredattendees field. But this did not work.
parent.Xrm.Page.getControl("requiredattendees").setFocus();
I used to use parent.document.forms[0].namedItem(srcDataFlds[fld]).value; to get the value in CRM 4 and 2011 but this does not work in CRM 2013. So as the SDK suggested I changed the code to use parent.Xrm.Page however it seems to give the problem above.
The questions are why is the focus not lost when I click the button on the IFRAME? If I click on any field in the form the focus changes so why not the IFRAME.
Also how can I get the JavaScript to read the value in the location field without having to click away from the location field. (Hopefully read the value in a supported way)?
I just want the user to be able to enter the value in the location field and click the button in the IFRAME.
I also noticed that when you click the IFRAME the On Change Event is not fired for the location field.
So far the only way round this is to click on another field (or pressing enter/tab) before clicking on the button that fires the Javascript.
Both these problems have been recognized by Microsoft and have been fixed in “Update Rollup 1 for Microsoft Dynamics CRM 2013 Service Pack 1”

java.util.ArrayList incompatible with [Ljava.lang.Object check box group

I have a Check box group, whose values are computed by using the selected values of another Check box group. So when I do
var check6:com.ibm.xsp.component.xp.XspSelectManyCheckbox = getComponent("check6");
ArrSelected = check6.getSelectedValues();
to get the selected values, the following exception occurs:
Error calling method 'getSelectedValues()' on java class 'com.ibm.xsp.component.xp.XspSelectManyCheckbox'
java.util.ArrayList incompatible with [Ljava.lang.Object;
Check6 gets its values from a session scope variable that is computed on beforePageLoad event and I have also set the default value.
Note that this does not happen onload of the page, but when the first partial refresh happens. Does anyone know what this exception indicates?
Thanks a lot!
Bind the value of the selectItems for the second check box group to precisely the same expression the first checkbox group's value attribute is bound to.
This article provides a lengthy description of the reason why, but here's a very quick summary: if you ask a component what its value is, it has to ask the data it's bound to. So skip the component, and ask the data yourself.
So, if your first group looks like this:
<xp:checkBoxGroup value="#{currentDocument.FirstField}">...
Then your second group should look like this:
<xp:checkBoxGroup value="#{currentDocument.SecondField}">
<xp:selectItems value="#{currentDocument.FirstField}">
</xp:checkBoxGroup>
When the user's selection in the first group is posted to the data source, the second group will reflect the changes because they're linked to the same property on that data source. Slight caveat: if your page includes any required fields, you may need to skip validation on the onchange event that triggers the second group to recalculate.
the reason is simple, this class has no method getSelectedValues() (as far as I can see it, look here for more info: http://public.dhe.ibm.com/software/dw/lotus/Domino-Designer/JavaDocs/XPagesExtAPI/8.5.2/index.html?overview-summary.html)
Maybe you could bind the control to a scoped variable and then access this variable to compute your other values?

Using standard validation for read only edit boxes?

Some of my recent posts have to do with the fact that I am doing all of my validation in my Submit button.
The reason I am doing this is that I have a button that sets some read only edit boxes. Well you can configure a validation for a read only edit box but it does not execute at run time.
Since I could not figure this out and wanted to have a consistent look for validation I used my own validation on my Submit button.
Is there a way to validate read only fields?
One nice thing about putting all of the code in the Submit button is that all of the validation code is all in the same place but I can see where it also can cause portability issues when using custom controls.
Also another question is how to fire off validation if my Submit button is not marked as a Submit button.
As Dec says, the ReadOnly flag causes the content of the field to be rendered without the <input> tag. This makes validation impossible on the client side and since there is no data being submitted back to the JVM, validation coded on the field is ignored on the submit.
However, the data source QuerySaveDocument is triggered. Put your validation in there and/or put it in the fields that are rendered (readOnly=false) and be sure to set disableClientSideValidation="true" on all fields with validators on them.
Your QuerySaveDocument code looks something like this (assuming location is the field which is readOnly).
if (personDoc.getItemValueString("Location") == "") {
#ErrorMessage("The inherited location is blank and that is bad.");
return false;
}
return true;
With this, the field based validators will fire first and if they are all successful the QuerySaveDocument fires. This means if any field based validators fail, their messages will appear in your message area but the QuerySaveDocument message will not appear. QuerySaveDocument messages ONLY appear after all field based validators succeed.
When a read only field is rendered to the web browser it does not render using <input> tags but rather a simple <span> tag.
Validation can only be performed on proper input tags so the scenario you are experiencing is correct. There is no field for it to validate in read-only mode.
There is an option to 'display disabled in read only' which will render an <input disabled="true"> type tag for the field but I'm not sure off the top of my head is validation will work for those fields either because if a field is read-only then there really should be no need for any validation because your programmatically putting the value into the field and you should be validating it programmatically before you add the value.

Resources