Grouping dynamically created elements - javascript

Below is my function to create and remove text boxes dynamically, however I am looking for a method by which I can group these items into one text box (preferably through the use of a button located below the text boxes or something..). The jist is that I've four columns, each with these functions to add and remove the text boxes, therefore I also wondered if that after grouping the text boxes would the undo function now be useless? Apologies for my lack of knowledge in this area, and thank you in advance for your help
function addText(e) {
let week = e.target.closest('.week'),
area = week ? week.querySelector('textarea') : null,
text = area ? area.value : '';
if (text.length) {
let item = document.createElement('p');
item.innerText = text;
week.appendChild(item);
area.value = '';
}
}
function removeText(e) {
let week = e.target.closest('.week'),
item = week ? week.querySelector('p:last-of-type') : null;
if (item)
item.remove()
}
document.body.addEventListener('click', event => {
if (event.target.closest('[add-text]'))
addText(event);
if (event.target.closest('[remove-text]'))
removeText(event);
})
<div id="planner">
<div class="week week1">
<div class="add">
<h1>Weeks</h1>
<textarea></textarea>
<button type="button" add-text>Add text</button>
<button type="button" remove-text>Undo</button>
</div>
</div>
<div class="week week2">
<div class="add">
<h1>Topics</h1>
<textarea></textarea>
<button type="button" add-text>Add text</button>
<button type="button" remove-text>Undo</button>
</div>
</div>

Related

How can I assign the var to the innerHTML of individual buttons when the buttons are created through a for loop?

Using Django, my buttons are created using a for loop and assigned values based on model values.
Based on which button is click, I want to update the "new_note_header" with the innerHTML of the button.
I have created the following JavaScript, which works but only when the first button clicked.
<script>
function ProjectSelect () {
var x = document.querySelector('button').innerHTML;
document.getElementById('new_note_header').innerHTML = x;
}
document.addEventListener('DOMContentLoaded', function () {
document.querySelector('button').onclick = ProjectSelect;
});
</script>
<div class = project_container>
{% for project in projects %}
<button class = individual_project_container>
{{ project }}
</button>
{% endfor %}
</div>
<div class = note_header_container>
<div class = new_note_header, id = new_note_header>
New Note
</div>
</div>
I would be grateful for any help in adapting the JavaScript so it works for all buttons clicked.
querySelector will take the FIRST element that satisfies the selector
You could use querySelectorAll and assign a click event handler to each, but I recommend using delegation:
document.addEventListener('DOMContentLoaded', function() {
const nnHead = document.getElementById('new_note_header');
document.getElementById("project_container").addEventListener("click", e => {
const tgt = e.target.closest("button");
if (!tgt.matches(".individual_project_container")) return; // not a button
nnHead.textContent = tgt.textContent.trim();
});
});
<div class="project_container" id="project_container">
<button class="individual_project_container">Project 1</button>
<button class="individual_project_container">Project 2</button>
<button class="individual_project_container">Project 3</button>
</div>
<div class="note_header_container">
<div class="new_note_header" id="new_note_header">
New Note
</div>
</div>

Select a button by its value and click on it

How can I select a button based on its value and click on it (in Javascript)?
I already found it in JQuery:
$('input [type = button] [value = my task]');
My HTML Code for the Button is :
<button type="submit" value="My Task" id="button5b9f66b97cf47" class="green ">
<div class="button-container addHoverClick">
<div class="button-background">
<div class="buttonStart">
<div class="buttonEnd">
<div class="buttonMiddle"></div>
</div>
</div>
</div>
<div class="button-content">Lancer le pillage</div>
</div>
<script type="text/javascript" id="button5b9f66b97cf47_script">
jQuery(function() {
jQuery('button#button5b9f66b97cf47').click(function () {
jQuery(window).trigger('buttonClicked', [this, {"type":"submit","value":"My Task","name":"","id":"button5b9f66b97cf47","class":"green ","title":"","confirm":"","onclick":""}]);
});
});
</script>
What is the equivalent in JS and how may i click on it
(probably like this: buttonSelected.click(); ) .
And how do i run the javascript of the button clicked ?
Use querySelector to select it. Then click()
Your HTML has a button and not an input element so I changed the selector to match the HTML.
let button = document.querySelector('button[value="my task"]');
button.click();
<button type="submit" value="my task" id="button5b9f54e9ec4ad" class="green " onclick="alert('clicked')">
<div class="button-container addHoverClick">
<div class="button-background">
<div class="buttonStart">
<div class="buttonEnd">
<div class="buttonMiddle"></div>
</div>
</div>
</div>
<div class="button-content">Launch</div>
</div>
</button>
Otherwise, use this selector:
document.querySelector('input[type="button"][value="my task"]')
Note that if you have multiple buttons with the same value you'll need to use querySelectorAll and you'll get a list of all the buttons.
Then you can loop over them and click() them all.
Edit - new snippet after question edit
jQuery(function() {
jQuery('button#button5b9f66b97cf47').click(function() {alert('success')});
document.querySelector('button[value="My Task"]').click();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="submit" value="My Task" id="button5b9f66b97cf47" class="green ">
<div class="button-container addHoverClick">
<div class="button-background">
<div class="buttonStart">
<div class="buttonEnd">
<div class="buttonMiddle"></div>
</div>
</div>
</div>
<div class="button-content">Lancer le pillage</div>
</div>
you can try:
var elements = document.querySelectorAll("input[type = button][value=something]");
note that querySelectorAll returns array so to get the element you should use indexing to index the first element of the returned array and then to click:
elements[0].click()
and to add a event listener u can do:
elements[0].addEventListener('click', function(event){
event.preventDefault()
//do anything after button is clicked
})
and don't forget to add onclick attribute to your button element in html to call the equivalent function in your javascript code with event object
I am not recommended this way because of excess your coding but as you mentioned, below are the equivalent way.
$(document).ready(function() {
var selectedbuttonValue = "2"; //change value here to find that button
var buttonList = document.getElementsByClassName("btn")
for (i = 0; i < buttonList.length; i++) {
var currentButtonValue = buttonList[i];
if (selectedbuttonValue == currentButtonValue.value) {
currentButtonValue.click();
}
}
});
function callMe(valuee) {
alert(valuee);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<input type="button" class="btn" value="1" onclick="callMe(1)" />
<input type="button" class="btn" value="2" onclick="callMe(2)" />
<input type="button" class="btn" value="3" onclick="callMe(3)" />
Using JavaScripts querySelector in similiar manner works in this case
document.querySelector('input[type="button"][value="my task" i]')
EDIT
You might save your selection in variable and attach eventListener to it. This would work as you desire.
Notice event.preventDefault() -function, if this would be part of form it would example prevent default from send action and you should trigger sending form manually. event-variable itselfs contains object about your click-event
var button = document.querySelector('input[type="button"][value="my task" i]')
button.addEventListener('click', function(event){
event.preventDefault() // Example if you want to prevent button default behaviour
// RUN YOUR CODE =>
console.log(123)
})

Script tag in ng repeat

I'm trying to set a an elements that are intially hidden but the script tag inside my ng-repeat is only executing once.
<h2 class="primary-header"> Get Settings </h2>
<div ng-repeat='feature in features'>
<p></p>
<button type="button" class="btn btn-default"
ng-click='genericGet(feature.func)'>
{{feature.tag}}
</button>
<div ng-hide={{feature.hide}}>
<pre>
{{feature.status | json}}
</pre>
</div>
</div>
$scope.features =[];
$scope.features[0] = {};
$scope.features[0].tag = 'pop';
$scope.features[0].hide = true;
$scope.features[0].status = '';
$scope.features[0].func = 0;
$scope.features[0].url = 'pop';
$scope.genericGet = function(number){
$scope.features[number].hide = false;
}

How to dynamically append templates to a page in Angular

So the situation is as follows:
I have an input bar where a user can search up a business name or add a person's name (and button to select either choice). Upon hitting enter I want to append a unique instance of a template (with the information entered by the user added). I have 2 templates I've created depending of if the user is searching for a business or a person.
One approach I've thought about is creating an object with the data and adding it with ng-repeat, however I can't seem to get the data loaded, and even then don't know how I can store reference to a template in my collection.
The other idea I've come across is adding a custom directive. But even then I've yet to see an example where someone keeps appending a new instance of a template with different data.
Here is the code so far:
payments.js:
angular.module('payment-App.payments',['ngAutocomplete'])
.controller('paymentController', function($scope, $templateRequest/*, $cookieStore*/) {
$scope.businessID;
$scope.address;
$scope.isBusiness = false;
$scope.payees = [];
$scope.newPayee = function () {
this.businessID = $scope.businessID;
this.address = $scope.address;
}
$scope.submit = function () {
var text = document.getElementById("businessID").value.split(",");
$scope.businessID = text[0];
$scope.address = text.slice(1).join("");
$scope.newPayee();
}
$scope.addPayee = function () {
$scope.submit();
$scope.payees.push(new $scope.newPayee());
console.log($scope.payees);
}
$scope.selectBusiness = function () {
//turns on autocomplete;
$scope.isBusiness = true;
}
$scope.selectPerson = function () {
//turns off autocomplete
$scope.isBusiness = false;
}
$scope.fillAddress = function () {
// body...
}
})
.directive("topbar", function(){
return {
restrict: "A",
templateUrl: 'templates/businessTemplate.html',
replace: true,
transclude: false,
scope: {
businessID: '=topbar'
}
}
})
payments.html
<h1>Payments</h1>
<section ng-controller="paymentController">
<div>
<div class="ui center aligned grid">
<div class="ui buttons">
<button class="ui button" ng-click="selectBusiness()">Business</button>
<button class="ui button arrow" ng-click="selectPerson()">Person</button>
</div>
<div class="ui input" ng-keypress="submit()">
<input id="businessID" type="text" ng-autocomplete ng-model="autocomplete">
</div>
<div class="submit">
<button class="ui button" id="submit" ng-click="addPayee()">
<i class="arrow right icon"></i>
</button>
</div>
</div>
<div class="search"></div>
<div class="payments" ng-controller="paymentController">
<li ng-repeat="newPayee in payees">{{payees}}</li>
</div>
<!-- <topbar></topbar> -->
</div>
(example template)
businessTemplate.html:
<div class="Business">
<div class="BusinessName" id="name">{{businessID}}</div>
<div class="Address" id="address">{{address}}</div>
<button class="ui icon button" id="hoverbox">
<i class="dollar icon"></i>
</button>
</div>
I ended up using a workaround with ng-repeat here. Still curious about the original question though.

Is JQuery breaking my functionality?

I am making an app, the user can either select an item or use their camera to get the qr code which translates into an item's ID.
The problem is that I think some JQuery is messing with my scope from working properly.
I have to get the QR code by listening to an innerHtml change, once it changes (DOMSubtreeModified) the following occurs.
var index = 0;
$('#result').one('DOMSubtreeModified', function(e) {
var code = "";
if (e.target.innerHTML.length > 0) {
code = e.target.innerHTML;
$scope.ToRun(code);
}
});
$scope.ToRun = function(code) {
for (i = 0; i < $scope.plantList.length; i++) {
if ($scope.plantList[i].plantcode == code) {
index = i;
break;
}
}
$scope.currentPlant = $scope.plantList[index];
$scope.plantDetails = false;
$scope.searchDetails = true;
}
For some reason the following does not have any effect on my ng-classes. As when an item is selected I hide the input dialogs, and show the result one.
$scope.plantDetails = false;
$scope.searchDetails = true;
But when a user selects the item manually it works just perfectly. (the items have an ng-click on it)
$scope.viewPlant = function(plant) {
$scope.currentPlant = plant
$scope.plantDetails = false;
$scope.searchDetails = true;
};
And the above works fine, with the ng-click. So why won't my new function that listens for an innerHtml change work?
HTML snippet
<div ng-class="{ 'hidden': searchDetails }">
<!-- CHOOSE INPUT TYPE -->
<div class="form-group" style="margin-bottom:0px">
<div class="btn-group btn-group-justified">
<div class="btn-group">
<button type="button" class="btn btn-default" ng-click="digits = false; qr = true">Plant Code</button>
</div>
<div class="btn-group">
<button type="button" class="btn btn-default" ng-click="digits = true; qr = false">QR Code</button>
</div>
</div>
</div>
<br />
<!-- QR CODE INPUT -->
<div ng-class="{ 'hidden': qr }">
<img id="blah" src="./images/placeholder.png" />
<span class="btn btn-default btn-file">
<i class="glyphicon glyphicon-camera"></i>
<input type="file" onchange="readURL(this);handleFiles(this.files)">
</span>
<div id="result">xxxxxx</div>
<canvas id="qr-canvas" width="800" height="600"></canvas>
</div>
<!-- MANUAL SELECTION INPUT -->
<div ng-class="{ 'hidden': digits }">
<input ng-model="search.$" style="width:100%; font-size:30px; text-align:center" placeholder="Plant Code" />
<div style="overflow: auto; max-height:250px">
<table class="table table-striped" style="background-color:lightblue">
<tr ng-repeat="plant in plantList | filter:search" ng-click="viewPlant(plant)" style="cursor:pointer">
<th>{{plant.name}}</th>
<th>{{plant.plantcode}}</th>
</tr>
</table>
</div>
</div>
<div>
</div>
</div>
<div ng-class="{ 'hidden': plantDetails }">
// results - this should appear when one of the above is entered.
// works for manual selection, but not qr code
</div>
Just confused on why my QR input will not fire off the change-class options to hide the searchDetails div and show the plantDetails div
EDIT: Doing a small test, it seems that my class variables are indeed not updating at all. I just put the values at the bottom of my page and they do not update when hitting the block of:
$scope.plantDetails = false;
$scope.searchDetails = true;
You need to let Angular know about the change. Add this at the end of your method and let me know if it works.
$scope.$apply();

Categories

Resources