-2

I want to replace the content in the current element with and html string taken out of an object.

It has to work dynamically regardless of what div, p...etc it is in.

<div id="content">
    <h5><script>$(this).append(en.login_terms_and_conditions);</script></h5>
</div>
Nikk
  • 7,384
  • 8
  • 44
  • 90
  • what have you tried so far / – Akhil Aravind Jun 13 '18 at 10:09
  • @AkhilAravind What you see above. And `document.write`—which works but doesn't replace the content just adds it to the bottom. – Nikk Jun 13 '18 at 10:10
  • use `$(this).html()` instead of `append()`. – vikscool Jun 13 '18 at 10:11
  • @vikscool Tried that one already, didn't work. No error is thrown in the console either. – Nikk Jun 13 '18 at 10:11
  • can you create a snippet showing problem. Sorry but I am not clear what you are asking for – Muhammad Usman Jun 13 '18 at 10:12
  • I have an object where I have strings with different translation. The object is named `en` for english. I am trying to pull the contents for item `login_terms_and_conditions` and replace them in the container. – Nikk Jun 13 '18 at 10:13
  • The possible duplicate shows how to use jQuery to replace HTML content. Please us the exact selector you wish to replace the HTML with, such as `$(#content h5).html()` or similar. If you have issues with determining the exact selectors that would be a separate issue. Also check out the jQuery online documentation on [**.html()**](http://api.jquery.com/html/) and more to get a better understanding how it works. – Nope Jun 13 '18 at 10:18
  • @Nope - The OP doesn't want to use a selector at all, they want to do it by context. – T.J. Crowder Jun 13 '18 at 10:20
  • @T.J.Crowder I'd imagine a mapping function still will need to use selectors, no? Even if marked with `data-title` or similar attribute to mark where a title goes for example no matter which language. Then again, if translation is what the aim is, maybe JavaScript language files would be better suited? Or the server could serve the correct language strings as needed? – Nope Jun 13 '18 at 10:22
  • 1
    @Nope - See [my answer](https://stackoverflow.com/a/50834722/157247); no selectors. But as I also say in that answer: I wouldn't do it this way. As you say, there have to be better solutions. – T.J. Crowder Jun 13 '18 at 10:25
  • @T.J.Crowder I see. I never seen contextual aware script tags in practice. Was about to re-open the question as it does seem to ask for a different solution but someone already done so. – Nope Jun 13 '18 at 10:28
  • @T.J.Crowder in your answer you add text to the element, but what if you need to add a key's value of an object ? You need to declare that object in every ` – Mihai T Jun 13 '18 at 10:52
  • @MihaiT - No, you'd just define the object in any `script` prior. They all share the same global environment. I've updated the answer to make that clearer. – T.J. Crowder Jun 13 '18 at 11:17
  • @T.J.Crowder great. Thanks :) – Mihai T Jun 13 '18 at 11:22

4 Answers4

2

It's possible to do what you've shown, but it's probably not a good idea. You'd use $(document.body.lastElementChild):

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
// Presumably you have something defining that `en` variable and the object it refers to:
var en = {
    login_terms_and_conditions: "terms and conditions here"
};
</script>
<p>one</p>
<p>two</p>
<p>three</p>
<div id="content">
<script>$(document.body.lastElementChild).html(en.login_terms_and_conditions);</script>
</div>
<p>four</p>
<p>five</p>
<p>six</p>

...or of course, just $("#content") if that id is always on the element.

This works because the element is added to the DOM as of when your script runs (the details on that are complicated, but covered in the spec), even though the element's end tag has not yet been parsed.

I wouldn't do that, though, for a couple of reasons, not least that if you're doing this with jQuery, you have to load jQuery prior to that element, which holds up the rendering of your page. You could fix that by not using jQuery for this bit:

<script>
// Presumably you have something defining that `en` variable and the object it refers to:
var en = {
    login_terms_and_conditions: "terms and conditions here"
};
</script>
<p>one</p>
<p>two</p>
<p>three</p>
<div id="content">
<script>document.body.lastElementChild.innerHTML = en.login_terms_and_conditions;</script>
</div>
<p>four</p>
<p>five</p>
<p>six</p>

...but it still seems like there are simpler solutions, like just document.write-ing the content, or using server-side templating.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

Your example is not quite how jQuery works. The location of the script is irrelevant to the scope of this when attempting to affect an element.

Instead you need to select the #content element directly, then call html() with the value of the login_terms_and_conditions property. Try this:

var en = {
  login_terms_and_conditions: '<h2>fizz buzz</h2>'
}

$(function() {
  $('#content').html(en.login_terms_and_conditions);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
  <h5>foo bar</h5>
</div>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • This is not dynamic though...I have to target it by ID. Which is why I was trying to use `$(this)`. – Nikk Jun 13 '18 at 10:15
  • I want to be able to add it in the html like so ` `... – Nikk Jun 13 '18 at 10:16
  • Again, that's not how jQuery works. You need to select the element first. As I explained above, the scope of `this` is not magic. It is not affected by where you define the script. – Rory McCrossan Jun 13 '18 at 10:17
0

First, this does not work as you want. You have to select an element first and then refer to it with this.

Second, even if you would want to add an object key directly into html, that's not possible. ( is possible in JSX but that's another thing :) ).

Third, to make it more dynamic (as I understood you want), you can add some specific data-attributes to your html elements. For example a data-obj='content' for the content and so on. Then, you can iterate your en object and add en[key] value to it's respective html element with the data-obj.

See below

const en = {
  title: 'Title in english',
  content: 'Some content in english here <br/>Some content in english here  ',
  link: 'Link text'
}

for (let key in en) {
 if( en.hasOwnProperty(key) ) {
      let element = $(`[data-obj='${key}']`)
      element.html(en[key])
    } 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content">
 <h5 data-obj="title"></h5>
 <p data-obj="content"></p>
 <a data-obj="link"></a>
</div>
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Mihai T
  • 17,254
  • 2
  • 23
  • 32
-2

If you want to target by id, then you could try something like this:

$("#content").html(en.login_terms_and_conditions);