How to trigger recomputation of computed property by DOM manipulation - ractivejs

In my test suite I'd like to confirm the effect of entering a character into a text input field. It should result in the change of a computed value.
It is, in fact, working correctly and recomputing when I type characters into the text field.
If I set the text field using
$('#my_input_field').val("F")
the computed value is not changed. Nor does it change if I trigger a keydown or keyup event on the input element. How can the property recomputation be triggered programmatically through DOM manipulation?

You can use ractive.updateModel(keypath) to force two-way bindings to update:
<input value='{{value}}'/>
ractive.find('input').value = 'newValue';
ractive.updateModel('value'); // or just `ractive.updateModel()`
console.log( ractive.get( 'value' ) ); // 'newValue'
If you want to cause the update by triggering artificial DOM events, use the change event, because that's what the two-way binding is listening for (rather than keydown and friends). It has to be a native DOM event, not a jQuery event (which uses a different mechanism) – the Ractive test suite uses simulant to make this a bit less of a hassle.

Related

Update two input fields in different components with redux

I am trying to get the following behavior in react using redux. I have two side by side components both have a <input> textfield that displays the same value. When I edit either of the field's, I want to dispatch an action and have redux store update the state of my app in both components
Exactly like asana app.
when I edit the field on left it updates the field on the right side as well
and when i edit the field on right, It updates the text field on left as well
I can only get it working one way and not both ways. I am using the value prop of the <input> textfield and keeping a state variable to update the <input> textfield as described in
react-docs.
I have state variable in one component and other one directly listens to the props.
I tried using the defaultValue prop if <input> textfield but it runs into other problems of not updating value when switching between different items
Hard to answer this without seeing your code, but based on what you're saying it sounds like you are storing one input's value on state?
If I want a value to be linked to a global store, I wouldn't store it on state. I'd do something like this (a bit pseudocody but hopefully you get the idea!)
onChange: function (e) {
this.props.dispatch(updateName(e.target.value));
},
render: function() {
return (
<input value={this.props.name} onChange={this.onChange} />
);
}
The dispatch causes an update to the global store which then cascades that updated name value back down to the react component you are currently typing in, as well as the other input elsewhere that is populated by the same data.

Informing RactiveJS about new object properties in magic mode

I'm new to Ractive.js and using "magic mode" so that updates to my JS objects automatically trigger updates to my UI. Everything is working great except that I have some properties which are added to my bound objects after my Ractive instances are rendered. This means that Ractive doesn't see changes to those properties, so the "magic" doesn't work for them.
As a workaround, I've found that I can just initialize those properties with 'empty' values before passing them to Ractive, but it feels a little unnatural.
Is there a preferred way to inform Ractive that I've added a new property to an object that it should start tracking?
My experince is that you can du that in 2 ways.
The first is the one you describe in your post.
The second is to "add" the property through the template that you use to render the object.
What ractive actually do when you set magic mode to true is "wrapping/replacing" your field with a property wich monitores the changes to the field.
I have had som issues using magicmode when i use Object.DefineProperty on my data objcect. (stuff get called twice)
I would go for soulution 1, and define all fields ahead of time.
Also be aware of setting your field(wich is actually now a property replaced by ractive) to something that is not a valuetype as that will again overwrite the property and mess up magicmode.

Adobe DTM Capturing ID from Class

I'm new to Adobe DTM so please be gentle with me! What I'm trying to do is to have a Data element hold the value of the ID of a clicked button of class "b1".
<button type="button" class="b1" id="value 1">button 1</button>
<button type="button" class="b1" id="value 2">button 2</button>
How should my Data Element be set-up since I don't want any initial value in it?
How do I structure the Event rule to capture the value of the clicked button?
I do know that I have to set the tag/selector to .b1 with event type of "click" in the condition but how do I source the "ID" value of the clicked button and assign to the Data Element.
Thanks,
Bill
Example...
Create an Event Based Rule, name it whatever you want.
Within Conditions, for the Event Type select "click".
For Element Tag or Selector put "button.b1" (no quotes). This is basically the equivalent of a css (or e.g. jQuery) selector you'd use for targeting button elements that have class "b1".
Note: You may or may not need to checkmark the Apply event handler directly to element option, depending on how your site is setup and what all is already hooked to the elements.
Now, under Rule Conditions Criteria, choose "Data > Custom" and click the "Add Criteria" button, which will then show a Custom codebox section.
Within that codebox, enter the following:
var id=this.id||'';
_satellite.setVar('b1_button_id',id);
return true;
So the way this works is that within a condition, this should be a reference to the button that was clicked. So we use that, along with DTM's _satellite.setVar() method to set a data element called "b1_button_id" to the value of the button's id attribute. Then we return true to ensure that the condition is always true, so that this condition will not prevent the rule from triggering.
From there, in any of the sections of the rule, you can reference the data element with either %b1_button_id% syntax (like in one of the form fields for setting a var through DTM) or you can use _satellite.getVar('b1_button_id') within any of the custom code blocks in the rule.
Note: data elements created on-the-fly with the .setVar() method only persist for the duration/scope of the rule being evaluated. DTM does not have an officially documented way of creating or updating persistent data elements or setting any other features that you have available from the actual Rules > Data Elements section, but there are some workarounds depending on what you want to do.
Another Note: You didn't specifically mention a need for this, but since it may be a next step that might come up.. as mentioned, within the context of a condition, this is a reference to the element for the event (in this case, the "click" event). If for some reason you need to reference this within a codebox in the Javascript / Third Pary Tags section, be aware that this will remain in context if you do NOT check the Execute Globally option, but if you DO check that option, then this will no longer be a reference to the event element.
If you need a reference to this AND you need the code to be executed globally, then you can create a data element following the instructions above, except just use this as the value, e.g.
_satellite.setVar("this_reference",this)
Then, within the codeblock you can use _satellite.getVar("this_reference") to get it.

'data-renderif' in Batman.js

What exactly does the data-renderif attribute do with Batman.js?
I initially thought that it would render the DOM node only if the attribute value would be true. But then there's data-insertif that does that as expected.
data-renderif is only meant to defer evaluating the bindings of a node's children until the binding value is updated to true. You probably want to use it in conjunction with data-insertif or data-removeif.
The dataChange method for this binding can be viewed here. This function basically just removes the data-renderif attribute and initializes the children node's bindings.

Textfield value empty when I fill it with javascript

I am using modalpopup to enter some value in a textfield. After the value is selected in the modalpopup view, the modalpopup is closed and the value takes the appropriate value. Even if the value is displayed in the textfield, the textfield1.text returns an empty string. When I see the source code (html), I see that even the textfield isn't displaying anything; it hasn't really had this value input, because the appropriate html input field hasn't got a value yet.
This is the code I use to fill this textfield:
function CloseRequestModal(s)
{
document.getElementById('<%=txtRequest.ClientID%>').value = s;
var mpu = $find('<%=ModalPopupExtender3.ClientID%>');
mpu.hide();
}
Please help.
I would need to see source HTML cause it looks like you have template language mixed into your javascript but perhaps instead of "textfield1.text" you use "textfield1.value"?
Additionally, you would need to view "generated" source (with a browser plugin) or inspect the node with web inspector on safari/chrome or firebug on firefox in order to see the change that you made with javascript.
i fixed this problem in an alternate way.
even if the value is there (in the textfield), none of the events is fired, to let know the browser / compilator that the value really exists.
so i decided, despite editing the value of the textfield, i store this value in the session too. in this case, the value is displayed for user needed in the interface, and on the other hand i use the value that i stored in the session.

Resources