Dynamically name divs in partial for use later? - javascript

I have a partial view which contains a div, then that div id is currently static. If I use this partial view multiple times, my Javascript class only loads the first div. What is the MVC convention to give these divs a unique ID so this doesn't happen any longer? Would generating a random number work?
Sample code:
<div id="test"></div>
<script type="text/javascript">
var loader = new Class('test');
</script>
Ideally I'd like it so every time I render the partial view, an incrementing number is appended to id="test.

Seems like there are many ways to tackle this. It looks like it is important that you be able to reference the additional element in a JS class after loading it. There are a couple of approaches that come to mind.
1) Add div dynamically via JS ( I am using jquery here to simplify the task ):
add to your class definition:
<script type='text/javascript' >
/* you need to add a static method to your class to create
a unique id.
Note that this should not be part of your partial view - it
is only defined once - wherever you have defined your class.
*/
Class.idNum = 0;
Class.uniqueId = function() { return 'MyDiv_' + idNum++; };
</script>
partial becomes:
<script type='text/javascript' >
// you need to have a
var newId = Class.uniqueId();
var newDiv = jQuery('<div id="' + newId + '" />' );
// figure out where you need to append it, e.g. to the html body:
jQuery('body').append( newDiv );
var loader = new Class( newId );
</script>
2) However, a simpler method might be avoiding ids altogether, which is more typical in this kind of dynamic code in my experience. In this solution, you add all your divs via partials, identify them as a group with a unique class name, and then reference that class name to grab all those divs as a group and iterate over them to create your classes. Of course, you would have to rewrite your class to refer to these divs by their DOM elements rather than an ID attribute.
Partial becomes:
<div class='MyDescriptiveClassName' ></div>
Then, after all partials have been added, you would have something like the following javascript:
<script type='text/javascript' >
jQuery('.MyDescriptiveClassName').each( function( index, elem ) {
// pass in the DOM element for accessing this div.
var loader = new Class( elem );
});
</script>
Hope that helps.

Related

If URL contains this string then hide all divs with this class/id (loop script)

I am trying to hide some divs when url contains an specific string.
For example, i have this code that hides the first div:
<div id="ficha">Hello</div>
<div id="ficha">world</div>
<div id="ficha">...</div>
<script>
if (/info|mapo/.test(window.location.href)) {
document.getElementById('ficha').style.display = 'none';
}
</script>
URLs:
www.example.com/all ------> Not hide the div
www.example.com/info-----> Hide the div
www.example.com/mapo---> Hide the div
The first problem with the script is that it only hides the first div saying Hello, but i want to hide all the divs. So, i think it's necessary to do a loop... ¿how can i do that?
The second thing is running two different scripts to hide different divs according the url string content.
Maybe this can be achived by making an else function. Always the loop its necessary and even better if it's executed after load page.
For example:
<div id="ficha">Hello</div>
<div id="ficha">Hello2</div>
<div id="ficha2">world</div>
<div id="ficha2">...</div>
<!-- First script hides divs with id="ficha" if url string has "info" or "mapo" -->
<script>
if (/info|mapo/.test(window.location.href)) {
document.getElementById('ficha').style.display = 'none';
}
</script>
<!-- Second script hides divs with id="ficha2" if url string has "all" -->
<script>
if (/all/.test(window.location.href)) {
document.getElementById('ficha2').style.display = 'none';
}
</script>
The code will be execute in Database Activity of Moodle.
Thanks in advance.
This script will help you.
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
window.onload = function () { //The function to execute when the page is loaded
var string_contain = ''; //Set this as your string
var url = window.location.href;
if(url.indexOf(string_contain) >= 0) { //If url contains then...
var x = document.getElementsByClassName("your_class"); //Create an array that contains your divs with your_class class
for(var a = 0;a<x.length;a++) { //Do some stuff for each value of the array
x[a].style.display = 'none';
}
}
}
</script>
</head>
<body>
<div class="your_class"></div>
</body>
</html>
Remeber that the ID is associated with just one element, so it won't work if you're trying to access more than one element.
You've got a few issues here:
First, like user adeneo mentioned in their comment, you cannot share IDs. Classes, however, can be shared so you probably want your <div> elements to say class="ficha".
Second, you want to hide or show divs based off of a string in the URL, but your URLs are composed of unique paths. You're trying to hide divs, when you should just be building the pages differently. Unless there's more information you need to add about this.
www.example.com/mapo is, at least in the representation you've provided, a different HTML page from www.example.com/info so why not build them as separate pages rather than going through unnecessary logic to show and hide <div> elements?
The third issue: you don't want a for loop so much as a for-each loop. This first question will give you direction on how to select all elements with the specified class:
JavaScript get elements by class name and tag name
Then using the array you've selected from the above information, you can use Javascript Documentation for using forEach on arrays to change your elements' visibility.
Since its not unique, a CSS class would be more appropriate. Something like this should work:
function hideItemsByClass(className){
var matchedItems = document.getElementsByClassName(className);
for(var i = 0; i < matchedItems.length; i++){
matchedItems[i].style.display = 'none';
}
}

Copy divs with certain id's to targets with related id's

How do I copy the content from all divs with a certain class or a certain beginning of an id to a bunch of divs with related id's? The examples I found didn't go through multiple copies. I have a solution that is working ok but instead of calling each copy with the id I would like to make the logic better.
Here's what I have now.
HTML (handlebars template)
<!-- the id comes from handlebar content. There are many like this -->
<pre><code id="target-example-01" class='language-markup'></code></pre>
<!-- this content is put to place once handlebars has rendered the page -->
<div id="code-examples" style="display: none;">
<div class='code-example' id="source-example-01">
this is my a code example... there are many like me...
</div>
</div>
Javascript
var source = document.getElementById('source-example-01').innerHTML;
var target = document.getElementById('target-example-01');
if (target) target.innerHTML=source;
This works ok but I have 100 examples so I wouldn't like to have 300 lines of code to manually maintain just to copy the content. How do I go through all the divs with "code-example" class and copy their content to divs with a matching id. All the source divs will have the id="source-(example-identifier)" and all the target divs will have the id="target-(example-identifier)". I guess the class wouldn't be needed if the code would go through all items with the id beginning with "source-"
I would be old school and stick with using getElementsByClassName() but since the question is how to target divs will have the id="target-(example-identifier) you can use querySelectorAll()
document.querySelectorAll('div[id^="source-example-"]')
for more information about querySelectorAll()
Returns a list of the elements within the document (using depth-first pre-order traversal of the document's nodes) that match the specified group of selectors. The object returned is a NodeList.
So the output is very much like using getElementsByClassName()
If you have any questions please leave a comment below and I will reply as soon as possible.
How to target a specific tag with a class and id?
document.querySelectorAll('div.code-example[id^="source-example-"]')
You will still need to loop through the contend just like you would for returning elements by class name but this query selector will only return div elements with the class name code-example and contains source-example- in the id attribute.
function QuerySelector() {
var Selector=document.querySelectorAll('div.code-example[id^="source-example-"]');
for(var i=0; i<Selector.length; i++){
alert(Selector[i].innerHTML);
}
}
<div class="code-example" id="source-example-01">Content Line One. - with class and id </div>
<div class="code-example">Content Line Two. - with correct class but no ID</div>
<div class="code-example" id="source-example-02">Content Line Three. - with class and id </div>
<button onclick="QuerySelector()">Get</button>
I hope this helps. Happy coding!
How do I go through all the divs with "code-example" class and copy
their content to divs with a matching id
Assuming that index of code-example elements is same as that of targets, then try
var allCodeExamples = document.getElementsByClassName( "code-example" );
for ( var counter = 0; counter < allCodeExamples.length ; counter++ )
{
var index = ("0" + counter).slice( -2 );
var target = document.getElementById( "target-example-" + index );
target.innerHTML = allCodeExamples[counter].innerHTML;
}
You can make use of data attributes for this using jquery:
<!-- the id comes from handlebar content. There are many like this -->
<pre><code id="target-example-01" class='language-markup'></code></pre>
<!-- this content is put to place once handlebars has rendered the page -->
<div id="code-examples" style="display: none;">
<div class='code-example' id="source-example-01" data-target="#target-example-01">
this is my a code example... there are many like me...
</div>
</div>
$(function(){
var targetId;
$(".code-example").each(function(){
targetId = $(this).attr("data-target");
$(targetId).html($(this).html());
});
});
I realised it makes more sense to check which examples are on the page and fetch the content for their source id's. I added another class to the code-tags "target-example"
Here's the javascript (jquery would probably make it nicer looking)
var examples = document.getElementsByClassName('target-example');
var i;
var id;
for (i = 0; i < examples.length; i++) {
id = examples[i].id;
var source = document.getElementById('source-'+id).innerHTML;
if (source) examples[i].innerHTML=source;
}

dynamically changing a div ID and other element's ID within the div

this is the div im trying to copy
{%for i in current_user.posts%}
<div class = "own_posts" id = "{{'id_' + i.id|string}}">
<img src = "{{url_for('static',filename='user_prof_pic/' + current_user.prof_pic)}}">
{{current_user.first_name}}
<p>{{i.post}}</p>
<div class ="like_comment">
<ul>
<li>like</li>
<li>comment</li>
</ul>
</div>
<form class ="comment_form">
<input type="text" action = "#" name = "comment_box" class ="comment_box" id = "{{'id_' +i.id|string}}">
<input type="submit" value="comment" class ="submit" id = "{{'id_' + i.id|string}}">
</form>
</div>
{%endfor%}
so far I've been successful at prepending it and changing the newly prepended div's ID using jquery like this.
var count = 4
$(".submit").click(function(event){
event.preventDefault()
var id = $(this).attr("id")
var comment = $(".comment_box#" + id).val()
console.log(count)
count++
$.ajax({
type:"POST",
url:"#",//"{{url_for('main.ProfilePage',user = current_user.first_name)}}",
data: JSON.stringify({"comments":comment}),
contentType:"application/json;charset=UTF-8"
});
var div_copy = $(".own_posts#id_2").clone()
var div_copy2 = div_copy.attr("id","id_" + count)
$("#own_stream").prepend(div_copy2)
});
however the form ID within the prepended div still contains the ID of the div it was cloned from. to clarify
var div_copy = $(".own_posts#id_2").clone() the form in this div contains an id of id_2 so the newly prepended div's form id is still id_2
I changed the prepended div's ID doing this:
var div_copy = $(".own_posts#id_2").clone()
var div_copy2 = div_copy.attr("id","id_" + count)
$("#own_stream").prepend(div_copy2)
but I don't know how to access the form within this newly cloned div and change it's form ID.
how do we achieve this?
also am I doing this right? Im trying to learn web development and wan't to understand how sites like facebook,twitter etc. are showing your newly posted statuses/tweets into the page without refreshing it.
is what I'm doing the gist of how that works? if not
shed some light on a newbie
also this is just a test to practice the concepts
If all you are attempting to do is retrieve the form element using jQuery, based on your source, you have multiple options.
var form = $(".own_posts#id_2 > form");
/* or */
var form = $(".own_posts#id_2 > .comment_form");
I don't normally suggest the direct descendant method because if your genealogy changes in the future, it will fail. You are using templates so intuitively I see future changes to it a possibility. Using a unique identifier or known singular class and searching the entire div chain makes more sense to me.
var form = $(".own_posts#id_2 .comment_form");
/* or */
var form = $(".own_posts#id_2").find(".comment_form");
Those two options should be roughly equivalent for your purpose and can use either.
Also I would be careful with non-unique ids. You may get away with it by only searching smaller scoping chains, but you're only supposed to have one on the page. This is why most functions that retrieve by id will return only the first object found, rather than a collection.
I don't know how you're using the ids, but perhaps something like id="{{'posts_' + i.id|string}}" and so on to utilize unique prefixes.

What is an efficient way to inject j/s variables into a reusable block of HTML without mixing the two in a j/s file?

Basically, I have an autocomplete function to help users select an item. When they select an item, a series of variables relating to the item are saved. Once they click 'add', the variables are then injected into an HTML template, and the HTML template is injected into the DOM. My question is, how can I do this without having to mix my HTML code with the j/s code i.e. var example = "<div id='" + divId + "'></div>"; (etc.) I hope the question is clear enough.
Have you looked into jQuery Templates? It's basically client-side data binding, which seems like what you are trying to do.
For example, you can do stuff like this..
Assuming you have a list of Song objects, defined as:
var song = {
title : 'Purple Rain',
artist : 'Prince'
};
HTML:
<!-- Template definition -->
<script id="tmpl_songList" type="text/html">
<li>
<a>
<span>${title}</span>
<span>${artist}</span>
</a>
</li>
</script>
<!-- HTML container to host data-bound list -->
<ul id="song_list"></ul>
JS:
// bind data (songList) and append to HTML container.
$.tmpl($('#tmpl_songList'), songList).appendTo($('#song_list'));
You could do:
var example = $("<div />").attr("id",divId);
But when you have a lot of nested tags it can be tedious to create each element, in those cases i mix them up.
Try:
var myID = "id";
var myText = "Some Text"
$('<div/>', {
id: myID,
html: myText
}).appendTo('body');
You can add more properties, if needed.
On the other hand, if your manipulations are complex, use a template engine. It is easier to maintain.

Writing to a non-unique div with Javascript

I'm building a multi-feed RSS reader for school.
aList is the div that encompasses each individual feed (the amount of feeds will fluctuate).
theTitle is the div that will be filled with the attribute of the current feed. Additionally, if clicked, it will load a list of attributes from the current feed into theContent.
I'm wondering how I can dynamically load the attributes into theContent when theTitle is clicked, since theContent and theTitle are going to be non-unique divs (I can't give them IDs).
Thanks for your help in advance,
-Andrew
document.getElementsByClassName('aList').getElementsByTagName('div')
You should look into jQuery selectors for that and other DOM Manipulation. Something like
$("div.theContent").attr("name", "value");
by using jquery, you may use code like the following:
$(".theTitle").bind("click", function(){
$el = $(this);
$el.parent().$(".theContent").load('ajax/content.php?news=' . $el.text());
});
this will make all your links clickable, an on click, update their corresponding content divs with the value of ajax/content.php?news=theTitle-value
Use a nice Javascript library such as Prototype or jQuery. Seems petty now, but these frameworks save you tons of time in the long run.
In both frameworks, you can select that div with:
$('div.theTitle')
With jQuery, you can do:
$('div.theTitle').click( function() {
var title = $(this).text();
var contentDiv = $(this).siblings('div.theContent');
// Do something with contentDiv and the title
} );
This will make every theTitle div have an onClick event that does something with its associated theContent div.
<div class="aList">
<div class="theTitle" onclick="fillContentBox(this)"></div>
<div class="theContent"></div>
</div>
And in your script ...
function fillContentBox(div) {
var theContentDiv = div.parentNode.getElementsByTagName("div")[1];
// statements that do things with theContentDiv
}
You have to be able to determine which element you want to update if you don't want to update more than one. If the elements are grouped inside something else that does have an "id" value, you can take advantage of that.

Categories

Resources