jQuery clone() copies data...sometimes...? - javascript

Using the sample below, I have a tr that I am duplicating. It contains a jQuery autocomplete. The first time it is cloned, the auto complete functionality does not work because the attached data("items") is null. The second time the Add button is clicked, the autocomplete works. Thereafter, clicking Add once again produces a non-functioning autocomplete.
Adding a breakpoint inside of the makeAutoComplete function shows that items is always null except for when clicking Add the second time!
Can anyone explain this strange behavior?
HTML/JS (Fiddle here: http://jsfiddle.net/SDvF4/12/)
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Test!</title>
<style type="text/css">
tr.Template
{
display: none;
}
</style>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script type="text/javascript" src="http://code.jquery.com/ui/1.8.18/jquery-ui.js"></script>
<script type="text/javascript">
$(document).ready(function ()
{
var textbox = $(".AutoComplete");
makeAutoComplete(textbox);
$("#addButton").click(function ()
{
var attrRegex = /\d+/;
var template = $("tr.Template");
var newRow = template.clone(false);
var newRowIndex = (template.siblings().length + 1);
newRow.removeClass("Template");
newRow.find("*[id]").each(function ()
{
var element = $(this);
element.attr("id", element.attr("id").replace(attrRegex, newRowIndex));
});
newRow.find("*[name]").each(function ()
{
var element = $(this);
element.attr("name", element.attr("name").replace(attrRegex, newRowIndex));
});
newRow.insertBefore(template);
newRow.find(".AutoComplete").each(function ()
{
makeAutoComplete($(this));
});
});
});
function makeAutoComplete(textbox)
{
var items = textbox.data("items");
var test = textbox.data("test");
if (items == null)
{
if (test == "JSM")
alert("ERROR: data.items not copied but data.test was!");
else
alert("ERROR: data.items not copied nor was data.test!");
}
textbox.autocomplete(
{
minLength: 0,
source: items
});
}
</script>
</head>
<body>
<table>
<tbody>
<tr class="Template">
<td>
<input id="test_0" name="test_0" class="AutoComplete" type="text"/>
<script type="text/javascript">
var testData = [{ label: "One", value: 1 }, { label: "Two", value: 2 }];
$("#test_0").data("items", testData);
$("#test_0").data("test", "JSM");
</script>
</td>
</tr>
</tbody>
</table>
<br/><br/>
<button id="addButton">Add</button>​
</body>
</html>

There were multiple issues I had to fix to get this to work.
First was pointed out by #pimvdb - I wasn't IDing the elements correctly so the second new row had the same ID as the template row.
Second, you can't simply call autocomplete on a widget that is already an autocomplete - first you have to destroy it:
textbox.autocomplete("destroy");
textbox.removeData("autocomplete");
The 12th revision works correctly: http://jsfiddle.net/SDvF4/12/

Related

How to create a button that calls a function and passes parameters in jQuery?

I am trying to create a button in jQuery which has a onClick event and which calls a function and passes some parameters. Here is what I tried so far :
var user_array = [];
user_array['recipient_name'] = recipient_name.value;
user_array['co_name'] = co_name.value;
var myTable = $('#myTable').DataTable();
var rowNode = myTable.row.add(['<button type="button" id="button_edit" onclick=edit_customer_request(1,user_array)"name="edit_customer">Edit</button>'
])
.draw()
As you can see I am adding a new row in the table which has a button. I am able to create the button, so, it displays. However, it doesn't work, it doesn't call that function onclick. Pay attention to the parameters, I am trying to pass two parameters, first one is just a number and the second is an array : onclick=edit_customer_request(1,user_array)
EDIT. Screenshot:
I may have misunderstood the request, but here is what I think you are trying to do.
Here is a self-contained solution you can run for yourself:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Demo</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.min.css">
<link rel="stylesheet" type="text/css" href="https://datatables.net/media/css/site-examples.css">
</head>
<body>
<div style="margin: 20px;">
<table id="myTable" class="display dataTable cell-border" style="width:100%">
<thead>
<tr><th>Foo</th></tr>
</thead>
</table>
</div>
<script type="text/javascript">
var recipient_name = { "value": "Jon Smith" };
var co_name = { "value": "Starbucks" };
var user_obj = {};
user_obj['recipient_name'] = recipient_name.value;
user_obj['co_name'] = co_name.value;
function edit_customer_request(id, data) {
data_obj = JSON.parse(data);
console.log("In the function!");
console.log("ID: " + id);
console.log("recipient name: " + data_obj['recipient_name']);
console.log("co. name: " + data_obj['co_name']);
}
$(document).ready(function() {
var myTable = $('#myTable').DataTable();
var btnHtml = '<button type="button" id="button_edit" onclick="edit_customer_request(1, JSON.stringify(user_obj))" name="edit_customer">Edit</button>';
var rowNode = myTable.row.add( [ btnHtml ] ).draw();
} );
</script>
</body>
</html>
When you click the button, the edit_customer_request function is called, and it logs the following messages to the console (using my sample data):
In the function!
ID: 1
recipient name: Jon Smith
co. name: Starbucks
Some points to note:
I changed your var user_array = []; to this: var user_obj = {}; because I think you need an object here, not an array.
The code uses JSON.stringify() to convert an object into text, so it can be passed as a parameter to the function - and then converted back to an object using JSON.parse().
I took a guess at some sample data to make the demo run.

HTML input & button to pass to function using jquery

this is my first question on StackOverflow and my first time working with Chrome Extensions.
I am trying to get user input from an html popup and use jquery to pass that input to a javascript function. The openNewPopup function works here, and the removeATab function works only if I hard code a specific tab index within the function (not passing in the index).
My background.js
function openNewPopup() {
chrome.tabs.create({
index: 0,
url: "http://google.com"
}, function(tab) {
console.log(tab);
});
}
function removeATab(removeTab) {
chrome.tabs.query({currentWindow: true}, function(tabs) {
lastTabId = tabs[removeTab].id;
chrome.tabs.remove(lastTabId);
});
}
My popup_script.js
document.addEventListener("DOMContentLoaded", function() {
var backgroundPage = chrome.extension.getBackgroundPage();
document.querySelector('#newTabButton').addEventListener('click',
function() {
backgroundPage.openNewPopup();
});
document.querySelector('#btnRemove').addEventListener('click',
function() {
var indexRemove = document.querySelector('#tabRemove');
backgroundPage.removeATab(indexRemove);
});
});
And my popup.html
<!DOCTYPE html>
<html>
<head>
<title>Work with tabs</title>
<script src="popup_script.js"></script>
</head>
<body>
<h3>"Open new tab"</h3>
<button id="newTabButton">Make a new tab!</button>
<div class="remove">
Remove tab:<br>
<input type="number" name="tabRemove" id="tabRemove">
<br>
<input type="button" id="btnRemove" value="Remove">
</div>
</body>
</html>

How to program a button to change stylesheets with javascript

Please note that I am not using classes. I haven't found an answer for this SPECIFIC question.
Using javascript, how can I program a button to change the stylesheet each time the button is clicked?
I've tried different if, else if and else, but when I try them, it breaks the code (ie, it will change the color to blue if red, but not back again).
It works with 2 buttons, but getting it to change each time a single button is clicked seems to be eluding me. I got feed up and programmed a second button to change it back.
This works for 2 buttons:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>"Your Title Here"</title>
<link id="um" rel="stylesheet" href="stylesheet1.css">
<style>
</style>
</head>
<body>
<p>booga</p>
<button id="x" onclick="myFunction()">blue</button>
<button id="x1" onclick="myFunction1()">red</button>
<script>
function myFunction() {
if (document.getElementById("um").href = "stylesheet1.css"){
document.getElementById("um").href = "stylesheet2.css"}
}
function myFunction1() {
if (document.getElementById("um").href = "stylesheet2.css"){
document.getElementById("um").href = "stylesheet1.css"}
}
</script>
</body>
I would like to be able to get rid of the second button and second function and have it all with one button.
EDIT...
I tried this, and it failed.
function myFunction() {
if (document.getElementById("um").href == "stylesheet1.css")
{document.getElementById("um").href = "stylesheet2.css"};
else {document.getElementById("um").href = "stylesheet1.css"}
}
Make sure you're using == instead of = for your comparisons!
if (document.getElementById("um").href == "stylesheet1.css")
etc
Try this:
<button id="x" onclick="myFunction()">Change</button>
<script>
function myFunction() {
var link = document.getElementById("um");
var segments = link.href.split('/');
var currentStyle = segments[segments.length - 1];
var style = (currentStyle == 'stylesheet1.css') ? 'stylesheet2'
: 'stylesheet1';
document.getElementById("um").href = style + ".css"
}
</script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>"Your Title Here"</title>
<link id="um" rel="stylesheet" href="stylesheet1.css">
</head>
<body>
<p>booga</p>
<button onclick="myFunction('um','stylesheet1.css', 'stylesheet2.css')">swap</button>
<script>
function myFunction(id,a,b) {
var el = document.getElementById(id);
var hrefStr;
if(~el.href.indexOf(a)) {
hrefStr = el.href.replace(a, b);
el.href = hrefStr;
} else {
hrefStr = el.href.replace(b, a);
el.href = hrefStr;
}
}
</script>
</body>
</html>

Javascript/JSON error: not well formed

I am testing putting a text editor on my page and storing it as part of a JSON object.
HTML
<!DOCTYPE html>
<html>
<head>
<script src="http://tinymce.cachefly.net/4.0/tinymce.min.js" type="text/javascript"> </script>
<script type="text/javascript">
tinymce.init({
selector: "textarea"
});
</script>
<link rel="stylesheet" href="/jquery.mobile-1.3.2.min.css"/>
<script src="/jquery-1.9.1.min.js"></script>
<script src="/jquery.mobile-1.3.2.min.js"></script>
</head>
<body>
<form method="post" action="formSubmit.js">
<textarea name ="editor"></textarea>
<p><input type="submit" value="Submit"></p>
</form>
</body>
</html>
JS
$(document).ready(function () {
var text = $("editor").val();
var name = "project name";
var id = 5;
var item = new item(name, text, id);
var itemArray = localStorage.items;
if (itemArray == undefined) {
itemArray = [];
} else {
itemArray = JSON.parse(itemArray);
}
itemArray.push(item);
localStorage.items = JSON.stringify(itemArray);
});
I want to be able to store item in a JSON object. When I run this I receive a "not-well formed" error at line 1 of the Javascript. It's a very simple program I'm running and can't seem to pinpoint what is causing the error. Is the JSON done incorrectly or are scripts in my HTML header causing issues?
$("editor") is looking for an html tag called 'editor'. you probably want to attach an id attribute to your and do $('#editor')

Create and save new list item with Javascript and HTML 5

I have the following code.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function addChildElements()
{
var newdiv=document.createElement("li");
var newtext=document.createTextNode("test");
newdiv.appendChild(newtext);
document.getElementById("scribble").appendChild(newdiv);
}
</script>
<script>
function storeUserScribble(id) {
var scribble = document.getElementById('scribble').children;
localStorage.setItem('userScribble',scribble);
}
function getUserScribble() {
if ( localStorage.getItem('userScribble')) {
var scribble = localStorage.getItem('userScribble');
}
else {
var newdiv=document.createElement("li");
var newtext=document.createTextNode("test");
newdiv.appendChild(newtext);
document.getElementById("scribble").appendChild(newdiv);
}
document.getElementById('scribble').children = scribble;
}
function clearLocal() {
clear: localStorage.clear();
return false;
}
</script>
</head>
<body>
<ol id="scribble" contenteditable="false" onclick="storeUserScribble(this.id);">
</ol>
<input type="button" value="Add Child Element" onclick="addChildElements(); storeUserScribble(document.getElementById('scribble').id);"/>
</body>
</html>
Which is meant to save the list items as they are created, but i'm completely at a loss. This code doesn't work. I know it probably has something to do with:
var scribble = document.getElementById('scribble').children;
or
onclick="addChildElements(); storeUserScribble(document.getElementById('scribble').id);"
But that is about where my JS knowledge stops.
Any help is much appreciated.

Categories