2

I'm using jQuery 1.9.1, jQM 1.3 & knockout 2.2.1.

My html is as follows:

<div data-role="page" id="coloursView">
    <div data-role="content">
        <fieldset data-role="controlgroup">
            <legend>Colour:</legend>
            <input type="radio" name="colours" data-bind="checked: colour" id="radio-1" value="1" />
            <label for="radio-1">Red</label>
            <input type="radio" name="colours" data-bind="checked: colour" id="radio-2" value="2" />
            <label for="radio-2">Blue</label>
            <input type="radio" name="colours" data-bind="checked: colour" id="radio-3" value="3" />
            <label for="radio-3">Green</label>
        </fieldset>
    </div><!--/content -->
</div><!--/page -->

My view model is also very simple:

function ColoursViewModel() {
  this.template = "coloursView";
  this.colour = ko.observable("1");
  this.label = ko.observable(); // custom binding
}

Now, i would like to get the description of the selected colour, not the value. It seems to me, that i need a custom binding, like this one:

ko.bindingHandlers.label = {
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        $("radio", element).filter(function(el) { return $(el).text() === value; }).prop("checked", "checked");
    }
};

But i'm not able to get the text of the related label - the label-for text.

Someone could help? Thanks in advance

user2308978
  • 187
  • 3
  • 14

2 Answers2

1

Update

Here is another approach where to find only :checked items and remove white-space in text.

Checkbox

$('input[type=checkbox]').each(function () {
 if ($(this).is(':checked')) {
  var checkbox = $(this).prev('label').text();
  alert('Checkbox: ' + checkbox.replace(/\s+/g, ' '));
 }
});

Radio

$('input[type=radio]').each(function () {
 if ($(this).is(':checked')) {
  var radio = $(this).prev('label').text();
  alert('Radio: ' + radio.replace(/\s+/g, ' '));
 }
});

Updated Demo


Checkbox

$('div.ui-checkbox').find('span.ui-btn-text').text();

Radio

$('div.ui-radio').find('span.ui-btn-text').text();
Omar
  • 32,302
  • 9
  • 69
  • 112
  • wrap the input in a label is valid html, but this is not the case, so I think the trick shall be to find the label through the attribute label-for, something like this $('label[for='+element.id+']').text()); – user2308978 Apr 23 '13 at 09:52
  • Yes its possible, but i just noticed you need the checked ones only. So you need to go through them and pick the checked ones. i'll do another demo. @user2308978 – Omar Apr 23 '13 at 09:56
  • Thank You Omar, I found out also a change in latest jquery versions, to retrieve the radio, instead of input[radio] it shall be: input[type=radio][name=colours] – user2308978 Apr 23 '13 at 10:04
  • @user2308978 yup `$('input[type=radio][name=colours]')` works. – Omar Apr 23 '13 at 10:06
  • @user2308978 i have updated my demo, as text needs to be stripped of white-space. http://fiddle.jshell.net/Palestinian/PedEC/ – Omar Apr 23 '13 at 10:27
  • Hi Omar, thank You for the answer, i have now a fiddle to test more precisely the question: http://fiddle.jshell.net/MBeU7/ but i'm still not able to get it. i will put in my knockout nice-to-have-wish-list the label-for binding... – user2308978 Apr 24 '13 at 00:54
  • @user2308978 I understand what you're trying to reach. The text of an input is wrapped by label and two spans, so i dont know how to get it using KOjs. It's easy to manipulate it using jQuery but in KO, i dont whether you can direct it dig deeper into DOM elements. I'm reading about it and hopefully I come up with a solution. – Omar Apr 24 '13 at 08:17
0

Sorry if i answer myself, but i think i got it. At least for radio inputs.

Now, i have a custom binding handler at fieldset level, to keep the markup clean and more readable, as i can:

<fieldset data-role="controlgroup" id="front-colours" data-bind="frontColourLabel: frontColour">
    <legend>Front Colour: <span data-bind="text: frontColourDescription"></span> (Value: <span data-bind="text: frontColour"></span>)</legend>
    <input type="radio" name="front-colours" data-bind="checked: frontColour" id="fc-radio-1" value="red" />
    <label for="fc-radio-1">Red</label>
    <input type="radio" name="front-colours" data-bind="checked: frontColour" id="fc-radio-2" value="blue" />
    <label for="fc-radio-2">Blue</label>
    <input type="radio" name="front-colours" data-bind="checked: frontColour" id="fc-radio-3" value="green" />
    <label for="fc-radio-3">Green</label>
</fieldset>

this is the binding handler i come up:

ko.bindingHandlers.frontColourLabel = {
    update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        ko.utils.unwrapObservable(valueAccessor()); 
        var id = $('input:radio[name='+element.id+']:checked').prop("id");
        var radioText = $('label[for=' + id + ']').text();
        viewModel.frontColourDescription(radioText);
    }
};

the only tricky part here, is that the id of the fieldset is equal to the name of the radio-group, as it's easy to filter out what radio-group i want to address.

WORKING EXAMPLE: http://jsfiddle.net/h7Bmb/1/

I try now to get the checkbox part to work. Someone can help?

user2308978
  • 187
  • 3
  • 14