How to bind index to value attribute in vuejs - javascript

I want to bind an index to the value attribute of the hidden field.
I am trying this:
<div id="panel" class="panel panel-default mt" v-for="(question,index) in questions.slice().reverse()">
<input type="hidden" v-model="question.question_no" :value="index">
</div>
it is showing me this error:
what is the correct way to bind value attribute with an index?

V-model is essentially syntax sugar for updating data on user input events, plus special care for some edge cases.
So
<input type="hidden" v-model="question.question_no">
is same as
<input type="hidden" :value="index" #input="question.question_no=$event.target.question.question_no">
So you can't use both the syntax together.
Either use first one or second one according to your use case.
Edit
As input type is hidden
<input type="hidden" :value="index">
should be enough.
Reference

Related

Change input text to upper case using Alpine.js

I would like every character entered into my HTML input box to get uppercased. Here's the approach I am trying using the latest Alpine.js available via CDN.
<input
x-data="{myText: '' }"
x-text="myText" type="text"
#keydown="myText.toUpperCase();"
name="myText"
placeholder="Some Text"/>
This seems to have zero effect. What's the right way of doing solving this problem?
There are a couple of things going on. First of all, you're binding to keydown but not assigning your uppercased value to any reactive property. Second is that you probably want to use x-bind:value.
<input
x-data="{myText: '' }"
type="text"
#keyup="myText = $event.target.value.toUpperCase()"
:value="myText"
name="myText"
placeholder="Some Text"/>

Using conditional operators in v-model?

I have a vue component that shows a form populated with items from a selected item to edit. Now I don't want to have to use a second form for creating a new item. At the moment I auto populate and update the item with v-model which obviously updates the object. Am I not able to use conditional operators in this like so?
<form #submit.prevent>
<div class="field">
<label class="label">Job Title</label>
<p class="control">
<input type="text" class="input" placeholder="Job title" v-model="experiences[editIndex].title ? experiences[editIndex].title : ''" />
</p>
</div>
</form>
You can use conditional operators with v-model, but you can't give v-model a string like you're attempting in your example.
I wouldn't use the same form for editing and creating (might be preference). I would make the form its own component and then make two additional form components for editing and creating.
However, if you really want to handle the logic in each input's v-model directive, you would need to give it a variable in the last part of the ternary operator. Something like this:
v-model="experiences[i].title ? experiences[i].title : newExperience.title"
If you use eslint-plugin-vue it will complain about ternary in v-model.
ESLint: 'v-model' directives require the attribute value which is
valid as LHS. (vue/valid-v-model)
So I'd rather explicitly use a pair of :value and #input props.
Like that:
<input
type="text"
class="input"
placeholder="Job title"
:value="experiences[editIndex].title ? experiences[editIndex].title : ''"
#input="experiences[editIndex].title = $event.target.value"
/>
Also, you can use some function for #input, which will check property existence and add it if necessary.

How to handle different input types bound to same ng-model?

In a page, I have a section for date-range selection. A large portion of our user base is IE 10/11, which does not support input type="date". I'm using Modernizr to show/hide the date input based on the support, and when not, provide an input of type="text", both bound to the same ng-model. Typing into the text spams the console with errors, as the text and date are incompatible. Is there a way to fix this console spam? Using a third-party library is not an option.
<div class="col-md-3" data-ng-show="searchBillCreatedDate == 'custom'">
<label>From</label>
<input data-ng-model="searchFromDate" type="date" class="form-control" data-ng-show="browser.supportsDateInput">
<input data-ng-model="searchFromDate" type="text" class="form-control" data-ng-show="!browser.supportsDateInput" placeholder="yyyy-mm-dd">
</div>
Change your ng-show to ng-if like this:
<input data-ng-model="searchFromDate" type="date" class="form-control" data-ng-if="browser.supportsDateInput">
<input data-ng-model="searchFromDate" type="text" class="form-control" data-ng-if="!browser.supportsDateInput" placeholder="yyyy-mm-dd">
You're getting the error because it's binding to the the first input's model, which is a date input. ng-show just uses CSS to hide the element but it still exists in the DOM. ng-if, however, completely removes it from the DOM, leaving you with one ng-model="searchFromDate"

An AngularJS directive to validate a field when a non-zero sum has been entered into another

I have two form fields - an employee count and a gross payroll amount.
<div ng-repeat="payroll in report.payrolls">
<input type="number" min="0" class="input-mini" sister-value="{{payroll.grossPayrollAmount}}" ng-model="payroll.employeeCount" type="text">
<input ng-blur="payroll.grossPayrollAmount = Math.round(payroll.grossPayrollAmount)" type="number" min="0" class="input-small" ng-model="payroll.grossPayrollAmount" type="text">
</div>
The user does not have to enter a non-zero value for either. HOWEVER, if they enter a non-zero value for one then they must do so for the other, and that is what I want to validate against.
These fields repeat in sets - so a pair for each payroll, so I'm not sure if getting them by an ID or class will work.
I've written a few custom validation directives before, but never one that checks for a value in another, related field.
You could try to make a directive surrounding both inputs:
<directive>
<input type="number" min="0" ng-model="payroll.employeeCount" type="text">
<input ng-blur="payroll.grossPayrollAmount = Math.round(payroll.grossPayrollAmount)" type="number" min="0" class="input-small" ng-model="payroll.grossPayrollAmount" type="text">
</directive>
So both values will be available from it, you can access them with element.find().
You use element.find() just like you would use jQuery. For example, setting an id="employeeCount" to the first input, you can access it with element.find('#employeeCount'), so you get the first input element, finally you access to its value with element.find('#employeeCount').val().
note: if you're not used to jQuery, remember to add the dot (.) before a class name and a hash (#) before an id name.
Here, you have a list of methods that you can use with any element, including "find()": https://docs.angularjs.org/api/ng/function/angular.element
Update:
This will also work for multiple pairs of inputs, you just have to repeat the directive tag, for example:
<directive>
<input [...] >
<input [...] >
</directive>
<directive>
<input [...] >
<input [...] >
</directive>
The directive will work independently for each instance you create.

How to use an object as ng-value of a radio button?

Is there any way to use an object for ng-value of a radio button?
Imagine you have a radio button whose ng-model is an object, like this:
modelObject: {val:'', text:''}
And this would be the radio button:
<input type="radio" ng-model="data.modelObject" ng-value=""/>
Is there a way to do something like the following (obviously it doesn't work)
<input type="radio" model="data.modelObject" ng-value="val:option.id, text:option.text"/>
?
Thanks
I know I can use the ng-change directive. I'm just wondering if what I am asking it's possible, it would be very smart
EDIT:
as requested in the comments, I am giving a bit of extra info on my setup.
I want to save in the model both the value of the button and its label. So let's say I have an array in my controller called impactOptions and a ng-repeat directive to create the buttons:
<div ng-repeat="option in impactOptions" >
<input type="radio" ng-model="data.modelObject.val" id="rbGroup{{option.id}} ng-value="option.id"/>
<label for="rbGroup{{option.id}}">{{option.text}}</label>
</div>
The problem with this setup is that in that way I'm only saving the value of the button, while I would like to also save it's label. I really need it later.
I'm looking for a way to do something like this
<input type="radio" model="data.modelObject" ng-value="val:option.id, text:option.text"/>
You can have an object as the value in ng-value:
<div ng-app>
<input type="radio" ng-model="modelObject" ng-value="{val:1, text:'text'}"/>
<p>>{{modelObject|json}}<</p>
</div>
example fiddle
The values in ng-value can also be dynamic as well per request:
<div ng-app ng-init="opt={id: 1, text: 'some text'}">
<input type="radio" ng-model="modelObject" ng-value="{val:opt.id, text:opt.text}"/>
<p>>{{modelObject|json}}<</p>
</div>
updated example fiddle
You can use ng-value="option":
<input type="radio" model="data.modelObject" ng-value="option"/>
When you need id you can have it from $scope.option.id and when you need text you can access it from $scope.option.text. Check my answer here. Does this work for your case?

Categories

Resources