Reputation: 447
I'm new with KO and KO components.
I currently have a custom-component.js
, which perfectly works, to style all inputs of our project.
However, I'd like to get the exact same component working for textareas.
Currently, the template:
part of this component looks like :
viewModel: function (params) {
/* */
template: '<span data-bind="template: { afterRender: afterRender }">' +
'<label class="custom-label" data-bind="css:{\'custom-label-active\':focused}, text:label"></label>' +
'<input class="form-control" type="text" data-bind="enable: enable, valueUpdate: \'input\', css:{\'custom-label-input\':focused}, attr:{placeholder:label, id:id, type: type}, event:{focus:focus,blur:blur},value:value"/>' +
'</span>'
});
How should I update it to make it work for textareas too ?
I tried to add a default parameter like this :
this.element = (params.element == undefined || params.element == null) ? 'input' : params.element
but I'm not sure how to update my markdown ?
Should I just replace '<input'
by something like '<' + self.element + '...>'
What about the valueUpdate
? (I'm very new to all of this, sorry if it's a dumb question)
Thank you
Upvotes: 0
Views: 252
Reputation: 23372
Your template is shared by all of the component instances. There's no way to dynamically update it using the component's params, other than using knockouts own if
, template
, with
, etc. bindings.
If you know it will only support a limited set of elements, you can add an if
statement for each of them. E.g.:
<!-- ko if: element === "input" -->
<input/>
<!-- /ko -->
<!-- ko if: element === "textarea" -->
<textarea></textarea>
<!-- /ko -->
If you want to be able to pass any element, you could look in to using componentInfo.templateNodes
`. If that's what you want, let me know. I can extend my answer, but it's a more complicated approach.
Here's an example using the if
binding:
ko.components.register("custom-input", {
viewModel: function(params) {
return {
elementType: params.elementType,
value: ko.observable("Your input")
}
},
template: `
<div>
<label>
Your input here:<br>
<!-- ko if: elementType() === 'input' -->
<input type="text" data-bind="textInput: value">
<!-- /ko -->
<!-- ko if: elementType() === 'textarea' -->
<textarea cols="40" rows="10" data-bind="textInput: value"></textarea>
<!-- /ko -->
</label>
</div>
`
});
ko.applyBindings({
inputType: ko.observable("input")
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<h2>Config:</h2>
<label>
<input type="radio" data-bind="checked: inputType" value="input">
Use input
</label>
<label>
<input type="radio" data-bind="checked: inputType" value="textarea">
Use text area
</label>
<h2>Component:</h2>
<custom-input params="elementType: inputType"></custom-input>
Upvotes: 1