2

How to get form id or form class name using knockout js?

<span data-bind="text: $parent.id"></span>

I want to get at below location to form id or classname using ko.

<form class="form-shipping-address" id="shipping-form" data-bind="attr: {'data-hasrequired': $t('* Required Fields')}">

    <div id="shipping-new-address-form" class="fieldset address">

        <div class="field _required" data-bind="visible: visible, attr: {'name': element.dataScope}, css: additionalClasses" name="shippingAddress.firstname">

            <label class="label" for="HV9JGHI">Firstname</label>

            <!-- I want to get here form id -->
            <span data-bind="text: $parent.id"></span>


            <input class="validate-length minimum-length-10 maximum-length-100" type="text" data-bind="
            value: value,
            valueUpdate: 'keyup',
            hasFocus: focused,
            attr: {
                name: inputName
            }" name="firstname"  id="HV9JGHI"> 
        </div>

    </div>
</form>
Rakesh Jesadiya
  • 436
  • 1
  • 11
  • 25

1 Answers1

2

As you can read in the documentation on the binding context, there's an $element variable available, which links to a regular HTMLElement.

You can use this element to get to the parent, using parentElement

ko.applyBindings({});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<div id="parent-id">
  <div data-bind="text: $element.parentElement.id"></div>
</div>

Now, if you require more logic in the parent selection, you can use a helper method like the one used in this answer:

function closest(el, selector) {
  var matchesFn;

  // find vendor prefix
  ['matches', 'webkitMatchesSelector', 'mozMatchesSelector', 'msMatchesSelector', 'oMatchesSelector'].some(function(fn) {
    if (typeof document.body[fn] == 'function') {
      matchesFn = fn;
      return true;
    }
    return false;
  })

  var parent;

  // traverse parents
  while (el) {
    parent = el.parentElement;
    if (parent && parent[matchesFn](selector)) {
      return parent;
    }
    el = parent;
  }

  return null;
};

function closestFormId(el) {
  return (closest(el, "form") || {}).id;
}

ko.applyBindings({
  closestFormId: closestFormId
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<form id="form-id">
  <div id="parent-id">
    <div data-bind="text: closestFormId($element)"></div>
  </div>
</form>

Even though this works, I can't think of a reason you'd want to do this... Why not create an id property in your viewmodel and use this instead (via attr: { id: idProp })?

Community
  • 1
  • 1
user3297291
  • 22,592
  • 4
  • 29
  • 45