Just a minor problem, but it drives me nuts. I want to write my own widget using TabContainers. Now it seems, that the mixin-Classes can't call the TabContainer modules and start them. I tried a lots of stuff with different widgets, and it seems that there is just an issue with the TabContainer. Looking at the Doc I wasn't able to figure out whether it is a bug within Dojo or within my code. Nonetheless, this works
<script type="text/template" id="editMultilanguageDialog-form-template">
<form data-dojo-type="dijit.form.Form" data-dojo-attach-point="form">
<button data-dojo-type="dijit/form/Button" data-dojo-props="iconClass:'dijitEditorIcon dijitEditorIconCut', showLabel: false" type="button">cut</button>
</form>
</script>
...but this doesn't!
<script type="text/template" id="editMultilanguageDialog-form-template">
<form data-dojo-type="dijit.form.Form" data-dojo-attach-point="form">
<div data-dojo-type="dijit/layout/TabContainer" style="width: 100%; height: 100%;">
<div data-dojo-type="dijit/layout/ContentPane" title="My first tab" data-dojo-props="selected:true">
Lorem ipsum and all around...
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="My second tab">
Lorem ipsum and all around - second...
</div>
<div data-dojo-type="dijit/layout/ContentPane" title="My last tab" data-dojo-props="closable:true">
Lorem ipsum and all around - last...
</div>
</div>
</form>
</script>
The code called within the dialog.js looks like this:
define([ "modules/waitingDialog/dialog", "util/debugger", "stores/userStore",
"util/storeCache", "dojo/Evented", "dijit/Dialog", "dojo/_base/lang",
"dojo/_base/declare", "dijit/_Widget", "dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin", "dojo/dom", "dojo/_base/Deferred",
"modules/editMultilanguageDialog/controller", "stores/facultyStore",
"stores/degreeStore", "stores/beginOfStudyStore" ], function(wait,
debug, userStore, storeCache, Evented, Dialog, lang, declare, widget,
templatedMixin, widgetsInTemplateMixin, dom, Deferred,
editMultilanguageController, facultyStore, degreeStore,
beginOfStudyStore) {
return declare("editMultilanguageDialog", [ Dialog, Evented ], {
attributeMap : lang.delegate(widget.prototype.attributeMap, {
message : {
node : "messageNode",
type : "innerHTML"
}
}),
constructor : function(/* Object */kwArgs) {
debug.log("constructor called",
"editMultilanguageDialog.constructor()", 1);
lang.mixin(this, kwArgs);
var controller = new editMultilanguageController(kwArgs);
this.controller = controller;
var dialogTemplate = dom.byId("dialog-template").textContent;
var formTemplate = dom
.byId("editMultilanguageDialog-form-template").textContent;
var template = lang.replace(dialogTemplate, {
form : formTemplate
});
var contentWidget = new (declare([ widget, templatedMixin,
widgetsInTemplateMixin ], {
templateString : template,
widgetsInTemplate : true
}));
var content = this.content = contentWidget;
this.form = content.form;
contentWidget.startup();
}, [...]
This problem is driving me nuts. Thought anyone may have experienced same issues by writing custom widgets. Thx in advance!
Related
I am writing a simple test for my game component. Just checking if all child components are getting loaded in right. They all seem to work except WordFormComponent. I am guessing this is because I only render it when a async variable has been set to True. This happens only when all variables have been set.
My game.component.html looks like this:
<div class="u-w-full lg:u-w-[70%] u-mx-auto">
<a routerLink="/gameList" class="lg:u-bg-white hover:u-bg-gray-100 u-text-[13px] u-font-medium u-py-1 u-px-3 u-border u-border-gray-300 u-rounded u-flex u-items-center" style="max-width: fit-content">
<mat-icon aria-label="Submit word" class="u-h-[50%] u-text-base">keyboard_backspace</mat-icon>
Games overview
</a>
<div class="lg:u-grid u-grid-cols-3 u-gap-y-[2rem]">
<div class="u-col-span-full u-p-6 u-w-full u-bg-white u-rounded u-mt-1 u-border u-border-gray-200">
<app-final-word-form (onGuessFinalWord)="submitFinalWord($event)"></app-final-word-form>
</div>
<div clas="u-col-span-1">
<app-dashboard (onNextRound)="nextRound($event)"></app-dashboard>
</div>
<div class="u-col-span-2 u-row-span-2 lg:u-ml-[2rem]">
<div *ngIf="dataLoaded | async; then thenBlock else elseBlock"></div>
<ng-template #thenBlock>
<!-- Does not show up in test -->
<app-word-form [game]="game" [word]="word" [gameWord]="gameWord" (onGuessWord)="submitWord($event)"></app-word-form>
</ng-template>
</div>
</div>
</div>
And my test looks like this:
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ GameComponent, FinalWordFormComponent, DashboardComponent, WordFormComponent ],
imports: [ ToastrModule.forRoot() ]
})
.compileComponents();
gameFixture = TestBed.createComponent(GameComponent);
gameComponent = gameFixture.componentInstance;
gameService = TestBed.inject(GameService);
spyOn(gameService, 'createGame').and.returnValue(of({ 'Game': game, 'Gameword': gameWord, 'Word': word, 'Finalword': finalWord }));
gameFixture.detectChanges();
});
fit('should display titles of all child components', waitForAsync(() => {
gameFixture.detectChanges();
expect(gameFixture.nativeElement.querySelector('a').textContent).toContain('Games overview'); // Works
expect(gameFixture.nativeElement.querySelector('p').textContent).toContain('How to win: guess the finalword correctly.'); // Works
expect(gameFixture.nativeElement.querySelector('#wordheader').textContent).toContain('Game word.'); // Failed: Cannot read properties of null (reading 'textContent')
}));
Whenever I log this.dataLoaded when running my test it does return true. So that should not be the problem. It seems like the view does not pick up on it. Anyone knows how to make this work?
Using a database management tool (HeidiSQL) I can see that the content of an entry is storing returns (good):
MYSQL storing line breaks
However when I read the data on my front-end:
router.get('/story/:id', async (req, res) => {
try {
const getStory = await Story.findByPk(req.params.id, {
include: [
{
model: User,
attributes: ['username'],
},
],
});
const story = getStory.get({ plain: true });
res.render('story', {
story,
logged_in: req.session.logged_in,
});
} catch (err) {
res.status(500).json(err);
}
});
Rendered in Handlebars:
<div class="card">
<div class="card-content">
<p class="title">
{{story.title}}
</p>
<p class="content">
{{story.content}}
</p>
</div>
</div>
It eliminates the line-breaks:
no line-breaks
I'm wondering what I need to do to maintain the linebreaks.
I haven't tried modifying anything yet. I will try encapsulating the handlebars {{story.content}} in a string-literal to see if that does it.
So I found the answer - I needed to add a custom handlebars helper in the server.js
hbs.handlebars.registerHelper('breaklines', function(text) {
text = hbs.handlebars.Utils.escapeExpression(text);
text = text.replace(/(\r\n|\n|\r)/gm, '<br>');
return new hbs.handlebars.SafeString(text);
});
Then pass the content through the helper
<div class="card">
<div class="card-content">
<p class="title">
{{story.title}}
</p>
<p class="content">
{{breaklines story.content}}
</p>
</div>
</div>
I have a screen login in my aplication and to get the form data in framework i need to use formtoData but it wasnt working, so i decided to create another project and copy paste framework docs script but still isnt working.
Index.html(the test project)
<div class="pages navbar-through toolbar-through">
<!-- Page, "data-page" contains page name -->
<div data-page="index" class="page">
<!-- Scrollable page content -->
<div class="page-content">
<form id="my-form" class="list-block">
<ul>
<li>
<div class="item-content">
<div class="item-inner">
<div class="item-title label">Name</div>
<div class="item-input">
<input type="text" name="name" placeholder="Your name">
</div>
</div>
</div>
</li>
</ul>
</form>
<div class="content-block">
Get Form Data
</div>
</div>
</div>
</div>
js (test project)
// Initialize app
var myApp = new Framework7();
// If we need to use custom DOM library, let's save it to $$ variable:
var $$ = Dom7;
$$('.form-to-data').on('click', function(){
alert("dwdq");
var formData = myApp.formToData('#my-form');
alert(formData);
});
Does anyone know why is it not working? thx in advance.
They changed the function, instead of formToData now is formToJSON
You can use booth:
formtoData or formToJson will return the same value: [object Object]
Just use JSON.stringify() to get the desired result.
$$('.form-to-data').on('click', function(){
var formData = myApp.formToData('#my-form');
var formJSON = myApp.formToJSON("#my-form");
console.log(JSON.stringify(formData));
console.log(JSON.stringify(formJSON));
});
{"name":"Alexandre"}
{"name":"Alexandre"}
Or you can even serialize the form like that:
$$('.form-to-data').on('click', function(){
var formData = $$.serializeObject(myApp.formToJSON($$("#my-form")));
console.log(formData);
});
name=Alexandre
Edit: Framework7 got updated to v4, and now it works this way:
Single Line:
var dados = JSON.stringify(myApp.form.convertToData('#my-form'));
They changed the function again, at least in V2. The new function that works for me is:
var formData = myApp.form.convertToData("#form-id");
var formString = JSON.stringify(formData);
Framework 7 convertToData is ignoring input type text array: for example:
<input type="text" name="no_invoice[]" />
Removing [] doesn't work either.
F7 only take as array checkbox/radio fields, this bug must be solved.
I solved using javascript:
new FormData(your_form);
I'm working with Angularjs and firebase to create an app that is a task timer. I create the firebase object and all works fine except when I try to log task.newTask to the console. Here's a bit of my code (please note this is not all the code):
//HTML
<aside id="sidebar">
<section id="widget_1">
<h2 class="titles">Task History:</h2>
<input id="text-field" type="text" ng-model="taskText" />
<input id="task-button" type="button" value="Add Task" ng-click="addTask()" />
</section>
<section id="widget_2">
<h2 class="titles">Task List:</h2>
<table>
<tr ng-repeat="task in timer_tasks | orderBy: '-taskText'">
<td>{{ task.taskText }}</td>
</tr>
</table>
</section>
</aside>
//Controller:
(function() {
'use strict'
function HomeCtrl($scope, $firebaseArray, $interval) {
console.log('I see you home controller ... you are loaded sir!!!')
var timerRef = firebase.database().ref().child('timer_tasks');
$scope.timer_tasks = $firebaseArray(timerRef);
$scope.addTask = function () {
$scope.timer_tasks.$add({
taskText: $scope.taskText,
newTask: true
}).then(function (timerRef) {
$scope.taskText = '';
});
};
console.log(task.newTask);
On page load the error comes up at console.log(task.newTask);
Any help would be great. Thanks in advance!
If i'm understood correctly, you need to retrieve textbook value in controller which will build $scope.timer_tasks and later can be retrieved back to view in ng-repeat.
view
<aside id="sidebar">
<section id="widget_1">
<h4 class="titles">Task History:</h4>
<input id="text-field" type="text" ng-model="taskText" />
<input id="task-button"
type="button"
value="Add Task"
ng-click="addTask(taskText)"/>
</section>
</aside>
Script
myApp.controller('myCtrl', function($scope) {
$scope.addTask = function (value) {
console.log(" clicked : "+value);
};
});
All i did was bind the value upon addTask click from ng-model to ng-click and as you can see now you have that value in addTask function.
I think it may be useful if I show the wider scope :) below is my html:
<div class="resSection2 rel">
<div class="proceed rel">
<div ng-repeat="record in records">
<div class="rel fptsans {{record.className()}}">Balkans<i class="icon-check icon-2x posIco"></i></div>
</div>
</div>
</div>
Key factor here is the {{record.className()}} binding which depending on its value determines the behaviour of the record, whether it gets a proper styling or not. as you can see it is a reference to a function. And here is the JS:
var antroApp = angular.module('antroApp', []);
$scope.records = [
{id:0,
className: $scope.probieren,
recordName:$scope.alpeic.length
},
{id:1,
className: $scope.probieren,
recordName:$scope.alpeic.length
}
];
$scope.probieren = function(){
if($scope.records.recordName > 10){
$scope.records.className == 'special'
}
else{
$scope.records.className == 'normal'
}
}
}
antroApp.controller('dialogWindows', dialogWindows);
When I set up the className statically ("special" or "normal") it renders perfectly
but when it comes to a function, it all just gets stuck. really feel helpless about this. any tips appreciated.
You've set it up fine except they have to be defined in the other order, but in your dom when you use it call a function like this:
<div data-ng-repeat="record in records">
<div class="{{ record.className() }}">{{ record.recordName }}</div>
</div>
There's a few more issues with how you're referencing $scope.records.className instead of some index of the array for records but my answer should answer the specific question you have.