How to use jQuery built in functions in Mustache template - javascript

I have a mustache.js template
<script id="catagorie_list" type="text/template">
{{#rows}}<li>{{catagorie_name}}</li>{{/rows}}
</script>
in it, I want to make first letter of each {{catagorie_name}} as Capital Letter.
Example:
india --> India
australia-->Australia
Is it possible?

Use CSS, you might want to set a class like this on your a tag
.capitalize {text-transform:capitalize;}
And then your original code would look like
<script id="catagorie_list" type="text/template">
{{#rows}}<li><a class="capitalize" href="#">{{catagorie_name}}</a></li>{{/rows}}
</script>

Supposing the input object is:
var countries = {
"rows": [
{ "catagorie_name": "india" },
{ "catagorie_name": "australia" },
{ "catagorie_name": "spain" }
]
};
We append a function to it:
var func_var = {
"capitalize_name": function () {
return firstcap(this.catagorie_name);
}
};
jQuery.extend( countries, func_var ); // https://stackoverflow.com/a/10384883/1287812
The capitalization function:
function firstcap(str) { // https://stackoverflow.com/a/11370497/1287812
var len = str.length;
var re = /^\s$/;
var special = true; // signalizes whether previous char is special or not
for (var i=0; i<len; i++) {
var code = str.charCodeAt(i);
if (code>=97 && code<=122 && special) {
str = str.substr(0, i) + String.fromCharCode(code-32) + str.substr(i+1);
special = false;
}
else if (re.test(str[i])) {
special = true;
}
}
return str;
}
And finally, the template:
<script id="catagorie_list" type="x-tmpl-mustache">
<ul>{{#rows}}<li>{{capitalize_name}}</li>{{/rows}}</ul>
</script>

Related

Add space after dot

Good day. I've got some problem.
I've got input where I wrote some information.
Example:
<div class="wizard wizardstep1" ng-controller='someCtrl'>
<p class="wizardtitle">Put you Theme</p>
<input id="taskTheme" required type="text" placeholder="Put you Theme" ng-model="taskThemeWizardInputValue" ng-change="checkThemeWizardInputValue()">
</div>
And I've got my controller.
Example:
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
strt[i] = strt[i].charAt(0).toUpperCase() + strt[i].substr(1);
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
How I can add space after dot? Who knows?
Here is link to jsfiddle with my example.
We achieve it by adding space to each splitted string other than first one and an empty string
function someCtrl($scope) {
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
var addSpace='';
if(i>0 && strt[i].trim().length>0){
addSpace=' ';
}
strt[i] = addSpace+strt[i].trim().charAt(0).toUpperCase() + strt[i].trim().substr(1);
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app>
<div class="wizard wizardstep1" ng-controller='someCtrl'>
<p class="wizardtitle">Put you Theme</p>
<input id="taskTheme" required type="text" placeholder="Put you Theme" ng-model="taskThemeWizardInputValue" ng-change="checkThemeWizardInputValue()">
</div>
</div>
You can do this simply by changing strt.join('.') to strt.join('. ').
$scope.checkThemeWizardInputValue = function () {
if ($scope.taskThemeWizardInputValue === undefined) {
$scope.taskThemeWizardInputValue = "";
console.log($scope.taskThemeWizardInputValue);
console.log($scope.taskThemeWizardInputValue.length);
} else {
var strt = $scope.taskThemeWizardInputValue.split('.');
for (var i = 0 ; i < strt.length; i++) {
strt[i] = strt[i].trim();
if(strt[i].length > 0) {
strt[i] = ' '+strt[i].charAt(0).toUpperCase() + strt[i].substr(1);
}
}
$scope.taskThemeWizardInputValue = strt.join('.');
console.log($scope.taskThemeWizardInputValue);
console.log(strt);
}
}
This is working fiddle
I suggest creating a directive so that you can plugin this behaviour whenever required., rather than writing your ng-change in every controller.
In directive simple line element.val(event.target.value.split(".").join(". ")); will work for you., with help of directive controller parameter.
See example fiddle

Javascript: Replace 'x' only if it is the first word of a text, not anywhere else

I'm working on a simple JS code to replace some words with others in a text using an array.
<textarea id="text1">
e mi e
ke fo
e di
</textarea>
<button type="button" onclick="myFunction()">try</button>
<pre id="demo"></pre>
<script>
function myFunction() {
var str = document.getElementById("text1").value;
var mapObj = {
"k":"g",
" e": "B",
"e":"ar"
};
var re = new RegExp(Object.keys(mapObj).join("|"),"gi");
str = str.toLowerCase().replace(re, function(matched){
return mapObj[matched];
});
document.getElementById("demo").innerHTML = str;
}
</script>
The result is:
ar mi B
gar fo
ar di
But I desire to have this:
B mi B
gar fo
B di
If "e"s are to be changed before " e"s (separated e with a space before it), then " e"s will not be " e" but "ar", so in the array, I've put " e" above "e" and it works well.
However the problem is that the text may contain a separated "e" as the first word of the whole text or as the first word of a line with no space before it. When it's the case how can I replace this separated "e"with "B" and prevent it from being replaced with "ar".
The problem with your current code is that the .replace function is only taking a single variable input. This limits you from using more specific RegExp in your replace, as the matched element will not match the regex.
.replace's function option provides access to matched groups as the 1+nth variables. As a result we can leverage this to lookup our replacement strings in an array.
By utilising RegExp groups we can capture the values we're looking for and replace them as needed.
JS
var myFunction = function() {
var str = document.getElementById("text1").value;
var regexs = ['(k)','(^e|\\se)', '(e)'];
var replacers = ['g', 'B', 'ar'];
var re = new RegExp(regexs.join("|"),"gi");
// you would need to add variables to the function for each matching group you add (currently there are 3 so we have 3 groups)
str = str.toLowerCase().replace(re, function(raw, group0, group1, group2){
if(typeof group0 !== "undefined"){
return replacers[0]; // replaces with 'g'
}else if(typeof group1 !== "undefined"){
// skip over the first character (white space) and concatenate the replacement
return raw[0] + replacers[1]; // replaces with 'B'
}else if(typeof group2 !== "undefined"){
return replacers[2]; // replaces with 'ar'
}
return raw;
});
document.getElementById("demo").innerHTML = str;
};
document.getElementById('go').addEventListener('click', myFunction);
CSS
#demo{
white-space:pre;
}
NOTE: because you're outputting to an elements .innerHTML without the above CSS new lines are not displayed.
JS FIDDLE
Try The below code.
function myFunction() {
var str = document.getElementById("text1").value;
str = str.toLowerCase().split('k').join('g').split(' e').join(' B').split('\\n').join(' B').split('e').join('ar');
document.getElementById("demo").innerHTML = str;
}
Its a different approach but I got the expected output.
A simple workaround.
<script type="text/javascript">
var myfunction = function(){
var f = document.getElementById('text1').innerHTML;
var c = f.replace(/e/ig,'ar').replace(/\bar/ig,'B').replace(/k/ig,'g');
document.getElementById('text1').innerHTML = c;
}
</script>
This works.
<textarea id="source" cols="5" rows="5">
e mi e
ke fo
e di
</textarea>
<button type="button" onclick="convert()">Convert</button>
<textarea id="destination" cols="5" rows="5">
</textarea>
<script>
function replaceWord(searchFor, replaceWith, paragraph) {
if (paragraph) {
var lines = paragraph.split('\n');
for (lineNo = 0; lineNo < lines.length; lineNo++) {
var words = lines[lineNo].split(' ');
for (wordNo = 0; wordNo < words.length; wordNo++) {
if (words[wordNo] === searchFor) {
words[wordNo] = replaceWith;
}
}
lines[lineNo] = words.join(' ');
}
paragraph = lines.join('\n');
}
return paragraph;
}
function replaceWords(wordMap, paragraph) {
for(var searchFor in wordMap)
{
if(wordMap.hasOwnProperty(searchFor))
{
paragraph = replaceWord(searchFor, wordMap[searchFor], paragraph);
}
}
return paragraph;
}
function convert() {
var mapObj = {
"ke":"gar",
"e": "B"
};
var source = document.getElementById("source");
var destination = document.getElementById("destination");
destination.value = replaceWords(mapObj, source.value);
}
</script>
Here is the jsFiddle.
https://jsfiddle.net/1egs7zgc/
For what it's worth, your mapObj isn't really an array it's an object.

How can I merge an Array with an object in javascript

I'm having an array of object
var todos= [
{
id: 1,
name: test,
description: test
}
]
How can I insert an object with properties stored in different variable say
var newTodos={id:2,name:test2,description:test2,purpose:NA}
so that the final arrray looks like
var todos=
[
{
id: 1,
name: test,
description: test
},
id: 2,
name: test2,
description: test2,
purpose: NA
]
var todos= [
{
id: 1,
name: test,
description: test
}
]
var newTodos={id:2,name:test2,description:test2,purpose:NA};
todos.push(newTodos);
The answer you accepted is the right answer to the wrong question.
If you really want to add the properties of newTodos (which is misnamed; it is just a single todo) then you can do what the answer says, or more easily, just do
$.extend (todos, newTodos);
_.extend (todos, newTodos);
Object.assign(todos, newTodos);
or use your other favorite property merging utility.
However, I cannot imagine what you are going to usefully do with such a mutant object, which is an array with a single element which is a todo, and now is sort of a todo itself with the todo properties directly on it.
I'm guessing that what you want to do is add another todo to your array of todos, in which case as others have suggested you can just push it.
todos.push(newTodos)
If you actually mean newTodos to be an array of todos, as its name suggests, in other words, if its format is actually
var newTodos = [ {id:2,name:test2,description:test2,purpose:NA}, ... ];
Then to add it to todos you would concatenate:
todos = todos.concat(newTodos);
This is how you do it:
for (var index in newTodos) {
todos[index] = newTodos[index];
}
You can check the values of your array like this:
for (var index in todos) {
console.log(index + ": " + todos[index]);
}
EDIT: In conform with the asked fiddle, I add the fiddle and code:
<html><head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title> - jsFiddle demo</title>
<script type="text/javascript" src="/js/lib/dummy.js"></script>
<link rel="stylesheet" type="text/css" href="/css/result-light.css">
<style type="text/css">
</style>
<script type="text/javascript">//<![CDATA[
var VanillaRunOnDomReady = function() {
var todos= [
{
id: 1,
name: 'test',
description: 'test'
}
];
var newTodos={id:2,name:'test2',description:'test2',purpose:'NA'};
for (var index in newTodos) {
todos[index] = newTodos[index];
}
var output = "";
for (var index in todos) {
if (typeof todos[index] === "object") {
output += index + ": {";
var first = true;
for (var innerIndex in todos[index]) {
if (!first) {
output += ", ";
} else {
first = false;
}
output += innerIndex + ": " + todos[index][innerIndex];
}
output += "}<br>";
} else {
output += index + ": " + todos[index] + "<br>";
}
}
document.getElementById("output").innerHTML = output;
}
var alreadyrunflag = 0;
if (document.addEventListener)
document.addEventListener("DOMContentLoaded", function(){
alreadyrunflag=1;
VanillaRunOnDomReady();
}, false);
else if (document.all && !window.opera) {
document.write('<script type="text/javascript" id="contentloadtag" defer="defer" src="javascript:void(0)"><\/script>');
var contentloadtag = document.getElementById("contentloadtag")
contentloadtag.onreadystatechange=function(){
if (this.readyState=="complete"){
alreadyrunflag=1;
VanillaRunOnDomReady();
}
}
}
window.onload = function(){
setTimeout("if (!alreadyrunflag){VanillaRunOnDomReady}", 0);
}//]]>
</script>
</head>
<body>
<div id="output">a</div>
</body></html>

Change first letter in string to uppercase in JavaScript

I have an array of strings,
["item1", "item2"]
I'd like to change my array to
["showItem1", "showItem2"]
The most easy to understand way of doing exactly what you ask for is probably something like this:
var items = ["item1", "item2"];
​for (var i=0;i<items.length;i+=1) {
items[i] = "show" + items[i].charAt(0).toUpperCase() + items[i].substring(1);
}
console.log(items); // prints ["showItem1", "showItem2"]
Explanation: build a new string consisting of the string "show" + the first character converted to uppercase + the remainder of the string (everything after the first character, which has index 0)
Strings are array-like. You could do this:
var arr = ['item1', 'item2'];
for (var i=0, l=arr.length; i<l; i++) {
var letters = arr[i].split('');
arr[i] = 'show' + letters.shift().toUpperCase() + letters.join('');
}
Demo: http://jsbin.com/asivec/1/edit
arr.map(function(i) {
return 'show' + i.charAt(0).toUpperCase() + i.slice(1);
});
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
supported in Chrome, Firefox, IE9 and others.
Here is a reusable firstCharLowerToUpper() function I wrote for that task.
LIVE DEMO
<!DOCTYPE html>
<html>
<head>
<style>
span{
color:red;
}
</style>
</head>
<body>
<div>this is the text:
<span id="spn">
javascript can be very fun
</span>
</div>
<br/>
<input type="button" value="Click Here" onClick="change()"/>
<script>
function firstCharLowerToUpper(x)
{
var ar = x;
for (var i = 0; i < ar.length; i++)
{
ar[i] = ar[i].charAt(0).toUpperCase() + ar[i].substr(1);
}
// join to string just to show the result
return ar.join('\n');
}
function change()
{
var ar = ["javascript ", "can ","be ","very ","fun" ];
var newtxt = firstCharLowerToUpper(ar);
document.getElementById("spn").innerHTML = newtxt;
}
</script>
</body>
</html>

Opening input when writing #Q# in textarea

I have textarea. Now, I want to do that once you write "#q + number#" ( e.g. #q1# ), it will create new input field.
For example if you write: "Hello my name is #q1# and my favorite food is #q2#". It will open two input fields.
And when you delete one of those #q + number#, it will delete the same field that was intended to the #q#
For example: if you write "Hello my name is #q1# and my favorite food is #q2#, and the input fields look like that:
<input type="text" q="1" />
<input type="text" q="2" />
and next that I delete the #q1# it supposed to look like that:
and don't delete the value of q="2" input.
How can I do that in jQuery/JavaScript?
Take a look at this quick fiddle http://jsfiddle.net/NgxvP/1/
Here you have something to start playing with
<html>
<head>
<style>
#inputField { position:relative;
width: 200px;
height: 200px;
background-color: #cda;
}
</style>
<script src="jquery-1.7.1.min.js"></script>
<script>
// in_array function provided by phpjs.org
function in_array (needle, haystack, argStrict)
{
var key = '',
strict = !! argStrict;
if (strict)
{
for (key in haystack)
{
if (haystack[key] === needle)
{
return true;
}
}
}
else
{
for (key in haystack)
{
if (haystack[key] == needle)
{
return true;
}
}
}
return false;
}
var addedFields = new Array();
function checkFields(input, charCode)
{
var text = (charCode) ? input.value + String.fromCharCode(charCode) : input.value;
var pattern = /#q[0-9]#/g;
var matches = text.match(pattern);
if (!matches) { matches = new Array(); }
if (addedFields.length>0 && addedFields.length != matches.length)
{
for (var index in addedFields)
{
if (!in_array('#q'+ index +'#', matches))
{
$('#q'+index).remove();
delete addedFields[index];
}
}
}
if (matches)
{
for (var i=0; i<matches.length; i++)
{
var code = matches[i];
var index = code.match(/[0-9]/)[0];
if ( $('#q'+index).length == 0 )
{
addFields(index);
}
}
}
}
function addFields(i)
{
addedFields[i] = true;
var fields = '';
for (var index in addedFields)
{
fields += '<input type="text" q="'+ index +'" id="q'+ index +'" />';
}
$('#inputField').html(fields);
}
</script>
</head>
<body>
<div id="formID">
<form>
<textarea onkeypress="checkFields(this, event.charCode); return true;" onkeyup="checkFields(this); return true;"></textarea>
<div id="inputField"></div>
</form>
</div>
</body>
</html>
EDITED: to avoid appending unordered input text fields, but showing them always ordered by their index, as commented in dfsq answer
I created a jsfiddle for your convenience http://jsfiddle.net/2HA5s/

Categories

Resources