bmorenate
bmorenate

Reputation: 963

KnockoutJs: Pass data-bind values to javascript variable/object

I’m somewhat baffled by knockoutjs. I’ve gone through most of the tutorials and have a general understanding of how to use it. I can manipulate the UI just fine, but what I can’t understand is how KO communicates with other javascript functions outside of KO.

I think my goal is rather simple and straightforward. I need the value of the radio button that a user selected from a family of radio buttons. Here’s what I have.

HTML

<input type="radio" name="templateStyle" value="DR.php" data-bind="checked: tempStyle">
<input type="radio" name="templateStyle" value="DRH.php" data-bind="checked: tempStyle">
<input type="radio" name="templateStyle" value="PS.php" data-bind="checked: tempStyle">

<p>The template style selected is <span data-bind="text: selectedStyle"></span></p>

<button id="submitTemplate">Submit Template</button>

JS

var radioValue = { rv: "" };

function viewModel() {
    var self = this;

    self.tempStyle = ko.observable("DR.php");
    self.selectedStyle = ko.computed(function() {
            return self.tempStyle();
    },
        self
    );

    return self.selectedStyle();
}
ko.applyBindings(new viewModel());

$("#submitTemplate").click(function() {
    radioValue.rv = viewModel();

    console.log(radioValue.rv); 
});

This works fine on the UI side, but the radioValue.rv object just remains at “DR.php.” How do I update this to reflect the data-bind="text: selectedStyle" value?

I’ve tried variations of radioValue.rv = ko.toJS(viewModel()) but this did not work.

If this is completely wrong, how do I get the value of the templateStyle radio buttons? So I can use it in other aspects of my javascript?

Upvotes: 1

Views: 6310

Answers (2)

bmorenate
bmorenate

Reputation: 963

I'm leaving my original question unedited because it shows my mistakes.

I can’t believe it took me 2 days and a SO question to figure this out, but here it is.

HTML

<input type="radio" name="templateStyle" value="DR.php" data-bind="checked: tempStyle">
<input type="radio" name="templateStyle" value="DRH.php" data-bind="checked: tempStyle">
<input type="radio" name="templateStyle" value="PS.php" data-bind="checked: tempStyle">

<p>The template style selected is <span data-bind="text: selectedStyle"></span></p>

<button id="submitTemplate" data-bind="click: submitTemplate">Submit Template</button>

JS

var radioValue = { rv: "" };

function viewModel() {
    var self = this;

    self.tempStyle = ko.observable("DR.php"); // Set default selected radio button

    self.selectedStyle = ko.computed(function() {
            return self.tempStyle(); // Update viewModel to reflect user input
        },
        self
    );

    self.submitTemplate = function() {
        radioValue.rv = self.tempStyle(); // Return user input on button click

        console.log(radioValue.rv); // JS object can now be used anywhere
    };

}
ko.applyBindings(new viewModel());

Basically, I was trying to work outside of the viewModel to early.

I now see the light and understand why knockout is so good.

Upvotes: 1

mwcz
mwcz

Reputation: 9301

My Knockout is a little fuzzy, but I hope this will help. When do you this:

return self.tempStyle();

It's invoking tempStyle. tempStyle is ko.observable("DR.php"), so what's actually being returned is ko.observable("DR.php")(), aka, it's getting the value of the observable, not the observable itself.

Try removing the parens:

return self.tempStyle;

That way, radioValue.rv will be assigned to the observable itself, rather than the observable's value.

Upvotes: 0

Related Questions