SitePoint Sponsor

User Tag List

Results 1 to 10 of 10
  1. #1
    SitePoint Member
    Join Date
    Feb 2006
    Posts
    0
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Replacing Characters with Images

    I've been working on a project that would benefit from javascript code that would allow a user to input a number of characters, click submit and have the characters replaced with applicable images. for example, a user would type in the character 'A' and click submit, and it would be replaced with <img alt="" src="A.jpg"> instead. I've found a simple bit of older code that shows an example of doing so for a single character replacement here, albeit only with character for character replacement:

    Quote Originally Posted by javascript source
    <SCRIPT LANGUAGE="JavaScript">

    <!-- Begin
    function replaceChars(entry) {
    out = "a"; // replace this
    add = "z"; // with this
    temp = "" + entry; // temporary holder

    while (temp.indexOf(out)>-1) {
    pos= temp.indexOf(out);
    temp = "" + (temp.substring(0, pos) + add +
    temp.substring((pos + out.length), temp.length));
    }
    document.subform.text.value = temp;
    }
    // End -->
    </script>
    </HEAD>

    <BODY>

    <center>
    <form name="subform">

    <input type=text name=text size=40 value="abcdabcd"><br>
    <input type=button name=action value="Done!" onClick="replaceChars(document.subform.text.value);">

    <!-- Or to make it change when the user clicks the next -->
    <!-- field, use this instead of the previous two lines: -->

    <!-- <input type=text name=text size=40 value="abcdabcd" onBlur="replaceChars(this.value);"> -->

    </form>
    </center>
    I'd like to progress to multiple character replacements, and of course transforming the characters to images instead. any ideas?

  2. #2
    SitePoint Guru
    Join Date
    Apr 2006
    Posts
    802
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    An input element can only contain text, not images.

  3. #3
    SitePoint Member
    Join Date
    Feb 2006
    Posts
    0
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    the input would be text based, but the output would be graphical ideally. i'm not sure of another method of input outside of an input box + submit button, but if there is a more creative way that allows a graphical output that would be more than workable.

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    You could use the onchange or onblur events, or even the onkeypress event, but with the last one you would have to rule out special keys like ctrl and alt.

    Let's use the onblur event.

    The HTML would look like this

    Code HTML4Strict:
    <!-- The input element -->
    <input id="myText" type="text">
    <!-- And elsewhere, the place for the images -->
    <div id="myImages"></div>

    But where's the onblur attribute! It's not in the HTML code because such behaviour shouldn't be mixed in with the content. Do you have inline style attributes scattered all around your HTML code? No, you use CSS attributes instead and hook them in with class and id attributes.

    It's the same deal with JavaScript. Keep the script separate and use id attributes only where necessary to help the JavaScript get to where it's supposed to go.

    Place this script at the bottom of the document, just before the closing body tag.

    Code Javascript:
    // Get Input field
    var input = document.getElementById('myText');
     
    // Attach onblur event
    input.onblur = textToImage;
     
    function textToImage() {
    	var text = this.value;
     
    	var images = document.getElementById('myImages');
    	if (!images) {
    		// no place for images so exit
    		return;
    	} else {
    		// remove old images
    		while (images.firstChild) {
    			images.removeChild(images.firstChild);
    		}
    	}
     
    	// process each character
    	var character = '';
    	var image;
    	for (var i = 0; i < text.length; i++) {
    		character = text.substring(i, i+1);
     
    		// convert char to image
    		image = document.createElement('img');
    		image.setAttribute('src', character + '.img');
     
    		// add image to images area
    		images.appendChild(image);
    	}
    }
    Last edited by paul_wilkins; Feb 10, 2008 at 16:11.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  5. #5
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    The above code is alright and works fine, but there is a concern of what happens should JavaScript not be available.

    When there is no JavaScript the input does nothing and the images obviously don't appear. So how would we do this if we didn't have JavaScript?

    We would have a "Show pretty text" button that would passing the text via post or get to a php script that would process the text, and rebuild the page with the images in there.

    The images would then be created at some particular place by the php script, perhaps just below the inputted text, or after the form, or before some other section. For this example I will presume that the images are to be placed immediately after the input element.

    So how would the code look? You would have PHP that looks something similar to the JavaScript code to create the images

    Code PHP:
    ...
    output .= '
    <form method="post" action="thispage.php">
    <p><input id="myText" name="myText" type="text">
    <input type="submit" value="Show pretty text"></p>
    </form>
    <div id="images">
    ';
    if ($post['myText']) {
        output .= '<div id="images">';
        $text = $post['myText'];
        for ($i = 0; $i < strlen($text); $i++) {
            output .= '<img src="' . substr($text, $i, 1) . '.jpg">';
        }
        output .= '</div>';
    }
    // more page code, then
    echo output;

    Something like that anyway. The point is, The page should be made to work without JavaScript first, because then you can use JavaScript to make the page better.

    How would we use JavaScript to make the page better? We would remove the button and add the onblur event, so that the call back to the php code wouldn't be needed. As our JavaScript code uses DOM2 manipulation techniques, we should also let the page use the non-JavaScript technique if DOM2 is not supported.

    Code Javascript:
    if (document.getElementById) {
        // DOM2 is available, so use the JavaScript technique
     
        // Get Input field
        var input = document.getElementById('myText');
     
        // Find the submit button after the input element
        var el = input;
        while (el && el.type !== 'submit') {
            el = el.nextSibling;
        }
     
        // Remove the submit button
        el.parentNode.removeChild(el);
     
        // Attach onblur event
        input.onblur = textToImage;
    }
     
    function textToImage() {
        var text = this.value;
     
        var images = document.getElementById('myImages');
        if (!images) {
            // create the images area
    		images = document.createElement('div');
    		images.id = 'myImages';
    		// and place it just below the form
    		if (this.form.nextSibling) {
    			// there's already something below the form, so insert the images area just before that other something
    			this.form.parentNode.insertBefore(images, this.form.nextSibling);
    		} else {
    		    // the form has nothing after it, so add the images area to the bottom
    			this.form.parentNode.appendChild(images);
    		}
     
        } else {
            // remove old images
            ...
    // The rest of the code as before

    There are a couple of interesting situations above that should be explained a bit further.

    When removing the submit button, it's entirely possible to have multiple submit buttons in the one form, with different names to achieve different purposes. So instead of removing all submit buttons I've gone for removing just the button that comes after the input element. Another way to handle this would be to assign an identifier or a name to the submit button.

    Placing the image in the correct locationv initially seems to be easy. Just put it below the form. Unfortunately the DOM provides only two functions for us to use to do this, appendChild() and insertBefore(). appendChild works inside the given element, whereas insertBefore works outside of the element. Despite that though, it is still possible to add thing wheerever you desire. If the form element is the last one, that's quite easy and you just append the images area to the forms parent node. If the form is followed by other elements, you then should go to the element after the form, and insert the images area before that element. This technique might appear tricky at first, but with a little bit of understanding the DOM, it becomes apparent that these are robust ways of achieving the desired result.
    Last edited by paul_wilkins; Feb 10, 2008 at 22:27.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  6. #6
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    How can the above code be further improved.

    Some assumptions are made by the script that can be taken care of.

    First it assumes that it can use certain variables, which are created in the global namespace. We should place the code inside a function literal so that it doesn't affect the global namespace.

    Code Javascript:
    (function () {
        if (document.getElementById) {
            ...
        }
     
        function textToImage() {
            ...
        }
    })();

    It assumes that there is a myText identifier. If there isn't one then an element to remove won't be found, and that section will fail. The same trouble will also occur if the submit element can't be found. We can easily fix that by checking that the element exists before removing it.

    Code Javascript:
    // Remove the submit button
    if (el) {
        el.parentNode.removeChild(el);
    }

    But what happens if there is no myText element found. There are parts like assigning the onblur event that will fail. We could place another check around the whole section to find the input element, remove it and add the onblur event, but that's creating quite a lot of nesting. Instead, we can just return out of the function literal. There is no text area that can be found so there's no point in carrying on with the function.

    Code Javascript:
    // Get Input field
    var input = document.getElementById('myText');
    if (!input) {
        return;
    }

    Another useful check is for when the event calls the function. Once the images area has been cleared there's no point carrying on if the value is empty.

    Code Javascript:
    if (!text) {
        return;
    }
     
    // process each character
    ...

    When it comes to the loop, the text.length is calculated every time it loops through, so let's place that into a variable and help to improve things there.

    Code Javascript:
    for (var i = 0, textLen = text.length; i < textLen; i++) {
        ...
    }

    Then you could check for other things, such as making sure that the characters match a certain list before being used for images, or that the image exists, but it can be more useful if you see that the image isn't available so that something can be done about it.
    Last edited by paul_wilkins; Feb 10, 2008 at 23:42.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  7. #7
    SitePoint Member
    Join Date
    Feb 2006
    Posts
    0
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    wow, thanks pmw57. quite a bit of work there, I appreciate that. sry for the late reply as well. I'll have to experiment with putting it all together and making it work since the composition is above my coding-understanding

    Hopefully, it will make something like this:

    Enter Text Here (Submit Button)

    Area Where Images with appear after text is converted.

  8. #8
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by okguyjames View Post
    wow, thanks pmw57. quite a bit of work there, I appreciate that. sry for the late reply as well. I'll have to experiment with putting it all together and making it work since the composition is above my coding-understanding
    If it's any consolation the information is all good because I was working from a live example.

    If you do have any issues though, please don't hesitate to get in touch.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  9. #9
    SitePoint Member
    Join Date
    Feb 2006
    Posts
    0
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've followed the instructions from post #4 and now have an input box on the page. however, there is no submit button with it, although if the code allows the user to simply type in the characters and have them converted on-the-fly (without the manual button click) that would be a very nice unexpected feature. however, I'm missing the targeted area in the code where I input the variable characters and images though. I'm guessing the applicable character goes here:

    // process each character
    var character = 'applicable character';

    but I'm not sure where to input the image for the character. also, are multiple characters possible, and if so which portion of the code may be duplicated to achieve this? this is shaping up to be perfect for my application

  10. #10
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    Quote Originally Posted by okguyjames View Post
    I've followed the instructions from post #4 and now have an input box on the page. however, there is no submit button with it, although if the code allows the user to simply type in the characters and have them converted on-the-fly (without the manual button click) that would be a very nice unexpected feature.
    Currently the code is setup to remove the button that calls the php code to create the images, so that javascript can create the images itself without requiring the page refresh. This is a good standard practice so that it works should javascript be unavailable or disabled. It is very foolish to presume that javascript will always be there.

    Code javascript:
    // Remove the submit button
    el.parentNode.removeChild(el);
     
    // Attach onblur event
    input.onblur = textToImage;

    When it removes the button it updates the input area to use onblur to convert the characters, i.e., when you tab out, or select some other part of the page.

    That code can be updated so that the submit button changes to a normal button instead, which calls the appropriate JavaScript function.

    Code javascript:
    // Change submit button to a normal button
    el.type = 'button';
    button.onclick = textToImage;

    Quote Originally Posted by okguyjames View Post
    however, I'm missing the targeted area in the code where I input the variable characters and images though. I'm guessing the applicable character goes here:

    // process each character
    var character = 'applicable character';
    Please don't change that part. Putting anything in there won't affect anything, but it does serve a useful purpose.

    The variable called "character" is used throughout the loop to contain the current character that it's working on. By standard practice it's defined outside of the loop, and assigned a value to let you know what it's intended for. If it was going to be a number it would be 0 instead, or [] for an array, {} for a function and so on. So please, leave it as var character = '';

    Quote Originally Posted by okguyjames View Post
    but I'm not sure where to input the image for the character. also, are multiple characters possible, and if so which portion of the code may be duplicated to achieve this?
    If you look at the loop just below the comment that says "process each character" you will see that it takes each character from the entered value, builds a image filename from each character, and adds those images to the image area.

    So if someone entered "Foo" it would create three images, F.jog, o.jpg and o.jpg

    If you want to limit the characters that are allowed to be entered, that is another easy addition that can be made to the system.

    Quote Originally Posted by okguyjames View Post
    this is shaping up to be perfect for my application
    Thank you, you're very welcome.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •