I have tried to make an function with a onclick that when you click it, it will change the value from 'suspended' in true (this is about suspending a website user account)
suspended = false;
type user = User['suspended'];
function blokkeerFunctie() {
// get user & user element
document.getElementById('userInfo') && document.getElementById('blokkeren');
// blocks user when clicked
if (document.getElementById('blokkeer')?.addEventListener('click', blokkeerFunctie)) {
type user = !User['suspended'];
} else {
// deblocks user when clicked
document.getElementById('deblokkeer')?.addEventListener('click', blokkeerFunctie);
type user = User['suspended'];
}
console.log('blokkeerFunctie');
}
blokkeerFunctie();
I thought with !User i will reverse the boolean value from false in true, but that code isn't even read. ▼
'user' is declared but never used.ts(6196)
You shouldn't put event listeners in your conditional if/else in this way. Here's how I would approach what you're trying to accomplish. You will need to add types to these variables, but you'll get the basic logic here.
let User = {
suspended: true
};
let button = document.querySelector('#suspender');
function setSuspendButton() {
button.innerText = User['suspended'] ? 'Unsuspend' : 'Suspend';
}
window.addEventListener('load', () => {
button.addEventListener('click', blokkeerFunctie)
setSuspendButton();
})
function blokkeerFunctie() {
User['suspended'] = !User['suspended'];
setSuspendButton();
}
<button id='suspender'></button>
type user = creates a new type, not a value. It's unused in each branch of the if because you just create a new type, named user which shadows the type of the same name from the parent scope, which is never used by anything.
Furthermore, this line does nothing:
document.getElementById('userInfo') && document.getElementById('blokkeren');
This line gets up to two references to DOM elements, but doesn't save them anywhere, or perform any logic on them.
I think you want something more like this?
const user = {
name: 'Joe',
suspended: false
}
function blokkeerFunctie() {
// block/deblocks user when clicked
if (document.getElementById('blokkeer')?.addEventListener('click', blokkeerFunctie)) {
user.suspended = !user.suspended // toggle `suspended` back and forth
}
console.log('blokkeerFunctie');
}
blokkeerFunctie();
Working example
Related
I did a bunch of buttons on a navbar. These buttons can trigger different articles or lesson in two languages from side to side.
Later, I found that this is troublesome when I try to search for a specific article. So I decided that I'll add an input text bar to take my input and trigger a javascript function that I want.
I simplified the numbers in this post, but this is the core of the script. I named the functions with 4 digits numbers MMDD so I wish that I can type in a box 0312 and the function 0312 get executed.
However, I cannot seem to get it to work. Is that even possible in javascrip? If not what approach do you recommend?
function fr01() {
document.getElementById("fr01").innerHTML = "text here will appear in french"
}
function en01() {
document.getElementById("en01").innerHTML = "text here will apear in english"
}
function myFunction01() {
fr01();
en01();
}
function myFunction() {
var x = document.getElementById("myInput").value;
function 'x'
}
<input type="text" id="myInput" oninput="myFunction()">
<button onclick="myFunction01()">CHAPTER01</button>
the top part works perfectly fine and in realtime, when I press the corresponding button it shows both sides, when I try to type in number I get this error message
myFunction is not defined at HTMLInputElement.oninput
Didn't I already define it in the top portion?
Thank you for taking the time to read this.
Do call functions dynamically based on for example a text value, then you could create a map which connects a string to a function. An object is very similar to this. It has properties, which can be strings, and a value, which can be functions.
const actions = {
'foo': function() {
// Do something.
}
};
With this pattern you can create a list of valid options and the connect the corresponding functions that come with the list.
Now let's say you have a string. With that string you can select a function from the object with the bracket notation.
const string = 'foo';
const action = actions[action];
If a value is found, then action will now be a function. Otherwise it will be undefined.
The snippet below demonstrates this principle.
function omg() {
console.log('omg');
}
function bark() {
console.log('bark');
}
const actions = {
'0312': function() { // Regular function.
console.log('Hello')
},
'0420': () => { // Arrow function.
console.log('Wow')
},
'1360': () => console.log('Vroom'), // Arrow function variation.
'1337': () => { // Arrow function that calls two other functions.
omg();
bark();
},
'7331': [omg, bark] // Array with function references.
};
const form = document.querySelector('#form');
const actionField = document.querySelector('#action');
form.addEventListener('submit', event => {
const selector = actionField.value;
const action = actions[selector];
if (typeof action === 'function') {
action();
}
if (Array.isArray(action)) {
action.forEach(subAction => {
subAction()
});
}
event.preventDefault();
});
<form id="form">
<label for="action">Try me (0312, 0420, 1360 and 1337 will work)</label>
<input type="text" id="action" />
<button type="submit">Execute</button>
</form>
I'm using a js lib that uses react under the hood. I want to modify it to prefill an input on a form that it renders. I only have access to the top level react component from instantiation. How can I set the value such that react picks it up?
I've tried setting el.value and $el.attr('value', 'val') to no avail. I've also tried setting the state directly with el.__reactInternalInstance$abc123._currentElement.props.value but doesn't work either.
Calling:
const event = new Event("input", { bubbles: true })
el.dispatchEvent(event)
hasn't helped either.
I came up with a solution using jquery, couldn't get it to work without a library. The first line fills the field when the user clicks the input. The second fills it when they expand operation. Note that one gets called on expanding any operation. But jquery seems to work just fine with on click. Part of the problem is that the elements are created until the operation is expanded.
$('body').on('click', 'tr[data-param-name="<INPUT NAME>"] input', setInput)
$('.opblock').on('click', setInput)
I don't have the link for where I found the below call but this seems to set the value in a way that gets picked up by react.
function setInput (e) {
let xinput = $('tr[data-param-name="<INPUT NAME>"] input')
let target = xinput[0]
if (xinput.val() == '') {
let value = "INPUT VALUE"
const setter = Object.getOwnPropertyDescriptor(target, "value").set
const prototype = Object.getPrototypeOf(target)
const prototypeValueSetter = Object.getOwnPropertyDescriptor(prototype, 'value').set
if (setter && setter !== prototypeValueSetter) {
prototypeValueSetter.call(target, value)
} else {
setter.call(target, value)
}
const event = new Event("input", {bubbles: true})
target.dispatchEvent(event);
}
}
I want the user to have the option to add more stepTypes, stepCodes and properties. He can add an stepCode with an existing StepType, or with a different stepType, so, the object would like similar to this:
You see? In the stepType called 'guide', I have 2 stepCodes (G019, G040). In the stepType called 'success', I have just one (S003), and so on. Since I'm newbie with js and even more with objects, I'd like you guys to help me creating a function that checks if the stepType already exists, and then adds another stepCode to it (with its properties). And, if it doesn't exist yet, I want this function to create this new stepType, with the stepCode and its properties.
Currently, my code looks like this:
const checkStep = () => {
if (!Object.keys(procedures).length) {
let proc =
{[key]:
{
[stepType]: {
[stepCode]: {
[language]: stepText,
timeout,
nextInstruction,
}
}
}
}
setProcedures(proc)
}
else{
Object.entries(procedures).forEach((p, k) =>{
...
})
}
}
I call this function everytime the user clicks the "Add another step" button. The first part checks if the object already exists, and, if it doesn't, it creates the object with its key and so on (this part is working). What I don't know how to do is the ELSE part. I think we have to check if the stepType already exists in the object called procedures, but I don't know how to do it. I don't know how to put the stepCode and properties inside the existing object(procedures) either. Maybe I create a variable and do like: setProcedures (...procedures, variable). I don't want to lose the content I have in the procedure, just to add more content to it in the way I explained you.
P.S.: All the variables (stepType, stepCode, language, stepText, timeout, nextInstruction) are an useState. When the user writes anything in the input text field, I set the specific variable with the e.target.value.
Thank you.
You can do the loop on the each keys and if it matches then add to existing data or create a new stepType and add.
var newStepType = "test", stepCode="test1", language ="en", stepText="hello", timeout=9, nextInstruction="new ins";
Object.keys(procedure.DOF0014).forEach(key => {
//if newStepType matches insert stepCode. eg: stepType is "guide"
if(key === newStepType) {
procedure.DOF0014[key] = { ...procedure.DOF0014[key], ...{[stepCode]: {[language]: stepText,timeout,nextInstruction}}}
}else{
procedure.DOF0014 = {...procedure.DOF0014, ...{[newStepType]:{[stepCode]: {[language]: stepText,timeout,nextInstruction}}}};
}
});
Try this. I didnt tested code. But hope it works. I am sharing the idea how to do.
Object.keys(procedure).forEach(codes => {
Object.keys(procedure[codes]).forEach(key => {
if(key === newStepType) {
procedure[codes][key] = { ...procedure[codes][key], ...{[stepCode]: {[language]: stepText,timeout,nextInstruction}}}
}else{
procedure[codes] = {...procedure[codes], ...{[newStepType]:{[stepCode]: {[language]: stepText,timeout,nextInstruction}}}};
}
});
})
I have created a BPF in CRM 365. In that after selecting 1 value on first stage another stage gets opened and that will be last stage. As you can see in the screenshot, I need to call javascript function on click of "Finish" button. If I get that event, I would be checking the value of Create Follow up field. If that is No, then I will do some logic henceforth.
Now my question is : How to get that Finish button event in that stage so that it goes to javascript code?
Any pointers please?
This is a working example of an entity form's JavaScript web resource,
var PUBLISHER = PUBLISHER || {};
PUBLISHER.pub_entityname = PUBLISHER.pub_entityname || (function () {
return {
onFormLoad: function (executionContext) {
var formContext = executionContext.getFormContext();
// Declare BPF OnProcessStatusChange event handler and pass in
// your own function. Execution context is passed in automatically.
formContext.data.process.addOnProcessStatusChange(BpfStatusChange);
}
};
function BpfStatusChange(executionContext) {
var formContext = executionContext.getFormContext();
var bpfStatus = formContext.data.process.getStatus();
if (bpfStatus === "finished") {
// Do something.
} else if (bpfStatus === "aborted") {
// Do something.
} else if (bpfStatus === "active") {
// Do something.
}
}
})();
The 'OnProcessStatusChange' event handler needs to be created manually in the form's 'onLoad' event. There are three BPF statuses available, when a user clicks the 'Finish' or 'Next' button, this will react if the Business Process Flow's status changes.
MS Docs
So I'm trying to figure out how to use kind of an all-encompassing function to reduce bloat in my application. I've got a bunch of dialog windows that are handled via state, similar to this:
toggleSettingsDialogue = () => {
this.setState({settingsOpen: !this.state.settingsOpen});
}
I'm trying to reduce this function, which is repeated for each additional dialog, into one. My thought is to pass in two parameters - one for the dialog that's meant to be opened, and another that defines the state of that dialog - either true or false.
The issue is, I'm stuck on figuring out how to check if the first parameter passed (i.e. the name of the dialog window in state) exists or not.
Let's say we've got a state with...
state = {
diagSettingsOpen: false,
diagAddItemOpen: false
}
How would I check to see if any string passed as a parameter inside the function is actually there or not, and subsequently use that key to set state if it matches?
toggleSettingsDialogue = key => {
if(key in this.state)
this.setState(({[key]: val}) => ({[key]: !val}));
}
Here's how you can check the same -
let state = {
diagSettingsOpen: false,
diagAddItemOpen: false
}
function setState(stateName, value) {
if (state.hasOwnProperty(stateName)) {
state[stateName] = value;
} else {
console.log("invalid state");
}
}
setState("diagSettingsOpen" ,true);
console.log(state);
setState("diagSettingsClose" ,true);