Insert input if it does not exist - javascript

I am working on an email template editor where the user will select from a list of pre-existing templates and will be able to update the template as necessary. I had problems with using the CKEditor plugin across browsers and so I have attempted to create my own. When the user selects a template it opens in a modal window. To change the images I have included input tags which are removed upon close of the modal. This works so well and so good but if the user then wants to go back into the editor the input buttons are no longer there.
I want to add in the input button in the modal window if it does not exist. I have tried checking the length of the property but I am unable to return a value other than null whether it exists or not. My code is as follows:
function template1InputButtons() {
if ($("#imageInput1T1").length == 0) {
$('<input id="imageInput1T1" type="file" name="newImage1T1" onchange="previewImage1T1(this)" />').insertBefore('.article_media');
}
}
If I open it the first time the length comes up as one and so nothing is added as expected. If I remove and then click the button again length shows as 0 and input is added correctly as expected. If I then remove the input and click the button again the length comes up as 1 despite the control not existing.
Any ideas?

Try this:
function template1InputButtons() {
if (!$("#imageInput1T1")) {
$('<input id="imageInput1T1" type="file" name="newImage1T1" onchange="previewImage1T1(this)" />').insertBefore('.article_media');
}
}
and also assure that you have placed it inside ready function.

Try this:
if ($("body").find("#imageInput1T1").length == 0) {
$('<input id="imageInput1T1" type="file" name="newImage1T1" onchange="previewImage1T1(this)" />').insertBefore('.article_media');
}

Problem was a similar finding of class attribute article_media on the other modal my mistake thanks for the help anyway

Related

Show div when click on a different div, and show a different div when clicked again

I currently have made a way so the user can add another text field to the form by pressing on a 'add_another' div, this uses basic JS so when the user presses on the div 'add_another' the div 'author_2' is toggled.
I would like to make it so that when the user presses on the 'add_another' div for a second time it shows 'author_3' div, and when they press 'add_another' again, it then shows 'author_4'. I have put all the CSS and HTML divs in place to support this, I am just trying to adapt my code so it shows one div after another, rather then toggling a single div.
Here is my JS:
<script>
$(document).ready(function() {
$('.add_another').on('click', function(){
$('.author_2').toggle();
});
});
</script>
I have tried altering this code, however with no luck.
I haven't added my HTML as it is just 4 divs, 'author_1' 'author_2' ... 3...4
Thankyou for your help
There are two solutions to Your problem.
First one - use static code
It means the max author count is 4 and if user gets to 4, this is it.
If so - You need to store the number of authors already shown.
var authors_shown = 1;
$(document).ready(function() {
$('.add_another').on('click', function(){
authors_shown++;
if (!$('.author_'+authors_shown).is(":visible")) {
$('.author_'+authors_shown).toggle();
}
});
});
But there is also a second - more dynamic option.
What if user wants to input 10 or 20 authors? You don't want to pre render all that html code and hide it. You should clone the div and change its id or if the (HTML) code (for another author) is not too long, you can render it within JS code.
var div = document.getElementById('div_id'),
clone = div.cloneNode(true); // true means clone all childNodes and all event handlers
clone.id = "some_id";
document.body.appendChild(clone);
If it's a form, then change names of input fields to array as author_firstname[]
Also You can store number of added authors in another hidden field (so you know how long to loop the form fields on the server side.
The second option is a bit more complex and longer, but way more dynamic.
You should make another div when clicked on add_another:
something like this:
<script>
$(document).ready(function() {
$('.add_another').on('click', function(){
$('<div><input type="text" name="name[]" /></div>').appendTo('.your_container');
});
});
</script>
as you see, input's name has [] which means you should treat with the inputs as an array.
let me know if you got any further questions
good luck.

jQuery: toggling attribute within a toggleClass function

I'm trying to add an attribute to a searchfield only when it is visible, so I have the following code to a) hide the search form initially, b) toggle the visibility and c) add or remove the attribute "autofocus" to the form's input when the form is given the class "focus" (e.g being visible). The code for a) and b) works as it should, c) is my imagined take on how the addAttr() thing should be, but I don't really know Javascript so obviously it's not working. The question is: How do I make it work?
$("#searchwdgt").hide();
$(function() {
$('#show_search').click(function() {
$('#show_search').toggleClass('active');
$('#searchwdgt').toggleClass('focus').slideToggle(400);
if($('#searchwdgt.focus')) {
$('#searchwdgt input').addAttr('autofocus');
} else {
$('#searchwdgt input').removeAttr('autofocus');
}
return false;
});
});
The basic construct is simple. #show_search is an anchor that the user clicks to get the search form (#searchwdgt). To minimize the number of user clicks it would be nice if the attribute "autofocus" could be added to the input (has class "searchfield", is type "search", just for clarification) when the form becomes visible, but for UX purposes it can't be in place always (this messes with tab browsing since the form is hidden initially). So, any constructive pointers that can help solve the issue are most welcome. Thanks.
the function should be
.attr('autofocus','autofocus')
instead of
.addAttr('autofocus');
The reason it isn't working is that each attribute needs to have a value, even if it's null

Working With Dynamically Created Inputs

I have a dynamic form that you can add elements. Like, you type a name, and then if you have to write a new name, you click on 'Add Name', and another textbox appears.
Their names are names[]. I can process those inputs with PHP on the server-side. However, I want to make a calculation with those inputs, like writing all of them on the page as the user types.
However, because those inputs, those textboxes are created dynamically, Javascript only selects the first textbox with the name name[].
Let me make it clear. This way it'll be better. I got a textbox. I input age in there. If I want to enter a new age, I click 'Add Age' button, and a new input box pops out. I write the new age value. And as I type, on a 3rd textbox, the average of those age values get printed. But because of those input boxes, with names ages[] are created on the execution time (not the compile time, I'm not sure these are the appropriate words for those. Probably not, because nothing is compiling? - or is it?), I can't process them.
What must I do to solve this problem?
I used both
$('input[name=ages\\[\\]]').change(function(){
console.log('1');
});
and
$('input[name=ages\\[\\]]').on('input', function() {
console.log('2');
});
but it didn't work.
Thanks in advance.
There's no need to escape the square brackets (though you should enclose the whole field name in double quotes). This works for me:
$('input[name="names[]"]').on('change', function(){
console.log($(this).val());
});
Here's a jsfiddle demonstrating: http://jsfiddle.net/t7J5t/
Your problem is actually probably related to the fact that you're adding the fields dynamically. The way you're using your selector will only work on the fields that already exist. Fields that are added after that selector will not be picked up. What you want to do, then, is put the selector inside the .on, like this:
$('.container').on('change', 'input[name="names[]"]', function(){
console.log($(this).val());
});
This will bind the listener to the container, not the fields (just make sure your fields get added inside of the container; you can call it whatever you want).
Incidentally, there's no reason you have to restrict yourself from using the name attribute of fields when using jQuery selectors. For example, you could use a class:
<div class="container">
<input class="age" name="ages[]">
<input class="age" name="ages[]">
<!-- ... as many more as needed, added dynamically is OK ... -->
</div>
<script>
$(document).ready(function(){
$('.container').on('change', 'input.age', function(){
console.log($(this).val());
});
});
</script>
Here's a sample of it in action, where you can dynamically add fields, and it calculates the average:
http://jsfiddle.net/t7J5t/1/
Try to use:
$(document).on('change', 'input[name=ages\\[\\]]', function() {
console.log('2');
});

Dynamically created inputs with if else checkbox and multiple field validation

When the user clicks add more options, a from is created with javascript document.getElementById('addmore').innerHTML... It works great to display the form multiple times. I added a unique number each time to create unique IDs for each of the fields for submission. I have a checkbox that, if checked, needs to display another fields to get filled out:
document.getElementById('addmore').innerHTML += '<p><div class="required">*Type of Folder</div><label for="it09" class="hidelabel">Content Drive</label><input name="request['+fields+'][Type of Folder:]" id="cbpathCDB'+fields+'" type="checkbox" value="Content Drive" class="required" /><strong>Content Drive</strong> (A: drive)<br /><div id="pathCDB'+fields+'"><label for="newpathCDB"><span class="req">*Path to Content Drive Folder</span></label><input name="request['+fields+'][Path to Content Drive Folder:]" type="text" id="npcdb'+fields+'" size="50" class="required"/><br /><small>Path of folder to be created on Content Drive (A: drive)<br><em>(example: A:\drivefolder</em></small><br /></div></p>';
I have tried multiple ways (jquery included) of getting the next div, pathCDB+fields, to show when the checkbox is checked. It works fine without the +fields in there... see http://jsfiddle.net/kuVzV/4/ however, when I add the fields it fails to show/hide with the checkbox.
When the form is created though, the div doesn't show at first, just like it shouldn't... so I know the ID is correct. According to Firebug it is showing the correct ID with the field showing the correct # that is create...
I am at a loss right now.
Any suggestions on how to show/hide this div if the checkbox is checked for multiple inputs created dynamically?
Try checking out jQuery .show() and Jquery .hide(). I believe this is what you are looking for.
$(document).ready(function(){
$("#cbpathCDB1").on('click', $("#cbpathCDB1 input[type=checkbox]").is(":checked"), someFunction);
});
function someFunction(event){
if (event.target.checked){
$("#pathCDB1").hide('slow');
}
else{
$("#pathCDB1").show('slow');
}
}​
jsfiddle http://jsfiddle.net/FERMIS/7ThtT/6/ Here is an example with multiple fields.

Javascript won't update DOM on what appears to be recent Items

I'm using 100% pure javascript, tried Jquery but it didn't help. Code not working in FF/Chrome/Safari.
I have built Edit-In-Place functionality where when the user clicks "Edit" (calling external function with onclick - passing in item_id) -- a string of text is hidden to reveal an input with the same string of text in it. (by changing classes) "Edit" is also replaced by "Save". When done editing the string - the user clicks save, and everything reverts back to normal.
AJAX is processing all the updates - but commenting out the AJAX block does not fix it.
I am loading a stream of these objects. The javascript works for all of them - but only updates the DOM, visually anyway for what appears is items before the last 24 hours. The blocks themselves are identical. That is - items that have been added within the last 18-26 hours when I click "Edit", do nothing. BUT if I alert out the class of the element I want to edit it says "editing" (as opposed to "saved") like it is working. (see below) Although this change is never reflected in inspect element.
Code on Page
<input type="text" class="input_field" id="input_254" value="Foo" onkeydown="javascript: if (event.keyCode == 13) { update(254); }" style="display: none; ">
<span class="user_links" id="display_269" style="display:none;">Foo</span> //hidden span that holds the value and acts at the check
<span id="edit_state_269" class="saved" style="display: none;">Foo</span>
<span onclick="update(269)" id="edit_269">Edit</span>
External Javascript
function update(item_id) {
var links_span = document.getElementById('display_' + item_id);
var input_span = document.getElementById('input_' + item_id);
var string_old = document.getElementById('edit_state_' + item_id).innerHTML;
var state_check = document.getElementById('edit_state_' + item_id);
var edit_button = document.getElementById('edit_' + item_id);
if (state_check.getAttribute('class') == 'saved') {
// Hide the links display list and show the input field
links_span.style.display = 'none';
input_span.style.display = 'inline';
// Change the Edit button text and state_check
edit_button.innerHTML = 'Save';
state_check.setAttribute('class','editing');
//alert(state_check.getAttribute('class')); // this alerts "editing" although in DOM it is still "saved" on the blocks that are the problem
If any more details would be helpful - I will provide them.
It is a devil of a problem - with no obvious solution. Would really appreciate any direction you can give!
Solved. As usual it's the little things. The first few blocks were being loaded on page load - and then hidden as the user navigated resulting in duplicate IDs. Javascript naturally selected the one higher on the page - the one that was hidden.

Categories

Resources