how to run ruby in haml in javascript definition? - ruby

how can I run ruby code inside javascript in haml?
if I use var = #{message} in my example I get undefined local variable or method message
when I move - message = 'it works' above :javascript everything works fine
I want to run iteration .each inside :javascript. See the last code sample for what I need in final javascript code. Where I need to loop few ruby variables (or one hash of hashes of hashes?) to get this. Data (='basics') can have few elemenets. It can have children with few elements etc.
SO this haml code
%html
%head
:javascript
$(document).ready(function() {
- message = 'it works'
var = message
});
%body
- message2 = 'hi'
= message2
%div{:id =>"jstree"}
gives me this html code
<html>
<head>
<script type='text/javascript'>
//<![CDATA[
$(document).ready(function() {
- message = 'hi'
var = message
});
//]]>
</script>
</head>
<body>
hi
<div id='jstree'></div>
</body>
</html>
The final javascript code I want to produce using haml is the javascript variable
var data = [{
data: "basics",
attr: {},
children: [
{data: "login", attr: {run: "run"},
children: [
{data: "login", attr: {}}
]
} ,
{data: "Academic Year", attr: {run: "run"},
children: [
{data: "login", attr: {}},
{data: "Academic Year", attr: {filter: "mini", SOF: "yes"}}
]
}
]
}];

First, let's review what you seem to know:
Ruby requires you to define local variables before you use them.
You can run Ruby code on lines outside of a filter using - ....
You use #{...} markup to interpolate Ruby code inside a filter.
You say you want to run each, but presumably you want output from this; since the result of #{...} is turned into a string and put in your code, what you really want (probably) is map:
%html
%head
:javascript
var foo = [];
#{
limit = rand(4)+3
array = (0..limit).to_a
array.map{ |i| "foo[#{i}] = #{rand(12)};" }.join ' '
}
console.log(foo.length);
%body
Running the above code gives this output:
<html>
<head>
<script type='text/javascript'>
//<![CDATA[
var foo = [];
foo[0] = 2; foo[1] = 0; foo[2] = 11; foo[3] = 8; foo[4] = 0; foo[5] = 1;
//]]>
</script>
<body></body>
</head>
</html>
As you can see, the big #{...} block (which may span multiple lines) runs arbitrary Ruby code. The result of the last expression (in this case the map{...}.join) is converted to a string and placed in the output.

The haml documentation for filters states that you can interpolate Ruby code using #{}
- flavor = "raspberry"
#content
:textile
I *really* prefer _#{h flavor}_ jam.

Related

How to find item using wildcard in Kendo AutoComple

I am using Kendo with JQuery, And I need to create a search with wildcard
Ex: Apple%Red
How I can I do this?
Despite that I cannot find any reference to it in the documentation of autocomplete and it says filter needs to be String you can define it as a function that receives two parameters, the item to compare with and the value of the input field.
Now, the question is that given that you use % as a wildcard, makes me think that you should be using a server-side filtering but given that you ask for a JavaScript or jQuery implementation makes me think you ask for a browser implementation.
If your users can enter the wildcards using JavaScript regular expression syntax, you can simply do:
$("#autocomplete").kendoAutoComplete({
filter: function(input, pattern) {
var re = new RegExp(pattern, 'i');
return re.test(input);
},
dataSource: {
data: ["one", "two", "three"]
}
});
But if you want them to use % as wildcard for any character you can internally replace if by .* and do something like:
$("#autocomplete").kendoAutoComplete({
filter: function(input, pattern) {
pattern = pattern.replace('%', '.*');
var re = new RegExp(pattern, 'i';
return re.test(input);;
},
dataSource: {
data: ["One", "Two", "Three"]
}
});
NOTE: Important to note that by default autocomplete is case insensitive but you can control it using ignoreCase
Following a code snippet. Try entering t and t%e
var ignoreCase = true;
$("#autocomplete").kendoAutoComplete({
ignoreCase: ignoreCase,
filter: function(input, pattern) {
pattern = pattern.replace('%', '.*');
var re = new RegExp(pattern, ignoreCase ? 'i' : '');
return re.test(input);
},
dataSource: {
data: ["One", "Two", "Three"]
}
});
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.common.min.css" />
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.silver.min.css" />
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2018.1.221/js/kendo.all.min.js"></script>
<input id="autocomplete" />

How can I clean this code up better?

I have a script inserted into Magento and it does not seem to be behaving properly. Whenever it runs it actually feeds the contents of the html document back into the text box rather than the autosuggestion. Can anyone tell me what the issue seems to be? I think it might be the two functions conflicting, is there a good way to clean this up?
<script type="text/javascript" src="jquery-2.1.1.js"></script>
<script type="text/javascript" src="jquery.autocomplete.js"></script>
<script type="text/javascript" >
//<![CDATA[
$j = jQuery.noConflict();
$j(document).ready(function(){
$j("#antique_toys_materials").keyup
(function()
{
var tag= $j(this).val();
if(tag!='')
{
$j.ajax(
{
type: "GET",
url: "autocomplete.php",
data: "q=" + tag,
cache: true,
success: function(result)
{
$j("#antique_toys_materials").val(result);
}
}
);
}
return false;
}
);
}
);
//]]>
</script>
<script type="text/javascript" >
//<![CDATA[
$j = jQuery.noConflict();
$j(window).load(function(){
function calculate()
{
var values = [
$j("#cost").val(),
$j("#shipping_paid").val(),
$j("#tax_paid").val()
];
var percent_value = $j("#our_markup").val();
//---------------------------//
if (percent_value == 285)
{
var percent_value = 0;
}
var sub_total = eval( values.join('+') );
var total = eval("sub_total+(sub_total * percent_value)");
var shortened_total = total.toFixed(2);
$j("#price").val(shortened_total);
}
$j( document ).ready(function() {
$j(document).on('input', 'input', calculate);
$j(document).on('change', 'select,input', calculate);
});
});
//]]>
</script>
and it hooks up with this
<?php
$q=$_GET['q'];
$my_data=mysql_real_escape_string($q);
$mysqli=mysqli_connect('localhost','XXXXXXX','XXXXXXX','XXXXXXX') or die("Database Error");
$sql = "SELECT DISTINCT auto_complete_suggestions FROM auto_complete WHERE auto_complete_suggestions LIKE '%$my_data%'
ORDER BY CASE WHEN auto_complete_suggestions = '$mydata' THEN 0
WHEN auto_complete_suggestions LIKE '$mydata%' THEN 1
WHEN auto_complete_suggestions LIKE '%$mydata%' THEN 2
WHEN auto_complete_suggestions LIKE '%$mydata' THEN 3
ELSE 4
END, auto_complete_suggestions LIMIT 0,1";
$result = mysqli_query($mysqli,$sql) or die(mysqli_error());
if($result)
{
while($row=mysqli_fetch_array($result))
{
echo $row['auto_complete_suggestions']."\n";
}
}
?>
It works fine in isolation without the noConflict but then when I put it in Magento it seems to need some help and I'm sure that since it's feeding the html file back into it that something's wrong.
Thoughts? Thanks!
This is just a quick guess, but try using the word "jQuery" instead of "$". I had to change a few plugin scripts that interfered with prototype since it too uses the "$". Once I replaced all instanced of $ with the word jQuery, things started working as I expected.

Kartograph map won't display

I can't get Kartograph.js to display my .svg map. Here's what I've done:
I've successfully made a .svg map from a .shp using the most basic json file I could with kartograph.py, according to Kartograph's docs, doing the basic world.json -o world.svg. Here's the json:
{
"layers": [{
"src": "ne_50m_admin_0_countries.shp",
"simplify": 3
}]
}
I've set up a simple http host with python and directed chrome to the host, since I understand you can't do this locally.
I've written the code below. I don't get any errors, so I don't what I've done wrong. Could it be that I haven't put in any layers? I wanted to make as simple an example as possible for my first try.
<div id="map"></div>
<script>
function loadMap() {
var map = kartograph.map('#map');
map.loadMap('world.svg', function() {
});
};
</script>
<script src="jquery-1.11.0.min.js"></script>
<script src="kartograph.js-master/dist/kartograph.js"></script>
<script src="raphael-master/raphael-min.js"></script>`
Thanks guys.
You must add the layer of the svg file.
In this case: map.addLayer('layer_0');
All the code:
$(function() {
var map = kartograph.map('#map',800,600)
map.loadMap('world.svg', function() {
map.addLayer('layer_0');
});
});
To see the name of the layer i open the svg file with Inkspace, and then press Shift+Control+X.

how to set text in ckeditor

How do I set text in CKEditor? CKEditor also needs to integrate with ckfinder.
I tried doing
// I need to set ckeditor text with a value in code behind. To get that value from code bhind, I am using a div which would be set in code behind. This is not hidden currently but I would do that eventually. I need to set this value to my ckeditor.
<textarea id="editor1" name="editor1"></textarea>
<script type="text/javascript">
window.onload = function () {
var edt = CKEDITOR.replace('editor1', { toolbar: 'Basic' });
CKFinder.setupCKEditor(edt, '/ckfinder/');
var t = <%=editortext.InnerText %>;
CKEDITOR.instances.editor1.setData(t);
}
If I put some static text for t, var t = "Some Text";
and then set
CKEDITOR.instances.editor1.setData(t); it works fine.
If I use,
var t = <%=editortext.InnerText %>;
CKEDITOR.instances.editor1.setData(t);
ckeditor is no longer displayed. Only text area is displayed. How to set text in ckeditor ? Please help
This syntax may be useful here:
CKEDITOR.instances['editor1'].setData(t); // where editor1 is id
OR try this
edt.setData(t);
<script>
function SetContents(value ) {
var oEditor = CKEDITOR.instances.MainContent_editor1;
var t = document.getElementById('<%=editor1.ClientID %>').value ;
oEditor.setData(t);
}
</script>
<script type="text/javascript">
var ckEditor = CKEDITOR.replace('<%=editor1.ClientID %>', {
// extraPlugins: 'bbcode',
// fullPage : true,
extraPlugins: 'docprops',
removeDialogTabs: 'image:advanced',
filebrowserImageUploadUrl: 'Upload.ashx',
resize_enabled: false,
toolbar: [
['Source', '-', 'Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink'],
['FontSize', 'TextColor', 'BGColor'],
['Image']
]
});
var oEditor = CKEDITOR.instances.MainContent_editor1;
var t = document.getElementById('<%=editor1.ClientID %>').value;
oEditor.setData(t);
function pageLoad() { // this is because after postback jquery not working
var instance = CKEDITOR.instances['<%=editor1.ClientID %>'];
if (instance) {
CKEDITOR.remove(ckEditor);
}
CKEDITOR.replace('<%=editor1.ClientID %>', {
// extraPlugins: 'bbcode',
// fullPage : true,
extraPlugins: 'docprops',
removeDialogTabs: 'image:advanced',
filebrowserImageUploadUrl: 'Upload.ashx',
resize_enabled: false,
toolbar: [
['Source', '-', 'Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink'],
['FontSize', 'TextColor', 'BGColor'],
['Image']
]
});
var oEditor = CKEDITOR.instances.MainContent_editor1;
var t = document.getElementById('<%=editor1.ClientID %>').value;
oEditor.setData(t);
}
</script>
Check in your browser's console for errors first. Also observe what is rendered from your backend code into this template. Most likely what you're missing are quotation marks "" and/or your rendered string contains unescaped apostrophes/quot. marks.
Console is everything.
this post is quote old but I hope I am not too late for others to see this:
You forgot to enclose the server side code with quotes:
var t = "<%=editortext.InnerText %>";
the page will be rendered like this:
var t = "your text here";
instead of
var t = your text here;
using your code will definitely break javascript's parser
You just put double quotes
for example :-
var mata = CKEDITOR.replace('meta_des');
var editor = CKEDITOR.replace('des1');
mata.setData("meta_des; ?>");
editor.setData("description1 ;?>");
here my meta_des is ckeditor and i want past my value in that ckeditor i will just put double quotes on my php tag and simply it will print my value that comes in database it will print.

Change content [] object property without removing or adding

I setup a list of objects, add them to content[] array list. So far so fine. Ember DOM in App.list show correct data. Now, when I start altering the content properties without remove/add/replaceAt() any object in App.list it seems Ember doesn't pick this up.
View:
{{#each item in App.list.content}}
{{item.title}}
{{/each}}
Code:
function myApp() {
App = Ember.Application.create({});
App.Item = Ember.Object.extend({
title: null,
parent: null
});
App.MyList = Ember.Object.extend({
title: null,
content: [],
changed: function() {
console.log('here');
}.observes('content')
});
App.list = App.MyList.create({
title: "foobar",
content: [
App.Item.create({
title: "item1"
}),
App.Item.create({
title: "item2"
})
]
});
console.log(App.list.content);
// Add 3rd object to list
App.list.get('content').pushObject(
App.Item.create({
title: "item3"
})
);
}
..and later in some random Ember ArrayController I do this:
for (var i = 0; i < 2; i++) {
App.list.content[i].title = "I CHANGED YOU";
}
Looking at my App.list the content is correct, but view is not. Am I missing something? If I have to guess ArrayHasChanged() seems to be rigged for array size changed or object being changed which I'm not doing, I'm altering property data within specific objects of the content[] array. Is it possible or do I have to removeAt()/Add/Delete objects?
You need you use get and set so the observers/bindings trigger with your changes.
// Bad
App.list.content[i].title = "blah";
// Good
App.get('list').objectAt(i).set('title', 'blah');
If this still does not work for you there might be something else missing. If you could post a jsfiddle that would help a lot!

Resources