I am trying to create a dynamic form with Javascript, where it is possible to add more fields. And when the user starts typing in the added fields then suggestions should show based on a list. Suggested inputs based on written input
The added fields should look just like the one shown in 1. The Search function works by using querySelector to take the new field created. However, i receive a type error saying: TypeError: Cannot read properties of null.
The function works without newSearch(i), but i want to have this suggestion box appearing when adding more fields.
Source Code:
sites.html
<div class="sites-container">
<form class="sites-form" method = "POST" id="myForm" name="myForm">
<div class="wrapper">
<div id="Site-options">
<h1 class="sites-add-header"> Create a String </h1>
<p class="sites-add-text"> Choose Modules at String </p>
<div class="wrapper2">
<div class="search-input2">
<a href="" target="_blank" hidden></a>
<input type="text" placeholder="Type to search.." name="PV-modules">
<div class="autocom-box2">
</div>
<div class="icon2"><i class="fas fa-search"></i></div>
</div>
</div>
</div>
<div class="controls">
<i class="fa fa-plus"></i>Add Another String
<i class="fa fa-plus"></i>Remove Site
</div>
</div>
<button type="submit" class="sites-add-site button">Add Site</button>
</form>
</div>
<script>
let suggestions2 = {{ modules | safe}} ;
</script>
<script src="{{ url_for('static', filename='add-site.js') }}"></script>>
add-site.js
var site_options = document.getElementById('Site-options');
var add_more_fields = document.getElementById('add_more_fields');
var remove_fields = document.getElementById('remove_fields');
var count = 1;
add_more_fields.onclick = function(){
var i = count++;
var _div = document.createElement('div');
_div.setAttribute('id','new-div'+i);
_div.innerHTML = '<p class="sites-add-text"> Choose Modules at Site </p>' +
'<div class="wrapper2">' +
'<div class="search-input2" id="new-search-input' + i + ' ">' +
'<a href="" target="_blank" hidden></a>' +
'<input type="text" placeholder="Type to search.." name="PV-modules">' +
'<div class="autocom-box2 id="new-autocom-box' + i + '">' +
'</div>'+
'<div class="icon2" id="new-icon' + i + '><i class="fas fa-search"></i></div>'+
'</div>'+
'</div>';
newSearch(i);
site_options.appendChild(_div);
};
remove_fields.onclick = function(){
var elem = document.getElementById("new-div");
elem.parentNode.removeChild(elem);
}
function newSearch(i) {
// getting all required elements
var searchWrapper2 = document.querySelector("#new-search-input" + i);
var inputBox2 = searchWrapper2.querySelector("input"); // <- Here i get TypeError
var suggBox2 = searchWrapper2.querySelector(".autocom-box2");
var icon2 = searchWrapper2.querySelector(".icon2");
let linkTag2 = searchWrapper2.querySelector("a");
let webLink2;
// if user press any key and release
inputBox2.onkeyup = (e2)=>{
let userData2 = e2.target.value; //user enetered data
let emptyArray2 = [];
if(userData2){
icon2.onclick = ()=>{
webLink2 = `https://www.google.com/search?q=${userData2}`;
linkTag2.setAttribute("href", webLink2);
linkTag2.click();
}
emptyArray2 = suggestions2.filter((data2)=>{
//filtering array value and user characters to lowercase and return only those words which are start with user enetered chars
return data2.toLocaleLowerCase().startsWith(userData2.toLocaleLowerCase());
});
emptyArray2 = emptyArray2.map((data2)=>{
// passing return data inside li tag
return data2 = `<li>${data2}</li>`;
});
searchWrapper2.classList.add("active"); //show autocomplete box
showSuggestions2(emptyArray2);
let allList2 = suggBox2.querySelectorAll("li");
for (let i = 0; i < allList2.length; i++) {
//adding onclick attribute in all li tag
allList2[i].setAttribute("onclick", "select2(this)");
}
}else{
searchWrapper2.classList.remove("active"); //hide autocomplete box
}
}
function select2(element){
let selectData2 = element.textContent;
inputBox2.value = selectData2;
icon2.onclick = ()=>{
webLink2 = `https://www.google.com/search?q=${selectData2}`;
linkTag2.setAttribute("href", webLink2);
linkTag2.click();
}
searchWrapper2.classList.remove("active");
}
function showSuggestions2(list){
let listData2;
if(!list.length){
userValue2 = inputBox2.value;
listData2 = `<li>${userValue2}</li>`;
}else{
listData2 = list.join('');
}
suggBox2.innerHTML = listData2;
}
}
you need to call newSearch after adding the element
site_options.appendChild(_div);
newSearch(i);
and you need to remove extra space in the innerHTML, which is why id attribute doesn't get found, breaking all the code:
'<div class="search-input2" id="new-search-input' + i + '">' +
swap these two lines it should work fine . searchWrapper2 is null in your case.
newSearch(i); site_options.appendChild(_div);
site_options.appendChild(_div); newSearch(i);
Related
I have posts, and I have added an edit button if the user logged in is the owner of the post,
How can I edit the content on my posts when I click on the edit button?
My posts are classList which has Childs (Divs) of the content.
I didn't learn frameworks yet so I'm trying to do this with Pure JavaScript.
index.js
function build_post(post){
// create new div for each thing that needs to be shown
current_logged_in_user = document.querySelector('#user_detail').value;
const element = document.createElement('div');
const post_username = document.createElement('div');
const post_description = document.createElement('div');
const post_date_added = document.createElement('div');
const post_likes = document.createElement('div');
// add the text for each div
post_username.innerHTML = 'Username: ' + post.poster;
post_description.innerHTML = 'Content: ' + post.description;
post_date_added.innerHTML = 'Date: ' + post.date_added;
post_likes.innerHTML = 'Likes: ' + post.likes;
// append all divs to display-post
element.appendChild(post_username);
element.appendChild(post_description);
element.appendChild(post_date_added);
element.appendChild(post_likes);
element.classList.add('element');
console.log(element);
post_username.addEventListener('click', function() {
load_user_info(post.poster);
load_user_posts(post.poster);
});
if (current_logged_in_user == post.poster){
const edit_button = document.createElement('button');
edit_button.innerHTML += 'Edit'
element.appendChild(edit_button);
edit_button.addEventListener('click', function() {
edit_element(element);
});
}
document.querySelector('#show-posts').appendChild(element)
}
function edit_element(element_to_edit){
}
HTML if relevant
<div id="page-view"></div>
<div id="load-profile">
<div id="user-profile">
</div>
</div>
<div id="posts-view">
<h2>All Posts</h2>
<form id="post-form">
<!-- {% csrf_token %}-->
<h4>New Post</h4>
<textarea class="form-control" id="post-body" placeholder="Post"></textarea>
<input class="btn btn-primary" type="submit" value="Post">
</form>
</div>
<div id ="show-posts"></div>
You could change the Text-field to an Input with the value of the Text of the Post if the user is the owner of the post.
Where do you save the values? mysql?
I have a text box. When I click on the listed data (Data is getting from table). I need to set response table row ID in text box.
I need data to set like this "|13456|1400|14567|" in the text box.
Please help me to set id in text box. Currently I can set only one ID.
Please find the attached image
JS
$.post("getDetailsAjax.php", {keywords: keywords}, function(data){
$.each(data, function() {
var leftboxid = this.id;
var producer = this.producer;
var model = this.model;
var typ = this.typ;
var body = this.body;
var date_from = this.date_from;
var date_to = this.date_to;
var power = this.power;
var engine_code = this.engine_code;
var fuel = this.fuel;
var ccm = this.ccm;
var cylinders = this.cylinders;
$('#search-result').append('<div class="leftboxid_'+leftboxid+'" data-leftbox="' +leftboxid+ '"><a href="#" class="list-group-item"><p class="list-group-item-text">' +producer+ ' '+model+' '+typ+' ('+body+')</p><p class="list-group-item-text">' +date_from+ ' to ' +date_to+ '</p> <p class="list-group-item-text">' +power+' ps .' +engine_code+' . ' +fuel+ ' . '+ccm+' ccm . ' +cylinders+ ' cyl</p></div>');
/* right box */
$(".leftboxid_"+leftboxid).on("click", function(){
var setID = $(this).attr("data-leftbox");
$(".append-left-id").attr("value", setID);
});
});
}, "json");
Textbox
<div class="col-xs-4">
<input type="text" class="form-control append-left-id" placeholder="Result Field">
</div>
I think you want this
instead of this code:
$(".leftboxid_"+leftboxid).on("click", function(){
var setID = $(this).attr("data-leftbox");
$(".append-left-id").attr("value", setID);
});
use this :
$(".leftboxid_"+leftboxid).on("click", function(){
var setID = $(this).attr("data-leftbox");
$(".append-left-id").val($(".append-left-id").val()+"|"+setID);
});
You can append like so:
.....
var setID = $(this).attr("data-leftbox");
var val = $(".append-left-id").val();
$(".append-left-id").val(val+"|"+setID );
....
I am trying to write a small script that takes in two value. One is a name and the other is a password. Here is the code:
<textarea id="addName">Add a name</textarea>
<textarea id="addPass">Add a hashed password</textarea>
<button id="submit">
Submit user
</button>
<ul>
<li>Name: Nicolas
<br>Password (hashed): aslkdjf1231lk1jlkj5l4k5j64
</li>
</ul>
<script>
document.getElementById("submit").onclick = function addUser() {
var NAME = document.getElementById("addName");
var PASS = document.getElementById("addPass");
var unOrd = document.getElementById("ul");
var newLi = document.createElement("li");
unOrd.appendChild("newLi");
var newText = document.createTextNode("Name: " + NAME.value + " Password (hashed): " + PASS.value);
newLi.appendChild("newText");
};
</script>
I thought that, by putting the JS at the end of the HTML, it would be executed after the page is loaded and that it would solve the problem, but it is still returning:
"Cannot read property 'appendChild' of null".
ul is not id but tag name of your list element. You can get it like this:
var unOrd = document.getElementsByTagName("ul")[0];
You're adding a string for appendChild instead of actual element and you don't have element with id ul try:
<textarea id="addName">Add a name</textarea>
<textarea id="addPass">Add a hashed password</textarea>
<button id="submit">
Submit user
</button>
<ul id="someId">
<li>Name: Nicolas
<br>Password (hashed): aslkdjf1231lk1jlkj5l4k5j64
</li>
</ul>
<script>
document.getElementById("submit").onclick = function addUser() {
var NAME = document.getElementById("addName");
var PASS = document.getElementById("addPass");
var unOrd = document.getElementById("someId");
var newLi = document.createElement("li");
unOrd.appendChild(newLi);
var newText = document.createTextNode("Name: " + NAME.value + " Password (hashed): " + PASS.value);
newLi.appendChild(newText);
};
</script>
I am working on a site that is basically a list of items separated by categories. The user can add a category entering the name into the following form:
<form onsubmit="append_div(); add_cat(); return false;">
<input id="new_category"/>
<input type="submit" value="Add" id="add_btn_category" />
</form>
Two functions are called, append_div(), which dinamically creates a new child where the new category will be inserted, and add_cat(), which gets JSON from the server and should set the new content in the indicated selector.
function append_div(){
var nodelist = document.getElementsByTagName("h3").length;
var node = document.createElement("h3");
node.id = "new_space" + nodelist;
var new_sp = "'#new_space" + nodelist + "'"; // to be used in selector
node.className= "categories";
document.getElementById("append").appendChild(node);
}
function add_cat() {
var url = 'add_category.php?category=' + $('#new_category').val();
$.getJSON(url, function(data) {
$(new_sp).html(data[0].category);
});
}
Everything works except $(new_sp).html(data[0].category);. This is the code generated entering three different categories: aa, bb and cc.
`<div id="append">
<h3 id="new_space0" class="categories"></h3>
<h3 id="new_space1" class="categories"></h3>
<h3 id="new_space2" class="categories"></h3>
</div>`
But it should be:
`<div id="append">
<h3 id="new_space0" class="categories">aa</h3>
<h3 id="new_space1" class="categories">bb</h3>
<h3 id="new_space2" class="categories">cc</h3>
</div>`
Using the variable new_sp as a selector in $(new_sp).html(data[0].category); doesn't seem to work, but after checking posts with similar problems and trying many of the proposed solutions I could not solve the it. Any idea?
var new_sp = "'#new_space" + nodelist + "'"; // to be used in selector
should be
var new_sp = "#" + node.id; // to be used in selector
and the variable new_sp should defined outside the function append_div or it should be global to access in the function add_cat
Something like
var new_sp = "";
function append_div(){
var nodelist = document.getElementsByTagName("h3").length;
var node = document.createElement("h3");
node.id = "new_space" + nodelist;
new_sp = "#" + node.id; // to be used in selector
node.className= "categories";
document.getElementById("append").appendChild(node);
}
function add_cat() {
var url = 'add_category.php?category=' + $('#new_category').val();
$.getJSON(url, function(data) {
$(new_sp).html(data[0].category);
});
}
hey guys i have got this far with a chat system but now i am stuck at this point.
the js script will look for a element called chat and if it is not found it will put it in with all of the other elements stated here
<div class='chat' id='chat'><div class='ch' id='ch'><h2>Chat</h2></div><div class='chatbox'><div class='messages'></div><textarea id='message' class='chatinp' rows='3' cols='27'></textarea><button class='send'>Send</button></div></div>
My problem is how to insert that whole line of code with javascript into the html document.
how would you do this?
My javascript script is you need to see
<script type="text/javascript">
var num = new Number();
num = 0
function chat(){
if(!document.getElementById("chat")){
document.write("<div class='chat' id='chat'><div class='ch' id='ch'><h2>Chat</h2></div><div class='chatbox'><div class='messages'></div><textarea id='message' class='chatinp' rows='3' cols='27'></textarea><button class='send'>Send</button></div></div>")
}
else
{
var obj = document.getElementById("chat").cloneNode(true);
var p = $(".chat");
var offset = p.offset();
num = num + 1;
if (num <15) {
obj.id = obj.id + num;
document.getElementById("ch").id = obj.id;
document.body.appendChild(obj);
document.getElementById("chat").style.left = "700px";
}
}
}
</script>
Don't use document.write (it will overwrite everything in your document), but create div#chat dynamically, something like:
if(!document.getElementById("chat")){
var chatdiv = document.createElement('div');
chatdiv.id = 'chat';
chatdiv.className = 'chat';
chatdiv.innerHTML =
['<div class="ch" id="ch">',
'<h2>Chat</h2></div>',
'<div class="chatbox">',
'<div class="messages"></div>',
'<textarea id="message" class="chatinp" ',
'rows="3" cols="27"></textarea>',
'<button class="send">Send</button></div>'
].join(' ')
document.body.appendChild(chatdiv);
}
[Edit 2022] A more modern approach may be:
document.querySelector(`#chat`) || (_ =>
document.body.insertAdjacentHTML(
`beforeend`, `
<div id="chat">
<div class="ch" id="ch">
<h2>Chat</h2>
</div>
<div class="chatbox">
<div class="messages"></div>
<textarea id="message" class="chatinp" rows="3" cols="27"></textarea>
<br><button class="send">Send</button>
</div>
</div>`)
)();
document.querySelector(`#chat #message`).placeholder = `Type something!`;