I found a thread on S.O. similar to what I need here. jQuery removing an element and renumbering remaining elements
The above uses jQuery which we don't use so I'm not sure how to translate this idea of div renumbering to Dojo.
I inherited a massive web project that makes extensive use of Dojo 1.5. I totally dig what I understand of it so far but I have a question.
We have a page with numbered divs that I am successfully able to remove and delete the divs from. What I am needing though are divs in sequential order. Here's an example of what I need to re-div
<div id="filter_9_values_2_div">
<div id="filter_9_values_1_div">
<div id="filter_9_values_4_div">
Ideally in my javascript routine where I delete a div, I'd like to rename these in order so they look like this....
<div id="filter_9_values_1_div">
<div id="filter_9_values_2_div">
<div id="filter_9_values_3_div">
Does anyone have any idea how I would pull this off? I know how to successfully add a new div and make it unique but the idea of rewriting the divs is a complete mystery to me. As always many thanks in advance for the help. Janie.
dojo.query('div').forEach(function(el, index){
dojo.attr(el, "id", "filter_9_values_" + (index + 1) + "_div");
});
You might want to use something more specific as a query rather then using just "div" and if you needed more generic ID rather then having the "filter_9_values_..._div" you'd have to use regexp or split to build the string you want but this should give you the basic idea how to iterate over a collection of DOM elements and perform any action on them you could imagine.
Related
Update: 27th December 2016
I did change the heading, since every DOM element could be the target (it actually doesn't matter if it is a <p> element or not).
I've provided some more informations about what I'm using and what I'm trying to achieve. Maybe there are native electron ways to achieve this? Or libs which could help me too?
Product: I'm going to extract tgz files with XMLs in it. Those XMLs will be used to automatically fill tables in the finished product. After that the tables and paragraphs will be editable where users can add new rows to the tables and also add new paragraphs to the page.
Framework: I'm using electron to fire the whole thing up.
Backend: NodeJS 7.x.x to make use of ES6 features
Libraries: jQuery, Bootstrap, Angular, Materialize, lodash, async, moment
Please keep in mind that I already did achieve all of my product needs. My original question was and still is if there is a more performant way of doing this:
I have a html page which can have 'n' containers called pages. A page can hold multiple <p> elements. This <p> elements are set to contenteditable="true".
Now I'm trying to create a javascript function which is checking the single page height with something like this:
// Set max container height to 10cm.
let containerMaxHeight = 377.95276 // 1 cm = 37.795276px;
if(containerElement.clientHeight > containerMaxHeight){
/**
* do desired stuff.
*/
}
everything easy so far. The function is getting the innerHTML of the <p> element which is currently beeing edited and "break the site" into a new site if the page height is above the limit. I have thought out a recursion wich is removing words (most of the time 1-3) of the old <p> element and inserting them to a newly created page with a <p> element until the maximum height of the old page is set to its maximum value.
Here is an example of my recursion (simplified) which is removing words from the end of innerHTML like this:
let lastWordToBeRemoved = oldParagraphElement.split("\\s+").pop();
// append old value to new <p>
newParagraphElement.innerHTML += lastWordToBeRemoved;
// remove last Word from old <p>
oldParagraphElement.innerHTML.slice(0, -lastWordToBeRemoved.length);
/**
* Recheck height of old page container if it is above the
* maximum redo above code
*/
I've startet out with this example:
https://delight-im.github.io/HTML-Sheets-of-Paper/
as you can see the pages are getting bigger and bigger if you edit them. I've already prevented that with my JS function.
Now that you have an idea of what I'm doing: Is there a more performant and or elegant way of doing this? I'm highly interested to hear how you would solve this problem.
If there is anything still unclear let me know, I will update my answer.
Thank you in advance!
Regards,
Megajin
Instead of splitting words, I think you should insert another p element into the expected position instead. Then you can easily move the exceeding paragraph into the new page. For example
paragraphElement.innerHTML = paragraphElement.innerHTML.replace(lastWordToBeRemoved, '</p><p class="exceeding-paragraph">' + lastWordToBeRemoved);
newPage.insertBefore(oldPage.querySelector('.exceeding-paragraph'), newPage.firstElementChild);
Example code
var jqxhr=$.getJSON("http://search.twitter.com/search.json?callback=?",{q:query},
function(data) {
... question.
});
Question
Now i need to create for each tweet result something like this (for example...)
<article class="tweet">
<header>
<img class ="tweet_img"src="data.profile_image_url"/>
</header>
<p class="tweet-text">data.text</p>
</article>
Well, i know several ways to append each result to the document:
Creating a big HTML string and add the data from JSONP and append this to some container.
Create a p element, a header element... work with them and after that append a final Element to some container.
Now the question is: with your experience what is the correct way to do this?
I mean the correct way using good principles.
Please dont ask about the html, it's dumb example.
Thanks.
Well, best practices will tell you not to use the innerHTML property of a DOM element, which is what you'd be doing with option 1. But unless you are concerned about immediately operating on the code with Javascript, attaching events, or security concerns around tag injection (I don't know how much this is an issue anymore) then creating an HTML string and inserting it using innerHTML is going to be a lot quicker and easier to update.
There are several valid approaches that each have their own advantages...
The technique of just generating the HTML as a string in your java code and adding it with .innerHTML is known to be one of the fastest performing approaches...but it provides very little validation of your HTML.
Alternatively, you can build the HTML using DOM methods directly, creating tags and appending them to build the structure. This is generally safer in that you have more validation going on, but the DOM methods are extremely wordy, which makes them a bit painful to type...and the code is even more verbose as you have to add attributes one at a time as well.
My personal preference, especially since you're already using JQuery, would be to build the tags and text nodes using JQuery, and put them together using JQuery, which allows you to do so in bite-sized, more human-verifiable units, without becoming overly verbose.
This also has the advantage that JQuery's methods of producing new tags give you additional support for older browsers that did not adhere to DOM standards. Hopefully you don't actually have to care whether your page works for those older browsers, but more compatibility never hurts either.
In that approach, you'd write something like the following:
var article = $('<article class="tweet"></article>');
var header = $('<header></header>');
var image = $('<img class="tweet_img" src="' + data.profile_image_url + '"></img>');
var tweet = $('<p class="tweet-text">' + data.text + '</p>');
header.append(image);
article.append(header, tweet);
$("#id_of_content_area_to_add_the_tweet_to").append(article);
The cleanest way I know how is to use a template system like Mustache, instead of "HTML in JS"
var template = html_string, //HTML from a string or from AJAX
data = {...data...}, //structured data
html = $(Mustache.render(template,data)); //wrap in jQuery to operate
html.appendTo(somewhere_in_DOM);
If you want to attach some event handlers to the elements then you should generate them separately.
But if you don't want to attach any event handler then i will recommend first method
$("body").append('<article class="tweet"><header><img class ="tweet_img" src="'+data.profile_image_url+'"/></header><p class="tweet-text">'+data.text+'</p></article>')
I will recommend you to use some Template engine like Handlebars.js Which is the right solution for your problem.
Which is having many more options which has many more conditional options which can be useful in feature. Just visit the above link you will have some idea.
I have the following code that creates and deletes text boxes using javascript:
http://jsfiddle.net/JpYGg/8/
What I am aiming to do is infact create a set of three drop-down lists using this functionality instead of creating a textbox.
The code for the three drop-downs is shown here:
http://jsfiddle.net/MWH99/
I am a bit stuck as to how to achieve this. I added in the "dropdown" div and what I was thinking is to get the innerHTML of this div in order to use that to create the three lists every time?
The other question I have is how to have it so that these are generated by the javascript instead of an HTML one AND a JavaScript version.
Thank you for any help.
Martin
EDIT
I have the buttons working to create the next row of 3 drop-downs but they do not function the way that the original does, the parent drop-downs use javascript to identify the selection in the first drop-down in order to update the other two whereas the cloned ones lose this functionality.
Code cna be found here:
http://pastebin.com/pt1wef76
Original drop downs use dropdown.js which is http://pastebin.com/bDLpFWJY
Why not use a javascript library like jQuery for example. Would make this and many other things much easier. Could achieve what you want like this:
$('body').append('<!-- ANY HTML GOES HERE -->')
There's two basic approaches; create all of the elements in JavaScript, or copy a part of the DOM (some HTML) over and over.
People often put HTML in script tags (see jQuery Templating, for example), and then get the innerHTML of the tag and use that. For example,
<script type="text/plain" id="template">
<!-- HTML that you want to duplicate in here -->
</script>
<div id="contentcontainer">
</div>
...
<script type="text/javascript">
var addAnother = function( ) {
$("#contentcontainer").append(
$("#template").html()
);
};
</script>
This example makes use of jQuery primarily because jQuery is a lot less verbose and easier to read, but you certainly don't have to use jQuery. Here, the addAnother function will copy the HTML from #template and append it into #contentcontainer.
In your attempt above, you probably meant $('body').append($('#dropdown')); '#dropdown' is just a string, $('#dropdown') returns the element (or elements) with id="dropdown".
How do I get the values in between a DIV tag?
Example
<div id="myOutput" class="wmd-output">
<pre><code><p>hello world!</p></code></pre>
</div>
my output values I should get is
<pre><code><p>hello world!</p></pre>
First, find the element. The fastest way is by ID. Next, use innerHTML to get the HTML content of the element.
document.getElementById('myOutput').innerHTML;
document.getElementById("myOutput").innerHTML
innerHtml is good for this case as guys suggested before me,
If you have more complex html structure and want to traverse/manipulate it I suggest to use js libraries like jQuery. To get want you want it would be:
$('#myOutput').html()
Looks nicer I think (but I wouldn't load whole js library just for such simple example of course)
Just putting all above with some additional details,
If you are not sure about that div having some id is not there on html page then to make it sure please use.
var objDiv = document.getElementbyId('myOutput');
if(objDiv){
objDiv.innerHTML;
}
This will avoid any JavaScript error on the page.
I've been using JSON to handle AJAX functionality in my rails applications ever since I heard about it, because using RJS/rendering HTML "felt" wrong because it violated MVC. The first AJAX-heavy project I worked on ended up with 20-30 controller actions tied directly to specific UI-behaviors and my view code spread over controller actions, partials and rjs files. Using JSON allows you to keep view specific code in the view, and only talk to view agnostic/RESTful controller actions via AJAX to get needed data.
The one headache I've found from using pure JSON is that you have to 'render' HTML via JS, which in the case of AJAX that has to update DOM-heavy elements, can be a real pain. I end up with long string building code like
// ...ajax
success: function(records){
$(records).each(function(record){
var html = ('<div id="blah">' + record.attr +
etc +
')
})
}
where etc is 10-15 lines of dynamically constructing HTML based on record data. Besides of the annoyance, a more serious draw back to this approach is the duplication of the HTML structure (in the template and in the JS).* Is there a better practice for this approach?
(My motivation for finally reaching out is I am now tasked with updating HTML so complex it required two nested loops of Ruby code to render in the first place. Duplicating that in Javascript seems insane.)
One thing I've considered is loading static partial files directly from the file system, but this seems a bit much.
I like the idea of templating. In my experience it can really clean up that messy string manipulation!
There are many solutions, for example, check out John Resig's (creator of jQuery):
http://ejohn.org/blog/javascript-micro-templating/
I would go with creating an HTML structure that contains placeholders for the elements you'll need to update via AJAX. How much structure it applies will depend on what you're updating; if you know the number of elements you'll have ahead of time, it would be something to the effect of
<div id="article1">
<div id="article1Headline"></div>
<div id="article1Copy"></div>
<div id="article1AuthorInfo"></div>
</div>
<div id="article2">
<div id="article2Headline"></div>
<div id="article2Copy"></div>
<div id="article2AuthorInfo"></div>
</div>
You then write code that references the id of each element directly, and inserts into the .innerHTML property (or whatever syntactically more sugary way jquery has of doing same thing). IMHO, it's not really so terrible to have to assign the contents of each element, the part that you don't want to have to sprinkle through your AJAX functions is the HTML structure itself; in your app the content is volatile anyway.
However, it looks like you might have a list of an unknown number of elements, in that case it may be that you'd need to just put in a placeholder:
<div id="articleList"></div>
In that case I don't really see a way to avoid building the HTML structure in the javascript calls, but a reasonable amount of decomposition of your javascript should help that:
function addArticle( headline, copy, authorInfo, i ){
createDiv( "article" + i + "Headline", headline );
createDiv( "article" + i + "Copy", copy);
createDiv( "article" + i + "AuthorInfo", authorInfo );
}
(not working code of course, but you get the idea,)
You could use the load function in jQuery;
This loads the content of a page into a div like this:
$('#content').load("content/" + this.href.split('#')[1] + ".html", '', checkResponse);
Just make a dynamic view and you are good to go...
Just happened to find exactly what I was looking for: Jaml