KnockoutJS bindings not working - javascript

Ok getting frustrated on this one.... Using knockoutJS to do some visual interaction stuff.
What I have is a button that is going to make an AJAX call to validate some data. That call sends back a CanProceed property as well as an object that represents other view settings. The code works when I set CanProceed(true) this turns on a DIV that has more DIVs inside it, each of those visibility properties are bound to a Permissions.AllowXXX that is set from the server.
See the fiddle for an example
http://jsfiddle.net/RcCAx/
What I want to have happen is when I get the Permissions from the server I should be able to tell knockout about the object and have the page UI update but its not working. If I declare the observable first (like with the CanProceed property) it works, but if I try and use the ko.mapping.fromJS(serverdataobject) here its not updating stuff that was bound to it earlier.
Help......

See updated fiddle for a solution. The key here is to have Permissions be an observable

Related

Polymer 1.0 Lifecycle Event for Complete Rendered DOM

Background
I've been working with Polymer for a while. I've been converting from .5 and building new elements for a production app. We are currently using Polymer 1.0.6, and this particular issue is also using jQuery 2.x.x and typeahead.js.
Issue
We have an element that builds a dynamic list of label and inputs provided by a data source. in the ready function we get a list of input data, and set that to a local list variable that is bound to a foreach template to create the labels and inputs.
I was unable to find a Polymer element I really liked for typeahead, for Polymer 1.0. So I defaulted to using typeahead.js. my problem is that I cannot find a lifecycle event or workaround, to call the typeahead function after the dom has processed setting the bound list in the ready function.
Code
The easiest way to demonstrate this issue, was to create a HEAVILY trimmed down version in a jsbin. I know the element looks bad, it was cut down as much as possible to demo the core issue I'm facing.
http://jsbin.com/zivano/edit?html,output
What Have I Tried?
I've tried using the attached event, and while it does process after the ready function, the dom changes from ready have not taken effect. I found similar issues on SO domReady vs ready - Migrating to Polymer 1.0 I've tried both suggestions, the second is still being used in the jsbin, without success.
I have also bound the click event of my inputs to a function calling the typeahead setup code, to prove that if the calls are made after the dom is rendered it will work correctly.
Summary
If update a data bound, local variable in the ready function, is there a lifecycle event I can call that will guarantee that those dom changes will be rendered, so I can make a dom query against those new items? Or is there a work around that will let me call a js function on a dom element, one time after the element dom fully renders?
my problem is that I cannot find a lifecycle event or workaround, to
call the typeahead function after the dom has processed setting the
bound list in the ready function.
I think I had a problem like this . For my problem I found a solution using the following :
var self = this;
window.addEventListener('WebComponentsReady', function(e) {
// imports are loaded and elements have been registered
/*Example*/
console.log('Components are ready');
var p = self.getElementsByTagName("paper-item");//paper-item created dynamically
console.log(p);//can access and use this paper-item
/*Finish example*/
//here you can call typeahead because the dom has been processed
});
Sorry for my English or if I dont understand your question, my English is bad.
The Issue I had was that the data-bound list was populated through an ajax function, which was completed after the attached function, even if I made an async call inside of the attached function, it would still fail because of race conditions.
It's worth noting the answer by Flavio Ochoa, will work. I personally preffered to not have my custom elements add listeners to the Window. So i went a different route.
Since my issues we're predicated on guaranteeing that the bound list was updated, I wrapped the ajax call in a Promise, and added the typeahead init logic to the then statement. That solution appears to be working.
I do have some concerns whether the promise can guarantee that the bound list will have propagated to the DOM by the time the then statement is processed. But so far it has worked consistently. I'll edit this answer if I can prove otherwise.

FullCalendar Events lose user data after renderEvent or updateEvent

I have event objects I load into fullcalendar. Each event has a custom resources array field attached showing who the events are for. Loads fine. User can click on the event and eventClick gives me the event with the resources. I open a dialog to edit. After saving changes to the db, I want to update the calendar using updateEvent. The object I use to update contains the full resources array and all appears to update fine.
Here's the problem: Now when I click on the same event to edit again, the event returned by eventClick has the resources array length set to 0. i.e. all the resources elements are missing.
Thought maybe I wasn't updating with the 'original object' so tried removeEvents followed by renderEvent but get the exact same behavior.
What am I missing?
btw, using fullCalendar 1.6. I can just reload the calendar and it's fine, but I don't want to 'cause it flickers and means unnecessary bytes over the wire.
update
So if I use appointment.resources = angular.copy(appointment.resources) then everything works. I'm not clear on why though. Is it because the attached resources were from an angular $resource and when that refreshed the reference to the previous objects point nowhere?
I think it could be a reference problem.
When you create a fullCalendar event, it wraps the object to a new one.
So, if you do something like:
var myEvent = {id: 1, title: "MyTitle", resources:[1,2,3], start:moment()};
$.('#calendar').fullCalendar('renderEvent', myEvent);
It create another object, with some specific properties like backUps, specific methods, etc... You can access this object with:
var fcEvent = $.('#calendar').fullCalendar('clientEvents', myEvent.id);
But now:
fcEvent.resources != myEvent.resources
Anyway, is difficult to know exactly what's the problem without a piece of code. Is possible to create a Plunker?
You can use my public Skeleton for ui-calendar

.data('kendoComboBox') returning undefined when called from event handler

I'm developing a large scale web app using kendo UI, HTML5, Javascript & Require.js etc.. I'm having trouble figuring out why the call $(selector).data('kendoComboBox') on a jQuery object works in one context but not another. It works just after the successful $(selector).kendoComboBox(parameter.....) create kendo combo box call but not when I call it from an event handler. It appears the kendoComboBox object associated with the object selector is referencing has been lost? Can someone please shed some light on this.
One reason could be that the jQuery library is loaded again and the widget's data is lost. Other similar issues covered in our troubleshooting section.

Kendo UI: Get TextBox Value on Button Click

I am having a form, which comprises of several textboxes and one button.
I am using the Kendo UI MVVM format. How shall I get the value of each textbox and store it in an object on click of the button?
Will I have to use normal jQuery in order to get the values or is there some other way of getting the values from each of them?
Thanks
Hardik
Please take a look at these documentation pages:
http://demos.kendoui.com/web/mvvm/index.html
http://docs.kendoui.com/getting-started/framework/mvvm/observableobject
http://docs.kendoui.com/tutorials/mvvm-in-kendo-ui
These pages contain answers to most of the questions you'll have concerning Kendo UI MVVM. It would be silly and presumptuous of me to think that I could explain it better than the qualified and hard working individuals at Telerik that have so painstakingly compiled these documentation pages.
The gist of it is that you need to create an instance of the kendo.data.ObservableObject that has properties for the values you are working with. This is your view-model. Then in your markup for your text boxes, include values for the data-bind attribute that reference the properties in your observable object. Create a function in your view-model to handle the button's click event. Put a data-bind attribute in your button that binds the click event to your function. Finally, call kendo.bind(<element>, <observable object>), and that will connect the wires from your markup to your view-model object.
In your click event-handler, you can take the values of the view-model, and insert them into the object you need. You should not need to use "normal jQuery" for anything besides referencing the element to call bind on.
Quickly you can retrieve the value this way using JQuery:
$('#yourTextBoxID').data('kendoMaskedTextBox').value();
you can use this code:
$('#yourTextBoxID').val();

AngularJS changes to the $scope properties aren't reflected in the view without calling $scope.$apply

First here's a plunk: http://plnkr.co/edit/2gD0AB. This plunk doesn't seem to work correctly because $scope.$on("$viewContentLoaded") won't fire, but on my machine it works just fine and I hope you get the idea.
What I'm trying to do there is simply move field objects from $scope.fields to $scope.groupFields = [], $scope.listFields = [], $scope.dataFields = [] when dragging them to the appropriate droppable areas. I've manager to do this using jQuery UI and jQuery UI touch punch (just to be mobile safe).
If you drag an element from the fields box to the one of the empty boxes you'll notice nothing happens on the screen besides the field elements hanging around where you left them. But if do a console.log($scope.fields) in the drop event listener you'll notice that all of the field objects are correctly set inside each of the field boxes.
If you click the Add element button then you'll simply trigger console.log($scope.groupFields); and suddenly all the elements appear correctly in their corresponding boxes like intended in the first place.
After pulling my brains out and after searching the internet for some time I found out that $scope.$apply(), called in the drop event after the moveField function, actually fixes my issue.
And I don't understand why. Shouldn't there be a digest already running and updating the view based on what I'm doing in the controller?
Thanks!
Just because the code that handles these jQuery drop events is inside the controller, it doesn't mean it will run under the angularjs scope/word. For those changes to make effect, you will need to force the angularjs app to do a dirty checking on its models. That can be accomplished by calling $apply() or $digest() methods. You should always call one of these methods after handling an jQuery event that changes $scope properties or after a timeout (or interval).

Categories