Knockout - Disabling the default behavior of updating model when using binding value with form element - events

Knockout has the default behavior of updating the associated model if you change your focus (e.g. by clicking outside the input control) after editing the value inside an input control, populated by a binding of type Value.
Here is the link to the official documentation page explanation, section Parameters:
http://knockoutjs.com/documentation/value-binding.html
Do you know a way to disable this default behavior ?
The reason behind this : Im using Models that can tell if their last update requires persistent backup by comparing the previous value to the new one.
I would like to listen to the key up event on my form inputs but if I do that, knockout triggers twice event (the default one + the key up) to update the Model and the second one is basically telling my Model to replace the value by the same value because it is already updated, which it translates to "there is no need to do persistent backup since the value didnt change".
I would gladly appreciate any help or suggestion, since Im stuck and can't find a way around :)
EDIT
Couldnt reproduce the error with bare backbone code. It seems as "super cool" said that valueUpdate should override the default Blur event that triggers when you use form controls with binding Value.
It may be a bug introduced by the library Knockback that I use to create the ViewModel.
Despite all this, just replacing the binding Value by the binding textInput did the trick. Thank you all.

Don't listen to the event, subscribe to updates, which won't fire unless the value is changed. Using the textInput binding will register every change to the value, even those done using menu items like cut and paste, when they happen.
Equivalently, you can use the value binding along with valueUpdate: 'input'
vm = {
myvar: ko.observable(),
updates: ko.observableArray()
};
vm.myvar.subscribe(function(newValue) {
vm.updates.push(newValue);
});
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input data-bind="textInput: myvar" />
<div data-bind="foreach: updates">
<div data-bind="text: $data"></div>
</div>

Related

MUIInputLabel does not grow when TextField is empty

The TextFields in the Material-UI docs has the label which grows and shrinks depending on whether there's a value in the field.
Rather than a user input, I am trying to use JS to reset my TextField to "" when a button is pressed. This means if a user has keyed data into the TextField, if they press the reset button, the field is cleared while the label grows to refill the field.
What is happening is that while my data is cleared, the label remains small.
Where am I going wrong with this?
I've read that it's related to something called shrink, but I dont understand how its called.
A portion of my code, built using Material-UI and ReactJS
EntryField component
<TextField onChange={inputChangedHandler} label={props.label} value={props.value} type={props.type} required={props.required} name={props.name} id={props.id} inputRef={props.propsRef} />
Form component, which uses the EntryField component above, as well as the ReactJS
const refNumRef = useRef();
const [objRefNum, setRefNum] = useState();
(...)
function resetData(event){
setRefNum('')
}
(...)
<EntryField label="Ref Number" type="text" editData={setRefNum} value={objRefNum}
id="input_refNum" name="refNum" propsRef={propRefNumRef} />
So....after posting my question, I made more trial and errors and I somehow managed to get it to work; Im not sure why.
But the main change I made was setting a default to the useState like so
const [objRefNum, setRefNum] = useState("");
And somehow this managed to fix not just this issue with the TextField, but an issue Ive been having with a Select statement as well, where I had trouble resetting it to a default value.
I will eventually have to figure out how to declare this programmatically based on API calls where the default value will change based on the results........but this is fine for now.

dojox mvc at() target

I've created a sandbox with a demonstration of binding UI components to both data and state: http://dojo-sandbox.net/public/51073/1
It's my plan to generate code from a page definition creating a page-level widget which is templated. This widget will have its own scope, where the model and state will reside, which I am trying to simulate in the sandbox by way of the Page object.
The sandbox is working because the Page object is in the global state, which appears to be the default context for object resolution in mvc binding.
However the plan is to have a view widget supporting each page with both the Model and State contained within the widget's scope. The generated template for the view would be bound to both the Model and the State. I can establish the source via the 'target' property, but when the same UI component must be bound to two different models, one for value and one for state, the single source doesn't support this.
The Model data will come to me from the back-end, and the State data is derived via the State.Execute method once the Model data is present.
I've taken a look at the 'rel:' parameter of at(), but don't see how to leverage this syntax within a specific context, ie my view widget's scope. It seems to be working fine for the default global scope.
Is there a standard way to direct the data-dojo-props value binding at one source, and the data-mvc-bindings for attributes at another? Or, more precisely, what is the at('rel:') syntax which will support specifying the context of the relation, and not rely on the 'target' of the widget or containing widget?
If there is no way to specify the 'target' at this level, I will generate more logic in the Execute method to specifically set the html attribute on the component during state compilation.
data-mvc-bindings is for allowing non-widgets use dojox/mvc/at. If a widget is declared for an element data-dojo-props is the one for use instead.
If target is specified via data-dojo-props or data-mvc-bindings, it’ll be set eventually to the widget.target. ”rel:” syntax looks for a widget having .target up in DOM tree.
It means that one “group” cannot have more than one "relative binding target”, in case it’s one of your questions. You can have a “scope object” that contains pointers to more than one models and use it as a “relative binding target”, that may serve a similar purpose:
<div data-dojo-type="dijit/_WidgetBase"
data-dojo-props="target: {model0: model0, model1: model1}">
<input type="text"
data-dojo-type="dijit/form/TextBox"
data-dojo-props="value: at('rel:model0', 'value'),
disabled: at('rel:model1', 'disabled')" />
</div>
A working example can be found at http://jsfiddle.net/asudoh/M3bRC/. Hope these help.
Best, - Akira

knockout view model wrapped in observable

To avoid calling applyBindings multiple times on the same DOM element, I wrap my various viewmodels in an observable. then just change that observable to whatever view model i wanna see and BAM...that works.
until i do something like this:
<div data-bind="if:$data">
...some bindings in here
</div>
when i change view models, the bindings inside any "if:$data" blocks do not update.
here's a fiddle to really demonstrate this: http://jsfiddle.net/btrauma8/2TxME/
This would have worked properly prior to KO 2.2. In 2.2, we made if and ifnot more efficient by only re-rendering the section when the value actually changes between truthy/falsy.
There were many cases where people would bind against something like if: items().length and the entire section would be re-rendered everytime that an item was added.
In your case, you can overcome this pretty easily by just using the with binding instead of if. Since, you are binding against $data, it will not actually change the context and will give you the result that you are after.

kendoui validation tooltip in custom popup editor not positioning correctly

Please see jsfiddle for example, blank out First Name field to have validation tooltip show. In a normal form the validation tooltip positions correctly to the right of each element. But in the popup editor for the grid it still trying to position the tooltip below the element as if it where editing inline. I have tried <span class="k-invalid-msg" data-for="FirstName"></span>but it doesn't change anything. Is there a setting I am missing to get this working in popupeditor? I guess I could manually modify the .k-tooltip but I am hoping for something more built in that handles the positioning correctly, because I am not very good at css.
As you've discovered, the error template for the grid is different to that provided by the kendo validator when applied to standard inputs.
Unfortunately, the validator that is created internally by the grid does not pass along any errorTemplate that you might define in the options object and by the time the "edit" event fires, the validator has already been created and the error template compiled, hence why setting the errorTemplate in the manner you describe does not work. Really, I think the Kendo grid should respect any user defined errorTemplate option but until it does we have to hack a little bit.
The key is to define a custom template and to apply it in the edit event, but instead of using the options object, set the private instance directly. Not ideal, but it works:
edit: function (e) {
e.sender.editable.validatable._errorTemplate =
kendo.template($('#tooltip-template').html());
}
See this updated fiddle for an example of what I think you might be looking to achieve.
http://jsfiddle.net/nukefusion/eQ2j7/10/
(I would post this as a comment but not enough reputation yet...)
I'm successfully using nukefusion's solution. I, too, fought with the syntax error from jQuery for a long time and discovered through debugging that how you define the template is important. In particular, it appears that the template has to be written on a single line without any formatting, as in:
<script id="tooltip-template" type="text/x-kendo-template"><span class="k-widget k-tooltip k-tooltip-validation"><span class="k-icon k-warning"></span>#=message#</span></script>
If you try to make it "pretty" and format the html in the template, you get the syntax error. I don't know where the real bug is, as this sort of thing shouldn't cause an error. But it does and I stopped worrying about it once I got it to work correctly.

Updating JQuery dataTable table outside itself

I managed to get jquery datatables plugin to work with asp.net mvc 3 so it posts back json, and with a search function.
Problem now I that I need to move the search box and add a "language" filter outside it's "normal" position next to a custom made menu.
Is there a way that I can integrate:
Language: <select name="languageid">
<option value="SV">Swedish</option>
<option value="EN">English</option>
</select>
Keywords: <input type="text" name="keywords">
To refresh datatables when languageid or keywords change? and still have sorting, paging working?
My brain is only firing at half power today, but the short answer is that this can be done; it's just my suggestions that are kind of vague...sorry!
There are a whole set of language options in oLanguage; it was a bit "Too Long, Didn't Read" for me to sort through, but perhaps something there will help you identify where to set up a language switcher
You can remove the search box from the main table and set up your own, using the fnFilter method to trigger the search
Depending on how your other options are configured (server-side, for example), there are methods to trigger a refresh of the table. You would bind a listener for the languageid or keyword change action (.on('change', '#languageid', function(e) { /* ... */ })) which would fire the appropriate refresh action (in my instance which uses server-side, I use fnDraw())
I'm sorry about the directionless advice, but I wanted you to know at least that this is possible. Posting the question on the datatables.net forums directly might get you the best possible answer.

Resources