Dynamically add items from input with vuejs - javascript

In my vuejs project I have a form section to add facilities and appliances to a house. There is an input field to input a facility and button to add it to a list, but I am a bit unsure how to do this.
My HTML:
<div class="input-wrapper flex align-end">
<div class="input-wrap">
<label for="facility">Add facility like pooltable or swimmingpool</label>
<input type="text" v-model="facility" id="facility" class="bordered border-green" />
</div>
<div class="input-wrap">
<button class="button button-main button-green-light add-button" data-button-type="add" #click.prevent="addFacilities">Add</button>
</div>
</div>
The goal is to make it add the item to a list when clicking "Add" and then empty the input field, so I end up with something like this
<ul>
<li>Pool table<li>
<li>Swimming Pool<li>
<li>Fussball table</li>
</ul>
<input type="hidden" name="facilities" value="pool table, swimmingpool, fussball table" />

You need to use v-for for this case.
in list template part
<ul>
<li v-for="item in items" :key="item">{{item}}</li>
</ul>
in form template part
// .. form items
<input type="text" v-model="input">
<button type="button" #click="addToItems">Add</button>
in vue component js part
data: {
input: '',
items: [],
},
methods: {
addToItems() {
if (!this.input) {
// input value is empty
return;
}
// add item to reactive array items
this.items.push(this.input);
// clear the input
this.input = '';
}
}
See example here: https://codepen.io/Mgorunuch/pen/LYYGmQp

Related

How to get id of a dynamic input field in javascript

I want to create a dynamic form where I also apply JavaScript to the dynamic elements.
What I want to do right now is figure out which field (stored in array or whatever data structure) in JavaScript has been clicked so that I can apply the script to that particular field.
The HTML looks like this:
<div class="triple">
<div class="sub-triple">
<label>Category</label>
<input type="text" name="category" id="category" placeholder="Classes/Instances" required/>
<ul class="cat-list"></ul>
</div>
<div class="sub-triple">
<label>Relation</label>
<input type="text" name="relation" id="relation" placeholder="Properties" required/>
<ul class="rel-list"></ul>
</div>
<div class="sub-triple">
<label>Value</label>
<input type="text" name="value" id="value" placeholder="Classes/Instances" required/>
<ul class="val-list"></ul>
</div>
</div>
This "triple" div is dynamic and I want to create as many "triples" as the user wants, that also means the input fields of inside the "triple" section increase as well.
I'm confused on how to add javascript to one element of the input. For example I have inputs: category, relation and value and the user wanted 2 or more triples then the input ids could look like category2, relation2 and value2 or something similar to that.
let category = document.getElementById("category");
category.addEventListener("keyup", (e) => {
removeElements();
listDown(category, sortedClasses, ".cat-list")
});
If I lets say clicked on category2 for instance how do I tell that to my javascript since these fields are completely dynamic.
Summary: The user is adding repeat sections of triples (containing 3 input elements), where the id of each input element is generated dynamically. My script above works for the first triple section only as the ids are fixed, as for successive "triple" section the id of the fields get changed. How do I identify (see which element has been clicked) and get these dynamic ids
Try listening to the parent element and then using the event's target to figure out the identity of the input. Since the child elements events will bubble up you'll be able to listen to all children
e.g.
let parentElement = document.querySelector(".triple");
parentElement.addEventListener("click", (e) => {
console.log(e.target.id);
});
You can use the onfocus event
<div class="triple">
<div class="sub-triple">
<label>Category</label>
<input type="text" name="category" id="category" placeholder="Classes/Instances" onfocus="onFocusCategoryInput()" required/>
<ul class="cat-list"></ul>
</div>
<div class="sub-triple">
<label>Relation</label>
<input type="text" name="relation" id="relation" placeholder="Properties" onfocus="onFocusRelationInput()" required/>
<ul class="rel-list"></ul>
</div>
<div class="sub-triple">
<label>Value</label>
<input type="text" name="value" id="value" placeholder="Classes/Instances" onfocus="onFocusValueInput()" required/>
<ul class="val-list"></ul>
</div>
</div>

Get the list of all selected check boxes with Vue.js

How can I get a list of all check boxes that I selected with Vue?
This is my HTML which works and shows me a list of my products with a checkbox.
<li v-for="(product, index) in products">
<input :id="product.slug" :value="product.id" name="product" type="checkbox" />
<label :for="product.slug"><span></span></label>
</li>
What I want is that when I click on a button, it fetches all check boxes that I selected. And give me all the values.
But I can't figure out how to do it, because it'll break when I even try to add a v-model to the checkbox.
Just bind every checkbox value with a product and the v-model to the array checkedProducts
<li v-for="(product, index) in products">
<input :id="product.slug" :value="product" name="product" type="checkbox" v-model="checkedProducts" />
<label :for="product.slug"><span></span></label>
</li>
...
data(){
return{
...
checkedProducts:[]
....
}
}

jquery selecting child elements

The setup.
I am using MVC 5, and I have created a view with data sent in the form of a viewmodel.
With in this view I have rendered a List object as stacked div's, as seen below.
As you will see, I am displaying hidden fields, so that the viewModel send back the data to the controller on submit.
<div class="row item-row">
<div class="small-4 columns">
objType
</div>
<div class="small-6 columns">
<input id="object_0__Id" name="object[0].Id" type="hidden" value="999999">
<input id="object_0__Reference" name="object[0].Reference" type="hidden" value="myRef">myRef
<input id="object_0__RecordChanged" name="object[0].RecordChanged" type="hidden" value="NoChange">
</div>
<div class="small-2 columns remove-item">
<button class="button tiny expand centre button-gray" onclick="javascript: RemoveItem(999999);">Remove</button>
</div>
</div>
<div class="row item-row">
<div class="small-4 columns">
objType
</div>
<div class="small-6 columns">
<input id="object_1__Id" name="object[1].Id" type="hidden" value="000001">
<input id="object_1__Reference" name="object[1].Reference" type="hidden" value="myRef">myRef
<input id="object_1__RecordChanged" name="object[1].RecordChanged" type="hidden" value="NoChange">
</div>
<div class="small-2 columns remove-item">
<button class="button tiny expand centre button-gray" onclick="javascript: RemoveItem(000001);">Remove</button>
</div>
</div>
Ok, so the javascript function RemoveItem is:
function RemoveItem(id)
{
event.preventDefault();
var element = $(event.target).closest('.item-row');
$(element).closest('DeedReference_0__RecordChanged').val('Deleted'); ***** This is what I am trying to do.
$(element).hide();
}
From the above, when I click on say RemoveItem(00001), the variable element contains the following:
<div class="small-4 columns">
objType
</div>
<div class="small-6 columns">
<input id="object_0__Id" name="object[0].Id" type="hidden" value="000001">
<input id="object_0__Reference" name="object[0].Reference" type="hidden" value="myRef">myRef
<input id="object_0__RecordChanged" name="object[0].RecordChanged" type="hidden" value="NoChange">
</div>
<div class="small-2 columns remove-item">
<button class="button tiny expand centre button-gray" onclick="javascript: RemoveItem(000001);">Remove</button>
</div>
The value I need to update is object[0].RecordChanged, but at this moment in time, I do not know the index value. So I was planning on using the ends with selector, but am not able to get it to work.
I have got as far as:
$(event.target).closest('.item-row').children()[1]
But this gives me the div, since I have tried:
$(event.target).closest('.item-row').children()[1].Find('Id*"__RecordChanged"')
$(event.target).closest('.item-row [id*="RecordChanged"]')
$(event.target).closest('.item-row:[id*="RecordChanged"])
And using the variable
$(element [id*="RecordChanged"])
$(element [id$="RecordChanged"])
UPDATE
Fixed bug in code that was suggesting that I was looking at the wrong index.
Also, If I click the remove button for RemoveItem(000001), I am trying to update the value object_0__RecordChanged.
Changed view model to have an index property. Then changed placed the HTML.EditorFor within a foreach loop enabling me to populate the index property before it is rendered out.
Then the code was changed from:
function RemoveItem(id)
{
event.preventDefault();
var element = $(event.target).closest('.item-row');
$(element).closest('DeedReference_0__RecordChanged').val('Deleted'); ***** This is what I am trying to do.
$(element).hide();
}
to:
function RemoveItem(id)
{
event.preventDefault();
var recordChanged = '#object_' + id + '__RecordChanged';
$(recordChanged).val('Deleted');
var element = $(event.target).closest('.item-row');
$(element).hide();
}
Much simpler!

Populating dropdown field with text when a row is selected

I have HTML where I am trying to populate a drop-down with string data using jQuery when an item is selected from a drop-down.
<td class="col-md-3" colspan="4">
<label class="control-label">{{item.fields[11].displayName}}22</label>
<div class="dropdown" style="width:100%">
<input type="text" class="form-control dropdown-toggle" data-toggle="dropdown" data-ng-disabled="formReadOnly" data-ng-model="item[item.fields[11].name]" data-ng-keyup="comboBoxGenOptions(2, 148, item[item.fields[11].name], 'searchGenericOptions')" />
<ul class="dropdown-menu" style="width:100%">
<li class="GpiId" data-ng-repeat="name in searchGenericOptions" style="width:100%"><a data-ng-click="changeData(item.fields[11].name, name)">{{name}}</a></li>
</ul>
</div>
<label class="error" data-ng-show="issueSuppNum()">Please insert a valid generic name.</label>
#*<div class="GenId" data-strat-form-control data-field-display-id="1" data-vmformreadonly="formReadOnly" data-show-tool-tip="showToolTip(item.fields[7].htmlName)" data-strat-model="item" data-field="item.fields[7]"></div>*#
</td>
The drop down populates with an object:
When I click it, I want to show the GPI field:
$scope.changeData = function (propertyName, name) {
$scope.item[propertyName] = name;
$('GpiId').text(name.GPI);
};
The objects are being pulled on correctly:
What am I doing wrong and how do I fix it?
Edit: added class to field.
First, I think you missed a "." in your class selector.
$('GpiId').text(name.GPI);
to
$('.GpiId').text(name.GPI);
Second, since you are already using angular, I would try to use {{}} within GpiId instead.

two forms, two divs, appending data from only one form to only one div?

I have a slider with two slides, both containing an identical form. When I submit from one or the other form, I want to append the data from that form into the slide containing the form. I can obtain data from only one form, but I just can't get the append to only work on one slide. It always adds to both. I can't just use different IDs because I will be using ajax to change the non-visible slide based on forward or back slide navigation so the slider is theoretically infinite.
Here is my html (simplified for easier viewing):
<div class="flexslider">
<ul class="slides">
<li>
<ul class="table">
<li>
<div class="clearfix">
<span class="nameSpan">Customer One</span>
</div>
</li>
</ul>
<form class="addNewCustomerForm" method="post">
<h1>Add New Customer</h1>
<input type="text" name="customerName" id="customerName">
<input class="button" type="submit" value="Add New Customer">
</form>
</li>
<li>
<ul class="table">
<li>
<div class="clearfix">
<span class="nameSpan">Customer One</span>
</div>
</li>
</ul>
<form class="addNewCustomerForm" method="post">
<h1>Add New Customer</h1>
<input type="text" name="customerName" id="customerName">
<input class="button" type="submit" value="Add New Customer">
</form>
</li>
</ul>
</div>
And here is my javascript (Again, simplified):
$(".addNewCustomerForm").submit(function(event) {
$.post('addNewCustomer.asp', $(this).serialize(), function(result){
$(".table", this).append(result);
$(".newLine").slideDown();
})
return false;
});
You probably want something like this
$(".addNewCustomerForm").submit(function(event) {
var thisForm = $(this);
$.post('addNewCustomer.asp', $(this).serialize(), function(result){
thisForm.parent().find('.table').append(result);
$(".newLine").slideDown();
})
return false;
});
(tested it locally, changed first to find)
That's because $(".table", this) matches both slides.
You can solve this by giving each slide and id, like id="slide1"
Then do $("#slide1") (or slide2) depending on which was submitted.
You basically need the bind the form to the slide, since each slide has it's own form.
Similarly you might need to do a similar thing for $(".addNewCustomerForm"). Give each form a unique id and bind one submit handler to #slide1, and the other to #slide2

Categories