Reload DIV from javascript - javascript

I'm not an experience programmer in JavaScript and I'm struggling with reloading data in a specified DIV.
I have an example here. The original code is more complex I contains a calendar with disabled days. After the update new disabled days are calculated and should be listed in the calendar. However this example shows the issue. When clicking the button the text "Updated text" should appear instead of "Original text".
Any suggestions?
var bla = "Original text";
function js_updtest() {
bla = "Updated text";
$("#test").load(" #test");
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="inlay">
<div id="middle">
<div id='test'>
<script type="text/javascript">
document.write(bla)
</script>
</div>
<input type='button' value='Update' name='Updatetext' onclick='js_updtest();'>
</div>
</div>

There are a couple of fundamental problems here, and your best bet is probably to start over on some introductory JavaScript tutorials. But specifically the two problems are:
Here you set a new value to a variable:
bla = "Updated text";
But you don't re-use that variable anywhere. It was used once, with its initial value, when the page loaded. Updating the value of a variable doesn't update all of the places where it has already been used.
After updating it, use it. For example:
document.getElementById('test').innerText = bla;
(Note that this would also be a better way to initially use the variable on page load. document.write() is pretty much universally frowned upon. Don't think of it in terms of writing to the document, think of it in terms of identifying the DOM element to update and updating it.)
What are you even trying to do here?:
$("#test").load(" #test");
The jQuery .load() function is for making an AJAX request to fetch new content from the server and directly write it to a target element. But that doesn't appear to be what you want to do here at all. It looks like this statement (and jQuery in general) can just be removed.

Related

How do I tell a Javascript method to wait until after binding values to execute in DotVVM?

I use a value binding (<dot:HtmlLiteral Html="{value: BannerHTML}" class="mainBanner"/>) to generate some of my page content based on a number of variables.
I also need to run some javascript on the generated HTML to fix a few minor niggles, like matching font size for unusual scaling scenarios and the like. As standard, I place executable javascript at the end of an HTML document.
Generated HTML in one of these scenarios:
<div class="mainBanner" data-bind="html: BannerHTML">
<div class="mainBanner-upper">some text</div>
<div class="mainBanner-face" id="mainTitle">some other text</div>
<div class="mainBanner-lower">some more text</div>
</div>
JS to operate on that HTML:
(requires https://github.com/adactio/FitText.js)
window.fitText(document.getElementById("mainTitle"));
As far as I can see, the javascript executes before the HTML is generated, and javascript that is executed on the element returns Cannot read property 'xyz' of null. How do I tell it to wait? I tried both binding the javascript file to a resource, and simply writing it in with <script> tags at the end of the body element without success.
As your problem seems to be DOM related, I can propose you two approches.
Your javascript must check and wait for DOM. On which I strongly suggest you to read this answer to ...how to call a function when the page/DOM is ready...
Add your script dynamically after your data is binded (I'm not really sure about this)
Good luck.
EDIT
So I went and took a look to the dotvvm documentation to look for events calls and noticed something interesting :
Every DotVVM page includes Dotvvm.js which defines dotvvm in the global scope. This object can be used to access viewmodel and react to various page events.
This allows you to access specifics events fired by DOTVVM, you only have to find the one you need in your case. I provided you with an example below.
You could try something like this (the event may no be the one you need) :
<script>
//By subscribing to the event, your code will only be executed
// if "init" event is fired by dotvvvm
dotvvm.events.init.subscribe(()=>{
window.fitText(document.getElementById("mainTitle"));
//basically enclose the content of your script tag with this.
});
</script>
Please do read the documentation as I may have omitted something ? DOTVVM Javascript Events

Injecting HTML5 data attributes vs. Injecting javascript data structure

I am curious as to which of the following is better practice (and why):
Injecting data as HTML 5 data attributes:
<div class="someDiv" data-for-popup="someData"></div>
Injecting a <script> into the file with some data structure
<script>
var myMap = new Map();
myMap.set('someKey','someValue');
</script>
In both cases, I would be using javascript/jQuery to look up the value, but which is the better solution?
A little background: I am creating a static page (no communication back and forth with the server besides servicing the page) so I can't use AJAX or any other server communication to service the data. The data being injected is used for a popup that is displayed on the page when "more information" is requested for a certain page object. In other words, I need the data to be present somewhere on the page, and I'm looking for the best avenue to do so, and I am also curious why that would be the best option.
Which one is better will depend on the use you want to give to that value, and on how the value is related to a particular element. So there's not a generic answer to your question, as it would go in a case-by-case basis. A good rule of thumb would be what some people commented:
If the data is useful and specific to that element, use data-*.
If there's no connection between the data and an element, use a variable in <script>.
But there's a misconception in your question, and you are missing (imho) a really important use case: data-* attributes are not exclusive for JavaScript, they can be seen and used in CSS (as part of a selector or to be used as a value), while variables inside a <script> tag are hidden to the CSS and cannot be used.
Right now data-* attributes are mainly supported in the content property for ::before and ::after but, at least in theory, they will be allowed in other properties making them more useful for styling purposes. For example:
div[data-columns] {
column-count: attr(data-columns);
}
That rule will save you having multiple rules in your CSS, it will simplify your code and make it more robust and easier to maintain... sadly, it is not supported yet.
Store in the DOM element only what is specific for it, such as text and/or title for the popup window.
In this way your JS function can rely on the element to construct the popup.
<button data-content="My popup content" data-title="My title">More information</button>
<button data-content="My 2nd content" data-title="My 2nd title">More information</button>
$("document").on("click", "button", function () {
var $this = $(this),
title = $this.data("title"),
content = $this.data("content");
//open your popup
//$this.popup({ title: title, content: content });
})
As others have said, you should only store short, specific information about the element with a data-*.
If you are looking to display a 'more info' style popup, containing lots of information. I would store that information in a hidden div that is referenced by the element. Then use JS to show that element.
<button type="button" data-target="#product-1-more-info">Product 1</button>
<button type="button" data-target="#product-2-more-info">Product 2</button>
<div id="product-1-more-info" style="display:none;">
More awesome info about product #1
</div>
<div id="product-2-more-info" style="display:none;">
More awesome infor about product #2
</div>
<script>
$('button').click(function() {
$($this.data('target')).show();
});
</script>
Of course this can be dressed up with animations and light box effects. But now you aren't storing giant amounts of data in the element and your JS is much simpler.

Replacing text with javascript?

After much trial an error and some progress I still can't mange to change every instance of ,- with kr on my website.
I'm very much a beginner at JS and have pieced together the following code from several sources. Is the code the problem or something else?
function skrivkr() {
var skrivkr = $('div').text().replace(/\,-/g, 'kr');
$('p').html(skrivkr);
}
window.onload = skrivkr();
Update:
Thanks for the replies. The site loads jquery 1.10.7.
#Niet the Dark Absol: No, I don't want to put anything in p elements. How do I remove that part? I just want to find all ,- and simply replace with kr without changing any formatting.
Update
OK! Progress, kind of. The ENTIRE content of every <strong> and <dd> now changes to (0), instead of kr. With the odd exception of those tags including ,-. I haven't designed the site myself.
If it helps, one of the ,- appears in the following markup:
<a href="xxxx" rel="nofollow">
<span class="amount">1</span>
<span class="photo">
<img src="xxxx" alt="product name" width="62" height="42">
</span>
<span class="description">
Prtoduct name
<strong>4444,-</strong>
</span>
</a>
And the lastest script I'm applying is:
$(document).ready(function() {
$('strong, dd').html($('strong, dd').html().replace(/,-/g, 'kr'));
});
As has been mentioned innumerable times here on SO, do not try to manipulate the DOM as a string. Pain awaits.
Instead, traverse the DOM, finding text nodes, and perform whatever transformation you want to make on each text node. There are many ways to do that.
In your case, you have many problems, as mentioned already by some of the commenters and responders:
You're setting window.onload to undefined (the result of calling skrivkr), instead of to skrivkr itself.
You're extracting the text value of an element, which consists of the concatenation of all text down all levels, performing the replacement, then sticking it back in with html. This will wipe out all the element structure below.
Minor point, but there's no need to escape the comma in the regexp.
You're extracting the textual content of all div elements in the entire document, transforming it, then adding that back as the content of all p elements in the entire document. It's hard to imagine that's what you want to do.
You can update the content of each div like this
$(document).ready(function() {
$('div').each(function(){
var newText = $(this).html().replace(/,-/g, 'kr');
$(this).html(newText);
});
});
You can remove the var "newText = " and replace it with $(this).html($(this).html().replace(/,-/g, 'kr'));
The first example is easier to understand perhaps if you are new to programming.
You will, however only change the content of text placed in tags.
I would place the text to replace in a div with some predefine class, like "autoKronor", it would then look like this:
<div class="autoKronor">123,-</div>
and
$(document).ready(function() {
$('.autoKronor').each(function(){
var newText = $(this).html().replace(/,-/g, 'kr');
$(this).html(newText);
});
});
to en sure that only text you intended to change gets changed..
Example here: http://jsfiddle.net/akm1uw8h/2/
Also note the use of $(document).ready(); instead of window.onload. It does what you intended to do with window.onload.
if you really want to change EVERY single instance of ",-" to "kr" then you could do this:
$(document).ready(function() {
$('body').html($('body').html().replace(/,-/g, 'kr'));
});
But i strongly advice against the last example because it will be the slowest to compute and more importantly you might change stuff you don't intend to, like any script block inside the page body (with that i mean other javascripts)

Pass a PHP variable from a loop via an onclick

This may have been answered elsewhere but I couldn't find a question which fit my circumstances.
I have a site page which out puts in DIVs records from a database, this the same DIV looped. In this DIV I have a button which brings up a modal box. This modal DIV however is not coded within the looped DIV.
I need the modal box to be able to get the ID of the record for the data which the looped DIV is showing.
The button is:
<a href = "javascript:void(0)"onclick = "document.getElementById('light2').style.display='block';document.getElementById('fade').style.display='block'">
<div class= "obutton feature2">Reserve Book</div>
</a>
I assume I'll need to use java script somehow, but I don't know how to use it in this manner.
Ideally using some sort of form $_POST would be easiest with the form button having the set value of the $row->ID, but I can't make a form button also a can I?
Sorry for the possibly silly question, as I've said I've found similar things asked, but always find it hard to understand the full workings on other peoples scenarios as opposed to my own.
All help appreciated -Tom
I think the key to your answer is understanding how JS (and jQuery) uses this. When a function is called, the caller is almost always passed as the this variable. For example:
<button data-id="1234" onclick="runThisFunction()" value="run" />
<script>
function runThisFunction() {
//Do Stuff
var data_id = this.data('id');
};
</script>
In the above code, this contains the button that was clicked on. You can get lots of information from the this variable. In jQuery, you can even get to siblings, parents, or children in the DOM.
Here is an example solution to your question:
http://jsfiddle.net/yr6ds/1/
Here is a more elegant solution:
http://jsfiddle.net/yr6ds/2/

reccommended way to output HTML from JavaScript

I know this has probably been asked before, but here goes: I have a web application that needs to generate modal dialogs. alert, confirm, and prompt are too simple and ugly, and that modal window function...it's a long story. I can't use it. So, I'm going to create the modal box using DOM functions and CSS. However, I need to put quite a lot of content into the dialog, and I'm wondering what the best way to do this is. Putting the HTML into a string and using innerHTML is unwieldy. I could use the DOM, but that's annoying and takes too much time to code. I know I can use a script with a weird type tag (something like x-random/x-htmlstuff) and then copy it's content to the innerHTML, but is there a better, more "official" way to do this?
if the layout of the modals are static, just put them into the HTML of the page. Use CSS to set them to display: none when the page is displayed normally. When you want to display the model, use
document.getElementById('modal-id').style.display = 'block';
I've heard that some people use this solution:
<script type="text/html" id="popup_html">
html...
</script>
(of course, you should make it invisible)
But, most likely, if you're trying to write a lot of HTML from javascript, then you should retrace and think if there's a better way.
If you're using the same div multiple times, you should just create it in the HTML page, and display it when needed
if you're creating a new element - see if you can use the document.createElement and appendChild methods (assuming there aren't many nodes involved)
if neither apply - retrace. For large projects, maybe object-oriented javascript can help.
There's no magical way that I'm aware of. I usually just use innerHTML and write the HTML out in a well formatting from such as:
box.innerHTML = "<div id='boxChild'>\n" +
" <p>Put whatever content here</p>\n" +
"</div>";
The \n make it so if you view your code, it will be well formatted, and no one long string once the JS writes it.
A way to do this, is to generate the popups within the html and show or hide them when you need, like this:
<div class="myPopup">
<div class="pop-message msg-01">This a pre generated alert with the id: <span class="dynamic-field-01"></span></div>
<div class="pop-message msg-02">This another pre generated alert with the id: <span class="dynamic-field-02"></span></div>
<div class="pop-message msg-03">...</div>
</div>
.pop-message {
display: none;
}
Now while user navigates the page, you are going to hide and show the .pop-message's while replacing those .dynamic-field's if needed.
I would suggest having the HTML for your modal content in separate files, and then loading it asynchronously when you need it to popup the modal.
partials/modal.html
<div class="content">My modal content</div>
main.js
var modalContent = null;
function _fillModal() {
modal.innerHTML = modalContent; // something like this
}
function openModal() {
if (!modalContent) {
// XMLHttpRequest, which populates the modalContent variable
// and in the callback, calls _fillModal()
}
// If already filled, just call
_fillModal()
}
If you want the content to be dynamic, make modal.html a template, and use a JS template library (for example http://underscorejs.org/#template), or write a simple RegExp replace yourself.
I'd suggest loading it with innerHTML or using jQuery to simplify things, but if you need
a modal window, could you use the jQuery UI modal dialog, shown here?
If you have the content loaded in divs in your HTML, and have them have css display:none;, and then show them with
document.getElementById("unshown-div").style.display="block";
If you can use jQuery, a modal box could be done with
<div id="modal" style="display:hidden">
Here is a modal dialog bbox
</div>
and your script:
$("#dialog").dialog();
Whatever you do, just don't use document.write()

Categories