dynaically add checkboxes in angular js? - javascript

<div class="field row">
<div class="span2">{{field.field_title|underscoreless}}:</div>
<div class="span4">
<div ng-repeat="option in field.field_options" class="row-fluid">
<label>
<input type="checkbox" value="{{option.option_value}}" name="{{field.field_title}}[]" id="{{field.field_title}}" ng-required="field.field_required" ng-model="field.field_value" ng-disabled="field.field_disabled"/>
<span ng-bind="option.option_title"></span>
</label>
</div>
<span class="required-error" ng-show="field.field_required && !field.field_value">* required</span>
</div>
</div>
This is my anugular js code.. I want to add checkboxes dynamically and it added well. but the problem is when i select one checkbox other one also gets checked.. I dont know what to do ? Any help or suggestion?

In your code you have
ng-model="field.field_value"
means one model for all checkboxes. You have to make that model dynamic too.
Soluton -
ng-model="field[field_value]"

Like already pointed out, you are binding each checkbox to the same model, which results in checking all at once when checking one (click updates model => this triggers updating the view again, checking all boxes).
Try binding the option values to an array like this:
ng-model="field.value[option.value]"
The whole template code:
<div class="field row">
<div class="span2">{{field.title}}:</div>
<div class="span4">
<div ng-repeat="option in field.options" class="row-fluid">
<label>
<input type="checkbox" value="{{option.value}}" name="{{field.title}}[]" id="{{field.title}}" ng-required="field.required" ng-model="field.value[option.value]" ng-disabled="field.disabled"/>
<span ng-bind="option.title"></span>
</label>
</div>
<span class="required-error" ng-show="field.required && !field.value">* required</span>
</div>
<pre>{{field.value}}</pre>
</div>
I also changed the property names without the redundancies (field.field_value => field.value and so on). In the controller:
$scope.field = {
title:'Test Field',
options:[
{
value: 'A',
title: 'Option A'
},
{
value: 'B',
title:'Option B'
},
{
value: 'C',
title: 'Option C'
}]
}
field.value then has values like
{"A":false,"B":false,"C":true}
Have a look at this plnkr: https://plnkr.co/edit/4qiUUyYCPsmvkaOEdHTk?p=preview

It's because all checkboxes get the same id when you do id="{{field.field_title}}". Change it to something like option.id instead.
And you're also binding them all to ng-model="field.field_value", it should be ng-model="option.value" (or what ever property is correct for your data in option)

Related

Repeat Selectize select field

I have a form where the user can input multiple addresses, city, street+nbr and country.
For this field to be repeated I use the jquery repeater library. For the city field I want to use a selectize input field.
I am trying to repeat those 4 fields when clicking on the button, it copies everything correctly but the selectize field does not contain inputs (i guess this is because they have the same id?) but I don't know how to instantiate another selectize instance on that object.
This is my code:
HTML:
<div class="row">
<div class="form-group col-12 mb-2 address-repeater">
<div data-repeater-list="stcity">
<div class="input-group mb-1" data-repeater-item>
<div class="row">
<div class="col-md-8">
<div class="form-group">
<label for="companystreet"><?=lang("flow_company_street")?></label>
<input type="text" id="companystreet" class="form-control" placeholder="<?=lang("flow_company_streetname")?>" name="companystreet" required data-validation-required-message="<?=lang("flow_company_street_validation")?>">
<div class="help-block font-small-3"></div>
</div>
</div>
<div class="col-md-4">
<div class="form-group">
<label for="companystreetnumber"><?=lang("flow_company_nbr")?></label>
<input type="text" id="companystreetnumber" class="form-control" placeholder="<?=lang("flow_company_streetnbr")?>" name="companystreetnumber" required data-validation-required-message="<?=lang("flow_company_nbr_validation")?>">
<div class="help-block font-small-3"></div>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="form-group">
<label for="companycity"><?=lang("flow_company_city_or_commune")?></label>
<select id="companycity" class="companycity-select" name="companycity" autocomplete="new-password" required data-validation-required-message="<?=lang("flow_company_city_or_commune_validation")?>">
<option value="" selected><?=lang("flow_company_select_city_or_commune")?></option>
<?php
foreach ($citiesbe as $city) {
//Values are prefilled from javascript
$key = strtolower($city->name_nl) . "," . $city->zip_code;
echo "<option value=\"$key\"> $city->name_nl ($city->zip_code)</option>";
}
?>
</select>
<div class="help-block font-small-3"></div>
</div>
</div>
<div class="col-md-6">
<div class="form-group">
<label for="companycountry"><?=lang("flow_company_country")?></label>
<select id="companycountry" class="companycountry-select" name="companycountry" autocomplete="new-password" disabled>
<option value="BE" selected><?=lang("flow_company_country_belgium")?></option>
</select>
</div>
</div>
</div>
</div>
</div>
<button type="button" data-repeater-create class="btn btn-primary">
<i class="ft-plus"></i> Add new address
</button>
</div>
Javascript:
// Custom Show / Hide Configurations
$('.address-repeater').repeater({
show: function () {
$(this).slideDown();
},
hide: function(remove) {
$(this).slideUp(remove);
}
});
Since the button is not the selectize element, I don't know how to assign it to the newly created element.
Funny, I ran into a similar problem, but couldn't find a solution, so I had to work it out myself. Here's an explanation to the solution I applied to get selectize and jquery.repeater to work nicely.
First, checking through the browser console, you'll find out that selectize removes all the select options except the empty option, and uses it to populate it's own dropdown which is generated via javascript. This becomes a problem for jquery.repeater because it only repeats or creates a duplicate based on the initial page load, and not after. So, what gets repeated is the only select option left in the select element, which in this case (unfortunately) is the empty select option. Here's a pen explaining this, feel free to toggle the category targeting selectize in the select element to see for yourself.
So, here are the steps I took to get it to work nicely:
On repeating of the form (show() of the repeater instance), you'll need to delete the duplicated element completely from the DOM.
Create another select element(s) in the DOM with the preferred (or same) attributes/options.
Instantiate selectize on the newly created select element(s).
I'll suggest you add a class to the .form-group wrapper housing the .companycity-select select element. This will help to append a new select element at the exact place only, since there are other .form-group in the code. Check my solution below:
// Assuming your have the select element wrapper as <div class="form-group select-wrapper">
$('.address-repeater').reapeter({
show: function() {
$(this).slideDown();
// Remove the created element
$(this).find('.companycity-select').remove();
// Repeater rewrites your name attributes to avoid collisions within the same form,
// so we need to follow this same rule
// Get the length of the currently repeated items, to be used as the index for new elements
var count = $('div[data-repeater-item]').length;
// Create the new select element. The select name is based on the new name by repeater
var new_select_option = '<option value="" selected>Select city or community</option>';
var new_select_element = '<select id="companycity" class="companycity-select" name="stcity['+count+'][companycity]" autocomplete="new-password" required>'+new_select_option+'</select>';
// Append newly created element to DOM. Remember the new class added to the form-group?
$(this).find('.form-group.select-wrapper').append(new_select_element);
// Create a new instance of selectize on the new select element
$(this).find('.companycity-select').selectize({
// Populate your select options data via ajax,
// see docs: https://selectize.dev/docs.html
valueField: '',
labelField: '',
searchField: [],
options: []
});
}
});

Set variable value in jQuery to Javascript calculator

I have a form with a price calculator and while I am able to set all text fields and such using a jQuery script, I can't figure out how to simply set a variable in that jQuery script that is used in a price calculator in another Javascript on the page.
There is a text field with an id of #price_draftarticles that I set a value to - that works but I also have a variable called price_draftarticles that is being added to other variables to create a total. I referenced my Form_Calculator() function but it's still not updating the total.
Relevant form code
<div class="col-sm-8">
<div class="radio">
<label>
<input class="structype" type="radio" name="CorpStructure" id="price_structureop3" value="I want to provide my own structure" onClick="checkRadioCS(); Form_Calculator();"><strong>I want to provide my own structure</strong>
</label>
</div>
</div>
<div class="row">
<div class="col-sm-8">
<div class="checkbox">
<label>
<input name="DraftArticles" type="checkbox" id="DraftArticles" onClick="checkRadioTF(); Form_Calculator();" value="Yes">DETAILS
</label>
</div>
</div>
<div class="col-xs-4 col-sm-2">
<input name="price_draftarticles" type="text" class="form-control fcalc" id="price_draftarticles" value="" readonly>
</div>
</div>
My jquery function
<script>
$(function () {
$('.structype').change(function () {
if ($(this).val() === 'I want to provide my own structure')
{
$("#DraftArticles").prop("checked", true);
$("#price_draftarticles").val('$25.00');
$("price_draftarticles").val('25.00');
$('#CustomStructureDetail').show('500');
}
if ($(this).val() == 'Standard structure template one class of shares') {
$('#CustomStructureDetail').hide('500');
}
if ($(this).val() == 'Two classes of shares') {
$('#CustomStructureDetail').hide('500');
}
});
checkRadioTF();
checkCheckBox();
Form_Calculator();
checkeFileJur();
});
</script>
Looks like you forgot the '#' character in
$("price_draftarticles").val('25.00');
This should be
$("#price_draftarticles").val('25.00');
As what #BYates said the selector missed '#' for price_draftarticles.
$("#price_draftarticles").val('25.00');
But if you're trying to get/set value of the input using it's name. The selector should be like this:
$('input[name="price_draftarticles"]').val('25.00')

Stop multiple field filling with v-model?

I'm pretty new to Vue.js and while I've figured most of the problems I'm hitting out, I can't get my head around this one.
I'm displaying a list of posts based on API output, and want to have a comments box for each post. Posting to the API is working fine and it adds it without a problem, but because I'm using the same v-model for each input in the loop any text entered is replicated throughout all other matching inputs due to the binding.
<div class="row" v-if="">
<div class="col-md-11">
<input type="text" class="form-control" value="" title=""
placeholder="Add comments here.." v-model="note.note">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-default" style="margin-left: -1.5rem" v-on:click="addNote(task.id)">Add Comment</button>
</div>
</div>
JS:
addNote: function (id) {
if (this.note.note) {
Vue.http.headers.common['X-CSRF-TOKEN'] = document.querySelector('#token').getAttribute('value');
this.$http.post('api/note/create/' + id, this.note).then(function (response) {
this.fetchTaskList();
});
}
}
Screenshot:
Is there a different directive I should be using? Or is there another way around this?
You can do this by using index in v-for and then binding each box to the notes comment like so:
<!-- use index, so we know where we are in the loop -->
<div v-for="(note, index) in notes">
{{ note.note }}
<!-- Bind to the comment at the given index -->
<input v-model="notes[index].comment" />
</div>
Now you just need to set that up in data:
data: {
notes: [
{note: 'note 1', comment: ''},
{note: 'note 2', comment: ''},
{note: 'note 3', comment: ''}
]
}
Here's the JSFiddle: https://jsfiddle.net/efxzmq9s/

How to make the change event work, in select, after change ngModel

I use Angular2, and have html code
<div class="row">
<div class="col-xs-3 form-group">
<select class="form-control"
id="country"
[(ngModel)]="testSelectModel"
(change)="testSelectChange($event)">
<option *ngFor="let item of textCollection"
[value]="item.id">
{{item.name}}
</option>
</select>
</div>
<div class="col-xs-3 form-group">
<input type="text"
class="form-control"
[(ngModel)]="testSelectModel"/>
</div>
</div>
I also have a collection of textCollection, objects which - {
name: 'foo',
id: 1
}...
I enter (id) in input 1, and wanted see selected item in tag select.
Yes, all is well, the item has changed, but the event "testSelectChange" - is not invoked..
example
Somebody faced such?
If you modify the input, testSelectChange() won't get called, even though the select DOM element and the input DOM element are both bound to the same component property, testSelectModel. Angular will only call testSelectChanges() if there is a change to one of select's DOM properties, and this doesn't happen when you change the input value.
I suggest breaking up the event and data binding – use [ngModel] and (ngModelChange) – for each binding:
<select [ngModel]="testSelectModel"
(ngModelChange)="testSelectChange($event)">
...
<input [ngModel]="testSelectModel"
(ngModelChange)="testInputChange($event)">
Note that $event will be set to the current value of the select or input.
Then manually call the the select change event handler from testInputChange():
testSelectChange(newValue) {
console.log('testSelectChange', newValue);
this.testSelectModel = newValue;
this.resultWorkModel = newValue;
}
testInputChange(newValue) {
console.log('testInputChange', newValue)
this.testSelectModel = newValue;
this.testSelectChange(newValue); // manually trigger other event handler
}
Plunker
Besides what the other commenters have said, you might also need to write your handler in a Future, because the changes to testSelectModel might not have taken effect before testSelectChange($event) has happened.
This was the case in Angular1.
This should work:
Plunker Code
html:
<select class="form-control" #type [(ngModel)]="testSelectModel" (change)='testSelectChange(type.value)'>
<option *ngFor="#item of textCollection" [value]="item.id">
{{item.name}}
</option>
</select>
class:
testSelectChange(val: string) {
console.log('I call', val);
this.resultWorkModel = this.textCollection.find((obj) => obj.id == val).name;
}
The event for handle changes in the model is ngModelChange, your code should be like this:
<div class="row">
<div class="col-xs-3 form-group">
<select class="form-control"
id="country"
[(ngModel)]="testSelectModel"
(ngModelChange)="testSelectChange($event)">
<option *ngFor="let item of textCollection"
[value]="item.id">
{{item.name}}
</option>
</select>
</div>
<div class="col-xs-3 form-group">
<input type="text"
class="form-control"
[(ngModel)]="testSelectModel"/>
</div>
</div>
This is a example in Plunker Enjoy.

How to add data from scope to select box

I'm fairly new to angular, so hopefully this is a super simple question for someone to nail.
I have a form (cut down version below) that I want to be able to have a live preview being shown as the user fills in the form.
All was going well with standard fields, however I've hit a roadblock with <select> fields.
<div ng-app="jobcreate">
<div class="row fullWidth" ng-contoller="JobCtrl">
<div class="medium-6 columns">
<form method="POST" action="http://localhost:3030/job/create" accept-charset="UTF-8">
<label for="title">Enter a title</label>
<input placeholder="title" id="title" required="required" ng-model="job.title" name="title" type="text" />
<br />
<label for="title">Pick template</label>
<select ng-model="job.template" ng-options="template.Name for template in templates" name="template"></select>
</form>
</div>
<div class="medium-6 columns">
<div class='job-detail {{ job.template || "default" }}'>
<h2>{{ job.title || "Enter a title"}}</h2>
<h2>{{ job.template || "Pick a template"}}</h2>
<pre>Templates: {{templates | json}}</pre>
</div>
</div>
</div>
</div>
And here is the js:
angular.module('jobcreate', []).controller('JobCtrl', function($scope) {
$scope.templates = [
{ID:'default', name:'Default'},
{ID:'obnoxious', name:'Obnoxious'}
];
});
I have a jsfiddle here so you can see it in action: http://jsfiddle.net/2m8jm/4/
As you can see, entering something in the title field works as intended, but I'm struggling to get the contents of the $scope.colors to fill in the select field
In your fiddle : http://jsfiddle.net/2m8jm/4/, you have choosed templates as an data array for ng-options but there is not scope variable named templates in the controller JobCtrl. I have renamed $scope.colors to $scope.templates and modified the ng-options bit - ng-options="template.ID as template.name for template in templates".
Here is a working plunker : http://plnkr.co/edit/wsbxkjRqTEU2yfcHOV0D?p=preview
Update
Is there a way to not have the first empty value be in the select field?
Yes, Couple of ways.
1) Initialize job.template with some default value in your markup as :
<label for="title" ng-init="job.template='obnoxious'">Pick template</label>
<select ng-model="job.template" ng-options="template.ID as template.name for template in templates" name="template"></select>
2) Define controller as follows to set default value for job.template inside the controller :
.controller('JobCtrl', function($scope) {
// some other codes
$scope.job = {};
$scope.job.template = 'default';
});

Categories

Resources