I Have plugin CKeditor, when I Write text with "$100", ckeditor remove this string, when I save. How I Can resolve this problem?
JS:
<script type="text/javascript">
jQuery(document).ready(function () {
CKEDITOR.config.allowedContent = true;
CKEDITOR.config.extraPlugins = 'dragresize,jsplus_stat';
var editorMd = CKEDITOR.replace('edit_md', {contentsCss: '/css/tools.css'});
var editorRu = CKEDITOR.replace('edit_ru', {contentsCss: '/css/tools.css'});
var editorEn = CKEDITOR.replace('edit_en', {contentsCss: '/css/tools.css'});
//CKFinder.SetupCKEditor( null, '/js/ckfinder3/' );
//CKEDITOR.config.wordcount = {showWordCount: true}
CKEDITOR.config.filebrowserBrowseUrl = '/js/kcfinder/browse.php?opener=ckeditor&type=files';
CKEDITOR.config.filebrowserImageBrowseUrl = '/js/kcfinder/browse.php?opener=ckeditor&type=imagesnew';
CKEDITOR.config.filebrowserFlashBrowseUrl = '/js/kcfinder/browse.php?opener=ckeditor&type=flash';
CKEDITOR.config.filebrowserUploadUrl = '/js/kcfinder/upload.php?opener=ckeditor&type=files';
CKEDITOR.config.filebrowserImageUploadUrl = '/js/kcfinder/upload.php?opener=ckeditor&type=imagesnew';
CKEDITOR.config.filebrowserFlashUploadUrl = '/js/kcfinder/upload.php?opener=ckeditor&type=flash';
//CKFinder.setupCKEditor(null);
/*
CKFinder.setupCKEditor( null, {
skin: 'moono',
swatch: 'b',
onInit: function( finder ) {
finder.on( 'files:choose', function( evt ) {
var file = evt.data.files.first();
//console.log( 'Selected: ' + file.get( 'name' ) );
} );
}
} );
*/
/*
CKEDITOR.editorConfig = function(config) {
config.filebrowserBrowseUrl = '/js/kcfinder/browse.php?opener=ckeditor&type=files';
config.filebrowserImageBrowseUrl = '/js/kcfinder/browse.php?opener=ckeditor&type=images';
config.filebrowserFlashBrowseUrl = '/js/kcfinder/browse.php?opener=ckeditor&type=flash';
config.filebrowserUploadUrl = '/js/kcfinder/upload.php?opener=ckeditor&type=files';
config.filebrowserImageUploadUrl = '/js/kcfinder/upload.php?opener=ckeditor&type=images';
config.filebrowserFlashUploadUrl = '/js/kcfinder/upload.php?opener=ckeditor&type=flash';
};
*/
jQuery('#date_show').datetimepicker({
locale: 'en',
format: 'YYYY-MM-DD HH:mm:ss'
});
});
function openMedia() {
window.open('<?=$adminRoot . 'news/media/id/' . $item->id . '/'?>', '_blank', 'width=800,height=600');
return false;
}
</script>
Code when I load CKeditor, and config this. Please help me fix this problem.
CKEditor is a JavaScript application. It has nothing to do with saving data. I also haven't heard of any built-in filter removing "$100" string. Things you might want to check:
Run CKEDITOR.instances.yourEditorInstanceName.getData();. If "$100" is not there, please look for some third-party script reacting to \$\d pattern or something similar. Another thing to check would be a third-party CKEditor plugins. Perhaps you have some "before save" plugin which filters out such strings.
Please check your server-side code if it doesn't contain any filter removing strings starting with $. Debugging whole request (when editor data is submitted) might also help you find out where exactly "$100" gets removed.
Related
I have a project foreign key in by Phase model. I'm having hard time Create a dependent drop-down list inside my Django admin page.
I want to when user select a project from (project drop-down) phase of that project show in second dop-down
What would be the best way to achieve this?
It would be great if the dropdowns filter items based on the value of its parent.
class Project(models.Model):
name = models.CharFieldmax_length = 100, unique= True)
short_name = models.CharField(max_length= 4, unique= True)
slug = models.SlugField(max_length= 100, allow_unicode=True, null=True, editable= False)
location = models.OneToOneField(Location, on_delete = models.SET_NULL, null= True, blank= False, verbose_name= 'موقعیت')
start_date = models.DateField(default= timezone.now, null= True, blank= True)
end_date = models.DateField(default= timezone.now, null= True, blank= True)
duration = models.IntegerField(default= 0, editable= False)
class Phase(models.Model):
title = models.CharField(max_length= 20)
class ProjectPhase(models.Model):
project = models.ForeignKey(Project, on_delete= models.CASCADE, related_name= 'phase')
phase = models.ForeignKey(Phase, on_delete=models.CASCADE, related_name= 'project')
start_date = models.DateField(default= timezone.now)
end_date = models.DateField(default= timezone.now)
duration = models.IntegerField(default= 0, editable= True)
1. import a js media file in ModelAdmin for Generaldata:
class YourModelAdmin(admin.ModelAdmin):
form = YourModelForm
#list_display = ['your fields',]
class Media:
js = ("yourapp/selectajax.js",)
admin.site.register(YourModel, YourModelAdmin)
2. create a new js file which saved yourproject/yourapp/static/yourapp/ directory or another proper directory.
jQuery(function($){
$(document).ready(function(){
$("#id_project_select").change(function(){
// console.log(obj.currentTarget.value);
$.ajax({
url:"/get_phases/",
type:"POST",
data:{project: $(this).val(),},
success: function(result) {
console.log(result);
cols = document.getElementById("id_phase_select");
cols.options.length = 0;
for(var k in result){
cols.options.add(new Option(k, result[k]));
}
},
error: function(e){
console.error(JSON.stringify(e));
},
});
});
});
});
3. create a view to process ajax
#login_required
def get_phases(request):
project = request.POST.get('project')
phases = {}
try:
if project:
prophases = Project.objects.get(pk=int(project)).phase
phases = {pp.phase.title:pp.pk for pp in prophases}
except:
pass
return JsonResponse(data=phases, safe=False)
4. add 'get_phases/ to urlpatterns.
Notice that you should modify some codes as your need.
The answer by Blackdoor is a good approach and it's the one we just implemented, but it has a couple of problems:
It's only executed when you change the main select, and I wanted the dependant select to be filtered also on page load.
Does not keep que selected item in the dependant select.
In his solution, in step 2, replace his code with this one and adapt the names (I'm using service and sub_service instead of project / phase):
jQuery(function($){
$(document).ready(function(){
var clone = document.getElementById("id_sub_service").cloneNode(true);
$("#id_service").change(function(){
update_sub_services($(this).val(), clone)
});
update_sub_services($("#id_service").val(), clone)
});
function update_sub_services(service, clone) {
$.ajax({
url:"/chained_dropdowns/get_sub_services/",
type:"GET",
data:{service: service,},
success: function(result) {
var cols = document.getElementById("id_sub_service");
cols.innerHTML = clone.innerHTML
Array.from(cols.options).forEach(function(option_element) {
var existing = false;
for (var k in result) {
if (option_element.value == k) {
existing = true
}
}
if (existing == false) {
$("#id_sub_service option[value='"+option_element.value+"']").remove();
}
})
},
error: function(e){
console.error(JSON.stringify(e));
},
});
}
});
As you can see, now instead of removing all the items from the dependant select and then refilling it (which leaves you without the selected property and any other custom property), it removes the options that should not be there.
I'm not a JS developer and I don't know jQuery so my modifications are in native JS, please feel free to improve it :)
Is there a way to get objectId parameter from js and send it as parameter to Url action?
JS:
function ButtonClick(objectId) {
App.testID.fireEvent("click", objectId);
}
Ext.net:
Html.X().ID("testID").DirectEvents
(
de =>
{
de.Click.Url = Url.Action("TestMethod", "TestController");
de.Click.ExtraParams.Add(new Parameter("objectId", "I need objectId here"));
}
)
I came with diferent solution when I saw compiled code in debugger.
You can create direct event like this:
Html.X().ID("testID")
.Listeners
(
l =>
{
l.AfterRender.Handler = #"App.testID.on('testEvent', function(id) {
Ext.net.directRequest({
url: '/TestController/TestMethod',
extraParams:
{
'objectId': id
}
});
});";
}
)
And fire it with:
function ButtonClick(objectId) {
App.testID.fireEvent("testEvent", objectId);
}
Just add the raw code as the value string and add ParameterMode.Raw to the Parameter instance, like this:
de.Click.ExtraParams.Add(new Parameter("objectId", "App.MyComponent.Id", ParameterMode.Raw));
(based on Examples Explorer - Layouts > CardLayout)
Or alternatively, a custom object:
de.Click.ExtraParams.Add(new
{
myTargetId = JRawValue.From("this.up('button').id")
});
(based on Examples Explorer - Models > Data Annotations)
I have a problem with my application developped with angular & apache cordova on android.
On the first place I fetch the contact list from my smartphone and store it in a var : $scope.listecontacts
// alert('nb contacts '+contacts.length);
for (var i = 0; i < contacts_1.length; i++)
{
if(contacts_1[i].phoneNumbers != null && contacts_1[i].name != null && typeof contacts_1[i].phoneNumbers != 'undefined')
{
if($scope.numero_tel==0)
{
$scope.numero_tel = contacts_1[i].phoneNumbers[0].value;
}
$scope.listecontacts.push(contacts_1[i]);
}
}
And in a second time I try to display it in the html dom like this :
<div ng-repeat="t in listecontacts" >{{(t.name.formatted)}}</div>
When I launch my application it runs fine but when I go back in the home page and then go on the view that fetch the contact list, the DIV is not filled with the contact list.
I have checked the variable : $scope.listecontacts and it is not empty....
Has anyone ever meet this problem ?
Have you got any Idea ?
Thanks a lot !
I have tried to use a service this way :
app.factory('ContactService', function($window, $q, $rootScope){
var options = new ContactFindOptions();
options.filter = "";
options.multiple = true;
var filter = ["displayName", "name","phoneNumbers"];
// navigator.contacts.find(filter, onSuccess, onError, options);
return {
getContactList : function(onSuccess, onError){
navigator.contacts.find(filter,function(contacts){
$rootScope.$apply(function(){
onSuccess(contacts);
})
}, function(){
$rootScope.$apply(function(){
onError();
})
}, options)
}
}
})
And then in my controller :
$scope.get_contacts = function()
{
/*alert('get_contacts');*/
try
{
ContactService.getContactList(function(contacts)
{
But nothing chages, I check the variables with the console with via USB and Chrome and the array is fileld with thje value but the HTML doesn't displays the data.
Thanks for your help !
Actually my service was running fine I just had to change
this :
<option ng-repeat="t in listecontacts" value="{{(t.phoneNumbers[0].value)}}" >{{(t.name.formatted)}}</option>
to this
<option ng-repeat="t in listecontacts.liste_1" value="{{(t.phoneNumbers[0].value)}}" >{{(t.name.formatted)}}</option>
since I used an object instead of an array for "listecontacts"
$scope.listecontacts= {
liste_1: []
};
I'm using select2 for tagging and I have it setup such that a user can add new tags as well. The issue that I'm dealing with is validating the user entry and adding the sanitized tag to selection.
To be more specific, when a user enters a space in a tag, i use formatNoMatches to display a js link to sanitize the tag and then add the tag programmatically. This code seems to run without errors but when sanitize is called all selections of the input are cleared.
Any clues where i might be going wrong?
var data=[{id:0,tag:'enhancement'},{id:1,tag:'bug'},{id:2,tag:'duplicate'},{id:3,tag:'invalid'},{id:4,tag:'wontfix'}];
function format(item) { return item.tag; }
function sanitize(a){
$("#select").select2('val',[{
id: -1,
tag: a
}]);
console.log(a);
};
$("#select").select2({
tags: true,
// tokenSeparators: [",", " "],
createSearchChoice: function(term, data) {
return term.indexOf(' ') >= 0 ? null :
{
id: term,
tag: term
};
},
multiple: true,
data:{ results: data, text: function(item) { return item.tag; } }, formatSelection: format, formatResult: format,
formatNoMatches: function(term) { return "\"" + term + "\" <b>Is Invalid.</b> <a onclick=\"sanitize('"+ term +"')\">Clear Invalid Charecters</a>" }
});
Only this solution works for me:
function convertObjectToSelectOptions(obj){
var htmlTags = '';
for (var tag in obj){
htmlTags += '<option value="'+tag+'" selected="selected">'+obj[tag]+'</option>';
}
return htmlTags;
}
var tags = {'1':'dynamic tag 1', '2':'dynamic tag 2'}; //merge with old if you need
$('#my-select2').html(convertObjectToSelectOptions(tags)).trigger('change');
After hacking on it some more i realized that I should be setting the new item to the "data" property and not value.
var newList = $.merge( $('#select').select2('data'), [{
id: -1,
tag: a
}]);
$("#select").select2('data', newList)
You can set new value (if tags you can pass array) and trigger 'change' event.
var field = $('SOME_SELECTOR');
field.val(['a1', 'a2', 'a3']) // maybe you need merge here
field.trigger('change')
About events: https://select2.github.io/options.html#events
I am trying to find out why the filter function isn't working, but I am stucked. This is the first time I am using Dojo but I am not really familliar with that framework. I am trying and searching for maybe 2 or 3 hours but I can't find a solution.
Waht I want, is to implement a filter or search mechanism. But it is not working, yet...
This is my code:
dojo.require('dojo.store.JsonRest');
dojo.require('dijit.layout.ContentPane');
dojo.require("dijit.form.Button");
dojo.require('dojox.grid.DataGrid');
dojo.require('dojo.data.ObjectStore');
dojo.require('dijit.form.TextBox');
dojo.require('dojox.data.AndOrReadStore');
dojo.require('dojo._base.xhr');
dojo.require('dojo.json')
dojo.require('dojo.domReady');
dojo.ready(
function(){
var appLayout = new dijit.layout.ContentPane({
id: "appLayout"
}, "appLayout");
var textBox = new dijit.form.TextBox({
name: "searchbox",
placeHolder: "Search ..."
});
var filterButton = new dijit.form.Button({
label: 'Filter',
onClick: function () {
searchWord = textBox.get('value');
query = "id: '"+searchWord
+"' OR date_A: '"+searchWord
+"' OR dateB: '"+searchWord
+"' OR product: '"+searchword+"'";
grid.filter({complexQuery: query}, true);
}
});
store = new dojo.store.JsonRest({target:'products/'});
grid = new dojox.grid.DataGrid(
{
store:dojo.data.ObjectStore({objectStore: store}),
structure:
[
{name:'id', field: 'id'},
{name:'date_A', field: 'dateA'},
{name:'date_B', field: 'dateB'},
{name:'product' , field: 'product'},
],
queryOptions: {ignoreCase: true}
});
textBox.placeAt(appLayout.domNode);
filterButton.placeAt(appLayout.domNode);
grid.placeAt(appLayout.domNode);
appLayout.startup();
}
);
Would be very nice if u can tell me what's wrong with this dojo code...
The result is, that the loading icon appears and after a while the unfiltered data is shown... There is no exception thrown.
Thanks in advance.
Ok, I have solved it with the AndOrReadWriteStore. You can also use an AndOrReadStore. The problem was, that the JSON data wasn't in the right format. You can see the right format here: dojotoolkit.org/api/dojox/data/AndOrReadStore. The other change is: I used the url instead the data attribute inside the store. So finally it is working now. Thx anyway.
Here's an example of a filter that uses both an AND and an OR:
grid.filter("(genre: 'Horror' && (fname: '" + searchWord + "' || lname:'" + searchWord + "'))")
So the users search word is filtered across fname and lname as an OR but it also searches for genre = Horror as an AND.
This document has other examples...
http://livedocs.dojotoolkit.org/dojox/data/AndOrReadStore