Generating HTML toggle buttons with JavaScript and initializing them - javascript

I have a div:
<div id="div1">
</div>
And I'm trying to generate "toggle" buttons (http://www.bootstraptoggle.com/) with JavaScript:
<script>
var count = 1;
function foo() {
var newButton = "<input type=\"checkbox\" id=\"" + count + "\" checked data-toggle=\"toggle\"><br>";
document.getElementById('div1').innerHTML += newButton;
$('#' + count).bootstrapToggle();
// also tried re-initializing the first created button, this won't work either..
//$('#1').bootstrapToggle();
count = count + 1;
}
setInterval(foo, 4000);
</script>
This creates the buttons just fine, but those have to be initialized first by calling.
$('#1').bootstrapToggle();
The problem is, that when I have generated the first button and generate the second, the first one stops working. I have also tried to re-initialize the first button in the same div, but that won't work either.
Please, if there's a better way to do this I'd be glad to receive some help (or better, example code) on how to do this. The thing is that I cannot do this other way, because I'm generating these from JSON input.

As Rajesh says, the +=innerHTML is causing problems.
This will work:
<div id="container"></div>
var count = 1;
function createButton() {
var newButton = "<input type='checkbox' id='" + count + "' checked data-toggle='toggle'><br>";
$('#container').append(newButton);
$('#' + count).bootstrapToggle();
count = count + 1;
}
setInterval(createButton, 1000);
Edit: You can also tidy things up a little to lose the ugly count global:
function createButton() {
$('<input/>', {
type: 'checkbox',
checked: 'checked',
data: {
toggle: 'toggle'
}
})
.appendTo('#container')
.bootstrapToggle();
}
setInterval(createButton, 1000);

Related

Using jQuery to replace tags within an array?

I am new to Javascript and JQuery and I am trying to replace all my tags with upon first click, and then replace with on the second click, and so forth.
Basically just cycling through them so on each click I have a 3d rendered box or sphere. I tried to run it with this code however it does not work.
When I checked the console, only the lines were getting logged, so it doesn't seem to be replacing them correctly. I need to keep the tags within each preserved as I work.
var counter = 0;
var myArr = ["a-sphere", "a-box"];
$("#targeted").click(function() {
if(counter == myArr.length) counter = 0;
$(myArr[counter]).replaceWith(function() {
var myString = "<" + myArr[counter] + ">" + $(this).html() + "</" + myArr[counter] + ">";
console.log(myString + counter);
return myString;
});
counter++;
});

Limit the input in Fieldset

I am trying to create a section of my webstore where the customer can 'build' their own bundle and choose any combination of 5 items.
I have a set of buttons which, when clicked, add their value to a Fieldset along with a button to remove it in case they misclicked or changed their mind.
All the components work fine, but I don't know how to limit the Fieldset to only five items. Is there a way to either count the lines, then stop accepting input
after five or look for 'Remove' five times?
I'm still fairly new to coding and not too sure what is possible.
This input will end up being submitted in a form.
Here is my Fiddle and below is my Javascript code which i have tried for it :
$(document).ready(function () {
$(".buttons").click(function () {
var intId = $().length + 1;
var item = $(this).html();
var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + intId + "\"/>");
var removeButton = $("<input type=\"button\" class=\"remove\" value=\"Remove\" />");
removeButton.click(function () {
$(this).parent().remove();
});
fieldWrapper.append(size);
fieldWrapper.append(removeButton);
$("#buildyourkit").append(fieldWrapper);
});
});
This will give you the current quantity of elements added to the . Just make sure that there is still room for another before appending a new one.
$("fieldset .fieldwrapper").length
I've forked your fiddle. Just look at the console while adding new items to the fieldset.
You can have a global variable which will count up and disable all buttons if over 5 every time you add a field, and down and enable all buttons every time you remove a field.
Also, it is a bit nicer to just set a live handler listening for any remove buttons, rather than make a new function and bind a new listener for each button, so I demonstrated; but it is not obligatory (your way works, too, given it's just 5 elements).
$(document).ready(function () {
var buttonMaxID = 0;
var buttonCount = 0;
$('$buildyourkit').on('click', '.remove', function () {
$(this).parent().remove();
if (buttonCount-- >= 5) {
$('.buttons').prop('disabled', false);
}
});
$(".buttons").click(function () {
if (++buttonCount >= 5) {
$('.buttons').prop('disabled', true);
}
var item = $(this).html();
var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + (buttonMaxId++) + "\"/>");
var removeButton = $("<input type=\"button\" class=\"remove\" value=\"Remove\" />");
fieldWrapper.append(size);
fieldWrapper.append(removeButton);
$("#buildyourkit").append(fieldWrapper);
});
});
What I propose is designing a manager class to maintain all functions/methods that must interact with the UI. This allows you to define your data set in one place, and keep the UI binds in one place. By doing so, you set yourself up with a cleaner code base, easy refactoring, and quickly make code modifications. Also, you get all this goodness without any global variables, another great bonus.
The code does look like its larger, but once you understand the simplicity of the manager you will see the possibilities I outlined above.
$(document).ready(function () {
//Create a new Kit Manager
var kitManager = new KitManager();
$(".buttons").click(function () {
kitManager.add(this);
});
$(".report").click(function () {
kitManager.getKit();
});
});
function KitManager()
{
//Static amount of items to return
var MAX_ITEMS = 5;
//Where the items should be visually displayed on the UI
var kitLegend = $("#buildyourkit");
//Internal array for storing the items added
var items = []
function add(element)
{
if(items.length < MAX_ITEMS)
{
var itemNumber = items.length + 1;
var item = $(element).html();
var fieldWrapper = $("<div class=\"fieldwrapper\" id=\"field" + itemNumber + "\"/>");
var removeButton = $("<input type=\"button\" class=\"remove\" value=\"Remove\" />");
//Add item to the array collection
items.push(item);
//Bind a remove function to the newly created button
removeButton.click(function () {
kitLegend[0].removeChild(fieldWrapper[0]);
items.splice(itemNumber, 1);
});
//Append UI components to container
fieldWrapper.append(item).append(removeButton);
//Append to main legend
kitLegend.append(fieldWrapper);
}
else
{
//Simple alert to user
alert('You\'ve Reached The Maximum Number of Items');
}
}
//Simple function for demonstration of a reporting feature
//or potential method for returning the stored items
function getKit()
{
for(var i=0,length=items.length;i <length;i++)
{
console.log(items[i]);
}
}
//Expose public method call
return {
add:add,
getKit: getKit
};
}
http://jsfiddle.net/x97S5/
I hope you find the solution acceptable, and if you have any further questions please ask.
For more information on the solution and technique proposed take a look at Key Principles of Maintainable JavaScript

Dynamic Button not refreshing CSS properties

First time posting = )
I have been searching for a little while and have tried many ('refresh').trigger , ('create') and markup answers other members have suggested or I have seen on other posts. I am pretty new to JS JQM but I am having troubles having my dynamically added buttons viewed with the CSS properties. I have tried other solutions posted on similar questions such as:
How to add dynamic jquery button?
Jquery Dynamically generated buttons no css
A few other posts too.
Sorry in advance if already answered, I could not find a solution.
Here is my code:
The Reason I made the button a variable was because of another form post suggested it then refreshing that way...
$( '#csvButton' ).on( 'click', function() {
$('#viewData').empty();
$('#testView').empty();
$.ajax( {
url: 'xhr/data.csv',
type: 'GET',
dataType: 'text',
success:function ( result ) {
//console.log(result);
var lines = result.split("\n");
//console.log(lines);
var dataRow = lines[0];
var dataCol = dataRow.split(",");
for (var lineNum = 1; lineNum < lines.length; lineNum++) {
var row = lines[lineNum];
var columns = row.split(",");
var thisButton = $("<a>").attr("href", "#").attr("data-role", "button").attr("data-theme", columns[1]).attr("data-icon", columns[2]).text(columns[0]);
thisButton.appendTo('#testView');
$('<ul>' + '<li><b>' + dataCol[0] + " " + columns[0] + '</b></li>' +
'<li>'+ dataCol[1] + " " + columns[1] + '</li>' +
'<li>'+ dataCol[2] + " " + columns[2] + '</li>' + '</ul>'
).appendTo('#testView');
}
}
});
});
return false;
});
I am having trouble with thisButton displaying properly with CSS properties. I am made it a link with data-role="button" and trying it as a
my CSV has button name "Settings", button theme "a", and button icon "gear" data.
Any help would be great. #testView was a temp I created to test ideas to get CSS properties to work.
Thanks in advance!
Well you're working on dynamic buttons so it seems it would be better if you set css to a class and then add class to button dynamicaly.
Try add class to your css code with parameters you need and then in your code put somewhere
$("#testView").addClass("name of your class");
I'm sorry but i can test this solution right away so i'm not sure if its working as you wish.
Good Luck :)
You can remove or put CSS properties with this:
E.g.:
$("#testView").class('display', 'none');
Look at this Porperty CSS documentation

Javascript removeChild array

this looks simple enough but I just can't get it to work. I could add DOM elements but I just can't remove them when using an array.
<script language="javascript">
fields = 0;
count = 0;
function addInput() {
if (fields != 10) {
var htmlText = "<input type='search' value='' name='field[]' />";
var remButton = "<input type='button' value='del' onclick='remove()' />";
var newElement = document.createElement('div');
newElement.id = 'SomeID'+fields;
newElement.innerHTML = htmlText + remButton + newElement.id;
var fieldsArea = document.getElementById('text');
fieldsArea.appendChild(newElement);
fields += 1;
} else {
...
}
count++;
}
// NEED HELP FROM HERE PLEASE
// You don't need to Loop, just get the button's id and remove that entire 'SomeID'
function remove() {
fieldsArea = document.getElementById('text');
fieldsArea.removeChild(SomeID1); <-----------------------THIS WORKS!
fieldsArea.removeChild(SomeID+count); <------------------THIS JUST WOULDN'T
count--;
}
</script>
In the remove function, writing SomeID1 works and delete the first added element but when I try to use a 'count', I just can't delete my 'elements'.
Any help would be most appreciated.
Thank you!
You have to get a reference to the element first. Currently you are passing an undefined variable SomeID to the function.
E.g.:
var element = document.getElementById('SomeID' + fields);
// or starting by zero: var element = document.getElementById('SomeID0');
element.parentNode.removeChild(element);
If you want to remove the div for which the button was clicked, you have to pass a reference to the corresponding div to the remove function.
'<input type="button" value="del" onclick="remove(this.parentNode)" />';
this will refer to the button and as it is a child of the div, this.parentNode refers to that div.
You also have to change your function to accept the element that should be removed:
function remove(element) {
element.parentNode.removeChild(element);
count--;
}
You probably also have to update fields, but I'm not sure how your code is supposed to work.
If you want to remove all of them you have to loop:
for(;fields--;) {
var element = document.getElementById('SomeID' + fields);
element.parentNode.removeChild(element);
}
Also have a look at the documentation of removeChild.
The removeChild needs a node (DOM element) as parameter. In this case
fieldsArea.removeChild(SomeID+count);
you could for example pass the node this way
fieldsArea.removeChild(document.getElementById('SomeID'+count));

Javascript running twice

I have to develop a small application for school and I first designed in photoshop a bit and "converted" it into html. That went all fine. I created a custom dropdown with javascript and it worked smoothly. I've just tried implementing CodeIgniter into the design but the javascript started running twice.
I've tried comparing the code of the plain html version with the codeigniter result but I can't seem to find any difference.
Can any of you maybe help me?
Here's the CodeIgniter result:
http://intellia.itforit.net/index.htm
As asked by Krof Drakula here are the most important pieces of code:
The actual jquery plugin: (styleForm.js)
;(function($){
$.fn.styleForm = function() {
var form = this;
/* Select */
$('select', this).each(function(){
var div = '<div class="styledSelect"><ul>';
var first = false;
$('option', this).each(function(){
var cssclass = "";
if(!first) {
first = true;
cssclass = 'class="first"'
}
div += '<li ' + cssclass + ' id="' + $(this).attr("value") + '">' + $(this).text() + '</li>';
});
div += '</ul></div>';
$(this).hide();
$(this).after(div);
});
$('.styledSelect ul').toggle(function(){
$('li:not(.first)', this).show("fast");
}, function(){
$('li:not(.first)', this).hide("fast");
});
$('.styledSelect ul li:not(.first):not(.selected)').click(function(){
var id = $(this).attr('id');
var content = $(this).text();
$('.styledSelect ul li.first').attr('id', id).text(content);
$('.styledSelect ul li').css({'font-weight': 'normal'});
$(this).css({'font-weight': 'bold'});
/* SELECT in Select form item */
var selected = $('select option[value="' + id + '"]:not(.first)', form).get(0);
selected.setAttribute("selected", "selected");
//$(form).submit();
});
};
})( jQuery );
And here's where it gets launched: (canvasDrawing.js)
$(document).ready(function(){
$('form').styleForm();
//Unimportant canvas stuff
});
Thanx in advance,
Duckness
The problem is that your canvasDrawing.js, in the "unimportant canvas stuff", causes a javascript error. If the canvas it describes actually exists, your styleForm stuff only runs once. So add this to your HTML:
<canvas id="floorplan"></canvas>
And magic will happen. Or, in your canvasDrawing file, add clause like this right after styleForm:
var canvas = document.getElementById('floorplan');
if (!canvas)
return;
I'm not actually all that clear why having an error in that function causes it to run twice, but it's definitely the problem. See it: your code + a canvas element = working.

Categories

Resources