ExtJs HtmlEditor image upload? - javascript

I am using ExtJs4.2.1 as the frontend and asp.net mvc 4 as the backend. My customer has the following requirements:
They wanna copy bunch of stuff from a document(like .docx file etc.) directly into the extjs's htmleditor. So, there will inevitably be mixtures of rich texts and images inside the editor, which is a problem because the html editor of extjs can not upload picture directly. So, I wonder if there is an solution for this? I googled a lot, and some of the answers will involve to add a extra button for the editor and pop up an add File panel to let the customer insert image. I think it is little bit tricky. Could I filter out the picture in the editor and directly upload it without popping up another selection panel? Anyway, is there a more elegant way to do things like this?
Any help relating this topic will be really appreciated.

Although I have not tried this you could use TinyMCE which has a plugin that claims to do this http://www.tinymce.com/wiki.php/Plugin:paste
There is an ExtJS component for TinyMCE https://www.sencha.com/forum/showthread.php?198699-Ext.ux.form.TinyMCETextArea-a-text-area-with-integrated-TinyMCE-WYSIWYG-Editor.

ExtJs HtmlEditor image upload
Ext.onReady(function() {
Ext.create('Ext.window.Window', {
title: 'Test panel',
renderTo: Ext.getBody(),
items: [{
xtype: 'htmleditor',
itemId: 'txtBody',
fieldLabel: 'Body',
enableFormat: false,
enableFont: false,
enableFontSize: false,
enableColors: false,
allowBlank: false,
listeners: {
render: function(editor) {
editor.getToolbar().add({
xtype: 'button',
text: 'fileIUpload',
handler: function() {
new Ext.Window({
title: 'Image Upload',
closable: true,
itemId: 'wndImageUpload',
height: 120,
width: 300,
items: [{
xtype: 'form',
itemId: 'frmFileUpload',
fileUpload: true,
items: [{
xtype: 'fileuploadfield',
fieldLabel: 'Select Image',
name: 'Upload',
itemId: 'imgFileUploadField',
labelWidth: '90',
margin: '20 0 0 0'
},
{
xtype: 'button',
text: 'Submit',
scope: this,
margin: '15 0 0 200',
//handler: function (config) {
// var ns = config.ns;
// var form = ns.frmFileUpload.getForm();
// form.submit({
// url: 'Admin/UploadEmailTemplateImage',
// success: function (fp, result) {
// var imagePath = '/Upload/EmailTemplateImage/' + result.result.data);
// var imageHeight = result.result.imageHeight;
// var imageWidth = result.result.imageWidth;
// var html = '<img src="' + imagePath + '" Height= "' + imageHeight + '" Width= "' + imageWidth + '"/>';
// ns.txtBody.setValue(html);
// ns.wndImageUpload.hide();
// },
// failure: function (fp, result) {
// Ext.Msg.alert(t('Error'), result.result.message);
// }
// });
//}
},
]
}]
}).show();
}
});
}
}
}
]
}).show();
});

Change the editor to Ext.ux.form.TinyMCETextArea.
While creating the component, initialize the tinyMCEConfig parameter of the editor with a config object having paste_data_images: true

Related

The problem with getting the top container component. Extjs

When I click on a tree record, I try to set the values ​​of this record and set these values ​​in the form.
In the eventcler itemclick: this.showDataFields function is triggered:
....
showDataFields: function(view, record, item, index, event) {
//got a form with fields
var panel = view.up('maintab');
console.log(panel)
//var formfield = panel.down('actionform');
//assign values from selected record to form fields
//formfield.loadRecord(record);
},
..........
In this function, view.up ('maintab') is underfined.
The maintab is Ext.tab.Panel which houses the tree.
Why can not get the topmost container and how to do it correctly?
Made an example in fiddle
thank
You should use view.up('treepanel').nextSibling().getForm().setValues(record.data) in your showDataFields function to set these values ​​in the form.
You could have provided a better example, therefore within the limitations that were proposed.
The answer I got was this were the changes in the ActionFormTree class that got the code below:
Ext.define('Fiddle.view.ActionFormTree', {
extend: 'Ext.form.Panel',
alias: 'widget.actionformtree',
xtype: 'actionform',//mainform,
initComponent: function(){
var me = this;
Ext.apply(me,{
items: [{
xtype: 'form',
border: false,
anchor: '100%',
height: 100,
layout: {
type: 'vbox',
align: 'middle',
pack: 'center'
},
items: [{
xtype: 'textfield',
name: 'text',
fieldLabel: 'Наименование',
itemId: 'name_field',
}, {
xtype: 'textfield',
name: 'code',
fieldLabel: 'Код',
itemId: 'code_field',
}]
}],
buttons: [{
text: 'Save Changes',
scope: me,
handler: function (button) {
//Эта панель со значениями полей
form = me.down('form');
var mainpanel = me.up('#maincontainer');
var treeform = mainpanel.down('usertree');
var sel = treeform.getSelectionModel().getSelection()[0];
store = treeform.getStore();
console.log(treeform)
store.suspendAutoSync()
var child = sel.set({
text: 'Измененное',
leaf: true
});
sel.expand()
store.resumeAutoSync();
//var currRecord = form.getRecord();
//if (currRecord) {
// form.updateRecord();
// form.reset();
//}
}
}]
});
me.callParent(arguments);
}
});
So, in this example, for it to work, you will need to have a node selected to work.
Hope it helps and finalize your question.
Sample to your code

w2ui grid hide and show not working properly

I am working on w2ui grid and I need to hide and show it based on certain condition. Grid is not showing back even though visibility:visible property is applied after it is hidden. It is just showing a line.
Please have a look at my code below:
HTML:
<div id="LastMileGrid" class="col-lg-6 col-sm-12 col-md-6" style="width: 100%; height: 150px"></div>
Javascript:
$('#LastMileGrid').w2grid({
name: 'LastMile',
show: {
toolbar: true,
footer: true,
toolbarReload: false,
toolbarColumns: false,
lineNumbers: true,
},
columns: [
{ field: 'recid', caption: 'ID', size: '10%', sortable: true },
//{ field: 'Header', caption: 'Header', size: '20%', editable: { type: 'text' }, sortable: true },
{ field: 'Description', caption: 'Description', size: '50%', editable: { type: 'text' }, sortable: true }
],
toolbar: {
items: [
{ id: 'add', type: 'button', caption: 'Add Record', icon: 'w2ui-icon-plus' },
{ id: 'remove', type: 'button', caption: 'Remove Record', icon: 'w2ui-icon-cross' }
],
onClick: function (event) {
if (event.target == 'add') {
var Index = w2ui['LastMile'].records.length;
w2ui['LastMile'].add({ recid: w2ui['LastMile'].records.length + 1 });
}
if (event.target == 'remove') {
var grid = w2ui["LastMile"];
grid.method = 'DELETE';
grid.delete();
}
}
},
//records: [{ recid: 'AAA' }, { recid: 'BBB' }, { recid: 'CCC' }]
});
And when opening the pop up I call the function,
$('#popup').w2popup('open', {
onOpen: function () {
if ($("#ddlMode").val() == "AIR" && ($("#drpServiceScope").val() == "D2D" || $("#drpServiceScope").val() == "A2D")) {
$('#LastMileGrid').attr("style", "visibility:visible;height:160px:")
}
else {
$('#LastMileGrid').attr("style", "visibility:collapse;")
}
},
modal: true,
});
You can try to call w2ui["LastMile"].refresh() after hiding or showing.
Answering to help others as I am late :D.
After spending a lot of time to resolve the issue,I have formulize below 2 solutions for w2ui grid show hide issue or column size issue :
1.Change the size of columns to px instead of %.
ie. use
{ field: 'lname', caption: 'Last Name', size: '30px' }
instead of
{ field: 'lname', caption: 'Last Name', size: '30%' },
2. If you wish to keep column size in % due to some requirement:
Depending on where you are rendering grid,you need to handle the resizing.
Calling refresh on grid will send data request again to server.
I don't wanted grid to make call to server each time I show/hide grid, hence written the resize of my own.
To help understand the function please note that in my application,
I have followed naming convention as follows:
If I create a grid then it will be id+"_grid",
If create a form that it will be id+"_form",
same for layout id+"_layout".
So I can get the associated component to a id and establish relation between them.
Call resize() function after you call show().
If below function doesn't help, try adding some milli seconds delay between show and my function resize().
function resize(id){
var grid=id+"_grid";
var layout=id+"_layout";
var form=id+"_form";
if(w2ui[layout]){
if($(w2ui[layout].el("main")).hasClass("w2ui-grid")){ /*means in w2ui layouts main has grid hence call resize. Calling refresh on layout "main" will make grid to reload data again ,hence grid resizing is handled in next case */
w2ui[layout].resize();
}else{
w2ui[layout].refresh();/*means main has element other than grid so refresh */
}
}
if(w2ui[form])
w2ui[form].resize();
if(w2ui[grid])
w2ui[grid].resize(); //if grid is directly rendered without a layout resize helps
}

Remove field firing event click in afterLabelTextTpl

I want to remove a form field, firing a click event in a afterLabelTextTpl.
However, I am not able to remove each field individually.
Fiddle: https://fiddle.sencha.com/#fiddle/1ie7
The two span textfields has the same id. It must be so because the text fields are added dynamically from a standard textfield
If you cannot set the id individually, you can set the id to be unique by taking advantage of the way the XTemplate in beforeLabelTextTpl generates markup. One way to do this is to append the field's generated id to the word 'icon' (or some other prefix):
'<span id="icon{id}" ...
When rendered, this will replace {id} with the field's id property. Then you can refer to this unique id in the afterrender handler:
var simboloEl = Ext.get("icon" + field.id);
Fiddle: https://fiddle.sencha.com/#fiddle/1iek
This happen because you use same id's for both fields and when you click on first one it works for second one also.
Please Check Fiddle:https://fiddle.sencha.com/#fiddle/1ien
Ext.create('Ext.form.Panel', {
title: 'Simple Form',
bodyPadding: 5,
width: 350,
// The form will submit an AJAX request to this URL when submitted
url: 'save-form.php',
// Fields will be arranged vertically, stretched to full width
layout: 'anchor',
defaults: {
anchor: '100%'
},
// The fields
defaultType: 'textfield',
items: [{
fieldLabel: 'First Name',
name: 'first',
allowBlank: false,
beforeLabelTextTpl: [
'<tpl>',
'<span style="color: red; cursor: pointer"; class="' + Ext.baseCSSPrefix + 'required">X </span>',
'</tpl>'
],
listeners: {
afterrender: function(field){
var form = this.up('form');
var simboloEl = Ext.get(field.getEl().dom.childNodes[0].getElementsByClassName('x-required')[0]);
//var simboloEl = Ext.get("icon");
if(simboloEl){
simboloEl.on("click", function () {
form.remove(field);
});
}
}
}
},{
fieldLabel: 'Last Name',
name: 'last',
allowBlank: false,
beforeLabelTextTpl: [
'<tpl>',
'<span style="color: red; cursor: pointer"; class="' + Ext.baseCSSPrefix + 'required">X </span>',
'</tpl>'
],
listeners: {
afterrender: function(field){
var form = this.up('form');
var simboloEl = Ext.get(field.getEl().dom.childNodes[0].getElementsByClassName('x-required')[0]);
//var simboloEl = Ext.get("icon1");
if(simboloEl){
simboloEl.on("click", function () {
form.remove(field);
});
}
}
}
}],
renderTo: Ext.getBody()
});

How can I get the file content from uploadfilefield?

I am trying to get the file content from uploadfilefield using ExtJS4, but do not know how?
I have this code for uploadfilefield:
{
xtype: 'fileuploadfield',
buttonText : 'Upload CSV',
buttonConfig:
{
icon: 'images/upload.png',
tooltip:
{
text: 'some hints',
width: 200
}
},
buttonOnly: true,
listeners:
{
'change': function(fb, v)
{
// v returns the filename
// HOW CAN I GET THE FILE CONTENT?
}
}
}
I was thinking that maybe fb has the content, but alert(JSON.stringify(fb)) gives me an error about fb being a circular object.
I am guessing that there has to be other way/event. Also I want to get the file content right away after pressing open on the dialog box. I cannot use submit button to do this afterwords.
Thanks my fellow StackOverflowers ;)
Addendum:
I am looking at this EXAMPLE on Sencha:
Ext.create('Ext.form.Panel', {
title: 'Upload a Photo',
width: 400,
bodyPadding: 10,
frame: true,
renderTo: Ext.getBody(),
items: [{
xtype: 'filefield',
name: 'photo',
fieldLabel: 'Photo',
labelWidth: 50,
msgTarget: 'side',
allowBlank: false,
anchor: '100%',
buttonText: 'Select Photo...'
}],
buttons: [{
text: 'Upload',
handler: function() {
var form = this.up('form').getForm();
if(form.isValid()){
form.submit({
url: 'photo-upload.php',
waitMsg: 'Uploading your photo...',
success: function(fp, o) {
Ext.Msg.alert('Success', 'Your photo "' + o.result.file + '" has been uploaded.');
}
});
}
}
}]
});
What is being passed to 'photo-upload.php'? How this php is supposed to get the content of the file?
Before HTML5, there was no access to the file content until after uploading it to a server and handling it from there. The browser was not be able to do anything with this file without first submitting the form.
EDIT:
From Neil McGuigan's comment above, it looks like the HTML5 FileReader API can possibly do some of the things you need. I have never used this, but more info is available herE: https://developer.mozilla.org/en-US/docs/Web/API/FileReader/
I found my answer here in extjs file uploader folder (modified it a little for my app)
$returnResponse = $_REQUEST['returnResponse'];
sleep(1);
if ($returnResponse != "")
{
header('HTTP/1.0 '.$returnResponse.' Server status', true, $returnResponse);
echo '{success:false, message:"File could not be uploaded to server."}}';
}
else
{
$file = $_FILES['filedata-inputEl'];
$fileName = $file['name'];
$fileSize = $file['size'];
$temp_file = $file['tmp_name'];
// ....
}

ExtJS GridPanel width

I'm using Ext JS 2.3.0 and have created the search dialog shown below.
The search results are shown in a GridPanel with a single Name column, but notice that this column does not stretch to fill all the available horizontal space. However, after I perform a search, the column resizes properly (even if no results are returned):
How can I make the column display correctly when it's shown initially? The relevant code is shown below:
FV.FindEntityDialog = Ext.extend(Ext.util.Observable, {
constructor: function() {
var queryTextField = new Ext.form.TextField({
hideLabel: true,
width: 275,
colspan: 2,
});
var self = this;
// the search query panel
var entitySearchForm = new Ext.form.FormPanel({
width: '100%',
frame: true,
layout:'table',
layoutConfig: {columns: 3},
items: [
queryTextField,
{
xtype: 'button',
text: locale["dialogSearch.button.search"],
handler: function() {
var queryString = queryTextField.getValue();
self._doSearch(queryString);
}
}
]
});
// the search results model and view
this._searchResultsStore = new Ext.data.SimpleStore({
data: [],
fields: ['name']
});
var colModel = new Ext.grid.ColumnModel([
{
id: 'name',
header: locale['dialogSearch.column.name'],
sortable: true,
dataIndex: 'name'
}
]);
var selectionModel = new Ext.grid.RowSelectionModel({singleSelect: false});
this._searchResultsPanel = new Ext.grid.GridPanel({
title: locale['dialogSearch.results.name'],
height: 400,
stripeRows: true,
autoWidth: true,
autoExpandColumn: 'name',
store: this._searchResultsStore,
colModel: colModel,
selModel: selectionModel,
hidden: false,
buttonAlign: 'center',
buttons: [
{
text: locale["dialogSearch.button.add"],
handler: function () {
entitySearchWindow.close();
}
},
{
text: locale["dialogSearch.button.cancel"],
handler: function () {
entitySearchWindow.close();
}
}
]
});
// a modal window that contains both the search query and results panels
var entitySearchWindow = new Ext.Window({
closable: true,
resizable: false,
draggable: true,
modal: true,
viewConfig: {
forceFit: true
},
title: locale['dialogSearch.title'],
items: [entitySearchForm, this._searchResultsPanel]
});
entitySearchWindow.show();
},
/**
* Search for an entity that matches the query and update the results panel with a list of matches
* #param queryString
*/
_doSearch: function(queryString) {
def dummyResults = [['foo'], ['bar'], ['baz']];
self._searchResultsStore.loadData(dummyResults, false);
}
});
It's the same issue you had in an earlier question, the viewConfig is an config item for the grid panel check the docs , so it should be
this._searchResultsPanel = new Ext.grid.GridPanel({
viewConfig: {
forceFit: true
},
....other configs you need,
To be more precise the viewConfig accepts the Ext.grid.GridView configs, feel free to read the docs on that one too.
Otherwise this seems to be the only problem, and i refer the column width, not the gridpanel width. On the gridpanel you have a title and two buttons who doesn't seem to be affected. So i repeat the gridPanel's width is ok, it's the columns width issue.
Try to remove autoWidth from GridPanel configuration, because setting autoWidth:true means that the browser will manage width based on the element's contents, and that Ext will not manage it at all.
In addition you can try to call .doLayout(false, true) on your grid after it was rendered.
Try to add flex: 1 to your GridPanel

Categories

Resources