I have a container with DataView type:
Ext.define('CustomView', {
extend: 'Ext.DataView'
});
Also, I have a remote store that contains: [{id: 1, name: 'abc'}, {id: 2, name: 'test'}].
I want to display those items in dataview in this way in html:
<ul>
<li>abc</li>
<li>test</li>
</ul>
In Sencha Touch 1 we can achieve that by setting tpl config and <tpl for="."> xtemplate tag. In Sencha Tocuh 2 it doesn't work anymore because setTpl works only when 'data' is present and I use a store. setItemTpl sets a template for each item so it doesn't work either. I could render manually the template and use setHtml but the 'tap' event wouldn't work on items.
How can I set my template to make it render the needed html in SC2 keeping the tap event?
dataview is used for custom renders of stores (Sencha Docs Dataview).
"Use DataView whenever you want to show sets of the same component many times"
Unfortunately, it too has the same restriction as listview in that you can only specify an itemTpl (or dataitem) and can't control the markup generated for the entire component.
I think your best option is to create a custom view using a panel and writing the store reading logic yourself.
Related
Background
I'm using tiptap-vuetify to implement a message/chat UI where users see an editable Tiptap instance for creating new messages as well as several uneditable Tiptap instances (one for each already-sent message in the thread the user is viewing).
I have the editable instance output data in JSON format, which I store in my database in a JSONB field.
Problem
When I load the JSON for sent messages from the database, only plaintext messages show up; if I applied any kind of styling (bold, italics, lists, etc.), nothing at all shows up.
The code I'm using for the uneditable Tiptap instances is this:
<tiptap-vuetify
v-model="message.content"
:editor-properties="{ editable: false }"
output-format="json"
/>
Here's a screenshot of the message object (and message.content) for the "bold asdf" example above:
When i was looking in the documentation -> Get started
I see that the content is HTML.
As it usually is inside any tiptap.
Your content data is an object with alot of nested data. I don't think the plugin/component can handle that type of format.
Try save your data as HTML to your .json and there for also fetch the data as HTML from your .json.
Example:
{
messages: [
{
"id": 1,
"content": "<p>foo bar</p>"
},
{
"id": 2,
"content": "<p>hello world</p>"
},
]
}
(New to answer questions on stackoverflow)
I figured out the fix:
I didn't realize I needed to include the :extensions prop for all of the HTML features I wanted to use (bold, italic, etc.) in the editor that would render the HTML. I thought those extensions were just used to add the toolbar buttons, but they are also used to render the JSON that those buttons produce.
To then hide the toolbar, I just used the example toolbar-slot code from the readme, and the toolbar was gone.
Here's the working code:
<tiptap-vuetify
v-model="message.content"
:extensions="extensions"
:editor-properties="{ editable: false }"
>
<template #toolbar="{ buttons }">
<pre>{{ buttons }}</pre>
</template>
</tiptap-vuetify>
I have a custom menubutton in my tinyMCE editor that uses specific HTML elements elsewhere on the page as the menu items. I use a jQuery selector to get the list of elements and then add one each as a menu item:
c.onRenderMenu.add(function(c,m) {
m.add({ title: 'Pick One:', 'class': 'mceMenuItemTitle' }).setDisabled(1);
$('span[data-menuitem]').each(function() {
var val = $(this).html();
m.add({
title: $(this).attr("data-menuitem"),
onclick: function () { tinyMCE.activeEditor.execCommand('mceInsertContent', false, val) }
});
});
});
My problem is that this only happens once when the button is first clicked and the menu is first rendered. The HTML elements on the current page will change occasionally based on user clicks and some AJAX, so I need this selector code to run each time the menu is rendered to make sure the menu is fully up-to-date. Is that possible?
Failing that, is it possible to dynamically update the control from the end of my AJAX call elsewhere in the page? I'm not sure how to access the menu item and to update it. Something using tinyMCE.activeEditor.controlManager...?
Thanks!
I found a solution to this problem, though I'm not sure it's the best path.
It doesn't look like I can make tinyMCE re-render the menu, so instead I've added some code at the end of my AJAX call: after it has updated the DOM then it manually updates the tinymce drop menu.
The menu object is accessible using:
tinyMCE.activeEditor.controlManager.get('editor_mybutton_menu')
where mybutton is the name of my custom control. My quick-and-dirty solution is to call removeAll() on this menu object (to remove all the current menu items) and then to re-execute my selector code to find the matching elements in the (new) DOM and to add the menu items back based on the new state.
It seems to work just fine, though tweaks & ideas are always welcome!
Does anyone know if it is possible to have multiple icon buttons on a Sencha Touch list item that listen to different events? If so, how can I accomplish this?
For instance, say I have a list of people and there's an icon for email, phone and a map to their location for each person. I want to show 3 small icons and be able to map each icon to do 3 separate actions.
This depends on how you are creating your buttons.
If the buttons are simple HTML using itemTpl, you can just listen to the itemtap event on List and use the event argument to detect which button you pressed. You could do this via a custom attribute or even a className:
myListItemTapListener: function(list, index, target, e) {
var el = Ext.get(e.getTarget());
if (el.hasClass('map')) {
this.navigate(index);
} else if(el.hasClass('email')) {
this.email(index);
} else if(el.hasClass('phone')) {
this.phone(index);
}
}
If your buttons are actual Ext.Button's inside a component List, you can simply add a listener onto each button when you create the component. There is an example of how to do this in the DataView Guide in the Sencha Docs.
Component DataView may help you. You can see this [guide]: http://docs.sencha.com/touch/2-0/#!/guide/dataview-section-4
I have wrote a [demo]: https://github.com/hs3180/Sencha-Touch-Component-DataView
, in app/view/,
Main.js, a dataview component with useComponets true, and set defaultType to 'demo.view.Item'.
Item.js, a DataItem, the visible content of each item is a panel ( in Card.js ). I use datamap to link name in record ( within store ) to userName ( in demo.view.Card ).
Card.js, a Panel for each person. A user name title and 3 buttons.
I have one Textfield, Combo and a Radio. I want to get values of these 3 fields on clicking one button. How I can get the values of above 3 without using Ext.getCmp('id').getValue();
Is there any other method is their to get the values,
please let me know.
It depends on how you have contained your fields and the button you want to click to get their values.
You can navigate up and down your containers
var TheComponent = this.up('form').down('#MyTextField')
This climbs up your container hierarchy until it finds a 'form' container (doesn't matter what its Id or name is) and them climbs down until it finds a component with the id: 'MyTextField'
If your radio button is in a radio button group container you can retrieve an object that has all your 'on' key/values.
If your container is a form you can use the method proposed by lzhaki and retrieve an object that contains all the values on your form. Just remember that combo boxes behave differently to text boxes.
Each of these methods will return either a single value or an object containing a group of values.
In ExtJS 4.1, I found the prior example was close, but incorrect:
var TheComponent = this.up('form').down('#MyTextField')
There is no "down" method in the form object (apparently form fields aren't included in the down method's navigation logic).
Here's what worked for me to set initial focus on an edit field within a form.
var theForm = this.down('form').getForm();
var theField = theForm.findField('idEditVolname');
theField.focus();
You still must use getForm() to get the embedded form object, followed by findField() to locate the specific field - at least that's what works for me.
I don't know if this is still relevant, but here goes.
First of all, in Extjs4 and up, you use Ext.ComponentQuery.query() instead of Ext.getCmp().
What this allows you to do is access any xtype you have directly, just like the up, and down methods mentioned in other answers, but this method doesn't need any anchors as it searches the entire component hierarchy. Since you have only one of each element on the page that would be very easy to achieve without using id's.
I would name the main panel that contains the fields, but that's just for convenience.
Look at this fiddle
The code is really simple:
var panel = Ext.create('Ext.panel.Panel', {
renderTo: Ext.getBody(),
name: 'myForm',
title: 'Sample Test',
layout: 'anchor',
height: 200,
items: [{
xtype:'textfield',
fieldLabel: 'text',
value: 'Oh yeah!'
}]
});
var myVal = Ext.ComponentQuery.query('panel[name=myForm] textfield')[0];
alert (myVal.getValue());
The same can be done with the radio and combo fields, and you don't need a form for that, though it is more logical that way.
I have an metro style app which has a few tiles in the home page in some random order. If I remove one of those tiles all the other tiles should rearrange themselves to fill the gap created by removing a single tile. You can observe the same phenomenon in Windows 8 desktop view. Is it possible to achieve it using either WinJS or WinRT.
If I correctly understood your needs, if you use a ListView or a GridView which is bound to an IObservableCollection, the items will automatically fit correctly when deleting / adding items.
Using IObservableCollection (or ObservableList) allow you to add a ChildrenTransitions (Choose the AddRemoveTransitions to automatically add the "correct" animation for adding / removing item.
I have not tested this in JS/Html, but in Xaml/C# it's working great.
You can do it by modifying the ListView data source directly.
For example,
// create a reference of your data source so that it can be accessed
// when you need to modify it
var yourBindingList;
...
// code where you bind your data to your list view
yourBindingList = WinJS.Binding.List([{id: 1, name: 'one'},
{id: 2, name: 'two'}, {id: 3, name: 'three'}]);
var listViewControl = document.getElementById('yourListViewDiv').winControl;
WinJS.UI.setOptions(listViewControl, {
selectionMode: 'single',
itemDataSource: yourBindingList.dataSource,
itemTemplate: yourItemTemplate,
});
...
// code where you remove the first item in your list view
yourBindingList.splice(0, 1);
Hope this helps.