How to convert dynamically added elements into JSON and back - javascript

Quick context: This is an application that mimics a magnet board. I want to save the location and id of all draggable elements and later load the file and set those properties and create/delete missing/unnecessary elements. To save the files I utilize Node.js and Electron.
I thought using JSON would be sensible since it can convert directly from JS but how does one do that with an unknown amount of elements?
This Javascript Code adds one of those elements to my page when the corresponding button is pressed:
$("#item1").mousedown(function (e){
var newpin = document.createElement("DIV");
var pinimage = document.createElement("IMG");
pinimage.setAttribute("src", "Media/2D_Container_Alfa.jpg");
pinimage.setAttribute("id", "Alfa");
pinimage.setAttribute("height", "70px");
newpin.setAttribute("position","relative");
newpin.setAttribute("top","20px");
newpin.setAttribute("left","140px");
newpin.setAttribute("display","block");
newpin.setAttribute("class", "draggable ui-draggable ui-draggable-handle");
newpin.appendChild(pinimage);
document.body.appendChild(newpin);
});
$("#item2").mousedown(function (e){
var newpin = document.createElement("DIV");
var pinimage = document.createElement("IMG");
pinimage.setAttribute("src", "Media/2D_Container_Bravo.jpg");
pinimage.setAttribute("id", "Bravo");
pinimage.setAttribute("height", "70px");
newpin.setAttribute("class", "draggable ui-draggable ui-draggable-handle");
newpin.appendChild(pinimage);
document.body.appendChild(newpin);
});
-

You could create the JSON variable outside any functions that might reduce its scope, and then add them in as and when you need to.
let myJson = {};
function onMouseDown(event) {
let thisId = event.id;
myJson[thisId] = location;
}

You mean
localStorage.setItem("draggable",JSON.stringify($('.draggable').map(function(){
return this.id
}).get()));
or
$.post("saveonserver",{"data":JSON.stringify($('.draggable').map(
function(){
return this.id
}).get()
});

Related

Editing the contents of an object tag with JQuery

I have this JQuery function:
var objects = document.querySelectorAll('object');
// Iterate through objects
$('object').each( function() {
var link = $(this).attr('data');
$(this).append('click here');
});
It goes through all <object> items in a page and appends a link to the end of them (all of the objects in this case are used to create an embed document.) However, I want to edit the function so that it also edits an attribute in the object tag, preferably changing the name attribute, and also add an if statement to check to see if the object tag contains this new name.
You can use .attr() to get/set the name attribute, also you can use .is() along with attribute selector
// Iterate through objects
var $objects = $('object');
$objects.each(function() {
var $this = $(this);
$this.append('<a href="' + $this.attr('data')
'">click here</a>');
var nametoset = ''; //some logic to find the name
if ($objects.is('[name="' + nametoset + '"]')) {
//name already exists so do something
} else {
$this.attr('name', nametoset);
}
});
$('object').each( function() {
var link = $(this).attr('data');
var newlink = $('click here');
newLink.attr("name","jonny");
$(this).append(newLink);
});
OR
$('object').each( function() {
var link = $(this).attr('data');
var newname = "jonny";
var newlink =$ ('click here');
$(this).append(newLink);
});

HTML elements created by the content script are not accessible by the content script

Within content script I use on.Message.addListener to add images with a class name to the currently active web page.
chrome.extension.onMessage.addListener(function (message, sender, sendResponse) {
// Selecting HTML tags
var divs = document.getElementsByTagName("div");
// Creating a full URL to use icon1
var imageUrl = chrome.extension.getURL("icons/icon1.png");
// Function to create an image
function PlaceImage(source_x, source_y, imageUrl) {
var newImage = document.createElement("img");
newImage.src = imageUrl;
newImage.style.position = "absolute";
newImage.style.left = source_x + 'px';
newImage.style.top = source_y + 'px';
// Assigning a class name
newImage.className = "label-key";
// Add an element to the HTML document
document.body.appendChild(newImage);
}
// Divs
for(var j=0; j<divs.length; j++) {
// Get the position of an element with getBoundingClientRect
var position = divs[j].getBoundingClientRect();
var x = position.left;
var y = position.top;
y -=32;
// Create comment image
PlaceImage(x, y, imageUrl);
}
});
Later I try to write to console by clicking on one of just created images by:
$(".label-key").click(function () {
console.log("hello");
});
There is no reaction of the browser.
I tried to write to console by accessing some class element with a different name, which was part of the original web page(received from the server). It worked fine.
More over I created another element within content script, but this time outside of onMessage.AddListener:
var newDiv = document.createElement("div");
document.body.appendChild(newDiv);
newDiv.style.width = "100px";
newDiv.style.height = "100px";
newDiv.style.backgroundColor = "red";
newDiv.className = "label-key";
It also worked fine. jQuery was able to access this element.
Therefore, I think there is something wrong with html elements created by the onMessage.addListener part of content script.
For additional reference: when I right-click on the newly created element "Inspect element" - I can see that the element is part of the html document. However, if I click "View page source" the element is not there.
Well, you are creating a new element of the class label-key, but the click handler assignment does not automagically extend to newly-created elements.
$(".label-key").click(...) is not behaving like a CSS rule despite looking like one: it collects all elements that match at the time of invocation and binds a listener for them.
So, if you add more images later, you need to add a click handler again:
function PlaceImage(source_x, source_y, imageUrl) {
var newImage = document.createElement("img");
newImage.src = imageUrl;
newImage.style.position = "absolute";
newImage.style.left = source_x + 'px';
newImage.style.top = source_y + 'px';
// Assigning a class name
newImage.className = "label-key";
newImage.click(function () {
console.log("hello");
});
// Add an element to the HTML document
document.body.appendChild(newImage);
}

create id dynamically

I am creating a element dynamically how would i give this an id?
_addQuestionElement : function() {
var el = new Element('div');
el.addClass('dg-question-label');
el.set('html', this._getCurrentQuestion().label);
$(this.html.el).adopt(el);
},
im using moo tools and jquery.
Many Thanks
Your code looks like Mootools, here's how I'd do it (cleaned up your code a bit)
_addQuestionElement: function() {
var el = new Element('div', {
'class': 'dg-question-label',
html: this._getCurrentQuestion().label,
id: 'yourId'
});
$(this.html.el).adopt(el);
}
If you're generating the same element multiple times, your id will need to somehow be unique each time.
You could also do without that el variable (unless of course it's used somewhere further in the function that you didn't include)
_addQuestionElement: function() {
$(this.html.el).adopt(new Element('div', {
'class': 'dg-question-label',
html: this._getCurrentQuestion().label,
id: 'yourId'
}));
}​
Just assign the id via (if you created the element with new Element()):
var yourCustomId = "myId";
el.id = yourCustomId;
Or use Mootools attr-setting capabilities:
var yourCustomId = "myId";
el.setProperty("id", yourCustomId);
You can give it like this,
var uniqueNumber = 1; //define uniqueNumber globally and increament at each element creation
With javascript
el.id = 'idprefix' + uniqueNumber++)
With jQuery
$(el).attr('id','idprefix' + uniqueNumber++);
In jQuery, to create a div with an ID, you would do something like this:
function createDiv(id) {
$("body").append("<div id=" + id + "></div>");
}
createDiv("myNewDivId");
_addQuestionElement, I think you need to generate a unique id for each question element.
var IDs = 0;
var pfx = "id_";
_addQuestionElement : function() {
...
el.attr("id", pfx + ++IDs);
var el = $('<div />') .attr('id', myVal);
all elements created or accessed by MooTools automatically get a unique uid (for the DOM) anyway, saves you from having to keep state yourself (if you want to be doing this automatically).
console.log( Slick.uidOf( new Element('div') ) )
so...
_addQuestionElement: function() {
var el = new Element('div.dg-question-label', {
html: this._getCurrentQuestion().label
});
// prefix number with uid-
el.set('id', 'uid' + Slick.uidOf(el)).inject(this.html.el);
},
to give it an id via the combined element constructor, it goes:
var el = new Element('div#someid.dg-question-label') or add it in the properties passed to the constructor:
new Element('div', { id: 'foo' })
You can use the jQuery plugin idfy.
Full Disclosure: I wrote that plugin :)

Getting HTML value from Tinymce

Is there a way to get HTML contents from TinyMCE editor using jQuery so I can copy this over to another div?
I tried several methods like val() on content but it doesn't seem to be working...
if you are initilizing with jquery adaptor
$(selector).tinyMCE().getContent();
Using jQuery:
<textarea id="content" name="content">
$('#content').html()
Using TinyMce API:
$('#content').tinymce().activeEditor.getContent() // overall html
$('#content').tinymce().activeEditor.getContent({format : 'text'}) // overall text
$('#content').tinymce().selection.getContent() // selected html
$('#content').tinymce().selection.getContent({format : 'text'})) // selected text
if you are using tinymce, i would use it's internal methods to get the content you need. when i need to get content within the active editor, i do this:
var rawString = tinyMCE.activeEditor.getContent();
i invoke that method within an event handler function.
here is the documentation:
tinymce api
use TinyMCE's API to get it:
alert(tinyMCE.activeEditor.getContent());
Use text(); instead of val();.
I was trying charlietfl method: $(selector).tinyMCE().getContent();
There was an error:
[$(selector).tinyMCE().getContent();][1]
This way with activeEditor worked for me:
activeEditor
tinymce.activeEditor.getContent()
Source
Here is my code:
$(document).ready(function() {
$(document).on("click", ".btnClassClose", function () {
var tinyMCEcontent = tinymce.activeEditor.getContent();
var getAttrIDArray = [];
$("#" + getelementId).html("");
$("#" + getelementId).html(tinyMCEcontent);
$("#" + getelementId).append(buttonEDI);
var PageName = new Object();
PageName["mdlPageId"] = getelementId;
getAttrIDArray.push(PageName);
var PageName = new Object();
PageName["mdlPageContentHtml"] = tinyMCEcontent;
getAttrIDArray.push(PageName);
var PageName = new Object();
PageName["mdlPageName"] = "Default";
getAttrIDArray.push(PageName);
var PageName = new Object();
PageName["mdlAligen"] = "Central";
getAttrIDArray.push(PageName);
var PageName = new Object();
PageName["mdlOrderNumberHorizontal"] = "1";
getAttrIDArray.push(PageName);
alert(JSON.stringify(getAttrIDArray));
var contentGetAttrIDArray = SecondMainSendAjax("CMS?handler=Content", getAttrIDArray);
});
});

Add a js function to the DOM?

I have a very simple HTML page. After everything is loaded, the user can interact with it perfectly. Now, at some point, the user clicks on an element. An ajax call is made and new data is being requested. I now want to remove the previous element the user clicked on with the element(s) the user has requested (on the same page) - practically remove the old element from the DOM and add the new one. Well, I did this as well, but I am unable to add a function to the newly created element. This is my function:
setCountry = function(value){
document.getElementById('country').innerHTML = value;
}
and I'm trying to add it like this to my element
a_tag.setAttribute("href", "javascript:setCountry(countries[i]);");
The function is being called and writes "undefined" to the innerHTML element. I set the attribute using a for loop and just above the for loop I alert an element from the array to be sure it's correct, and it prints out the correct value.
I assume the problem happens because the function is being created on the first load of the DOM, but I'm not sure. Can anyone shed some light on what is really happening here and what I should do to correct it? I want to be able to add more functions so not looking for a work around writing an innerHTML tag, I just want to understand what I'm doing wrong.
Thank you.
Edited with more code
//declare an array to hold all countries form the db
var countries = new Array();
function getCountries(region) {
document.getElementById('scroller').innerHTML = '';
//send the data to the server and retreive a list of all the countries based on the current region
$.ajax({
type: "POST",
url: "scripts/get_countries.php",
data: {
region: region
},
success: saveDataToArray,
async: false,
dataType: 'json'
});
//save the data to an array
function saveDataToArray(data){
var i = 0;
while (data[i]){
countries[i] = data[i];
i++;
}
}
scroller = document.getElementById('scroller');
//create a ul element
var holder = document.createElement("ul");
//here create a back button which will recreate the whole list of regions
var total = countries.length;
for(i=0;i<total;i++){
//create the first field in the list
var bullet_item = document.createElement("li");
//create an a tag for the element
var a_tag = document.createElement("a");
//set the redirect of the tag
a_tag.setAttribute("href", "javascript:setCountry(this);");
//create some text for the a_tag
var bullet_text = document.createTextNode(countries[i]);
//apend the text to the correct element
a_tag.appendChild(bullet_text);
//apend the a_tag to the li element
bullet_item.appendChild(a_tag);
//apend the item to the list
holder.appendChild(bullet_item);
}
//apend the holder to the scroller
scroller.appendChild(holder);
}
function setRegion(region){
document.getElementById('region').innerHTML = region;
}
setCountry = function(value){
document.getElementById('country').innerHTML = value;
}
There is no need for quoting the code in a string. Instead of this:
a_tag.setAttribute("href", "javascript:...")
Try to form a closure:
a_tag.onclick = function () { ... }
Note that by default <A> elements without HREF do not look normal, but you can fix that with CSS.
Problem solved
Everything was good apart from the way I was declaring the href parameter
a_tag.setAttribute("href", "javascript:setCountry("+'"'+countries[i]+'"'+")");
it's all the usual, a game of single quotes and double quotes.
Thanks everyone for pitching in ideas. Much appreciated as usual
Adrian

Categories