preventDefault not working correctly Dynamics 365 - javascript

I am trying to get my form to give an alert and prevent save if it meets a certain criteria (the if statement) and save if anything else but if I stick preventDefault inside the IF it still allows me to save.
I have tried putting it outside the IF but then no matter what I can't save the form and my formContext.data.save() doesn't work.
function denyCreateVariationSor(executionContext)
{
debugger;
var id = Xrm.Page.getAttribute("gilm_variation").getValue()[0].id;
var url = 'gilmartins-test.crm11.dynamics.com/.../gilm_variations eq ' + id + ')';
var variationStatus;
var formContext = executionContext.getFormContext();
fetch(url).then(response => response.json()).then(data =>
{
var arr = data.value;
variationStatus = arr[0]["gilm_variationstatus"];
if (variationStatus != 870110000)
{
executionContext.getEventArgs().preventDefault();
alert("You can't add a SOR onto a completed/cancelled variation");
}
else
{
formContext.data.save()
}
});
}

Related

Initial load and when I change value of input doesn't show message in JavaScript

everyone, I have some problem with fetching data and displaying message on initial loading as well as when I change some of the input filed value. The idea here is to display specific message in two cases after doing some calculation.
const potrosnja = document.getElementById('potrosnja');
const nagib = document.getElementById('nagib');
const input = document.querySelectorAll('input[type="number"]');
const submitBtn = document.getElementById('submitBtn');
const poruka = document.getElementById('poruka');
let str = document.querySelector('input[name="strane-sveta"]:checked').value;
let godisnjaPotrosnja = parseInt(potrosnja.value);
let nagibKrovaInput = nagib.value;
//On button submit it fetches data and calculate the value needed for yearly consumption of energy
//fetching data
async function dataFetch(){
let response = await fetch('./csvjson.json')
let data = await response.json();
data.map(strana => {
strana.strana.map((item, i) => {
try {
if(item == str && nagibKrovaInput == strana.nagib) {
let result = Math.ceil(godisnjaPotrosnja / strana.vrednost[i]);
console.log("try works")
poruka.innerHTML = `You need <span class="kw">${result}</span>`
}
}
catch(err) {
poruka.innerHTML = `Please fill required fields.`
console.log(err)
}
})
})
}
//event listeners
submitBtn.addEventListener('click', () => {
dataFetch()
console.log('clicked')
input.forEach(input => {
if(input.value == ''){
input.classList.add("active");
}
})
})
I can see that the problem is inside try function, it like condition isn't treated on initial load, and I have to reload page so it would work. Can someone help me understanding what is the problem?
Ok, I found solution... First thing I have to do Is to check if nagibKrovaInput == strana.nagib, after I get true, I compared does the indexOf item is equal as str and after I get true, it will display something. I also changed on click on the button to send values to data function as an arguments and It solved the problem. Tnx for help.

Trying to get the elements of a page when it fully loads but I either get undefined or null. Why?

I've been working on this for two days now and I still can't figure out why my elements are sometimes either returning null or other times returning undefined but never returning the properties themselves. I've set their ID's in the respective HTML file and I still get null or undefined.
I've tried using setTimeout() but that didn't work because I was redirecting to a new page. I tried using an event listener on the document with DOMContentLoaded. I've even tried window.onload
var userEmailDisplay;
var newPaswordInput;
var confNewPaswordInput;
var submitNewPasswordBtn;
const urlParams = getAllUrlParams(window.location.href);
const actionCode = urlParams.oobCode;
window.onload = () => {
var doc = document;
switch (urlParams.mode) {
case 'resetPassword':
handleResetPassword(actionCode);
break;
case 'recoverEmail':
handleRecoverEmail(actionCode);
break;
case 'verifyEmail':
handleVerifyEmail(actionCode);
break;
}
// get new password elements
/* if (window.location.href.indexOf("new-password") > -1) {
userEmailDisplay = doc.getElementById('account-email-new-pswd');
newPaswordInput = doc.getElementById('new-password-input');
confNewPaswordInput = doc.getElementById('conf-new-password-input');
submitNewPasswordBtn = doc.getElementById('update-pswd-sub-btn');
} */
}
function handleResetPassword(actionCode) {
// Verify the password reset code is valid.
auth.verifyPasswordResetCode(actionCode).then(function (email) {
window.location.href = "https://couch-potato-880f0.firebaseapp.com/email/new-password.html";
console.log("code verified");
confirmThePswdReset(actionCode, email);
}).catch(function (error) {
console.error(error);
});
}
function confirmThePswdReset(actionCode, email) {
window.onload = () => {
userEmailDisplay = document.getElementById('account-email-new-pswd');
newPaswordInput = document.getElementById('new-password-input');
confNewPaswordInput = document.getElementById('conf-new-password-input');
submitNewPasswordBtn = document.getElementById('update-pswd-sub-btn');
console.log(submitNewPasswordBtn + ' + ' + userEmailDisplay);
if (submitNewPasswordBtn && userEmailDisplay) {
submitNewPasswordBtn.addEventListener('click', function (e) {
e.preventDefault();
const accountEmail = email;
console.log('submit btn clicked');
const newPassword = newPaswordInput.value;
const confNewPasswordValue = confNewPaswordInput.value;
userEmailDisplay.innerHTML = `Email: ${accountEmail}`;
if (newPassword != confNewPasswordValue) {
alert('The new passwords must match!');
return;
}
console.log(newPassword);
// Save the new password.
auth.confirmPasswordReset(actionCode, newPassword).then(function (resp) {
// Password reset has been confirmed and new password updated.
alert("All good");
window.location.replace('/email/confirm-password-reset.html');
}).catch(function (error) {
console.error(error);
});
});
}
}
}
I expect when I click the submit button on the new password page, there's the alert box to pop up saying that everything is good and the password has been reset but that never happens. The code only goes up to the if-statement that checks if submitNewPasswordBtn and userEmailDisplay exist and are not null. I know that because I never get an output log saying that the submit button was clicked. Sometimes I never even get the output checking that submitNewPasswordBtn and userEmailDisplay exist and have values.

Having issues with w/auto-populating last search result on my html form page when hitting refresh, using only javascript and local storage

I want to rerun the search or populate the results as if the user never left.
So I visit the page, search for cats and get some results based on cats. I close the tab, come back later, and rather than find myself on a fresh page that has no results, I’m provided with the results from my last search. I am only allowed to use Javascript and local storage to achieve this. Here is my JS file:
var search = document.getElementById('searchTerm');
if(!localStorage.getItem('input')) {
populateStorage();
}
// To set the event to listen to
const form = document.querySelector('.js-search-form');
// To listen when user hits submit or press enter
form.addEventListener('submit', (e) => {
// Start of the query string
const base = `https://api.themoviedb.org/3/search/movie?include_adult=false&page=1&`;
// Extension of the query string
const searchTerm = document.querySelector('#searchTerm').value;
const language = `en-US&`;
const api_key = `7ab3cb18b4ad4a07bbd8bb01acfa7091`;
// The complete build of the url
const url = `${base}query=${searchTerm}&language=${language}api_key=${api_key}`;
// The get method
const option = {
method: 'GET'
}
// Stops the default action
e.preventDefault()
fetch(url)
//Parse data
.then( response => {
if (response.ok) {
return response.json()
} else {
throw response
}
})
// Do something with data
.then( data => {
console.log(data)
// Output results
let resultElement = '';
if(data.results.length > 1) {
resultElement += `
<h2><span>Results for ${searchTerm}</span></h2>
<section class="js-search-results clearfix">
`;
if(data.results) {
data.results.forEach(function(results){
resultElement += `<article class="item">
<div class="container">
<img src="https://image.tmdb.org/t/p/w500${results.poster_path}"/>
<div class="content">`;
if(results.title.length > 17) {
resultElement += `<h3>${results.title.substr(0,17)}...</h3>`;
} else {
resultElement += `<h3>${results.title}</h3>`;
}
resultElement += `<p>Released: ${results.release_date}</p>`;
resultElement += `</div>
</div>
</article>`;
});
resultElement += `</section>`;
populateStorage()
} else {
resultElement += '<p class="no-results">No results</p>';
}
document.querySelector('.js-search-results').innerHTML = resultElement;
}
})
.catch(err => {
console.log(err)
})
})
function populateStorage() {
localStorage.setItem('searchTerm', document.getElementById('searchTerm').value);
}
EDIT -
You are calling localStorage.getItem('input'); but you are saving the local storage item as searchTerm please make these names consistent with one another
you either need to change localStorage.getItem('input')
TO
localStorage.getItem('searchTerm');
OR
change localStorage.setItem('searchTerm', document.getElementById('searchTerm').value)
TO
localStorage.setItem('input', document.getElementById('searchTerm').value)
-Edit-
Assuming that this is wrapped in a document ready function, update your initial check of storage to look like this...
var search = document.getElementById('searchTerm');
//This assumes that you corrected your getItem to reference 'searchTerm'
if(!localStorage.getItem('searchTerm')) {
populateStorage();
}
else {
search.value = localStorage.getItem('searchTerm');
}
Your code never makes a call to actually populate that field so this should fix that.

Protractor test hangs when clicking on element

I have been trying to write a protractor test that selects an item from a custom dropdown menu. The only problem is that when it tries to click an element other than the last one in the list it hangs and timesout. When I remove the click() method invocation it seems to work fine. Since all these calls are done asynchronously I also don't see a way of stopping the loop when it finds the element. My code looks like this:
var it = null;
for(var i = 1; i <= totalNumberOfAccounts; i++) {
var listItemLocator = '//div[#id="payment-accounts"]/div/ul/li[' + i + ']/label/div/div[2]/div[2]/span[2]';
var item = browser.driver.findElement(protractor.By.xpath(listItemLocator));
item.getText().then(function(value) {
if(value === accountNumber) {
it = item;
}
console.log(value);
})
.then(function clickOption() {
console.log('Clicking...');
if (it) {
console.log('Clicking desired item');
it.click();
console.log('Clicked..');
}
})
}
I also tried this approach:
this.selectRichSelectOption = function (selector, item) {
var selectList = browser.driver.findElement(selector);
selectList.click();
var desiredOption = '';
var i = 1;
selectList.findElements(protractor.By.tagName('li'))
.then(function findMatchingOption(options) {
console.log(options);
options.some(function (option) {
console.log('Option:');
console.log(option);
var listItemLocator = '//div[#id="payment-accounts"]/div/ul/li[' + i + ']/label/div/div[2]/div[2]/span[2]';
console.log(listItemLocator);
var element = option.findElement(protractor.By.xpath('//label/div/div[2]/div[2]/span[2]'));
console.log('Element:');
console.log(element);
i++;
element.getText().then(function (value) {
console.log('Value: ' + value);
console.log('Item:');
console.log(item);
if (item === value) {
console.log('Found option..');
desiredOption = option;
return true;
}
return false;
});
});
})
.then(function clickOption() {
console.log('Click option');
console.log(desiredOption);
if (desiredOption) {
console.log('About to click..');
desiredOption.click();
}
});
};
The result of this one is even more strange. Now all of a sudden the getText() method invocation returns an empty String. But when I try to retrieve the e.g. the class attribute I get the correct value back. Where did the Text value go?
Can somebody please help me out?
This seems to be an issue with page load. After you select, the page does not load completely.
Try using a browser.sleep(timeInMs);
try using node 8+'s async functions such as await. I went through this headache and it was solved by awaiting for certain things to appear or have certain attributes.
await browser.wait(EC.presenceOf(element(by.xpath('path leading to element based off attribute'))))
Good luck

Issue with Javascript Variable Scope

I have a variable mutedUser which I would like to have persist to another function. I am having a bit of trouble with the variable persisting outside the click event. What would be the best way to have it so the "return mutedUser" would keep the "muted" string addition based on the conditions of the if statement being met? Thanks!
*The console.log's were me checking to see where the persistance stops
this.isUserMuted = function isUserMuted(payload) {
var mutedUser = '';
// If mute button is clicked place them into muted users list
// check for duplicates in list
$("#messages-wrapper").off('click', '.message button.muteButton');
$("#messages-wrapper").on('click', '.message button.muteButton', function(e) {
$('#unMute').show();
//create userId reference variable
var chatUserID = parseInt($(this).parent().parent().attr("data-type"));
//store userId in muted user object
mutedUsers[chatUserID] = {};
mutedUsers[chatUserID].id = chatUserID;
mutedUsers[chatUserID].muted = true;
if (mutedUsers[chatUserID] !== null && mutedUsers[chatUserID].id === payload.a) {
console.log("user is now muted");
mutedUser += ' muted';
console.log(mutedUser + 1);
}
console.log(mutedUser + 2);
});
return mutedUser;
};
If I understood what you're trying to do (by looking at the code), this would be the best approach:
// If mute button is clicked place them into muted users list
// check for duplicates in list
$("#messages-wrapper").off('click', '.message button.muteButton');
$("#messages-wrapper").on('click', '.message button.muteButton', function(e) {
$('#unMute').show();
//create userId reference variable
var chatUserID = parseInt($(this).parent().parent().attr("data-type"));
//store userId in muted user object
mutedUsers[chatUserID] = {};
mutedUsers[chatUserID].id = chatUserID;
mutedUsers[chatUserID].muted = true;
});
this.isUserMuted = function isUserMuted(payload) {
var mutedUser = '';
if (mutedUsers[payload.a] !== null) {
mutedUser += ' muted';
}
return mutedUser;
};
The code retains the array of mutedUsers, and isUserMuted function checks if provided user is in that array. In the code you provided, you would attach a new event handler every time isUserMuted function is called..
The isUserMuted function could even be shortened to:
this.isUserMuted = function isUserMuted(payload) {
return mutedUsers[payload.a] !== null ? ' muted' : '';
};
Edit
Sorry, my mistake. Another way is to pass in that variable, i.e.
this.isUserMuted = function isUserMuted(payload, isMuted) {
isMuted = '';
// If mute button is clicked place them into muted users list
// check for duplicates in list
$("#messages-wrapper").off('click', '.message button.muteButton');
$("#messages-wrapper").on('click', '.message button.muteButton', function(e) {
$('#unMute').show();
//create userId reference variable
var chatUserID = parseInt($(this).parent().parent().attr("data-type"));
//store userId in muted user object
mutedUsers[chatUserID] = {};
mutedUsers[chatUserID].id = chatUserID;
mutedUsers[chatUserID].muted = true;
if (mutedUsers[chatUserID] !== null && mutedUsers[chatUserID].id === payload.a) {
console.log("user is now muted");
isMuted += ' muted';
console.log(mutedUser + 1);
}
console.log(mutedUser + 2);
});
return isMuted;
};
You can't. If you return a string from the function, it will always be passed by value, i.e. copied; and it's value will not change any more. You would need to return a function that can access the current value of the local variable, or an object with a property that is changing.
As you already seem to have an object, option#2 will fit in well here:
function User() { // or whatever you have
…
var user = this;
// If mute button is clicked place them into muted users list
// check for duplicates in list
$("#messages-wrapper").on('click', '.message button.muteButton', function(e) {
$('#unMute').show();
//store userId in muted user object
mutedUsers[user.id] = user;
user.muted = true;
});
this.muted = false;
this.isUserMuted = function() {
return this.muted ? ' muted' : '';
}
}

Categories