0

I want to change text in my div (since it is server-bounded) so I need to change it through a script. Why is my javascript not working?

JS:

$(function() { 
     $(".byline:contains('May)").html('Posted during period of May');
});

HTML screenshot:

enter image description here

edit: when I fixed ('May) to (May) or ('May'), the new problem is that "geplaatst door" is also replaced, I only want to replace the line that contains May

Aprillion
  • 21,510
  • 5
  • 55
  • 89
John Doe
  • 29
  • 4

3 Answers3

1

you have extra single quote in :contains('May) => :contains(May)

edit: to only change 1 particular child of .byline, you need select only that one particular child element, not the whole parent element

edit2:

  • if you wish to only replace the exact text May to a new text, you can do that using regex replace, where the /.../g means global replacement, if the text May can be present multiple times:

    $(function() {
      var elem = $(".byline:contains(May)")
      var new_html = elem.html().replace(
        /May/g,
        "$1Posted during period of May$2");
      elem.html(new_html);
    }); 
    
  • but if you wish the change the whole textual part of the .byline element in between other nested elements that contains May, then it'll get more complicated - either avoid that by editing the HTML to wrap the text to its own element like <span class="date">May, 2015</span>, or see Is there an alternative to jQuery / sizzle that supports textNodes as first class citizens in selectors?, or use a bit more complex regular expression:

    $(function() {
      var elem = $(".byline:contains(May)")
      var new_html = elem.html().replace(
        /((?:^|>)\s*)[^<>]+May[^<>]+(\s*(?:<|$))/,
        "$1Posted during period of May$2");
      elem.html(new_html);
    });
    

fiddle: https://jsfiddle.net/Aprillion/f6mcawd1/3/

regex explanation: https://regex101.com/r/hL1eN7/

/((?:^|>)\s*)[^<>]+May[^<>]+(\s*(?:<|$))/g
    1st Capturing group ((?:^|>)\s*)
        (?:^|>) Non-capturing group
            1st Alternative: ^
                ^ assert position at start of the string
            2nd Alternative: >
                > matches the characters > literally
        \s* match any white space character [\r\n\t\f ]
            Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
    [^<>]+ match a single character not present in the list below
        Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
        <> a single character in the list <> literally (case sensitive)
    May matches the characters May literally (case sensitive)
    [^<>]+ match a single character not present in the list below
        Quantifier: + Between one and unlimited times, as many times as possible, giving back as needed [greedy]
        <> a single character in the list <> literally (case sensitive)
    2nd Capturing group (\s*(?:<|$))
        \s* match any white space character [\r\n\t\f ]
            Quantifier: * Between zero and unlimited times, as many times as possible, giving back as needed [greedy]
        (?:<|$) Non-capturing group
            1st Alternative: <
                < matches the characters < literally
            2nd Alternative: $
                $ assert position at end of the string
    g modifier: global. All matches (don't return on first match)
Community
  • 1
  • 1
Aprillion
  • 21,510
  • 5
  • 55
  • 89
  • Ok, it changes the entire line (also "geplaatst door") – John Doe May 14 '16 at 19:26
  • you didn't mention in the question that you don't want to change that... let me update my answer – Aprillion May 14 '16 at 19:28
  • Sorry about that! Newbie here. – John Doe May 14 '16 at 19:29
  • It now changes that name of the author. Posted by MAY, posted in the month of May. The capital letters should normally be the authors' name. – John Doe May 14 '16 at 19:33
  • I see.. `May` is not inside `...` as I assumed, but a there is a mix of plain text and other elements... – Aprillion May 14 '16 at 19:36
  • Correct. I guess it is mission impossible. – John Doe May 14 '16 at 19:41
  • not impossible, even if you don't have control over the HTML, only javascript.. but would be simpler if you could wrap the text you wish to replace into its own element like I suggested in the comment to your question – Aprillion May 14 '16 at 19:51
  • Thanks for your help, I'll try to fix it myself later on. – John Doe May 14 '16 at 20:06
  • uff, updated answer. editing the HTML would be MUCH simpler for future maintenance, but at least I could stretch my mind a bit... – Aprillion May 14 '16 at 20:14
  • 1
    I like your style and mindset. Also, your first code is working like a charm, thanks for that. Have a great weekend! – John Doe May 14 '16 at 20:17
  • One final question. If I want to change multiple months (January, etc), how do I do that? – John Doe May 14 '16 at 20:29
  • `new Regex(month, 'g')` instead of `/May/g` as per the link at the end of my answer – Aprillion May 14 '16 at 20:36
  • This does not work: – John Doe May 14 '16 at 20:44
  • `month` is supposed to be a variable holding a string, of course `May` without quotes wouln't work.. you said you want to use different months, why are you not using some decent editor that would tell you when you make these kind of mistakes? like atom or webstorm – Aprillion May 14 '16 at 22:18
0

Looks like you were missing a closing single quote in May.

$(".byline:contains('May')").html('Posted during period of May');

Working example right here: https://jsfiddle.net/b55Lv052/

napo
  • 869
  • 9
  • 19
  • [sizzle](https://sizzlejs.com/), the jQuery's selector engine, does not require the string inside `contains(text)` to be quoted – Aprillion May 14 '16 at 19:41
0

You can try this approach: You have to expand the selector and it will work

$(".byline>span:contains('May)").html('Posted during period of May');`

Kartikeya Sharma
  • 553
  • 1
  • 5
  • 22
  • And why i is that ? Can you explain the reason – Kartikeya Sharma May 14 '16 at 19:41
  • 1
    `You have to expand the selector and it will work` is not a true statement. the selector `.byline:contains(May)` is perfectly valid, once the extra quote is fixed. also, the TextNode containing `May` is a direct descendant of `.byline` and not inside a `span` – Aprillion May 14 '16 at 19:44
  • by using this css selector you will be changing all the text under the byline class and appending to html .You don't want that, you need to change the text under span .So in that case what should be the appropriate way – Kartikeya Sharma May 14 '16 at 19:47
  • 1
    the text is NOT inside any span. and you STILL have the extra quote error in your answer – Aprillion May 14 '16 at 19:48
  • And yes i am sorry you are correct . May is directly descendant of byline class div . I am sorry for my negligence. – Kartikeya Sharma May 14 '16 at 19:50