I'm creating my own templating engine which is used to render HTML.
Below, you have a template which will be rendered using my template engine:
{{TMPL:Import=../../../../Data/Templates/Ribbon/tabs.tmpl; Name=Tabs}}
<div id="{{Id}}" class="ribbon">
<!-- All the different tabs are being rendered here. -->
{{Render:Tabs; Value="Tabs"}}
</div>
Now, I was think about a technique on how I could make some sections render if a condition matches.
I tought to change my template as following:
{{TMPL:Import=../../../../Data/Templates/Ribbon/tabs.tmpl; Name=Tabs}}
{{If: "{{Id}}" != "Undefined"}}
<div id="{{Id}}" class="ribbon">
<!-- All the different tabs are being rendered here. -->
{{Render:Tabs; Value="Tabs"}}
</div>
{{EndIf}}
In human language, that would be, id the parameter "Id", which is passed by my template engine, is not "undefined, that I would render the div element.
But now I want to know how I can execute this condition.
Through the usage of regexes and replacements, the final condition will look like this:
"Undefined" != "Undefined"
But this is stored a a simple text value.
Is there a way in jQuery / Javascript, on how I can execute the condition stored in the string?
Kind regards,
eval('"Undefined" != "Undefined"')
Related
I have these lines of code:
<span
class="close-modal"
onclick="#Html.Action("SaveNotes", "CallCenter", new { activityId = item.callIdKey, noteText = "test1" })">
×
</span>
Notes: <br />
<textarea name="paragraph_text" rows="5" style="width:90%">
#item.NoteText
</textarea>
I would like to replace test1 from the noteText route variable and instead change it to whatever the value in the <textarea> tag is.
Is there an elegant way of doing this without writing a giant block of jQuery code?
#Html.Action() renders a partial view as an HTML string during page processing (on the server side). It doesn't exist any more in the markup, once the page is sent to the browser. You can't do what you are trying to do this way. At the very least, I'm sure you don't want to render a partial view inside the onclick event of your <span> tag.
Why not instead use an HTML helper for the <textarea> tag? Then you can get whatever value the user typed into it on the server code. You'll want to make the form post itself back to the server on the close-modal element:
<span class="close-modal" onclick="$('form').submit()">×</span>
<form method="post" action="#Url.Action("SaveNotes", "CallCenter", new { activityId=item.callIdKey }">
Notes: <br />
#Html.TextArea("noteText", item.NoteText, new { rows="5", style="width:90%" })
</form>
This assumes you have jQuery already (a common assumption with ASP.NET). You may not need the <form> tags if you already have a form on your page.
A #gunr2171 notes in the comments, the only way to dynamically update a link once it's been rendered to the browser is via some form of client-side scripting, typically JavaScript. In your case, I'd recommend doing something like this:
<span
class="close-modal"
data-href-template="#Url.Action("SaveNotes", "CallCenter", new {activityId = item.callIdKey, noteText="{note}"})"
>
×
</span>
Note: As #HBlackorby notes in his answer, you shouldn't be using #Html.Action() here; I assume you meant #Url.Action().
This way, your JavaScript has a template (data-href-template) that it can work against with a clearly defined token ({note}) to replace, instead of needing to parse the URL in order to identify where the previously replaced text is. Otherwise, you potentially end up in a scenario where you type e.g. CallCenter into your <textarea /> and it's now an ambiguous reference that you can't just blindly replace. Or, worse, you type 'a' and it's really ambiguous.
If you are already using jQuery on your site, the actual replacement might be done using something along the lines of:
$(document).ready(function () {
$('span.close-modal').click(function() {
var noteInput = $('textarea[name="paragraph_text"]');
var encodedNote = encodeURI(noteInput.text());
var template = $(this).data("href-template");
var targetUrl = template.replace("{note}", encodedNote);
window.location.href = targetUrl;
});
});
You can also do this without jQuery, obviously—and should if you're not already depending on it. The point is to illustrate that this doesn't necessarily need to be a "giant block of jQuery code". In fact, this could be done in just a few lines—and probably should be. I deliberately broke it out into multiple steps and variables for the sake of readability.
I'm working on a project where I have to delete en element in a certain condition (if). My code generates a <li> in which data is inserted via an array. I need to delete that <li> if some conditions are met.
Since removeParent() doesn't exist I've found different methods saying to use
e.parentNode.parentNode.removeChild(e.parentNode);
Rings a bell, it works in certains cases of course.
BUT
In my case, this is dynamically rendered elements in an array inside the <li> and there is no parent of the parent, so I get an error.
My script looks for an element in the <li>, in my test I use a <div> found by its class.
$(node).find('.results-name')[0].parentNode.remove();
Does NOT work unfortunately so I'm looking for other ideas...
Any clue?
Thanks a lot!
The thing is the code is huge and I can't copy/paste everything here.
Here's more info:
- in the page I have a template that's used by the javascript to populate a div with all the contents. I have ~20 results.
The template starts like this :
<script id="itemtemplate" type="geowacht/template">
<div class="results-name">
<h4 class="show-more-name itemaponaam" data-target="#result"></h4>
<div class="d-block" id="result">
<div class="itemaddress"></div>
<div class="itemgeodesc"></div>
<div class="itemphone"></div>
The pages calls a script that queries an API and returns 20 results. These results are parsed and added to the page using the template.
Here's the beginning of the code:
apiconfig.default_populateItemNode = function(node, apotheekData, wachtPeriodeData, authenticationData) {
$(node).find('.itemaponaam')[0].setAttribute('data-target', '#result-' + itemPos);
$(node).find('.buttons')[0].setAttribute('id', 'result-' + itemPos + '-buttons');
$(node).find('.buttons')[0].setAttribute('data-apbnb', apotheekData.pharmacy.id);
I simply try to let VueJS 2 render a inline condition while I add a value to an dom element. I know, that it is possible to use v-if to let elements appear or disappear based on conditions, but how can I use a inline-condition?
I will give an example. The following html describe my idea and I know that this lines generates an error. Both <span> elements are controlled by conditions which lets them appear or not and this works fine.
Now, I try to bind a value to the href attribute depending on a condition (which are in the parentheses for example).
<div id="vuemain">
<span v-if="diced < 6">Looser</span>
<span v-if="diced == 6">Winner</span>
<a :href="'https://link-to-whatever.com/'+{diced==6 : 'winner', diced<6 : 'looser'} ">LINK</a>
</div>
So after rendering by VueJS the <a> tag should be like:
<a href="https://link-to-whatever.com/winner"> <!-- If diced == 6 -->
OR
<a href="https://link-to-whatever.com/looser"> <!-- If diced < 6 -->
Do you understand what my problem is and is that somehow possible?
Many thanks in advance
Allan
This should work.
<a :href="'https://link-to-whatever.com/'+ (diced==6 ? 'winner' : 'looser')">LINK</a>
It looks like you were trying to use the object syntax, which won't really work in this case. Instead, just use the ternary above.
Is it possible to use the 'greater than' comparator in an ng-if in HTML?
The problem is that the ">" symbol prematurely closes the HTML tag.
ex.
this: <div ng-if="foo>0" class="bar"> (HTML STUFF) </div>
is read as: <div ng-if="foo"> (0 class="bar"> HTML STUFF) </div>
I ended up getting around this by using ng-if="foo!=0" but I could probably use the less than comparator instead but I was just curious in case I absolutely HAD to use the greater than symbol for some reason. Or would I perhaps have to move this logic somewhere else like in my controller instead of in my view?
EDIT 1
So it definitely seems like the comparator itself isn't the problem and something else is going on in my code. Oddly, when I have spaces before and after the comparator it works but without spaces it doesn't. I'm also using angular 1.3.15 if that means anything.
<div class="paginate" ng-if="list.total > 0"> works
<div class="paginate" ng-if="list.total>0"> does not work
This is an example of using the > symbol. This works fine.
<div ng-if="myvariable.length > 2">
</div>
I recommend creating a method on the scope and abstracting the logic of the condition. The business rules may expand and change. With a separate method you don't need to alter the template.
// in controller
$scope.isValidFoo = function () {
return $scope.foo > 0;
}
// in template
<div ng-if="isValidFoo()">...</div>
I just started using Mustache and I like it so far, but this has me perplexed.
I am using the GitHub gist API to pull down my gists, and part of what I want to do is include the embedding functionality into my page. The problem is Mustache seems to not want to have anything to do with my dynamic script tag.
For example, this works fine:
<div class="gist-detail">
{{id}} <!-- This produces a valid Gist ID -->
</div>
Additionally, this works perfect:
<div class="gist-detail">
<script src='http://gist.github.com/1.js'></script> <!-- Produces the correct embed markup with Gist ID #1 -->
</div>
If I try to pull these together, something goes terribly wrong:
<div class="gist-detail">
<script src='http://gist.github.com/{{id}}.js'></script> <!-- Blows up! -->
</div>
Chrome Inspector shows this:
GET https://gist.github.com/%7B%7Bid%7D%7D.js 404 (Not Found)
... which looks like to me something is weird with escapes or whatnot, so I switch over to the raw syntax:
<div class="gist-detail">
<script src='http://gist.github.com/{{{id}}}.js'></script> <!-- Blows again! -->
</div>
And I get the same result in Inspector:
GET https://gist.github.com/%7B%7B%7Bid%7D%7D%7D.js 404 (Not Found)
How do I get the correct values to embed in the script tag?
EDIT
I am injecting the template as follows (in document.ready:
function LoadGists() {
var gistApi = "https://api.github.com/users/<myuser>/gists";
$.getJSON(gistApi, function (data) {
var html, template;
template = $('#mustache_gist').html();
html = Mustache.to_html(template, {gists: data}).replace(/^\s*/mg, '');
$('.gist').html(html);
});
}
The actually template is inside of a ruby partial, but it is wrapped in a div (not a script tag, is that a problem?) (that's hidden):
<div id="mustache_gist" style="display: none;">
{{#gists}}
<!-- see above -->
{{/gists}}
</div>
I assume a div is ok rather than a script because in either case, I'm pulling the .html(). Is this a bad assumption?
To avoid automatic escaping in Mustache use {{{token}}} instead of {{token}}.
It seems like your template is in HTML and trying to retrieve the template using html() results in a pre-URL-escaped template to be returned. Try placing your template inside a <script type="text/html"> tag instead.
When you embed your template inside an HTML element that excepts more HTML elements as children, it may get processed by the browser as HTML. Escaping may occur. By using a <script> tag with a non-script content type, you're basically telling the browser not to touch your template.
It looks like your script is getting requested before Mustache has a chance to update the src property. What you want to do is define the template in a way that it's not parsed as part of the DOM. A common approach is to define your template inside of a <textarea> tag. This will preserve formatting and prevent character escaping.
<textarea id="gist-detail-template" style="display:none">
<script src='http://gist.github.com/{{id}}.js'></script>
</textarea>
Now, to instantiate the template:
var template = $('#gist-detail-template').val();
var html = Mustache.to_html(template, yourTemplateData);
Here's an official example: http://mustache.github.com/#demo