Javascript : Simple template processing

Dear Experts,
Need  2 JavaScript functions take a Text template and Text variable and return result as following:
Text Template example:
<div class="row">
   <div>{Lable}</div>
   <div>{Control}</div>
</div>

Open in new window

Text variable example:
{Control}

Open in new window

Result example 1 : if call _Before_fn and pass Text Template , Text Variable {Lable}
it should return :
<div class="row">
   <div>

Open in new window

Result example 2 : if call _After_fn and pass Text Template , Text Variable {Lable}
it should return :
</div>
   <div>

Open in new window


Result example 3 : if call _After_fn and pass Text Template , Text Variable {Control}
it should return :
</div>
</div>

Open in new window


for my  development environment I cant use any third party library , I just need pure JavaScript code, also I don't want to just replace {Control} with something,
I need to return before and after text.
ethar1Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Alexandre SimõesManager / Technology SpecialistCommented:
Why don't you stick with one time-proven template engine like the one provided by Underscore.js?

From their site is pretty easy to understand how it works.
1
Julian HansenCommented:
if call _Before_fn and pass Text Template , Text Variable {Lable}
it should return :
A bit hazy on exactly how you want to do this - can you expand on the above - what is the if doing and what is the _Before_fn doing - I get the general idea that you want to generate a top and a bottom section but not sure how that fits into your description of the process.
1
ethar1Author Commented:
Alexandre Simões, Thanks for your reply , I just don't want to use any third party library as mentioned above.

Julian Hansen : A FUNCTION to get a top and a bottom section exactly as you understand
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

Julian HansenCommented:
...exactly as you understand
You give me too much credit.

Why do you need a top and bottom - are you going to insert other stuff between.

Can you give us your code that uses the functions (in other word assume they exist - and then show us how you intend to use them and what the intended output is)
1
ethar1Author Commented:
welcome{Var1}this dog{var2}can go

I just need a function to return "welcome" if I pass "{Var1}"
and another function to return "this dog" if I pass "{var1}"

I already give very detailed example.
0
Alexandre SimõesManager / Technology SpecialistCommented:
Sorry mate, on my side I still don't understand what you need.

For starters I think you have an error in this last example, "this dog" should be {var2} no?
And after that, you want to conditionally change the text before the var placeholder based on if the var is passed or not?

Until when? I mean, if the logic is simple, not passing {var2} will wipe out the whole thing before no? Even {var1} and the Welcome... I don't get it.

Another thing is, the values of var1 and var2 are actually displayed where their placeholders are right?


I'm trying to get some logic out of this and the only thing that might be what you want is to wrap some containers and make them visible depending on if the variable is present or not, but that, and as you don't want to use any 3rd party tools, will be easier if constructed with javascript.

Something like this???

I'm out of ideas mate, maybe Julian can figure you out better :)
0
Julian HansenCommented:
Following on from AlexCode's post - and in the interests of speeding things up - I would like to see the actual use case for this in other words how it is intended to be used. To do this you write the code to use the functions as if they exist - along with parameters you expect to send to the function.

You then manually type out what you expect the results of to be.

I have a rough idea of what you want but I am not going to spend time on code until I understand fully.

As for having posted examples already - they are confusing me because they just result in empty div's based on your opening example you want to turn
<div class="row">
   <div>{Lable}</div>
   <div>{Control}</div>
</div>

Open in new window

Into
<div class="row">
   <div>
   </div>
   <div>
   </div>
</div>

Open in new window

Which seems like a really roundabout way of saying "I want to remove {Label} and {Control} from the template?"
0
ethar1Author Commented:
I will not call function#1 then function#2 to produce:
<div class="row">
   <div>
   </div>
   <div>
   </div>
</div>

Open in new window


I will call function#1 , then some code and procedures then function#2

I think now its very clear
0
ethar1Author Commented:
Alexandre Simões  : please take a look at this
http://jsfiddle.net/ethar1/tcmzmt87/
0
Julian HansenCommented:
Thank you for the fiddle it now makes sense. That is what I was asking for.

You want to find the text that exists before a specified value or after a specified value (but before the next value)
You can use regular expressions for this.
<script>
var s = "This is a {var1}test to see what {var2} some more text {var3} and some more text";

function after(str, searchStr)
{
  var afterregexp = new RegExp('\{' + searchStr + '\}(.*?)(\{|$)');
  return str.match(afterregexp)[1] || '';
  
}
function before(str, searchStr)
{
  var beforeregexp = new RegExp('\}?(.*?)\{' + searchStr + '\}');
  return str.match(beforeregexp)[1] || '';
}

var result = before(s, 'var1');
console.log('Before {var1} ' + result);
result = after(s, 'var1');
console.log('After {var1} ' + result);
result=before(s, 'var2');
console.log('Before {var2} ' + result);
result=after(s, 'var2');
console.log('After {var2} ' + result);
result=before(s, 'var3');
console.log('Before {var3} ' + result);
result=after(s, 'var3');
console.log('AFter {var3} ' + result);
</script>

Open in new window



Working sample here - go to console to see results
1

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Julian HansenCommented:
There is a bug in the before - needs to only look from the last '}' forward - will fix and post later.
1
ethar1Author Commented:
Yes , this is exactly what I am after
0
ethar1Author Commented:
ok, thanks waiting for the fix
0
Julian HansenCommented:
Just to clarify

before(s, '{var2}')

Must only return the text between {var1} and {var2} i.e. must exclude {var1} and what comes before it from the result?
0
Julian HansenCommented:
Here is a much simpler approach - uses approach of splitting string into an array based on { } delimited items
<script>
var s = "This is a {var1}test to see what {var2} some more text {var3} and some more text";

function after(str, searchStr)
{
  // CREATE ARRAY USING {searchStr} AS DELIMITER
  var parts = str.split(new RegExp('\{(.*?)\}'));

  // FIND indexOf str IN ARRAY
  var i = parts.indexOf(searchStr);
  // RETURN THE NEXT ITEM
  if (i) {
	return parts[i+1];
  }
  return '';
}
function before(str, searchStr)
{
  var parts = str.split(new RegExp('\{(.*?)\}'));  
  var i = parts.indexOf(searchStr);
  // RETURN THE PREVIOUS ITEM
  if (i) {
	return parts[i-1];
  }
  return '';
}

var result = before(s, 'var1');
console.log('Before {var1} ' + result);
result = after(s, 'var1');
console.log('After {var1} ' + result);
result=before(s, 'var2');
console.log('Before {var2} ' + result);
result=after(s, 'var2');
console.log('After {var2} ' + result);
result=before(s, 'var3');
console.log('Before {var3} ' + result);
result=after(s, 'var3');
console.log('AFter {var3} ' + result);
</script>

Open in new window


Updated sample here
0
ethar1Author Commented:
before(s, '{var2}')
must return all text before it until }
0
Julian HansenCommented:
Does the last sample posted do what you require?
0
ethar1Author Commented:
Julian Hansen , thanks for your response.
unfortunately its not working as supposed .

please check :
http://jsfiddle.net/ethar1/tcmzmt87/2/
0
Julian HansenCommented:
That is because you are including the { } in the query like this

getBeforeTemplate('{var1}')

Open in new window


Instead of like this

getBeforeTemplate('var1')

Open in new window

0
ethar1Author Commented:
ok, Thank you . now working
0
Julian HansenCommented:
You are welcome
0
ethar1Author Commented:
Dear Julian Hansen,
why { } removed from the resulted array?
suppose I have var1 in template it self like sTemplate = 'var1{var1} this dog {var2} can go';

will give wrong results.

if you need me to open new question please let me know
0
ethar1Author Commented:
when I try it at fiddle the array contains :
parts(0): welcome
parts(1): var1  ( split remove the splitting characters , why var1 is here?)
parts(2): this dog
parts(3): var2 ( split remove the splitting characters , why var2 is here?)
parts(4): can go

Open in new window


but in my environment the array contains: ( this is logical , split remove the splitting characters )
parts(0): welcome
parts(1): this dog
parts(2): can go

Open in new window


/**/*/*/*/*/*/*/
btw, it give an error at :
var i = parts.indexOf(sVariableName);
then I add:
if (!Array.prototype.indexOf) {
		Array.prototype.indexOf = function(obj, start) {
			 for (var i = (start || 0), j = this.length; i < j; i++) {
				 if (this[i] === obj) { return i; }
			 }
			 return -1;
		}
}

Open in new window

its look like I am using old version or something cant explain
0
Julian HansenCommented:
why { } removed from the resulted array?
Because the script splits the array based on variables inside {} - so it will ignore the first var1 in

var1 {var1} and only find the second

what may not work is this {var1}var1{var2}

The fix is simple - just move the \{ \} inside the brackets () so they are included in the match like this
function after(str, searchStr)
{
  var parts = str.split(new RegExp('(\{.*?\})'));  /* {} moved inside the () */
  var i = parts.indexOf(searchStr);
  if (i) {
	return parts[i+1];
  }
  return '';
}
function before(str, searchStr)
{
  var parts = str.split(new RegExp('(\{.*?\})'));  /* {} moved inside the () */
  var i = parts.indexOf(searchStr);
  if (i) {
	return parts[i-1];
  }
  return '';
}

Open in new window

You can now call like this
result = before(s, '{var1}');
result = after(s, '{var1}');

Open in new window

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.