remove the hidden values and <br> when replacing via .html - javascript

I have a code which allows me to add certain "absentees", along with their ID's through a hidden form, to the absentees list when I click on them. When I click on it again, the "absentee" is removed from the absentees list. However, when I click on it again, the list seems to extend further because of a br
in my code plus the hidden form value doesn't seem to be removed. I need the hidden value removed so that the removed absentee from the list will not be recorded in the database. I need the br
so that the absentee listing will be presentable.
Here's my code: http://jsfiddle.net/gk5pV/8/

I wholeheartedly agree with #charlietfl, just use a block level element. Also, use a single hidden input to track your absentees. Example fiddle, code below:
$(function() {
$("td").click(function() {
var $this = $(this);
var user = $this.attr('id');
var p = $('<p />').attr('user', user).text($this.text());
var absentees = [];
if ($('#absentees').val().length > 0) {
absentees = $('#absentees').val().split(',')
}
if ($(this).hasClass('on')) {
//console.log("Already marked absent");
//remove from collection
$("#collect").children('p[user="' + user + '"]').remove();
absentees.splice(absentees.indexOf(user), 1);
}
else {
//console.log(user);
//add to collection
$("#collect").append(p);
absentees.push(user);
}
$this.toggleClass('on');
$('#absentees').val(absentees.join(','));
});
$("#clicky").click(function() {
$('td').removeClass('on');
$("#collect").empty();
$('#absentees').val('');
});
});​

Solution is fairly simple. Wrap the text you want to append and hidden input in a block level element ( div, p, li etc) and you won't need a <br tag. WHen you remove the absentee from list you remove the block element and the input will be part of it so it will no longer exist. If you give the new block level element a class name you can simply attach your event handler to the class

Related

How can I Append the Id attribute Selector or Store the Id in Jquery variable and use that variable as selector?

I want to perform show/hide operation on textarea element on clicking the replay button using id as selector in jquery but my id is in the form id = "textarea"+dat.description_id i.e dat.description_id is the value that i have concate. and also I have put this element in loop so there are many textarea field on the page.
-if(data.length > 0)
each dat in data
form(action="/update/"+dat.description_id, method="post")
tr
td #{dat.description_id}
td #{dat.applied_date}
td #{dat.fullname}
td
td #{dat.complaint_name}
td #{dat.complaint}
td
div(style="display:flex")
-if(dat.status == 'Done')
p #{dat.replay}
-else
textarea(name="replay" id="textarea"+dat.description_id class="form-control" cols="30", rows="2")
button(type="submit" id="replay-btn"+dat.description_id class="btn btn-primary m-2" onclick="myfun()") Reply
By performing the Below Jquery Code there is no event occuring on page. According to me if I we can store the Id in the jquery variable we can do that thing but the question is how to use that variable as the selector OR ELSE how to append that dat.description_id in $("textarea").
PLESE tell ME the SOLUTION for this PRoblem......
script.
$(document).ready(function(){
$("textarea").hide();
$('#replay-btn').click(function(){
$("#textarea").toggle();
});
$("#textarea").keyup(function(){
var len = $(this).val().length;
if(len > 0)
{
$("#replay-btn").attr('type','submit');
}
else{
$("#replay-btn").attr('type','button');
}
})
});
One way to achieve this would be to create a data-controls attribute on the button element that matches the id of the corresponding textarea element. Then you could add a js-reply-button class to the button elements to bind the jQuery events.
I would recommend rewriting your Pug else statement as follows:
else
textarea.js-reply-textarea.form-control(id=`textarea_${dat.description_id}`, name='reply', cols='30', rows='2')
button.js-reply-button.btn.btn-primary.m-2(data-controls=`textarea_${dat.description_id}`, type='submit') Reply
With this structure, your jQuery to show/hide each text area when someone clicks the reply button could look like this:
$(document).ready(function() {
// hide the textarea elements
$('.js-reply-textarea').hide();
// when a user clicks the reply button
$('.js-reply-button').click(function() {
// get the value of the button's data-controls attribute
let textareaId = $(this).attr('data-controls');
// use it to target and toggle the right textarea element
$('#' + textareaId).toggle();
});
});

jQuery slideDown not working on element with dynamically assigned id

EDIT: I cleaned up the code a bit and narrowed down the problem.
So I'm working on a Wordpress site, and I'm trying to incorporate drop-downs into my menu on mobile, which means I have to use jQuery to assign classes and id's to my already existing elements. I have this code that already works on premade HTML, but fails on dynamically created id's.
Here is the code:
...
var menuCount = 0;
var contentCount = 0;
//find the mobile menu items
var submenus = $('[title="submenu"]');
if (submenus.length && submenus.parent('.fusion-mobile-nav-item')) {
console.log(submenus);
submenus.addClass('dropdown-title').append('<i id="dropdown-angle" class="fa fa-angle-down" aria-hidden="true"></i>');
submenus.each(function() {
$(this).attr("href", "#m" + menuCount++);
})
var content = submenus.parent().find('ul.sub-menu');
content.addClass('dropdown-content');
content.each(function() {
$(this).attr("id", "m" + contentCount++);
})
}
$(document).on('click', '.dropdown-title', function(e) {
var currentAttrValue = $(this).attr('href');
if ($(e.target).is('.d-active') || $(e.target).parent('.dropdown-title').is('.d-active')) {
$(this).removeClass('d-active');
$(currentAttrValue).slideUp(300).removeClass('d-open');
} else {
$('.dropdown-title').removeClass('d-active');
$('.dropdown-content').slideUp(300).removeClass('d-open');
$(this).addClass('d-active');
console.log($(currentAttrValue));
//THIS LINE FAILS
$(currentAttrValue).slideDown(300).addClass('d-open');
}
e.preventDefault();
});
I've registered the elements with the class dropdown-title using $(document).on(...) but I can't figure out what I need to do to register the elements with the custom ID's. I've tried putting the event callback inside the .each functions, I've tried making custom events to trigger, but none of them will get the 2nd to last line of code to trigger. There's no errors in the console, and when I console log the selector I get this:
[ul#m0.sub-menu.dropdown-content, context: document, selector: "#m0"]
0
:
ul#m0.sub-menu.dropdown-content
context
:
document
length
:
1
selector
:
"#m0"
proto
:
Object[0]
So jQuery knows the element is there, I just can't figure out how to register it...or maybe it's something I'm not thinking of, I don't know.
If you are creating your elements dynamically, you should be assigning the .on 'click' after creating those elements. Just declare the 'on click' callback code you posted after adding the ids and classes instead of when the page loads, so it gets attached to the elements with .dropdown-title class.
Check this jsFiddle: https://jsfiddle.net/6zayouxc/
EDIT: Your edited JS code works... There also might be some problem with your HTML or CSS, are you hiding your submenus? Make sure you are not making them transparent.
You're trying to call a function for a attribute, instead of the element. You probably want $(this).slideDown(300).addClass('d-active'); (also then you don't need $(this).addClass('d-active'); before)
Inside submenus.each loop add your callback listener.
As you are adding the class dropdown-title dynamically, it was not available at dom loading time, that is why event listener was not attached with those elemnts.
var menuCount = 0;
var contentCount = 0;
//find the mobile menu items
var submenus = $('[title="submenu"]');
if (submenus.length && submenus.parent('.fusion-mobile-nav-item')) {
console.log(submenus);
submenus.addClass('dropdown-title').append('<i id="dropdown-angle" class="fa fa-angle-down" aria-hidden="true"></i>');
submenus.each(function() {
$(this).attr("href", "#m" + menuCount++);
// add callback here
$(this).click( function(e) {
var currentAttrValue = $(this).attr('href');
if ($(e.target).is('.d-active') || $(e.target).parent('.dropdown-title').is('.d-active')) {
$(this).removeClass('d-active');
$(currentAttrValue).slideUp(300).removeClass('d-open');
} else {
$('.dropdown-title').removeClass('d-active');
$('.dropdown-content').slideUp(300).removeClass('d-open');
$(this).addClass('d-active');
console.log($(currentAttrValue));
$(currentAttrValue).slideDown(300).addClass('d-active');
}
e.preventDefault();
});
})
var content = submenus.parent().find('ul.sub-menu');
content.addClass('dropdown-content');
content.each(function() {
$(this).attr("id", "m" + contentCount++);
})
}
Turns out my problem is that jQuery is adding to both the mobile menu and the desktop menu, where the desktop menu is being loaded first when I search for that ID that's the one that jQuery finds. So it turns out I was completely wrong about my suspicions.

jQuery: focusout triggering before onclick for Ajax suggestion

I have a webpage I'm building where I need to be able to select 1-9 members via a dropdown, which then provides that many input fields to enter their name. Each name field has a "suggestion" div below it where an ajax-fed member list is populated. Each item in that list has an "onclick='setMember(a, b, c)'" field associated with it. Once the input field loses focus we then validate (using ajax) that the input username returns exactly 1 database entry and set the field to that entry's text and an associated hidden memberId field to that one entry's id.
The problem is: when I click on the member name in the suggestion box the lose focus triggers and it attempts to validate a name which has multiple matches, thereby clearing it out. I do want it to clear on invalid, but I don't want it to clear before the onclick of the suggestion box name.
Example:
In the example above Paul Smith would populate fine if there was only one name in the suggestion list when it lost focus, but if I tried clicking on Raphael's name in the suggestion area (that is: clicking the grey div) it would wipe out the input field first.
Here is the javascript, trimmed for brevity:
function memberList() {
var count = document.getElementById('numMembers').value;
var current = document.getElementById('listMembers').childNodes.length;
if(count >= current) {
for(var i=current; i<=count; i++) {
var memberForm = document.createElement('div');
memberForm.setAttribute('id', 'member'+i);
var memberInput = document.createElement('input');
memberInput.setAttribute('name', 'memberName'+i);
memberInput.setAttribute('id', 'memberName'+i);
memberInput.setAttribute('type', 'text');
memberInput.setAttribute('class', 'ajax-member-load');
memberInput.setAttribute('value', '');
memberForm.appendChild(memberInput);
// two other fields (the ones next to the member name) removed for brevity
document.getElementById('listMembers').appendChild(memberForm);
}
}
else if(count < current) {
for(var i=(current-1); i>count; i--) {
document.getElementById('listMembers').removeChild(document.getElementById('listMembers').lastChild);
}
}
jQuery('.ajax-member-load').each(function() {
var num = this.id.replace( /^\D+/g, '');
// Update suggestion list on key release
jQuery(this).keyup(function(event) {
update(num);
});
// Check for only one suggestion and either populate it or clear it
jQuery(this).focusout(function(event) {
var number = this.id.replace( /^\D+/g, '');
memberCheck(number);
jQuery('#member'+number+'suggestions').html("");
});
});
}
// Looks up suggestions according to the partially input member name
function update(memberNumber) {
// AJAX code here, removed for brevity
self.xmlHttpReq.onreadystatechange = function() {
if (self.xmlHttpReq.readyState == 4) {
document.getElementById('member'+memberNumber+'suggestions').innerHTML = self.xmlHttpReq.responseText;
}
}
}
// Looks up the member by name, via ajax
// if exactly 1 match, it fills in the name and id
// otherwise the name comes back blank and the id is 0
function memberCheck(number) {
// AJAX code here, removed for brevity
if (self.xmlHttpReq.readyState == 4) {
var jsonResponse = JSON.parse(self.xmlHttpReq.responseText);
jQuery("#member"+number+"id").val(jsonResponse.id);
jQuery('#memberName'+number).val(jsonResponse.name);
}
}
}
function setMember(memberId, name, listNumber) {
jQuery("#memberName"+listNumber).val(name);
jQuery("#member"+listNumber+"id").val(memberId);
jQuery("#member"+listNumber+"suggestions").html("");
}
// Generate members form
memberList();
The suggestion divs (which are now being deleted before their onclicks and trigger) simply look like this:
<div onclick='setMember(123, "Raphael Jordan", 2)'>Raphael Jordan</div>
<div onclick='setMember(450, "Chris Raptson", 2)'>Chris Raptson</div>
Does anyone have any clue how I can solve this priority problem? I'm sure I can't be the first one with this issue, but I can't figure out what to search for to find similar questions.
Thank you!
If you use mousedown instead of click on the suggestions binding, it will occur before the blur of the input. JSFiddle.
<input type="text" />
Click
$('input').on('blur', function(e) {
console.log(e);
});
$('a').on('mousedown', function(e) {
console.log(e);
});
Or more specifically to your case:
<div onmousedown='setMember(123, "Raphael Jordan", 2)'>Raphael Jordan</div>
using onmousedown instead of onclick will call focusout event but in onmousedown event handler you can use event.preventDefault() to avoid loosing focus. This will be useful for password fields where you dont want to loose focus on input field on click of Eye icon to show/hide password

Getting siblings value with javascript

I create a textarea and a button on a loop based on a certain condition:
while($row_c= mysqli_fetch_array($result_comments))
{
//some code goes here
<textarea type="text" id="pm_text" name="text"></textarea><br>
<button name="send_comment" id="post_comment" class="button" onClick="post_pm_comment()">Post</button>
}
Now in my function "post_pm_comment" I would like to access the text written in the textarea when the post button is clicked.
I tried this, but it only gives me the text of the first textarea and button created:
function post_pm_comment(thidid, pm_id, path, pm,getter)
{
var pm_text = document.getElementById("pm_text").value;
}
What should I do?
Thank you
Your code is outputting an invalid DOM structure, because id values must be unique on the page. You cannot have the same id on more than one element. Remove the id values entirely, you don't need them.
Having done that, the minimal-changes answer is to pass this into your handler:
onClick="post_pm_comment(this)"
...and then in your handler, do the navigation:
function post_pm_comment(postButton)
{
var pm_text;
var textarea = postButton.previousSibling;
while (textarea && textarea.nodeName.toUpperCase() !== "TEXTAREA") {
textarea = textarea.previousSibling;
}
if (textarea) {
pm_text = textarea.value; // Or you may want .innerHTML instead
// Do something with it
}
}
Live Example | Source

Modify this function to display all the checked checkboxes' values (instead of last selected)

I am replicating the functionality of a select/multiselect element and I'm trying to use this function to display the items which have been selected in the relevant container. I need to show all the values that have been selected in a comma-separated list, but it's currently only showing one selection (the last one made). It's also displaying the checkbox, background color, etc. of the list item selected instead of the checkbox value (i.e. value="Black").
I'm using this for a few multiselect form elements where I couldn't use the jQuery UI MultiSelect Widget because they needed to be styled in a very specific way (options displayed with background colors or images and spread out over several columns, etc.).
I've included the relevant code below, and I've posted a working example of the styled 'faux'-multiselect element here: http://jsfiddle.net/chayacooper/GS8dM/2/
JS Snippet
$(document).ready(function () {
$(".dropdown_container ul li a").click(function () {
var text = $(this).html();
$(".dropdown_box span").html(text);
});
function getSelectedValue(id) {
return $("#" + id).find("dropdown_box span.value").html();
}
});
HTML Snippet
<div class="dropdown_box"><span>Colors</span></div>
<div class="dropdown_container">
<ul>
<li><a href="#"><div style="background-color: #000000" class="color" onclick="toggle_colorbox_alt(this);" title="Black"><div class=CheckMark>✓</div>
<input type="checkbox" name="color[]" value="Black" class="cbx"/></div>Black</a>
</li>
<!-- More list items with checkboxes -->
</ul>
</div>
I've tried several other methods (including many of the ones listed here: How to retrieve checkboxes values in jQuery), but none of those worked with hidden checkboxes and/or the other functions I need to incorporate in these particular form elements.
well, to start with change click(..){..} in document.ready to
$(".dropdown_container ul li a").click(function () {
var text = $(this).html();
var currentHtml = $(".dropdown_box span").html();
var numberChecked = $('input[name="color[]"]:checked').length;
$(".dropdown_box span").html(currentHtml.replace('Colors',''));
if (numberChecked > 1) {
$(".dropdown_box span").append(', ' + text);
} else {
$(".dropdown_box span").append(text);
}
});
this will do the appending of text right.
however I couldn't understand the handling of images in the code.
Update, to handle just the value:
replace var text = $(this).html(); with
var text = $(this).find("input").val();
It might be easier to just grab all the values of the check boxes whenever the click event is triggered and then append the values to your span. Like http://jsfiddle.net/9w95b/
I would also suggest not putting the <input> tags inside your <a> tags.

Categories

Resources