I am having a requirement to include a repeating TextArea control (I created small jQuery snippet, that will clone the first textarea and append it to ul on hitting a button and therefore I am calling it as repeating text area control) inside a repeating DIV section (users will be presented with another add button and when that button is clicked it should clone the div and add that div to the main container. Users can hit the button as many times as they want and therefore I am calling it as repeating DIV).
I am not getting any idea of getting this task done. Here is the elaborated requirement. (It's similar to Repeating Field inside a Repeating Section in InfoPath)
Using jQuery I created a repeating textarea controls (TextAreas get added as list items on hitting Add button) and now I will be having a div which will need to have some textboxes and also need to include this repeating textarea field. ID's also need to unique for everything. As I mentioned above, there will be a button after that div and when the user hits that button, the entire div needs to be cloned and needs to be appended to the main container.
There are a huge number of different ways to do this. I recently had a project where I had to do this very thing. Here is a working Fiddle of the following code example:
HTML
<div id="container">
<span id="sholder"></span>
<br />
<input type="button" value="Add Section" class="addsection" />
</div>
<div id="section_template" class="template">
<div class="section">
<span class="taholder"></span>
<br />
<input type="button" value="Add Textarea" class="addtextarea" />
</div>
</div>
The key concept here is that I created a div section with class template, and in the CSS template is set to display: none;. I use it to more easily create a bigger section of HTML later in the CreateSection() function.
jQuery / javascript
$(function() {
//add the click handler to add a new section
$("input.addsection").click(CreateSection);
//add the click handler for the new section
//since the buttons are added dynamically, use "on" on the "document" element
// with the selector for the button we want to watch for.
$(document).on("click", "input.addtextarea", function() {
var section = $(this).closest("div.section");
AddTextarea(section);
});
});
function CreateSection() {
var section = $("#section_template div.section").clone();
var holder = $("#container span#sholder");
//get the current total number of sections
var sectionCount = holder.find("div.section").length;
//create the section id by incrementing the section count
section.attr("id", "section" + (sectionCount + 1));
//add a textarea to the section
AddTextarea(section);
//add the new section to the document
holder.append(section);
}
function AddTextarea(section) {
var sectionID = section.attr("id");
var holder = section.find("span.taholder");
//get the current total number of textareas in this section
var taCount = holder.find("textarea").length;
//create the new textarea element
var ta = $(document.createElement("textarea"));
//create the textarea unique id
var taID = section.attr("id") + "_textarea" + (taCount + 1);
ta.attr("id", taID);
//show the id... can be removed
ta.val("ID: " + taID);
//add the textarea to the section
holder.append(ta);
}
There are several helpful search functions in the above code: closest, find. Also, I'm using the clone function to duplicate that HTML section.
Also of note, I create the new textarea using $(document.createElement("textarea")). document.createElement is the fastest way for JS to create new HTML DOM objects.
And a bit of CSS for the example
div.template {
display: none;
}
div.section {
border: 1px solid black;
}
div.section textarea {
display: block;
}
This example keeps the IDs unique as you can see in the JSFiddle. However, reading those fields if they are posted to the server is an answer to another question.
Related
Hello i am trying to dynamically create divs, at a button click, and append a span element to it. When i click the button a function is called and a div is created but i can't display the contents of the span element.
I basically have a container div and want to create divs inside that container, with the contents of the span element present, through javascript.
function createDiv ()
{
var boxEle = document.createElement('div');
var container = document.querySelector('.container');
boxEle.setAttribute('id','box_id'+ dynamicid());
//console.log(boxEle.id);
boxEle.style.width = "40%";
boxEle.style.height = "500px";
boxEle.style.backgroundColor = 'yellow';
boxEle.style.margin = "20px";
boxEle.style.boxsizing = "border-box";
boxEle.innerHTML = '<span class="list-names"></span>';
container.appendChild(boxEle);
}
This span will show a list of names that were fetched from a database. The idea was to create how many divs i wanted with the list present in every created div.
If i change the span element and insert some random text it works fine. I also tried to create a php file with just the span element there and used jquery load to insert it into my div but it only works on the first div, if i create more than one then nothing shows on the rest.
After looking on here i tried to do everything with jquery but the problem was the same.
$(function(){
var count = 0;
$('#creatediv_id').click(function(){
$('#container_id').append('<div id="first'+count+'"><span class="list-names"></span></div>');
count++;
});
});
Don't really know what else i should try or if it is doomed.
Actually your code works just fine, did you check DOM after click, because elements are there, but your span hasn't got any text, so there is nothing on the screen, here is example with jQuery way:
$(function(){
var count = 0;
$('#creatediv_id').click(function(){
$('#container_id').append('<div id="first'+count+'"><span class="list-names">test</span></div>');
count++;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="creatediv_id">Create Div</button>
<div id="container_id"></div>
There are a few things I'd like help with. I have found pieces of the solution on stack overflow, but can't quite put it all together.
I'd want the user to add text to a text area, click a button to post the text to a parent element, and finally have the option to remove the posted text element from the parent. This is as far as I have gotten on the code. Thanks in advance for any suggestions.
<body>
<h4>A News Module.</h4>
<div id="container">
<p>Here is some news.</p>
</div>
<textarea id="alltext" rows="13" cols="53" placeholder="Add your news here."></textarea>
<br>
<input type="button" value="Submit News" onclick="addNews()">
<script>
function addNews(){
var addEl = document.createElement('p');
document.getElementById('container').appendChild(addEl);
}
function deleteNews(){
var deleteEl = document.getElementById('container');
deleteEl.parentNode.removeChild(deleteEl);
}
</script>
</body>
Also on jsfiddle: https://jsfiddle.net/lotus89/nvo1s5re/
Two things.
1) You need to add the text from the textboxt into the newly created element. Add the folowing line right after the creation:
addEl.textContent = document.getElementById('alltext').value;
This grabs the value of the texbox and sets it as the textContent of the newly created element.
2) addNews() needs to be in the global scope for jsfiddle
Add this line:
window.addNews = addNews;
Edit: Update fiddle - https://jsfiddle.net/rtj998gL/1/
Take a look at your addNews code. You're creating a new p and adding it to the container, but you're never putting anything in it.
function addNews(){
//Create blank P element
var addEl = document.createElement('p');
//Set the new element's content to match the textarea value
addEl.innerHTML = document.getElementById("alltext").value;
//Add it to the container
document.getElementById('container').appendChild(addEl);
}
If you put your <script> in the head of your page, your code would work fine. But being that it's in the <body>, your functions are not being found because they are out-of-scope. You can adjust for this by doing window.addNews = addNews within your <script> tags.
We have a website hosted at hubspot, we use their native WYSIWYG to design layouts then style them with css and js.
On the homepage http://www.lspatents.com/ it used to have a form under the "Get started here" title, it had around 10 questions, and used javascript to split them to steps so they can fit in the same area on the currently shown blank box.
It was working just fine till two days ago the form disappeared and left it with a blank area as you can see now, and as far as i know no one has touched this code recently.
Here is the js code that was used to manipulate the form
// Hero Form
$(window).load(function() {
// disable autocomplete to fix bug
$('.hero-form form').attr("autocomplete", "off");
$('.hero-form .hs-richtext').each(function() {
$(this).nextUntil('.hs-richtext').wrapAll('<div class="step" />');
});
// Hide Loading icon
$('.hero-form form').css('background', 'none');
$('.hero-form form .step:nth-of-type(2)').show();
// First Step to Second Step
$('.step').find('.hs-richtext').change(function() {
$('.step:nth-of-type(2)').hide().next().next().fadeIn();
});
// Second Step to Third Step
$('.step').find('.hs-input').change(function() {
var names = {};
$(':radio').each(function() {
names[$(this).attr('name')] = true;
});
var count = 0;
$.each(names, function() {
count++;
});
if ($(':radio:checked').length === count) {
$('.step:nth-of-type(4)').hide().next().next().fadeIn();
}
});
});
As far as i was able to tell, the developer used css to hide the whole form area with display:none; and used the js above to split the questions to steps and show a certain number in each step.
You can see the code being called in the footer so there is no problem with the link to the .js file, also if you inspect the element and disable the display:none; that's declared for any of the divs within the hero-form all questions get displayed, so there is no problem with the form either, so why has it stopped working?
Would appreciate any help,
This line will no longer work with your mark-up...
$('.hero-form form .step:nth-of-type(2)').show();
There are a number of additional divs that wrap your mark-up, placed there by react, React has placed a series of div inside your form which are being hidden by your existing CSS (which I assume used to just be a series of STEP's)
The CSS that hides the nodes is :
.hero-form form>div, .hero-form form>.step {
display: none;
}
The nodes that are being hidden with display:none
<div data-reactid=".0.0:$1">
<div class="hs-richtext" data-reactid=".0.0:$1.0">
<hr>
</div>
<div class="step">
<div class="hs_patent field hs-form-field" data-reactid=".0.0:$1.$patent">
<label placeholder="Enter your Do you have a patent?" for="patent-9fc8dd30-a174-43bd-be4a-34bd3a00437e_2496" data-reactid=".0.0:$1.$patent.0">
<span data-reactid=".0.0:$1.$patent.0.0">Do you have a patent?</span>
<span class="hs-form-required" data-reactid=".0.0:$1.$patent.0.1">*</span>
</label>
<div class="hs-field-desc" style="display:none;" data-reactid=".0.0:$1.$patent.1">
</div>
</div>
Your JQuery will add display:block to the DIV with the class 'step' bit wont alter the parent DIV (inserted by React) which still prevents your node from being shown.
You need to alter you JQuery to call show() on the parent() that contains the "step" div you wish to show.
Please check your browser console ans see you have problem loading this form:
https://forms.hubspot.com/embed/v3/form/457238/9fc8dd30-a174-43bd-be4a-34bd3a00437e
and this is the error:
net::ERR_NAME_RESOLUTION_FAILED
It's better you change your DNS to something like 8.8.8.8 and see if the problem still exists or not.
I followed this example
How to use jQuery to add form elements dynamically
Is it possible to add form elements dynamically to the dynamically generated form?
This is my code:
<html>
<script src="jquery.js" type="text/javascript"></script>
<script>
$(document).ready(function () {
$('#addRow').click(function () {
$('<div/>', {
'class' : 'extraPerson', html: GetHtml()
}).hide().appendTo('#container').slideDown('slow');
});
$('#addAttribte').click(function () {
$('<div/>', {
'class' : 'extraAttribute', html: GetHtml1()
}).hide().appendTo('#extraAttribute').slideDown('slow');
});
})
function GetHtml() {
var len = $('.extraPerson').length;
var $html = $('.extraPersonTemplate').clone();
$html.find('[name=firstname]')[0].name="firstname" + len;
return $html.html();
}
function GetHtml1() {
var len = $('.extraAttribute').length;
var $html = $('.extraAttributeTemplate').clone();
$html.find('[name=attribute]')[0].name="attribute" + len;
return $html.html();
}
</script>
<div class="extraPersonTemplate">
<input class="span3" placeholder="First Name" type="text" name="firstname">
Add Attribute
<div id="extraAttribute"></div>
</div>
<div class="extraAttributeTemplate">
<input class="span3" placeholder="Attribute" type="text" name="attribute">
</div>
<div id="container"></div>
<i class="icon-plus-sign icon-white"></i> Add another family member</p>
</html>
I realise there will be issues regarding names of the newly added form elements, but at this point I just want to be able to dynamically add even just a line of text to a dynamically generated form.
Edit: Sorry, forgot to mention what the problem was; the page starts off with just a link saying "Add another family member". This will add the extraPersonTemplate. This template also has a "Add Attribute" link which adds an extra form field to this newly added field.
However when I click "Add Attribute", I'd expect it to add extraAttributeTemplate to the bottom of the dynamically added form, but nothing happens.
There are two specific issues.
IDs are supposed to be unique. Having an anchor with an id of addAttribute for every person isn't valid, and only the first element found in the DOM will have the event bound. This isn't a problem at the start because there's only one of them, but does become a problem later on once you start adding additional family members.
Events bound in the ready handler are only bound to elements that exist when the code executes. If you're going to be adding new elements that you want to have those events bound you need to use event delegation:
$(document).on('click', '.addAttribute', function() {
// add an attribute here
// I've changed from an ID to a class selector
// you'll need to find a way to get a reference to the correct elements from a specific anchor
});
I've put together a demo with the changes detailed above.
This is probably a fairly easy question, but I'm new to JavaScript and jquery....
I have a website with a basic show/hide toggle. The show/hide function I'm using is here:
http://andylangton.co.uk/articles/javascript/jquery-show-hide-multiple-elements/
So here's my question..... I would really like the first 5-10 words of the toggled section to always be visible. Is there some way I can change it so that it doesn't hide the entire element, but hides all but the first few words of the element?
Here's a screenshot of what I would like it to do:
http://answers.alchemycs.com/mobile/images/capture.jpg
There are many different implementation possibilities:
You can divide the contents up into the first part and the second part (two separate spans or divs inside your main object) and hide only the child object that represents the second part, not hide the parent object.
Rather than hide the object at all, you can set its height to only show the first part (with overflow: hidden)
Change the contents of the main object to only have the first part as the contents (requires you to maintain the full contents somewhere else so you can restore it when expanded again).
Here's a working example of option 1: http://jsfiddle.net/jfriend00/CTzsP/.
You'd need to either:
Put in a span/etc. after the first n words, and only hide that part, or
Change the viewable region, or
Replace or toggle the span/etc. with the "collapsed" view.
The last is a bit more customizable; using two separate elements allows trivial games to be played (showing an image, for example, like a little curly arrow) without modifying adding/removing DOM elements.
I tend towards the last because it's simple and obvious, but that's a personal preference, and really isn't as true as it used to be.
You can do some plugin authoring,I did a sample demo here ,based on your screenshot
<div class="toggle">ShowHide</div>
<div class="content">some content some content some content some content some content <br/> some content some content some content </div>
<div class="toggle">ShowHide</div>
<div class="content">some content some content some content some content some content <br/> some content some content some content </div>
here is javascript/jquery code
jQuery.fn.myToggle = function(selector, count) {
var methods = {
toggle: function(selector, count) {
if ($(selector).is(':visible')) {
var span = $('<span>');
span.text($(selector).text().substr(0, count) + "...");
span.insertAfter($(selector));
$(selector).hide();
}
else {
$(selector).show();
$(selector).next('span').hide();
}
}
};
$(this).each(function() {
methods.toggle($(this).next(selector), count);
$(this).click(function(evt) {
methods.toggle($(this).next(selector), count);
});
});
};
$(function() {
$('.toggle').myToggle('.content', 3);
});
Here is a solution using css properties only instead of mangling the dom.
http://jsfiddle.net/AYre3/4/
Now if you want some sort of animation happening as well you'll probably need to do a bit of measurement along the way.