Show specific element on buttons click - javascript

I am in a situation that the user is presented with many different buttons.
When any button is clicked, a different form is spawned and a string is injected in the dom to notify the user which form is pressed.
Pseudocode:
<div id="notifier">
<h1 class="text-center">
<> SOMETHING SHOULD GO HERE<>
<script>
$(document).ready(function(){
$("#notifier").hide(); //hide the initial string since no form is pressed at the beginning
$("#editForm1").hide(); //hides form1 since no button is pressed
$("#editForm2").hide(); //hides form2 since no button is pressed
$("#btn_1").click(function(e) {
//SOMETHING SHOULD GO HERE AS WELL
$("#editForm1").show();
When button1 is pressed, form1 is spawned in the dom.
But i also want to inject the string "Form1" inside the div with id="notifier", to let the user know which form is spawned.
How do i do that?

Use the data-* attribute to store the target selector: data-formshow="#form-1"
Use a CSS class to hide your forms: .none { display: none; }
Use jQuery to select your buttons and forms
Use jQuery .addClass() and .removeClass() to manipulate the .none class
Use .not() to exclude specific Elements from a collection:
jQuery($ => {
const $notifier = $('#notifier'); // the <H1>
const $buttons = $('[data-showform]'); // the <button>s
const $forms = $('[id^="form-"]'); // the <form>s
$buttons.on('click', function(ev) {
ev.preventDefault();
const sel = $(this).data('showform'); // Get the selector
const txt = $(this).text(); // Get the text
const $form = $(sel); // Get the form Element
$forms.not($form).addClass('hide'); // Hide other forms
$form.removeClass('hide'); // Show target form
$notifier.text( txt ); // Preview button text into H1
});
});
.hide { display: none; }
<h1 id="notifier">CLICK A BUTTON</h1>
<button type="button" data-showform="#form-1">FORM ONE</button>
<button type="button" data-showform="#form-2">FORM TWO</button>
<form id="form-1" class="hide">I'm form ONE</form>
<form id="form-2" class="hide">I'm form TWO</form>
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>

Related

How to refactor my code so it's not repeating the same thing

I have 3 different buttons on my page, and when you click on one it checks the corresponding radio button.
Currently, I have each button with its own onclick function:
onclick="radioChecked1()"
onclick="radioChecked2()"
onclick="radioChecked2()"
And then there are the functions:
function radioChecked1() {
var package1 = document.querySelector("#package1");
package1.setAttribute("checked", 1);
}
function radioChecked2() {
var package2 = document.querySelector("#package2");
package2.setAttribute("checked", 1);
}
function radioChecked3() {
var package3 = document.querySelector("#package3");
package3.setAttribute("checked", 1);
}
These functions are doing the same thing, the only thing that changes is the number in the id of the input it's selecting.
I'm sure there's a way to simplify this into one function instead of a separate one for each button, I don't know how to do it.
You can refactor this code by simplifying the function and using parameters:
function radioChecked(id) {
var package = document.querySelector(id);
package.setAttribute("checked", 1);
}
Then on your buttons call the function with the corresponding id:
onclick="radioChecked('#package1')" onclick="radioChecked('#package2')" onclick="radioChecked('#package3')"
It depends a little on how your markup is written but if you add data attributes to both buttons and the radio buttons you can take the id from a button when it's clicked, and then find the corresponding id on a radio input.
Here I've wrapped the buttons and radio input in their own containers so that I can use event delegation - adding one listener to a parent container that catches events from its child elements as they bubble up the DOM, rather than attaching listeners to all of the elements.
// Instead of inline JS we cache the containers elements
// and then add one listener to the buttons container
const radios = document.querySelector('.radios');
const btns = document.querySelector('.btns');
btns.addEventListener('click', handleClick);
// If the clicked element is a button
// extract its id from its dataset, look for
// the corresponding radio input, and update the
// `checked` property
function handleClick(e) {
if (e.target.matches('button')) {
const { id } = e.target.dataset;
const radio = radios.querySelector(`[data-id="${id}"]`);
radio.checked = true;
}
}
fieldset { margin-top: 1em; }
<fieldset class="btns">
<legend>Buttons</legend>
<button data-id="radio1" type="button">Button 1</button>
<button data-id="radio2" type="button">Button 2</button>
<button data-id="radio3" type="button">Button 3</button>
</fieldset>
<fieldset class="radios">
<legend>Radio buttons</legend>
<label for="radio1">Radio1
<input data-id="radio1" type="radio" name="radioset">
</label>
<label for="radio2">Radio2
<input data-id="radio2" type="radio" name="radioset">
</label>
<label for="radio3">Radio3
<input data-id="radio3" type="radio" name="radioset">
</label>
</fieldset>
Additional documentation
querySelector
addEventListener
matches
Destructuring assignment

Input value of a cloned div not changing or firing events

I have a mock hidden div that I edit, clone and show to users. In this div is an input for which I set the value attribute using jQuery (tried with probably all methods). After I generate the new div and show it to users, the input does not fire any kind of events (focus, focusout, change) neither does the value of input change in HTML.
What am I missing or doing wrong?
Edit (code): HTML
<div class="item-wrapper" id="mock-item">
<div class="item-img"></div>
<div class="item-primary">
<p class="item-name">Foo Bar</p>
<input type="text" class="set-amount">
</div>
</div>
JS:
$("div.item-wrapper").click((e) => {
let item_id = e.currentTarget.id
let itemDetails = {
item_name: $(`#${item_id} .item.name`).text(),
suggested_amount: $(`#${item_id} #item-amount`).text(),
icon_url: $(`#${item_id} .item.big`).attr("style"),
}
$(".item-img", tmp).attr("style", itemDetails.icon_url)
$("#mock-item .item-name").text(itemDetails.item_name)
$("#mock-item .set-amount")[0].setAttribute("value", itemDetails.suggested_amont)
$("#mock-item").clone().removeAttr("id").appendTo(".item-wrapper").show()
})
Cloning an element removes all the event listeners from it. If you would like to listen for all event listeners on elements with a given selector, you can use jQuery's .on:
$(document).on("click", ".class", function () {
const $this = $(this);
});
You could also set the withDataAndEvents parameter on .clone to true: .clone(true).

How can I trigger an action when an element that has a html data attribute is clicked

How can I trigger an action when an element that has a html data attribute is clicked? I have this element on different places in the same document.
Html element
Sign In
<button href="#" data-trigger="modal" data-target="signUpModal">Sign Up</button>
Javascript
<script>
Let x = getElementByData('data-trigger')
</script>
When the any of the html element is clicked, it will return the object of that element that will include data-target
You can use document.querySelector("[data-attribute]") to get the first element with data-attribute or document.querySelectorAll("[data-attribute]") to get all elements that have data-attribute.
// Get all element that have data-field
const allFields = document.querySelectorAll("[data-field]");
console.log(Array.from(allFields));
// Get just the first element that has data-field=name
const elemName = document.querySelector("[data-field=name]");
console.log(elemName);
<div data-field="name"></div>
<div data-field="company"></div>
UPDATE
Now that you have supplied some code it is easier to understand what you where asking for.
function clickHandle(event) {
event.preventDefault(); // Stop the default action (will stop <a> to go to the link, so that you can open your own dialogue or do whatever you want.
const elem = event.target;
// your code here. You can access the data attributes via the dataset property:
console.log(elem.dataset.target);
}
// Get all elements that have data-trigger=modal, and add the clickHandle to them:
document.querySelectorAll("[data-trigger=modal]").forEach(
(elem) => elem.addEventListener("click", clickHandle)
);
Sign In
<button href="#" data-trigger="modal" data-target="signUpModal">Sign Up</button>

How to select element after it was added to DOM

On my HTML I have buttons list and text input field. Input field is to add extra buttons to my buttons list.
On jQuery I have eventListener when one of these buttons with .choices is clicked console log its value.
It works fine without any errors. But when I add extra button to my list with same class (.choices) new button appears but it doesn't respond to my click.
Any suggestions?
<div class="buttons">
<button id="button0" class="choices">Running</button>
<button id="button1" class="choices">Yoga</button>
<button id="button2" class="choices">Karate</button>
</div>
JS
$("#add-button").click(function(){
var inputValue = $("#add-input").val();
var generatedId = "button" + healthyChoices.length;
healthyChoices.push(inputValue);
$("<button>").attr("id", generatedId).appendTo(".buttons");
$("#" + generatedId).attr("value", inputValue);
$("#" + generatedId).attr("class", "choices");
$("#" + generatedId).text(inputValue);
$("#add-input").val("");
});
$(".choices").click(function(){
var selectedGroup = $(this).val();
console.log(selectedGroup);
});
The .click method does not handle elements dynamically added to the DOM. You should be using the .on method (as indicated by dfsq's comment).
See this SO post: Difference between .on('click') vs .click()

jquery .load() function multiple time

How do i load a test.html multiple time using jQuery.
function loadScreen()
{
$('#result').load('test.html');
}
main.html
<div id='result'></div>
<input type="button" value="click me" onclick="loadScreen()">
test.html
<body>
<p>
testing
</p>
</body>
Current situation
when i click the button click me. it will load once
show on main.html
testing
what i want to do
How can i do it when i click the button twice
it will show
testing
testing
and with different div id
1st time button click show testing <div id="result1">testing</div>
2nd time button click show testing <div id="result2">testing</div>
it will append incremental 1 at id.
load() will replace the content of the target element which is why it's not working as you want.
Try this instead:
function loadScreen() {
var divId = $("#result > div").length + 1;
$('#result').append("<div></div>").attr("id", "result" + divId).load('test.html');
}
Then it's about time you should use $.get(), then create a div via the $(), add in the contents using .html() and .appendTo() the results div.
var result = $('#result'), //cache result box
i = 0;
function loadScreen(){
$.get('test.html',function(data){ //initiate get
$('<div>',{ //create div for return data
id : 'result'+(++i) //add attributes
})
.html(data) //add data
.appendTo(result); //append to result
});
}

Categories

Resources