rails bootstrap x-editable emptytext - ruby-on-rails

I'm using Bootstrap X-editable in a Rails app. I would like to replace the word empty in a table cell with the name of the field.
The X-editable documentation says the emptytext will replace it.
But, the following doesn't work - I still get empty.
<a href="#" class="answer" data-type="textarea" emptytext="Description" data-pk="1" data-resource="task" data-source="/tasks" data-name="longdesc" data-url="/tasks/<%= task.id %> ">
This is the javascript:
$(".answer").editable
placement: 'bottom'
Thanks for the help.

it's not emptytext="Description" but data-emptytext="Description".
<a href="#" class="answer" data-type="textarea" data-emptytext="Description" data-pk="1" data-resource="task" data-source="/tasks" data-name="longdesc" data-url="/tasks/<%= task.id %> ">
You can also do it in javascript instead of inline html.
$('.answer.description').editable({
placement: 'bottom',
emptytext: 'Description'
});
EDIT about HTML5
Look here about HTML5 data-attribute. This is why all the x-editable's settings start with data-*.
EDIT Answering your comment
You can do like in the official demo Look at the sex select with the prepend data (and display tweak):
$('#sex').editable({
prepend: "not selected",
source: [
{value: 1, text: 'Male'},
{value: 2, text: 'Female'}
],
display: function(value, sourceData) {
var colors = {"": "gray", 1: "green", 2: "blue"},
elem = $.grep(sourceData, function(o){return o.value == value;});
if(elem.length) {
$(this).text(elem[0].text).css("color", colors[value]);
} else {
$(this).empty();
}
}
});
Or you can directly add a sourceData with {value: 0, text: 'Null'}

or you can use
$('.answer').editable({
placement: 'bottom',
defaultValue: 'Description' // for default value
});

Related

Not able to translate <a> tag inside div by i18next library

</head>
<body>
<div id="add">
<div data-i18n="key">You have to Click here to find better result</div>
// If I am using that way that translate complete div and remove link from my text.
<div data-i18n="key">You have to</div> Click here <div data-i18n="key3">to find better result</div>
// If I am using that way code working fine but for this I have to use 3 keys for single sentences. Is it possible to fix this by single key ?
<script>
i18next
i18next.use(window.i18nextBrowserLanguageDetector)
i18next.use(window.i18nextXHRBackend)
.init({
debug: true,
tName: 't',
handleName: 'localize',
selectorAttr: 'data-i18n',
targetAttr: 'i18n-target',
optionsAttr: 'i18n-options',
useOptionsAttr: true,
parseDefaultValueFromContent: true,
initImmediate: true,
fallbackLng: false,
interpolation: {
"escapeValue": true,
"prefix": "{{",
"suffix": "}}",
"formatSeparator": ",",
"unescapePrefix": "-",
"nestingPrefix": "$t(",
"nestingSuffix": ")"
},
detection: {
order: ['querystring', 'cookie', 'navigator', 'htmlTag'],
lookupCookie: 'i18next',
lookupLocalStorage: 'i18nextLng',
caches: ['cookie'],
},
"backend": {
"loadPath": "/locales/{{lng}}/{{ns}}.json"
}
}, function(err, t) {
jqueryI18next.init(i18next, $);
$('#add').localize();
});
</script>
</body>
This code translate complete div
a) Add the tag to your translated text. -> One key
"key": "You have to Click here to find better result"
and
<div data-i18n="html:key">You have to Click here to find better result</div>
to set innerHTML
b) Interpolate the a tag into translation. -> Two keys
"key": "You have to {{link}} to find better result"
with:
$('#add').localize({ link: 'Click here', interpolation: { escapeValue: false }});
translate Click here using i18next.t directly

give default value to md-autocomplete

How to pass default value in md-autocomplete?
Image 1 : HTML code
Image 2 : JS code
Image 3 : Output
As you can see, I am not getting any default country as output. Is there any way to do that?
Assign yr SearchText the default value & selectedItem the object.
$scope.local ={
...
searchText : 'Default Value',
selectedItem : 'Default object'
...
}
I write small codepen with autocomplete and default value.
What you must do:
Init main model.
Define model field, used in autocomplete md-selected-item property.
Define callback for loading autocomplete items.
Before save main model extract id (or other field) from associated field.
Main error in your code here:
$scope.local = {
...
selectedItem: 1, // Must be object, but not integer
...
}
(function(A) {
"use strict";
var app = A.module('app', ['ngMaterial']);
function main(
$q,
$scope,
$timeout
) {
$timeout(function() {
$scope.user = {
firstname: "Maxim",
lastname: "Dunaevsky",
group: {
id: 1,
title: "Administrator"
}
};
}, 500);
$scope.loadGroups = function(filterText) {
var d = $q.defer(),
allItems = [{
id: 1,
title: 'Administrator'
}, {
id: 2,
title: 'Manager'
}, {
id: 3,
title: 'Moderator'
}, {
id: 4,
title: 'VIP-User'
}, {
id: 5,
title: 'Standard user'
}];
$timeout(function() {
var items = [];
A.forEach(allItems, function(item) {
if (item.title.indexOf(filterText) > -1) {
items.push(item);
}
});
d.resolve(items);
}, 1000);
return d.promise;
};
}
main.$inject = [
'$q',
'$scope',
'$timeout'
];
app.controller('Main', main);
}(this.angular));
<head>
<link href="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-aria.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular-animate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-material/0.11.0/angular-material.min.js"></script>
</head>
<body ng-app="app" flex layout="column" layout-margin ng-controller="Main">
<md-content layout="column" class="md-whiteframe-z1" layout-margin>
<md-toolbar>
<div class="md-toolbar-tools">
<h3>Form</h3>
</div>
</md-toolbar>
<md-content class="md-whiteframe-z1">
<div class="md-padding">
<md-input-container>
<label for="firstname">First name</label>
<input type="text" name="firstname" ng-model="user.firstname" />
</md-input-container>
<md-input-container>
<label for="lastname">Last name</label>
<input type="text" name="lastname" ng-model="user.lastname" />
</md-input-container>
<md-autocomplete md-selected-item="user.group" md-items="item in loadGroups(filterText)" md-item-text="item.title" md-search-text="filterText">
<md-item-template>{{ item.title }}</md-item-template>
<md-not-found>No items.</md-not-found>
</md-autocomplete>
</div>
</md-content>
</md-content>
<md-content class="md-whiteframe-z1" layout-margin>
<md-toolbar>
<div class="md-toolbar-tools">
<h3>Model as JSON</h3>
</div>
</md-toolbar>
<md-content class="md-padding">
<p>
{{ user | json }}
</p>
</md-content>
</md-content>
</body>
I know this is an old question, but some people may benefit from my solution. I struggled with the problem of the model for the auto-complete being asynchronous and having my autocompletes as part of an ng-repeat. Many of the solutions to this problem found on the web have only a single auto complete and static data.
My solution was to add another directive to the autocomplete with a watch on the variable that I want to set as default for the auto complete.
in my template:
<md-autocomplete initscope='{{quote["Scope"+i]}}' ng-repeat='i in [1,2,3,4,5,6,7,8]'
class='m-1'
md-selected-item="ScopeSelected"
md-clear-button="true"
md-dropdown-position="top"
md-search-text="pScopeSearch"
md-selected-item-change='selectPScope(item.label,i)'
md-items="item in scopePSearch(pScopeSearch,i)"
md-item-text="item.label"
placeholder="Plowing Scope {{i}}"
md-min-length="3"
md-menu-class="autocomplete-custom-template"
>
then in my module:
Details.directive('initscope', function () {
return function (scope, element, attrs) {
scope.$watch(function (){
return attrs.initscope;
}, function (value, oldValue) {
//console.log(attrs.initscope)
if(oldValue=="" && value!="" && !scope.initialized){
//console.log(attrs.initscope);
var item = {id:0, order:0,label:attrs.initscope?attrs.initscope:"" }
scope.ScopeSelected = item;
scope.initialized = true;
}
});
};
});
this checks for changes to the quote["Scope"+i] (because initially it would be null) and creates an initial selected item and sets the autocompletes' selected item to that object. Then it sets an initialized value to true so that this never happens again.
I used timeout to do this.
$timeout(function() {
$scope.local = {selectedItem : 1}
}, 2000);

data-bind not working in kendo.template

I'm having troubles trying to implement a custom remove button in my Kendo Grid. This is the code I have:
View:
<div id="gridAdditionalLines">
Javascript:
var dataSourceGrid = new kendo.data.DataSource({
data: MyData, --> It's a type of Kendo.Observable
schema: {
model: {
Id: "Id",
fields: {
Id: { editable: false, nullable: true },
Column1: { editable: false, nullable: true },
Description: { validation: { required: true} },
Value: { validation: { required: true} }
}
}
}
});
$("#MyGrid").kendoGrid({
dataSource: dataSourceGrid,
editable: true,
navigatable: true,
toolbar: ["create"],
columns: [
{ field: "Description" },
{ field: "Value" },
{ command: [{name: "destroy", template: kendo.template($("#DeleteTemplate").html())}], width: 60}
]
});
This is the template I'm using for the remove button for each row:
<script type="text/x-kendo-template" id="DeleteTemplate">
<button class="btn btn-default" data-bind="click: Applicability.deleteLine">
<span class="glyphicon glyphicon-remove"></span>
</button>
With the code above, the Kendro Grid display the data properly. However, when trying to remove any row, at the moment to click in the Remove button, nothing happens.
do I missing something?
It has been a little while since I used Kendo, but if I remember correctly, since the grid itself is not MVVM bound, none of its child elements (including the rendered template) will be checked for MVVM data-bind attributes either.
If your grid was initialized with MVVM using data-role="grid" then I think the templates would be bound too.
I forget exactly how to do it, but I believe when the grid triggers its dataBound event, you can manually call kendo.bind(...) on the grid's child elements to get them to MVVM bind.
Your function for button click is missing here. Once you add this script a button is added to the grid, but what happens when you click on button is not specified
<script type="text/x-kendo-template" id="DeleteTemplate">
<button class="btn btn-default" data-bind="click: Applicability.deleteLine">
<span class="glyphicon glyphicon-remove"></span>
</button>
Then you have to add an onclick function for the button:
$('.btn.btn-default').on('click', function() {
var grid = $("#grid").data("kendoGrid");
var dataItem = grid.dataItem($(this).closest("tr"));
if(confirm('Are you sure you want to delete : ' + dataItem.name)) {
grid.dataSource.remove(dataItem);
grid.dataSource.sync();
grid.refresh();
}
});
Check jsbin here

Angular sortable orderby object property

I have a repeater ordered by a property of the objects in the repeater.
<div id='#TodoList' >
<div ng-repeat="todo in todos | filter:left | orderBy:'priority'">
{{ todo.text }}
</div>
</div>
The scope looks like this:
$scope.todos = [
{text: 'do 1', priority: 1},
{text: 'do 2', priority: 2},
]
Now I want to make the #TodoList sortable with jquery ui
jQuery("#TodoList").sortable();
How do I make the priority of each task update according to the new sortable position of the task?
Here's a working example. A few things can be improved there... but it works.
http://jsfiddle.net/QfERt/30/
$("#TodoList").sortable({
update: function( event, ui ) {
var uiArray = $("#TodoList").sortable('toArray');
for (var i = 0; i < $scope.todos.length; i++) {
$scope.todos[i].priority = uiArray.indexOf($scope.todos[i].text) + 1;
}
$scope.$apply();
}
});
jsFiddle: http://jsfiddle.net/AdrianMigraso/BTDdm/
your HTML
<div id='#TodoList' ng-controller="MyCtrl">
<ul id="sortable">
<li class="ui-state-default" ng-repeat="todo in todos | filter:left | orderBy:'priority'">
<span class="ui-icon ui-icon-arrowthick-2-n-s" ></span>
{{ todo.text }}
</li>
</ul>
</div>
you AngularJS code
function MyCtrl($scope) {
$scope.todos = [
{text: 'do 1', priority: 1},
{text: 'do 2', priority: 2},
{text: 'do 5', priority: 5},
{text: 'do 3', priority: 3},
{text: 'do 4', priority: 4},
];
$scope.$watch('todos', function(newVal,oldVal) {
$( "#sortable" ).sortable();
$( "#sortable" ).disableSelection();
});
}

knockout.js, jquery-ui, button click and param

I'm using jQuery UI to create a "button" to a given html element. I'm using Knockout.js to generate the html element (foreach).
However, I can't find the way how to pass a parameter to the click event for knockout.js generated items. In the following example, the somewhat static sampleButton works, but not the itemButton items.
http://jsfiddle.net/patware/QVeVH/
function ViewModel() {
var self = this;
self.ping = 'pong';
self.items = ko.observableArray([
{ display: 'Cars', id: 1 },
{ display: 'Fruits', id: 2 },
{ display: 'Humans', id: 3 },
{ display: 'Software', id: 4 },
{ display: 'Movies', id: 5 },
]);
}
ko.applyBindings(new ViewModel());
$("#sampleButton").button().data('someData',101);
$("#sampleButton").click(function(e){
alert('clicked sample: [' + $(this).data('someData') + ']');
});
$(".itemButton").button().data('someData',$(this).id);
$(".itemButton").click(function(){
alert('clicked item: [' + $(this).attr('foo') + ']');
});
ping-<span data-bind="text: ping"></span>
<div id="sample">
<div id="sampleButton">
<h3>Sample Button</h3>
Click here too
</div>
</div>
<div data-bind="foreach: items">
<div class="itemButton" data-bind="foo: id">
<h3 data-bind="text:display"></h3>
</div>
</div>​
Consider using ko.dataFor instead of applying data with jquery.
Working sample based on your example http://jsfiddle.net/QVeVH/6/
You can set everything up using a custom binding.
http://jsfiddle.net/jearles/QVeVH/7/

Resources