How to add same from input area when user press a button? - javascript

I am doing a form right now, I want to automatically add another input area, same as the line above, when user press a button.
<div class="row" id="1">
<div class="form-group col-lg-2">
<select class="form-control" id="select">
<option selected>Tag Name</option>
<option value="p">p</option>
<option value="br">br</option>
</select>
</div>
<div class="form-group col-lg-2">
<select class="form-control" id="class">
<option selected>Tag Class</option>
<option value="Day">Day</option>
<option value="BlockTime">BlockTime</option>
<option value="BlockTitle">BlockTitle</option>
<option value="Session">Session</option>
<option value="Person">Person</option>
<option value="Firm">Firm</option>
</select>
</div>
<div class="form-group col-lg-7">
<textarea class="form-control" rows="3" id="textArea">Please put the content inside this html tag.</textarea>
</div>
<div class="form-group col-lg-1">
<input type="button" class="btn btn-default" onclick="addLine()" value="Add">
</div>
</div>
This is a line of input area, I want to add the same html below the input area we have now when user press the "Add" button. Maybe using JQuery?
It should looks like this one.
This is what I tried:
function addLine() {
$('#1').clone().attr('id', '').appendTo('form');
}
For now, it seems work, but how should I do if I want to add id to the new created element, say, 2, 3, 4?
Also I am not sure am I did it the right, or best way.

Solution by jQuery
var n = 8 // adjust it in some way
var inputArea = ['<div class="form-group col-lg-'+n+'">',
'<textarea class="form-control" rows="3" id="textArea-'+n+'">',// let's be nice and not use same IDs twice
'Please put the content inside this html tag.',
'</textarea></div>'].join('')
$('.row').append(inputArea);
However make sure that your back end is ready to handle that input.
EDIT:
The solution might not be fancy and using clone() is completely fine too.
To keep track of ids I would add a simple variable like n that I would increment every time a new input area is added, and then add it to id.
So, init
var n = 0;
In addLine:
n++;
Set the id (doable in addLine too)
$target.attr('id', 'inputArea-'+n);//Assuming that $target is the inputArea in question

You can copy from a blueprint structure in the DOM and append your copy after the button.
var addline = function() {
var invisibleNewLine = jQuery('#blueprint').clone();
var visibleNewLine = invisibleNewLine.removeClass('invisible');
jQuery('#target').append(visibleNewLine);
};
jQuery('#add-line').click(addline);
Remove the onClick handler on the element and bind the event using jQuery.
<button id="add-line" class="btn btn-default">Add</button>
See the fiddle here: JSFiddle

Related

How can I pass the value from drop down list as a link for button?

I am creating a web app (using thymeleaf, html, css, javascript) and I ran into a problem. Say I have a search bar and a button like this:
Now this represents the functionality of an app and currently it can only search records from a table by their name. But I want to add some other functions like "search by population", "search by capital" etc. I was planning on creating a drop-down list next to the search bar where these options will be included, and the user will select from that list how he wants to search for a record. I can't see a way to do that. Currently this is a search bar code:
<h4 class="left">
<form ui-jp="parsley" th:action="#{/events/showByState}" th:object="${myState}" method="get">
<div class="row m-b">
<div class="child">Search by State Name:</div>
<div class="child"><input id="filter" type="text" th:field="*{officialStateName}" class="form-control input-sm w-auto inline m-r"/></div>
<div class="child box-3">
<button class="btn">Search!</button>
</div>
</div>
</form>
</h4>
So it is unclear for me how I do this because I need to specify the link for button based on what user will choose from the list. Any help is appreciated!
You can create a <select> element with options whose value indicate what the action of the form should be. Whenever its value changes, you can update the form's action.
document.getElementById('search-by').addEventListener('change', function(e) {
let searchBy = this.value;
console.log(searchBy);
this.form.action = `/events/${searchBy}`;
});
<form ui-jp="parsley" th:action="#{/events/showByState}" th:object="${myState}" method="get">
<div class="row m-b">
<div class="child">Search by
<select id="search-by">
<option value="showByState">State Name</option>
<option value="showByPopulation">Population</option>
<option value="showByCapital">Capital</option>
</select>:</div>
<div class="child"><input id="filter" type="text" th:field="*{officialStateName}" class="form-control input-sm w-auto inline m-r" /></div>
<div class="child box-3">
<button class="btn">Search!</button>
</div>
</div>
</form>

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: []
});
}
});

Select first value by default for a 'Select' box made dynamically

I want to select the first option in a select box by default. The challenge here is that the page might have multiple select boxes as they are created dynamically.
You will understand what I am trying to achieve by looking at my code.
HTML :
<form class="form-inline">
<div class="form-group form-group-grid" ng-repeat="fields in selectedTabData.requiredField" ng-switch="fields.paramType">
<label>{{fields.paramName}}<span class="asterisk" ng-if="fields.mandatory==true">*</span></label>
<input type="text" class="form-control" ng-switch-when="Text" ng-model="fields.fieldValue" ng-attr-id="{{fields.paramName}}Id">
<select class="form-control" ng-switch-when="DropDown" ng-options="field.paramKey as field.paramValue for field in fields.paramData" ng-model="fields.fieldValue" ng-attr-id="{{fields.paramName}}Id">
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary form-inline-grid-button" ng-click="getReport()">Run Report</button>
</div>
</form>
The selected data is available under the model $scope.selectedTabData.requiredField
In Controller I push the selected values in to a variable like :
$scope.selectedTabData.requiredField.forEach(function(item)
{
paramValue.push(item.fieldValue);
paramName.push(item.paramName);
})
I tried doing this :ng-init="fields.fieldValue = fields.paramData[0]"
<select class="form-control" ng-switch-when="DropDown" ng-options="field.paramKey as field.paramValue for field in fields.paramData" ng-model="fields.fieldValue" ng-init="fields.fieldValue = fields.paramData[0]" ng-attr-id="{{fields.paramName}}Id">
</select>
I am not sure how it will work. Can anyone help me out with this?
you can make it possible by ng-repeat inside tag
<select ng-model="fields.fieldValue">
<option ng-repeat="field in fields.paramData" value="{{field.paramKey}}">
{{field.value}}
<option>
</select>
and in controller add this line
$scope.fields.fieldValue = x;
and in this example, x is "field.value" that you want as default selected option.
This is the plunkr for your problem
https://plnkr.co/edit/mahONdv5xQBa5eUZJSoX

How to change innerHTML content such as(input field names,ids,onclick) attributes

I want to copy all content of a div into another div, but before copying I need to change all input fields names and ids. See the code below.
<div id="first_div">
<input type="text" name="firstname" id="firstname">
<select name="marital_status" id="marital_status">
<option value="1" selected='selected'>Select</option>
<option value="2">Single</option>
<option value="3">Married</option>
</select>
</div>
<div id="second_div">
</div>
Now I want to copy content of first_div into second_div,but before copying I need to change input field firstname into last_name, how to do it?
As I see you tagged jQuery in the question, you could use jQuery clone method to get started quickly : https://api.jquery.com/clone/
var clone = $("#first_div").clone();
then modifying the clone innerHTML like so
clone.find("#firstname").attr("id", "lastname"); // modifying div id
// do the same for every element you want to modify id, etc
//then finally append it to the second_div
$("#second_div").html(clone.html());
If you want a vanilla Javascript version:
var clone = document.getElementById('first_div').cloneNode(true);
clone.querySelector('#firstname').id = 'lastname';
document.getElementById('second_div').innerHTML = clone.innerHTML;
If you don't have jQuery added to your solution, it would be good to not add it at all, if only using for that.
By using pure javaScript
var fdiv = document.getElementById("first_div");
var clnNode = fdiv.cloneNode(true);
var clnInput = clnNode.querySelector('#firstname');
clnInput.setAttribute('id', 'lastname')
var secDiv = document.getElementById('second_div')
secDiv.innerHTML = clnNode.innerHTML;
Simply copy the inner html and replace the id:
var html = document.getElementById('first_div').innerHTML;
html = html.replace(/firstname/g, 'last_name');
document.getElementById('second_div').innerHTML = html;
<div id="first_div">
<input type="text" name="firstname" id="firstname">
<select name="marital_status" id="marital_status">
<option value="1" selected='selected'>Select</option>
<option value="2">Single</option>
<option value="3">Married</option>
</select>
</div>
<div id="second_div">
</div>

Appending inputs right after one another in correct order

So my problem is I have 2 anchors one called Add Spell one called Add General Change and I want general change inputs to append right after my general champion name input one by one and right now if you add any spells and then add general change it will append after that spell.
Here is working fiddle http://jsfiddle.net/e6y5903f/ and also on the webss http://89.69.172.125/cms2.0/
Most important bits of code
$('div#ChampionInput').on('click','a.AddGeneralChange', function(){
$(this).parent().children().last().after(
'<div class="GeneralChange">\
<textarea type="text" size="20" name="GeneralChangeDescription['+$(this).parent('div').data('id')+'][]" placeholder="Enter General Change Description" />\
<select name="GeneralChange['+$(this).parent('div').data('id')+'][]">\
<option value="buff">Buff</option>\
<option value="nerf">Nerf</option>\
<option value="new">New</option>\
<option value="change">Change</option>\
<option value="bugfix">Bugfix</option>\
</select>\
Remove General Change\
</div>');
});
The function above is the one that is giving me trouble it is $(this).parent().children().last().after( part I probably have to be more specyfic.
$('div#ChampionInput').on('click', 'a.RemoveGeneralChange',function(){
$(this).closest('.GeneralChange').remove();
});
There is one more minor issue which you can test out on the website every champion has a dropdown if you have 2 champions and you will delete the first one dropdown won't show up on the last one on the site but if you will add one more it will start working again that's bizzare.
Update HTML
Add Champion
<form name="second_form" id="second_form" method="POST">
<div id="ChampionInput">
<div class="GeneralChanges">
</div>
<div class="Spells">
</div>
</div>
<br><br>
<input type="submit" name="submit">
</form>
and what I've tried in jquery
$('div#ChampionInput').on('click','a.AddGeneralChange', function(){
$(this).parent('.GeneralChanges').append(
'<div class="GeneralChange">\
<textarea type="text" size="20" name="GeneralChangeDescription['+$(this).parent('div').data('id')+'][]" placeholder="Enter General Change Description" />\
<select name="GeneralChange['+$(this).parent('div').data('id')+'][]">\
<option value="buff">Buff</option>\
<option value="nerf">Nerf</option>\
<option value="new">New</option>\
<option value="change">Change</option>\
<option value="bugfix">Bugfix</option>\
</select>\
Remove General Change\
</div>');
});
The obvious solution is to do this:
$('div#ChampionInput').on('click','a.AddGeneralChange', function(){
$(this).parent().children('.GeneralChange').last().after(
This selects the last children of the parent (presumably Champion) having the class GeneralChange and adds a new element after it. Except this only works if there already is a GeneralChange element present. Since we start with none, we can't add any. We can fix it like this:
$('div#ChampionInput').on('click','a.AddGeneralChange', function(){
var elem = $(this).parent().children('.GeneralChange');
if(elem.length == 0) {
elem = $(this).parent().children();
}
elem.last().after(
But the mix of Spell and GeneralChange is pretty bad form and could lead to more annoyances regarding DOM manipulation. It also requires more logic to keep the order of elements.
A little restructuration is in order. We go from this:
<div class="Champion">
<div class="Spell"></div>
<div class="GeneralChange"></div>
</div>
To this:
<div class="Champion">
<div class="Spells">
<div class="Spell"></div>
</div>
<div class="GeneralChanges">
<div class="GeneralChange"></div>
</div>
</div>
Then, instead of targeting the last children of a specific class, we target the container in which they are supposed to go:
$('div#ChampionInput').on('click','a.AddGeneralChange', function(){
$(this).parent().children('.GeneralChanges').first().append(
Alternative code
$('div#ChampionInput').on('click','a.AddGeneralChange', function(){
$(this).siblings('.GeneralChanges').first().append(

Categories

Resources