Create cloned numbered forms dynamically with jQuery - javascript

I have a page where only one form appears. This form is:
<div style="display: none" class="article_properties">
<form id="article_properties_form">
<p>Page Number</p>
<p id="pageNumber"></p>
<p>Subtitle</p>
<input type="text">
<p>Text</p>
<textarea></textarea>
<input type="submit" value="Submit/Update">
</form>
<div id="addOne" style="width: 25px; height: 25px; background-color: orange; border-radius: 50%">
<p style="text-align: center; line-height: 25px">+</p>
</div>
</div> <!--End of article properties div-->
When the user clicks the #addOne div, a clone of that form is made. BUT, this form is technically not the same form, because it will have one small detail that will make it uniquely different. This detail is the page number. Every time the #addOne div is clicked, the page number becomes one less. The page number is chosen by the user prior to seeing this current page. For example, let's say the user picks 10 pages. The first form's page number will be 10, the next form when the user clicks the #addOne div it'll be 9 and so on. The first form will always stay at 10 and the second form will always stay at 9, the third form will always stay at 8 and so on.
Here's my current script:
<script>
var numPages; //Global var: number of pages user wants
$('#addOne').click(function() {
$('#pageNumber').text(numPages);
numPages--;
var articlePropsTemplate = $('#article_properties_form').clone();
$('#article_properties_form').append(articlePropsTemplate);
});
</script>
My current code is producing very weird results. When I click on the #addOne div, the form is being duplicated multiple times instead of once, and the number of pages is not being shown correctly in a logical countdown order. This form never refreshes and all information is relayed through Ajax.
Here's the jsFiddle: https://jsfiddle.net/9dzgg8m6/6/

Alter your form :
<div class="article_properties">
<form id="article_properties_form">
<div class="form-body">//add a class to wrap the elements for cloning
<p>Page Number</p><p class="pageNumber"></p>//change the id to class
<p>Subtitle</p>
<input type="text">
<p>Text</p>
<textarea></textarea>
<input type="submit" value="Submit/Update">
</div>
</form>
<div id="addOne" style="width: 25px; height: 25px; background-color: orange; border-radius: 50%"><p style="text-align: center; line-height: 25px">+</p></div>
</div> <!--End of article properties div-->
and your js
var numPages = 10;
$('.pageNumber').text(numPages);//add then number for the first element
$('#addOne').click(function()
{
numPages--;
var articlePropsTemplate = $('.form-body:last').clone();//clone the last wrapped elements
$('#article_properties_form').append(articlePropsTemplate);
$('.pageNumber:last').text(numPages);//append the number after it was placed on the page
});
https://jsfiddle.net/0738u576/

Related

JavaScript localStorage - Text input from Multiple User Cards

Please kindly let me know if this belongs in another thread.
I have a project involving user cards.
Objective:
1. add the ability to enter comments/tag in the provided text input for each user card.
2. save entered comments/tag using localStorage JavaScript.
3. saved comments/tag to be displayed in the user card where comments/tag was entered.
eg.
3 user cards, comments/tag entered on cards 1 & 3 only, onload tags comments/tag should appear on cards 1 & 3 only and card 2 will show placeholder or blank.
Problem:
If I enter a comment/tag on card 1, onload it displays as expected on card 1.
when comments/tags are entered on cards 2 or 3, onload comments/tag will appear on card 1 only, nothing on card where comments/tag were entered.
Am I forgetting something when i do forEach (or am i misusing it all together).
Appreciate any help/guidance, Im sorry Im new to JavaScript.
**prefer plain JavaScript code samples if possible.
My code link to CodePen - https://codepen.io/marcusnapoleon/pen/GRKzpeE
//SAVE
function saveTag(event) {
var tagTerm = event.target.value;
var tagTextInput = document.querySelectorAll("p.tagFilter");
tagTextInput.forEach(function (cardTags) {
localStorage.setItem("tag", tagTerm)
});
}
//RETRIEVE
function show(event) {
tagTextInput = document.querySelectorAll("p.tagFilter");
tagTextInput.forEach(function (getTags) {
var y = localStorage.getItem("tag");
document.getElementById("name").innerHTML = y
});
}
.card{
width: 300px;
border: 1px solid lightgrey;
padding: 5px 20px;
}
.container{
width: 60%;
margin-left: auto;
margin-right: auto;
display: flex;
justify-content: space-evenly;
padding: 100px 250px;
font-size: 1.2rem;
}
<!DOCTYPE html>
<html>
<head>
</head>
<body onload="show()">
<div class="container">
<div class="card">
<h2>Name : User One</h2>
<h2>Title : Job One</h2>
Enter your name: <input id="tagInput" onkeyup="saveTag(event)" type="text" placeholder="Comment here" >
<b>TAG:</b><p class="tagFilter" id="name">tag goes here</p>
<input onclick="clear()" type="button" value="CLEAR" />
</div>
<div class="card">
<h2>Name : User Two</h2>
<h2>Title : Job Two</h2>
Enter your name: <input id="tagInput" onkeyup="saveTag(event)" type="text" placeholder="Comment here" >
<b>TAG:</b><p class="tagFilter" id="name">tag goes here</p>
<input onclick="clear()" type="button" value="CLEAR" />
</div>
<div class="card">
<h2>Name : User Two</h2>
<h2>Title : Job Two</h2>
Enter your name: <input id="tagInput" onkeyup="saveTag(event)" type="text" placeholder="Comment here" >
<b>TAG:</b><p class="tagFilter" id="name">tag goes here</p>
<input onclick="clear()" type="button" value="CLEAR" />
</div>
</div>
</body>
</html>
You are setting values with same name, even though they are different values.
You should set values with different names. It can be editted like:
function saveTag(event) {
var tagTerm = event.target.value;
var tagTextInput = document.querySelectorAll("p.tagFilter");
tagTextInput.forEach(function (cardTags, itemIndex) {
localStorage.setItem("tag" + itemIndex, tagTerm);
});
}
This will save values with individual name, distingiushing indexes by 0,1,2.
EDIT 2019-09-27
I made some changes to your code, here it is: https://codepen.io/firesped1/pen/ExYJQgy?editors=1010
Before explaining what I did, I have to tell this:
HTML must not have duplicate IDs.
It's against the HTML standards, causing errors in ID selectors. If you want to select multiple elements at once, use class or tag selector.
The problem was you were saving the same values to different localStorage keys.I changed the logic to save directly to localStorage.
If you don't have parts that you don't understand, feel free to ask me.

how to add Parent Element Name to Child Element

i have an input Element that Get Name of Helper but Two Element has same id
it is incorrect for Edit this problem,
i want to Add Parent Div Id to Child Input.how can i Append ParentId to ChildId
<div class="wrapper-merge-input">
<div id="Stb" class="col-md-6 ">
<label class="control-label">StartDate</label>
#page.Html.Raw(fromHtml)
</div>
<div id="Edb" class="col-md-6 ">
<label class="control-label">EndDate</label>
#page.Html.Raw(toHtml)
</div>
</div>
</div>
*And *
<input type="text" dir="ltr" class="form-control"
name="#name" id="#name"
value="#value"
onclick="DatePicker.Show(this,'#today');" />
for example #name+Edb
The code below shows how you can use .attr("id") to get an element's id. In order to travel up one level to the parent DOM element you should use .parent().
You can also use .attr("id", "new-id") to set an attribute value. This can take strings or variables (as in the code below).
By placing the update code into a function you can call it on page load, after a click or any other event. I have made it run after a click of the button so you can see the id change.
I added some basic styling to make the demo a bit nicer to use.
Let me know if you wanted something else.
WARNING you will likely want to make the updateID() function more specific, so it does not act on every input on the page.
// Click event for button to demonstrate change
$("#startUpdate").click(function() {
updateID();
});
function updateID() {
// Cycle through each input - WARNING - you will want to make this more selective
$("input").each(function() {
// Update id of input from it's own name and it's immediate parent's id
$(this).attr("id", $(this).attr("name") + "-" + $(this).parent().attr("id"));
// Print message to console to demonstrate id
console.log("new id = " + $(this).attr("id"));
});
}
.wrapper-merge-input {
border: 1px solid black;
border-radius: 5px;
padding: 8px;
margin: 20px;
}
#Edb {
padding-top: 10px;
}
#startUpdate {
margin-left: 20px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper-merge-input">
<div id="Stb" class="col-md-6 ">
<label class="control-label">StartDate</label>
<input name="example1" id="example1" value="example1" onclick="DatePicker.Show(this,'#today');">
</div>
<div id="Edb" class="col-md-6 ">
<label class="control-label">EndDate</label>
<input name="example2" id="example2" value="example1" onclick="DatePicker.Show(this,'#today');">
</div>
</div>
<button id="startUpdate">Update IDs</button>

Submit dynamical form using JQuery

I´m not really sure I can do this, but it's worth the try.
I have a table with at least 10 items coming from a Mysql database. They are items for which you can bid. The idea is that every row (therefore, every item) has a button that can be clicked to enter the bid. This button opens a popup with a text field to enter the bid and a button to submit the form.
In order to identify the item the user is bidding for, I need its id, as well as the amount bid. The amount is really easy to get, but I´m struggling a lot with the item id.
Here is what I have:
$(document).ready(function(){
$(".show").click(function() {
$("#popup").show();
var $id = document.getElementsByClassName('show')[0].value;
console.log($id);
$("#jugador").val($id);
});
$("#close, #submit").click(function() {
$("#popup").hide();
});
});
#popup {
position: relative;
z-index: 100;
padding: 10px;
}
.content {
position: absolute;
z-index: 10;
background: #ccc;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.overlay {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: #000;
z-index: 5;
opacity: 0.4;
}
<td><button class="show" id="bid" value="<?php echo $row2["id"];?>"><img src="pictures/bidIcon.png" width="30" height="30"></button></td>
/*Popup*/
<div id="popup" style="display: none;">
<div class="overlay"></div>
<div class="content">
<header>
<div id="close">✖</div>
</header>
<form name="form1" method="post" action="bid.php">
<fieldset>
<label for="bid">Bid:</label>
<input type="text" name="bidAmount" id="bidAmount" size="8" />
<input type="hidden" name="item" id="item" />
<input type="submit" tabindex="-1" style="position:absolute; top:-1000px">
</fieldset>
<footer>
<button type="button" id="submit">Bid Now</button>
</footer>
</form>
</div>
</div>
I´ve been trying for a while with no luck. I will always get the item id for the first element no matter in which button I click.
Is it feasible what I want? Is this the correct approach? Should I use a different one?
Thanks a lot in advance.
Just change this line:
var $id = document.getElementsByClassName('show')[0].value;
To this:
var $id = $(this).val();
The problem is that with document.getElementsByClassName('show')[0].value you are querying the first occurrence of the .show button. With $(this) instead you will be accessing the current clicked button.
JQuery binds the events to the target where you attach the event, so this will always be a reference to the target of the event. Using $(this) will create a jQuery object of the target element permitting to apply jQuery functions to the element.
As a side note, you shouldn’t duplicate the elements ids. Every id must be unique in the html document, so it will be a good practice to make that id different for each button.
Hope it helps.
To access the current div element's Id you can use the ($this), which refers to the current javascript object.
$("div").click(function(){
alert($(this).attr('id'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="1">Num 1</div>
<div id="2">Num 2</div>
<div id="3">Num 3</div>
<div id="4">Num 4</div>
Here in this example, i have created div's which when clicked return's the id of that div.
When you do it like this var $id = document.getElementsByClassName('show')[0].value; it will always take the first element having class="show".
Which will contain the first item hence always gives the id of first item.
So instead of doing it like that you can do it like this:
var $id = $(this).val();
This will select the current item on which user has clicked so will give the id of that item.

How to use floating save button for large forms and hide that when actual save button is visible angularjs whose location is not just bottom of page

Hi I want to use a floating save button in my div
.fw_circle{
background-color: #53beb6;
position: fixed;
bottom: 20px;
right: 20px;
width: 55px;
height: 55px;
border-radius: 50%;
text-align: center;
font-size: 20px;
padding: 13px;
color: white;
z-index: 100;
}
<div class="div1">
<!-- Floating save button -->
<div class="fw_circle">
<i class="fa fa-floppy-o" aria-hidden="true"></i>
</div>
<div class="form-group">
<label>Name:</label>
<input type="text" ng-model="Name" class="form-control" maxlength="200" required/>
</div>
<div class="form-group">
<label>Name2:</label>
<input type="text" ng-model="Name2" class="form-control" maxlength="200" required/>
</div>
<div class="form-group">
<label>Name3:</label>
<input type="text" ng-model="Name3" class="form-control" maxlength="200" required/>
</div>
<div class="form-group">
<label>Name4:</label>
<input type="text" ng-model="Name4" class="form-control" maxlength="200" required/>
</div>
<!-- And so many other input fields-->
</div>
<div class="div2">
<!--Don't want that float button to be shown in this div as it has only a save button -->
<button class="btn">Save</button>
</div>
I want that the floating button should be visible in above div (i.e div1) with input fields
So that the user can save the form anytime in between and no need to scroll to the bottom to save the form.
But when he scrolled to the bottom and then he can see the save button in another div (i.e div2), in that case, the floating button should not be visible.
And the actual Save button is not exactly at the bottom of page
But the floating button is showing even if the save button is visible. Please suggest some method to achieve this.
You just need hide it with JavaScript:
var button = (find button)
$(div).css('display', 'none')
You can make that a function and trigger it on your convenience.
If it is as I understand in your code, you can select the button with: $('.fw_circle')
If you want to trigger it depending on whether the user has reached the bottom or the page, you can do so with the following piece of code from another answer here in SO:
window.onscroll = function(ev) {
if ((window.innerHeight + window.pageYOffset) >= document.body.offsetHeight) {
alert("you're at the bottom of the page");
}
};

Show table when its tab is clicked but hide other tables

So right now I have a section that has 3 tabs on it. Each tab is supposed to bring up a different table while simultaneously hiding the other 2 tables. When the page loads up it shows the first table (which it is supposed to do), but when I click one of the other two tabs nothing happens. I realize this has to be done with a Javascript onclick but I'm not familiar with it yet to know what I'm doing. I unfortunately have a lot of code that goes into making this work so i wont be able to post it on here but ill grab the code i think is most important and if you need any more info let me know. Please and thankyou for your help.
The tabs are "Pavement Section Editor", "Traffic", and "Condition"
HTML:
<div class='row' style="background-color: white; vertical-align:top; height: 250px;">
<div class="fifthDiv">
<br />
<article style="float: left; width: 100%; margin-left: 25px; height:250px;">
<section class="tabSection" id="tabmain">
<h2 class="large" style="font-size: 12px;">
Pavement Section Grid
</h2>
<p><div id="table_div_Main"></div></p>
</section>
#foreach (var layer in lstLayers)
{
if (layer != "Pavement Section" && layer != "Cores" && layer != "Inventory")
{
<section id="#("tab" + layer.Replace(" ", ""))" class="tabSection">
<h2 class="medium" style="font-size: 12px;">#layer</h2>
<p><div id="#("table_div_" + layer.Replace(" ", ""))"></div></p>
</section>
}
}
</article>
</div>
</div>
JAVASCRIPT:
function drawSectionData(data) {
return drawMe(data, 'Pavement Section Data', 'table_div_Main');
};
function drawTrafficData(data) {
return drawMe(data, 'Traffic Data', 'table_div_Traffic');
};
function drawConditionData(data) {
return drawMe(data, 'Condition Data', 'table_div_Condition');
};
//what i got so far on the javascript
$(".tabSection").children("h2").on('click', function() { console.log(this.closest("section")); })
The best way to implement tabs in your scenatio is to use jQuery Tabs - very easy and almost no additional coding required, and as added benfit it is free
Based on the assumption that:
You want to hide only the content that sits within the p of each
section and not hide the whole section itself because that would
mean that your click-able h2 will also become invisible.
You have removed div from within your section and are only using p
because inline elements do not allow to contain a block (in your
case, a div) element inside it. [Link], [Link] & [Link].
Your JavaScript code then may look like this:
var tabSections=$('.tabSection'); // select all .tabSection elements
tabSections.not('#tabmain').find('p').hide(); // hide all p elements found within tabSections stored above excluding #tabmain
tabSections.find('h2').on('click',function(){ // assign clicks to all h2 elements found within tabSections
tabSections.find('p').hide(); // hide all p elements found within tabSections
$(this).siblings('p').show(); // show the p element which is a sibling to the clicked h2 element
});
Snippet:
var tabSections=$('.tabSection');
tabSections.not('#tabmain').find('p').hide();
tabSections.find('h2').on('click',function(){
tabSections.find('p').hide();
$(this).siblings('p').show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<div class='row' style="background-color: white; vertical-align:top; height: 250px;">
<div class="fifthDiv">
<br />
<article style="float: left; width: 100%; margin-left: 25px; height:250px;">
<section class="tabSection" id="tabmain">
<h2 class="large" style="font-size: 12px;">
Main
</h2>
<p id="table_div_Main">Pavement Data</p>
</section>
<section class="tabSection" id="tabTraffic">
<h2 class="medium" style="font-size: 12px;">
Traffic
</h2>
<p id="table_div_Traffic">Traffic Data</p>
</section>
<section class="tabSection" id="tabCondition">
<h2 class="medium" style="font-size: 12px;">
Condition
</h2>
<p id="table_div_Condition">Condition Data</p>
</section>
</article>
</div>
</div>
Hope this helps.

Categories