Add <span> below a <div> - javascript

I am trying to learn javascript, but I stuck on a very simple problem.
I tried a lot of things for 3 hours but without success.
I have to insert this span tag below the div "form-control-tag-inner" :
<span class="label label-default"><span class="text-">nick</span><span class="close close-tag" aria-hidden="true">×</span><input type="hidden" name="participants[nick]" value="nick"></span>
And the html code :
<div class="form-group" id="receiver">
<label for="conv-dest">Receivers (Max 100)</label>
<div class="form-control-tag">
<div class="form-control-tag-inner">
<!--- Here i need to insert span tag -->
<input tabindex="1" type="text" autocomplete="on" class="filtre-tag" id="conv-dest" placeholder="Add">
</div>
</div>
</div>

Here is the code that adds span along with ability to attach events to newly added content:
var innerTag = document.querySelector('.form-control-tag-inner');
var innerInput = document.querySelector('#conv-dest');
var innerContent = document.createRange().createContextualFragment('<span class="label label-default"><span class="text-">nick</span><span class="close close-tag" aria-hidden="true">×</span><input type="hidden" name="participants[nick]" value="nick"></span>');
innerTag.insertBefore(innerContent, innerInput);
// sample event, attached on newly added content
var innerCross = document.querySelector('.form-control-tag-inner .close');
innerCross.onclick = function(){
console.log( 'click' );
return false;
};
<div class="form-group" id="receiver">
<label for="conv-dest">Receivers (Max 100)</label>
<div class="form-control-tag">
<div class="form-control-tag-inner">
<input tabindex="1" type="text" autocomplete="on" class="filtre-tag" id="conv-dest" placeholder="Add">
</div>
</div>
</div>

<div class="form-group" id="receiver">
<label for="conv-dest">Receivers (Max 100)</label>
<div class="form-control-tag">
<div class="form-control-tag-inner">
<p>This is a paragraph <span style="color:#FF0000;">
This is a paragraph</span>This is a paragraph</p>
<p><span style="color:#8866ff;">
This is another paragraph</span></p>
<input tabindex="1" type="text" autocomplete="on" class="filtre-tag" id="conv-dest" placeholder="Add">
</div>
</div>
</div>
refer above as example for using span tag.
If any other thing you looking please explain.
Thanks

Just another option.
You may also use DOMParser(), with that you convert simple HTML strings into DOM objects.
DOMParser() Docs
var span = '<span class="label label-default"><span class="text-">nick</span><span class="close close-tag" aria-hidden="true">×</span><input type="hidden" name="participants[nick]" value="nick"></span>',
form = document.querySelector('.form-control-tag-inner'),
nick = new DOMParser().parseFromString(span,'text/html').firstChild;
form.insertBefore(nick,form.firstChild);
<div class="form-group" id="receiver">
<label for="conv-dest">Receivers (Max 100)</label>
<div class="form-control-tag">
<div class="form-control-tag-inner">
<!--- Here i need to insert span tag -->
<input tabindex="1" type="text" autocomplete="on" class="filtre-tag" id="conv-dest" placeholder="Add">
</div>
</div>
</div>

Related

How to show container using jQuery and CSS

I am trying to build a smiley survey using only Front-End.
After hitting one of my radio buttons, the content should become visible for comments. My CSS is set up to display: none.
I have tried to do it using jQuery but nothing seems to be working.
Many thanks for your suggestions!
$("input[type='radio']").change(function(event) {
var id = $(this).data('id');
$('#' + id).addClass('face-cc').siblings().removeClass('none');
});
<div class="cc-selector row" id="moods">
<div class="col">
<input type="radio" type="radio" name="smile" value="angry" />
<label class="face-cc" for="angry">
<span class="far fa-angry" aria-hidden="div"></span>
</label>
<p>Terrible</p>
</div>
<div class="col">
<input type="radio" name="smile" value="grin-stars"/>
<label class="face-cc" for="grin-stars">
<span class="far fa-grin-stars" aria-hidden="div"></span>
</label>
<p>Excellent</p>
</div>
</div>
<div class="none" id="text">
<div class="container">
<form action="/action_page.php">
<div class="row p-5">
<div class="col-sm-12">
<div class="form-group shadow-textarea">
<label for="feedback">If you have any additional feedback,
please let us know below...
</label>
<textarea class="form-control p-2" id="comment" rows="7"
cols="20" placeholder="Comment here...">
</textarea>
</div>
<button type="submit" class="btn btn-danger">
Submit
</button>
</div>
</div>
</form>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
There are a few things incorrect with your approach. First is your use of the radio buttons in the HTML. For you to easily grab their individual click events and inspect their value, you want to add id attributes to them. I added some id's myself based on the radio button's name attribute that you already added.
Second, the jQuery which you used I changed completely to match thew use of the id attribute which I just added. This will look to see which radio button we just clicked on and if it matches the id of the radio button which will show the element, then we show the element accordingly.
You can also accomplish show/hide via CSS. I removed your CSS class of display: none; for the above to work, but you can keep it and use jQuery's toggleClass or addClass and removeClass using the above logic.
A few other comments. I simplified the logic by adding a ternary which you can read more on if you have not seen this syntax.
Last but not least is a quick search on StackOverflow can help, I found this answer which is the exact fix which you needed in your code from a jQuery perspective. I took the time to explain my approach here because you also needed HTML and CSS fixes to your approach.
If you think this answer helped, then feel free to 'accept' or 'mark up' the answer and welcome to Stack Overflow.
var text = $('#text');
var showId = 'grin-stars';
$('input[type="radio"]').click(function() {
$(this).attr('id') === showId ? text.show() : text.hide();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="cc-selector row" id="moods">
<div class="col">
<input id="angry" type="radio" name="radioBtn" value="angry" />
<label class="face-cc" for="angry">
<span class="far fa-angry" aria-hidden="div"></span>
</label>
<p>Terrible</p>
</div>
<div class="col">
<input id="grin-stars" type="radio" name="radioBtn" value="grin-stars"/>
<label class="face-cc" for="grin-stars">
<span class="far fa-grin-stars" aria-hidden="div"></span>
</label>
<p>Excellent</p>
</div>
</div>
<div id="text">
<div class="container">
<form action="/action_page.php">
<div class="row p-5">
<div class="col-sm-12">
<div class="form-group shadow-textarea">
<label for="feedback">
If you have any additional feedback, please let us know below...
</label>
<textarea class="form-control p-2" id="comment" rows="7"
cols="20" placeholder="Comment here...">
</textarea>
</div>
<button type="submit" class="btn btn-danger">
Submit
</button>
</div>
</div>
</form>
</div>
</div>

JQuery - get contents of certain divs

I am cloning a form, and it gives me a lot of data I don't want. I am already doing the following which helps
var formDataUnformatted = $("#content").html();
var cleanFormData = formDataUnformatted.replace(/\t/, "").replace(/ ui-draggable| element/gi, "").replace(/<div class="close">.<\/div>/g, "").replace(/ data-(.+)="(.+)"/g, "");
This still leaves me with a lot of stuff however. Now I can see myself doing many replace calls to clean everything up, which does not seem that good. The above leaves me with something like the following (but I have removed a lot of code which is not really necessary).
<input style="" class="ui-sortable-handle" name="_token" value="sdfsd" type="hidden">
<div class="tab-pane active ui-sortable-handle" id="editor-tab">
<fieldset id="content_form_name">
<legend>Document Name</legend>
</fieldset>
</div>
<div class="form-group-handle">
<label for="text_input" class="control-label col-sm-4">Text Input</label>
<div class="controls col-sm-7">
<input id="text_input" class="form-control" name="text_input" type="text">
</div>
</div>
<div class="form-group-handle">
<label for="textareaInput" class="col-sm-4 control-label">Text Area:</label>
<div class="controls col-sm-7">
<textarea rows="5" class="form-control" id="textareaInput" name="textareaInput" cols="50"></textarea>
</div>
</div>
My aim is to get the divs and contents of any div which has the class form-group-handle. So essentially, the above should be turned into
<div class="form-group-handle">
<label for="text_input" class="control-label col-sm-4">Text Input</label>
<div class="controls col-sm-7">
<input id="text_input" class="form-control" name="text_input" type="text">
</div>
</div>
<div class="form-group-handle">
<label for="textareaInput" class="col-sm-4 control-label">Text Area:</label>
<div class="controls col-sm-7">
<textarea rows="5" class="form-control" id="textareaInput" name="textareaInput" cols="50"></textarea>
</div>
</div>
Instead of finding all the bad divs, and using something like replace, is there any way to just find all divs with the class I want, and keep that content?
Thanks
Use clone to that specific class:
var clone = $('.form-group-handle').clone();
$(".form-group-handle").each(function()
{
console.log($('.form-group-handle').clone());
// or
console.log($('<div>').append($('.form-group-handle').clone()).html());
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input style="" class="ui-sortable-handle" name="_token" value="sdfsd" type="hidden">
<div class="tab-pane active ui-sortable-handle" id="editor-tab">
<fieldset id="content_form_name">
<legend>Document Name</legend>
</fieldset>
</div>
<div class="form-group-handle">
<label for="text_input" class="control-label col-sm-4">Text Input</label>
<div class="controls col-sm-7">
<input id="text_input" class="form-control" name="text_input" type="text">
</div>
</div>
<div class="form-group-handle">
<label for="textareaInput" class="col-sm-4 control-label">Text Area:</label>
<div class="controls col-sm-7">
<textarea rows="5" class="form-control" id="textareaInput" name="textareaInput" cols="50"></textarea>
</div>
</div>
If you use jQuery with class selector, the jQuery object contains only the divs you need
$('div.form-group-handle')
But the jQuery object contains a collection of DOM elements (you chan check the number of elements matching your selector with $.('div.form-group-handle').length), so you need to iterate through them to build your final string.
If you want the html of each div
var formDataUnformatted = '';
$('div.form-group-handle').each(function() {
formDataUnformatted += this.outerHTML;
// where 'this' represents each matching div
});
EDIT (regarding your comment to Jordan Lowe answer indicating that html is not in the DOM)
If formDataUnformatted is a string representing html, you can filter that content to get the collection of divs
$(formDataUnformatted).filter('div.form-group-handle');
With a mixture of a few of these answers, I seem to have found a problem. Some of the above were through errors because it is not a JQuery Object. So I came up with the following solution
var formDataUnformatted = $("#content").html();
var cleanFormData = formDataUnformatted.replace(/\t/, "").replace(/ ui-draggable| element/gi, "").replace(/<div class="close">.<\/div>/g, "").replace(/ data-(.+)="(.+)"/g, "");
var dataArray = new Array();
$(cleanFormData).filter('div.form-group-handle').each(function() {
dataArray.push(this.outerHTML);
});

Multi forms datas into array via Javascript

I have some forms like this:
<div class="well">
<form>
<span class="remove pull-right"><i class="fa fa-times pointer"></i></span>
<div class="form-group" style="margin:0">
<label for="image-link">Image Link</label>
<input type="text" name="image-link" value="" class="form-control" >
</div>
<div class="form-group" style="margin:0">
<label for="content">Content</label>
<textarea class="form-control" name="content" rows="10"></textarea>
</div>
<div class="form-group" style="margin:0">
<label for="author">Author</label>
<input type="text" name="author" value="" class="form-control" >
</div>
</form>
</div>
....
<div class="well">
<form>
<span class="remove pull-right"><i class="fa fa-times pointer"></i></span>
<div class="form-group" style="margin:0">
<label for="image-link">Image Link</label>
<input type="text" name="image-link" value="" class="form-control" >
</div>
<div class="form-group" style="margin:0">
<label for="content">Content</label>
<textarea class="form-control" name="content" rows="10"></textarea>
</div>
<div class="form-group" style="margin:0">
<label for="author">Author</label>
<input type="text" name="author" value="" class="form-control" >
</div>
</form>
</div>
The forms will be added more and more when I click the add button, so will have multi forms.
I want to submit multi datas into an json arrayjust looks like this:
"quotes":[
{"image":"image_link","content":"content","author:"author"}
{"image":"image_link","content":"content","author:"author"}
...
{"image":"image_link","content":"content","author:"author"}
]
which is an array will contain all of the forms' datas. And the amount of forms is not fixed. It will be changed when I click add button.
So how can I do that automatically.
Thank you so much!
You can iterate through all the form elements on the page by calling the following function:
function generateArrayData() {
var forms = document.querySelectorAll(".well form");
var quotes = [];
for(var i = 0; i < forms.length; i++) {
var form = forms[i];
quotes.push({
image: form.querySelector("input[name='image-link']").value,
content: form.querySelector("textarea").value,
author: form.querySelector("input[name='author']").value
})
}
return quotes;
}
The way this works is that querySelectorAll loads all of the form elements on the page within a div with the class .well. We then iterate through the elements from the previous query and use querySelector to pull out each individual element we'd like to extract.

jQuery .on() issue, console.log() works but element interaction doesn't

I am using this code inside $(document).ready(function(){ ... }):
$('#flavours').on('click', '.toggle-quantity', function(e){
e.preventDefault();
var $quantity_percent = $(this).parent().find('.quantity_percent');
if($quantity_percent.is(':hidden')){
console.log("is hidden");
$quantity_percent.show();
}else{
console.log("is not hidden");
$quantity_percent.hide();
}
});
What's happening is the console.log() is working, but the $quantity_percent is not showing/hiding.
Additionally, if I add an alert('test') to the beginning of the function (just after e.preventDefault) this also doesn't work, but the console.log() continues to work (it correctly logs 'is not hidden').
EDIT: Relevant HTML markup:
<div id="flavours">
<div class="row flavour" id="flavour_1" style="display: block;">
<div class="form-group">
<div class="col-xs-12">
<fieldset>
<legend>Flavour 1</legend>
<div class="col-sm-4">
<label>Flavour Name</label>
<input type="text" value="" name="flavour_name[]" data-flavour-id="1" id="flavour_name_1" class="form-control autocomp" placeholder="Flavour name">
<input type="hidden" value="" name="flavour_id[]" id="flavour_id_1" class="form-control flavour_id">
<p class="flavour_info"></p>
</div>
<div class="col-sm-6">
<label>Flavour Quantity <span class="fa fa-filter"></span> <span class="hidden-sm">Switch to </span>drops per ml</label>
<div class="input-group" id="quantity_percent">
<input type="text" class="form-control" id="flavour_percentage_1" name="flavour_percentage[]" placeholder="Flavour Quantity">
<span class="input-group-addon">%</span>
</div>
<div class="input-group" id="quantity_drops" style="display: none;">
<input type="text" class="form-control" id="flavour_drops_1" name="flavour_drops[]" placeholder="Flavour Quantity">
<span class="input-group-addon">drops/ml</span>
</div>
<p class="flavour_recommended_percentage"></p>
</div>
<div class="col-sm-2">
<label> </label>
<button class="btn btn-danger btn-block remove-flavour"><span class="glyphicon glyphicon-remove"></span> Remove</button>
</div>
</fieldset>
</div>
</div>
</div>
$(this).parent() is a label element which doesn't have a child with .quantity_percent
Also quantity_percent is an id and not a class. Use the ID selector
So use
var $quantity_percent = $('#quantity_percent');
instead of
var $quantity_percent = $(this).parent().find('.quantity_percent');
Note: IDs must be unique in HTML
EDIT: as per OPs comments
I updated it to a class rather than ID (as it's on a dynamically growing list)
Usage
var $quantity_percent = $(this).closest('.col-sm-6').find('.quantity_percent');
The .parent() targets the <label> therefore it can't find .quantity_percent

Trying to get the total to generate from quantity and price

I've been working on this for a little longer then needed, but I can't find what is going wrong here. I think I've looked at it way too long. I need to get the items to add up after quantity is add to the form.
Here is my HTML
<div class="row-fluid container-cart">
<div class="span4">
<div class="thumbnail">
<img src="http://myurl.com/image.jpg" />
<div class="caption">
<h3 class="">Title</h3>
<p class="">Description</p>
<div class="row-fluid">
<div class="span6">
<p class="lead">
<span id="item-price">100</span>
<span class="price-integer">
<input type="hidden" value="100">
</span>
</p>
</div>
<div class="span6">
<span>Quantity</span>
<input type="text" name="" id="quantity" class="stored quantity" autocomplete="off" value="">
</div>
<div class="span6">
<input type="text" name="base-total" id="base-total" class="stored readonly base-total" value="" readonly>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="span6">
Total:
<span class="total-cart">
<input type="text" name="total-cart" id="total-cart" class="stored readonly" value="" disabled="disabled">
</span>
</div>
Here is my JS
$('.quantity').on('keyup', function() {
var sum = 0;
$(".container-cart").each(function(i,o){
total = parseInt($(o).find(".quantity input").val(), 10) * parseInt($(o).find(".price-integer input").val(), 10);
if(!isNaN(total) /*&& total.length!=0**/) {
$(o).find(".base-total").val(total);
sum += total;
}
});
$("#total-cart").val(sum);
});
Looks like you typed a wrong selector, it's the .quantity input, the .quantity is an input, so it won't have any children, maybe you want to mean the input.quantity which means finding the input having class quantity.
Demo.

Categories

Resources