Why do vuelidate validators no longer react to input changes? - javascript

I have a problem regarding form validation with vuelidate. I’m using Vue 2.9.6 with vuelidate 0.7.5
I recommend opening this jsfiddle while reading my problem description:
jsfiddle.net/Philgarth/h5v7km2s/
(SO prevents me from posting the link properly, sorry .... just prepend "https://")
I’m developing an account book for private bank accounts and currently I’m working on the depositor-form-component, where users can add new depositors. Each depositor must have a name and at least one bank account to submit the depositor-form and return to the account-view-component.
As you can see in the jsfiddle I have a textfield for the name and a dropdown for the accounts which initially is empty and disabled. A new account can be drafted by clicking the „+“-button besides the dropdown. With „drafted“ I mean, that the account in the finished app shouldn’t get posted to the database right away. Because users should be able to create multiple accounts for a depositor only the finished and validated depositor-object with one ore more accounts is sent to the database by submitting the whole depositor-form.
While a new account is drafted, the variable „pendingAccountCreation“ is set to true, which is why the account fields are displayed via „v-if“ as well as two buttons to submit or discard the account data.
When clicking on either of these buttons, the validation-object „updatedAccount“ should be resetted, so that by drafting another account the fields neither are dirty nor have errors.
Now the problem is, that the validators don’t react to changes to the input field in some cases – e.g. „required“ remains false although the input field is not empty.
I made some tests and could determine that the error only occurs, when an account-draft is discarded by clicking the „x“-button while no other accounts are already created. As soon as at least one account is created and available in the dropdown everything works as expected and the validators react to input changes when drafting another account.
Now if you want to help me I ask you to reproduce the error in the jsfiddle and try to figure out, what I’m doing wrong here.
Thanks in advance and have a nice day 😊

Change this code:
discardAccountDraft(accountValidator) {
accountValidator.$reset();
this.selectedAccountIndex = 0;
if (this.updatedDepositor.accounts.length !== 0) {
this.selectedAccount = this.updatedDepositor.accounts[0];
this.updatedAccount = this.cloneObject(this.selectedAccount);
} else {
this.updatedAccount = this.cloneObjectModel;
}
this.pendingAccountCreation = false;
},
to this code (jsfiddle):
discardAccountDraft(accountValidator) {
accountValidator.$reset();
this.selectedAccountIndex = 0;
if (this.updatedDepositor.accounts.length !== 0) {
this.selectedAccount = this.updatedDepositor.accounts[0];
this.updatedAccount = this.cloneObject(this.selectedAccount);
} else {
this.updatedAccount = this.cloneObjectModel({
id: "",
accountNumber: "",
iban: "",
bic: "",
accountDescription: "",
});
}
this.pendingAccountCreation = false;
},
I've just added empty model to your cloneObjectModel function, because it expects one... And this fixed the problem you mentioned:
error only occurs, when an account-draft is discarded by clicking the „x“-button while no other accounts are already created

Related

Reading data from firebase everytime button is clicked, without having to refresh

I am quite the beginner in programming with web applications. My goal is to receive data from realtime firebase database.
So I have this code to read from realtime firebase application. When I do this I can actually see the output. My problem is that if I change a value in the input-box and submit again without reloading page, the javascript will not run the new input value.
For the console output in internet:
The problem is here, if I change value to "1" in input box without refreshing page, my program won't take that input and do stuff with it. Check below:
It's suppose to return a value of 0 and where i marked with circle it should say "1". If i refresh page and then put in 1 into input box, it works fine. But if I change back to 2 without refreshing. same problem.
I just want to do the same without user having to refresh page eveyrtime they type in new data.
Hope someone out there can help :) I watched so many tutorials for reading from database and I can't figure out what to do here.
You can use oninput JS event to capture a value when it is changed
var standNr = document.getElementById("standNr");
standNr.oninput = function() {
console.log(standNr.value);
}
<input type="text" id="standNr"/>
defineStand.addEventListener('submit', (e) => {
var stand_number = document.getElementById("standnr").value
var dbRef = database.ref('stand/' + stand_number + '/status')
e.preventDefault()
dbRef.on('value', function(snapshot) {
console.log(snapshot.val())
})
console.log(stand_number)
console.log(dbRef)
})
I solved it now. Works perfectly :D
My issue was that e.preventDefault wasn't placed after definings the variables :)

Adaptive Card clears input on submit

From a Microsoft Teams bot I send an Adaptive Card with input fields and a Submit action. When the user clicks Submit I receive the data entered but the form fields are cleared.
Why is this? What am I doing wrong? This behavior is extremely annoying as I can't verify the input and ask the user to correct it.
This happens in the desktop Teams app, Teams in a browser, Teams webchat in a web page and the Bot Emulator. In the Emulator it suffices for the field to loose focus.
In case it matters I use nodejs.
You're not doing anything wrong. That's just how Adaptive Cards work in Teams, perhaps as a way to signify that the data has been sent to the bot successfully. There may be something you can do to fix your problem though.
Adaptive Card input fields have a value property that allows you to specify the field's initial value. If you send a card to the user and the input fields' value properties are populated, the fields won't be empty. This means you can send such a card as an update instead of a new activity and it will look like the card has been modified in place, since Teams supports updating activities. If the update uses the same card but with the values the user entered then it will look like the card remains unchanged, which would fix your problem of the values disappearing.
There was a question about dynamically adding input fields to Adaptive Cards, and the answer contains sample code that preserves input field values:
var inputId = `text${i}`;
body.push({
type: "Input.Text",
id: inputId,
value: cardData[inputId] // This is where the value is preserved
});
If you want this whole process to be made easier with prebuilt code that you can install in NuGet packages, feel free to voice your support for these ideas on GitHub:
Bot.Builder.Community.AdaptiveCards
AdaptiveCard Prompt
While I was waiting for an answer to my question I came pretty much to the same conclusion as Kyle Delaney outlined above, you have to resend the data entered.
So I started to fiddle with my code and came up with this solution, not sure this is the best way.
As part of a waterfall step:
async W2_showCard(step) {
const card = CardFactory.adaptiveCard(this.makeFormCard());
return await step.prompt('formPrompt', { prompt: MessageFactory.attachment(card) });
}
The trick is in formPrompt which also ensures the user submits the form instead of doing something else.
// Workaround to make user click Submit or cancel dialog
this.dialogs.add(new ActivityPrompt('formPrompt', async prompt => {
const recognizedValue = prompt.recognized.value;
if (recognizedValue.type === ActivityTypes.Message) {
if (recognizedValue.value) {
const replyToId = recognizedValue.replyToId;
var oldCard = prompt.options.prompt.attachments[0];
var validated = true;
oldCard.content.body.forEach((item, i, body) => {
if (item.type === "Input.Text" || item.type === "Input.ChoiceSet") {
// preserve the user input
const newValue = recognizedValue.value[item.id];
item.value = newValue;
// some rudimentary input validation:
// assumes there is a corresponding text field just
// prior to the input field (input fields
// can't change their color)
if (newValue == '') {
body[i - 1].color = 'Attention';
body[i - 1].weight = 'Bolder';
validated = false;
} else {
delete body[i - 1].color;
delete body[i - 1].weight;
}
}
});
if( validated ) {
// remove the submit and cancel actions (not required, debatable)
delete oldCard.content.actions;
}
// update the card
const activity = prompt.context.activity;
activity.attachments = [oldCard];
activity.id = replyToId;
await prompt.context.updateActivity(activity);
if (validated) {
// this is to make input available in next waterfall step
prompt.recognized.value = recognizedValue.value;
return true;
} else {
await prompt.context.sendActivity(`Please check the form. Some values are missing`);
}
} else {
await prompt.context.sendActivity(`Please fill out form and press *"submit"* button or type *"cancel"* to stop.`);
}
}
return false;
}));

YouTrack Workflow: Prevent Deletion

I've created a very simple workflow task for a cloud based YouTrack instance. The idea is to prevent (stop workflow) deletion of issues (we'd prefer to keep all issues, even if they were submitted by mistake). The code is provided below.
var entities = require('#jetbrains/youtrack-scripting-api/entities');
var workflow = require('#jetbrains/youtrack-scripting-api/workflow');
exports.rule = entities.Issue.onChange({
// TODO: give the rule a human-readable title
title: 'When-issue-is-deleted',
guard: function(ctx) {
return ctx.issue.becomesRemoved;
},
action: function(ctx) {
workflow.check(false, 'Do not remove issues, please');
}
});
Though I believe it should work, when I tried to remove a new just created issue I received no error messages, and the issue was removed.
I'd recommend an easier way - just disable 'Delete issue' permission for the respective roles (https://www.jetbrains.com/help/youtrack/standalone/Create-and-Edit-Roles.html#editing_existing_roles) and users with these roles will not be able to delete issues.
As for becomesRemoved property which doesn't work properly - this is a known issue, please follow this ticket to receive further updates on it: https://youtrack.jetbrains.com/issue/JT-29303.
Just in case someone else stumbles upon this issue (quoting https://youtrack.jetbrains.com/issue/JT-55220)
To make your onChange rule triggered when an issue becomes removed, you'll need to specify the runOn attribute in the rule's declaration.
runOn: {
change: false,
removal: true
}

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;
}
}
}

Force a SaveForm in Dynamics CRM 2011 using JavaScript

In CRM 2011, I want to be able to force a save of a form. My requirement is as below.
When the user opens the form, I check if a particular field is empty or not.
If it is empty, I want to force a save, thereby triggering a plugin which will set the field.
My current code is as below. This is in the FormOnLoad function which is associated with LoadForm.
if(checkfield == null){
Namespace.Functions.Contact.FormOnSave();
}
else{
// do nothing.
}
Now, this fails with the following line
Can't execute code from a freed script.
I have no clue as to how to proceed further. As a temporary fix, what I have done is the following
if(checkfield == null){
setTimeout('Namespace.Functions.Contact.FormOnSave()',4000);
}
else{
// do nothing.
}
Any advice on why this is happening and how can I fix it without the timeout would be really helpful?
I have had a look at this question and this, but in my case the form does get loaded or has it actually not yet loaded?
Either way, how can I force a save of a CRM form?
You can save the Form by using:
parent.Xrm.Page.data.entity.save();
But It will only trigger if
(Xrm.Page.data.entity.getIsDirty() == true)
However there is a workaround to set IsDirty property true.
Run the Javascript function on PageLoad. Try to update the value of the field which you are planning to populate through plugin:
For e.g.
function OnPageLoad()
{
var yourField = Xrm.Page.getAttribute("new_yourfield").getValue();
if(yourField == null)
{
parent.Xrm.Page.getAttribute("new_yourfield").setValue("any value");
parent.Xrm.Page.getAttribute("new_yourfield").setSubmitMode("always");
parent.Xrm.Page.data.entity.save();
}
}
You could skip all of this mumble jumbo with loading your form twice with Javascript by creating a plugin registered on the read or the entity. (Or better yet and if possible, on the Create of the entity)
The Plugin would just check for the field, and if it's empty, perform whatever logic you need it to to update the field, then save it, and return the updated field (or possibly just populate the value and don't update the database until the user performs the save)

Categories