#circlon/angular-tree-component: How to customize checkbox template - angular-tree-component

I want to use custom templates for the tree nodes as shown here on their website
https://angular2-tree.readme.io/docs/templates
But I also need the checkbox tri-state functionality as demonstrated here
https://angular2-tree.readme.io/docs/tri-state-checkboxes
In this custom treeNodeFullTemplate example they have a checkbox as part of the template but it doesn't have the tri-state relationship between the parents and children. Is there a way to have a custom checkbox and keep all the correct event listeners etc.? I can't seem to find any documentation on the checkboxes API if there is one.
<tree-root id="tree" [focused]="true" [nodes]="nodes">
<ng-template #treeNodeFullTemplate let-node let-index="index" let-templates="templates">
<div class="tree-node">
<input type="checkbox" [checked]="node.isActive" (change)="node.toggleActivated(true)" />
<tree-node-expander [node]="node"></tree-node-expander>
<div
class="node-content-wrapper"
[class.node-content-wrapper-active]="node.isActive"
[class.node-content-wrapper-focused]="node.isFocused"
(click)="node.toggleActivated(true)">
<span [class]="node.data.className + 'Index'">{{ index }}</span>
<span [class]="node.data.className" [class.title]="true">{{ node.data.title }}</span>
</div>
<tree-node-children [node]="node" [templates]="templates"></tree-node-children>
</div>
</ng-template>
</tree-root>
I can see that the (change) method on the checkbox is not right but do I need to write my own one to get the parent and children and determine state on click? It seems strange that I can't just tap into an existing API.

Related

Material Design Lite *ngIf on Form Input Field Angular 5

I want to build some dynamic form fields.
When I put an *ngIf in fron of the div the material design does not work properly (no effects etc.).
Here is the input field that works
<div class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="number" id="playerCount" [(ngModel)]="playerCount" (ngModelChange)="setPlayerCount(playerCount)">
<label class="mdl-textfield__label" for="playerCount">Anzahl Spieler</label>
</div>
and the one that does not work
<div *ngIf="players" class="mdl-textfield mdl-js-textfield mdl-textfield--floating-label">
<input class="mdl-textfield__input" type="text" id="stuff">
<label class="mdl-textfield__label" for="stuff">stuff</label>
</div>
The second div should appear as soon as the first has been filled out.
You have to register new elements to MDL's componentHandler since *ngIf actually removes the element from the dom, you have to register that element every time Angular removes/inserts it.
You can either call componentHandler.upgradeAllRegistered(); every time *ngIf inserts the element or replace *ngIf with something that is just hides the element but not remove it.

post form data to rest api from Ember component

I'm trying to post data from an input and a button group in a component using Ember to my REST API using the actions up method, but the code is confusing me a bit and I haven't found a clear example of how to do it.
The site is a tracker for competitive games in Overwatch, so enter the rank after the game and see it in a list. There is one table, and one endpoint with no children in the API. Basically a simple to-do app, but i'm using components to keep everything modular. I also want to add edit and delete, but that is out of scope for this question.
app/templates/components/add-game.hbs
<form class="form-inline">
<div class="form-group">
<label class="control-label">
Rank <small>(After match)</small>
{{input value=rank type="number" min="4" class="form-control"}}
</label>
</div>
<div class="form-group">
<label class="control-label">
Outcome
{{#bs-button-group value=outcome type="radio" onChange=(action (mut outcome)) as |bg|}}
{{#bg.button type="default" value='W'}}Win{{/bg.button}}
{{#bg.button type="default" value='D'}}Draw{{/bg.button}}
{{#bg.button type="default" value='L'}}Loss{{/bg.button}}
{{/bs-button-group}}
</label>
</div>
<div class="spacer"></div>
<div class="form-group">
<button {{action 'saveGame'}} type="submit" class="btn btn-default btn-primary">Save</button>
</div>
</form>
app/components/add-game.js
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
saveGame() {
const outcome = this.get('model.outcome');
const rank = this.get('model.rank');
console.log(outcome);
console.log(rank);
}
}
});
app/application.hb
{{nav-bar}}
<div class="container-fluid">
<div class="row">
<div class="col-md-offset-2 col-sm-8 col-md-8 main">
{{add-game}}
<br>
{{game-table model=model.games}}
</div>
</div>
</div>
{{outlet}}
I feel like I have most of it there, im just missing a few things with the Data Down, Actions Up approach that Ember uses, but haven't found a clear example to work off that is similar to my code. As you can probably tell I've got the code sending the data to the console, but im not sure of the best way to send it up to the route to then be sent to the server. I think I need to use the model, but the specific code
I am using ember-bootstrap for the styling and custom button group component.
The whole project is on Github
You can get an overview of DDAU architecture of Ember here. When you want to send the action up to the parent to handle, you have to notify the component of the action where you want to pass out any event. Here in your case, if you want to handle the action saveGame in the parent (application), then you have to pass the action to the component add-game while invoking the component as below:
**Application.hbs**
{{game-table model=model.games saveGameInParent=(action 'saveGameInParent')}}
where saveGameInParent is the action present in the application controller. In the component, you need to call out this action explicitly to pass out the control from the component to parent.
**component/add-game.js**
import Ember from 'ember';
export default Ember.Component.extend({
actions: {
saveGame() {
// do you really mean to access these props from model??
const outcome = this.get('model.outcome');
const rank = this.get('model.rank');
this.saveGameInParent(outcome, rank);
}
}
});
And finally, in you application controller, there should be action named, saveGameInParent to handle the bubbled up action from the component.
**controllers/application.js**
actions: {
saveGameInParent(outcome, rank) {
// post your result to the server using any network library.
}
}
PS: It looks like you have mentioned rank and outcome as your direct component property in the component's template file. but in the saveGame action, you tried to access those from model, which you cannot do.

TYPO3 merge list and edit

I've got a TYPO3 backend module which lists a lot of elements. Now, I want to include in my list the edit form, but that doesn't work well at the moment.
Rendering is good, but if I send the form, I get the error:
Required argument "note" is not set.
My code looks like this:
<f:for each="{notes}" as="note">
<f:form action="update" name="note" object="{note}">
<textarea class="form-control gettooltip" rows="1" placeholder="Kommentar" title="Kommentar zur Note">{note.kommentar}</textarea>
</f:form>
</f:for>
How can I merge these two views correctly?
Your code cannot work because your textarea doesn't have a property (or you don't use the <f:form.textarea ViewHelper).
If you property map $note in your controller, the property must be passed to Fluid with the prefixed extension name and plugin name. This is done automatically when using the "property" argument of the textarea ViewHelper. The name attribute will then be:
<textarea name="tx_myext_myplugin[note]"...
Thîs will map to $note in the controller.
So if you don't use the ViewHelper, you need to manually prefix the name attribute to create an output like printed just above.
If you're planning to update multiple objects of the of the same kind in one request, this won't because because there is an Extbase limitation.
You could do the following:
Use a submit button for each note and save/reload the changes through AJAX.
<f:for each="{notes}" as="note">
<f:form action="update" name="note" object="{note}">
<f:form.textarea class="form-control gettooltip" placeholder="Kommentar" property="kommentar">{note.kommentar}</f:form.textarea>
<f:form.submit value="Update" />
</f:form>
</f:for>
Then you intercept the submit click, submit the form through AJAX and set the new content to the textarea.
If you want to have one form for all objects, you will need to prefix the fields
<f:form action="update" name="note">
<f:for each="{notes}" as="note">
<f:form.textarea class="form-control gettooltip" placeholder="Kommentar" name="note[note{note.uid}][kommentar]">{note.kommentar}</f:form.textarea>
</f:for>
<f:form.submit value="Update" />
</f:form>
You will then have an array of values and need to iterate in your controller and manually persist the changes.
For your problem - as #lorenz answered you need to use viewhelpers for rendering fields OR at least use valid name attributes for your fields...
Anyway, I'm wondering why do you want to reinvent the wheel - especially while creating BE modules, the fastest, easiest and most elegant way is... using TYPO3 forms. They handle many things, relations, localization, validation, RTE etc, etc. What's more you can also add own type of field to TCA and process with your own PHP and JS - very rare situation, but may be used i.e. for adding GoogleMap field,
#see: user type in TCA
Finally all you need to open the record from your BE module is creating proper link - which can be easily copied from List module (right click on the yellow pencil next to your record and copy the code), sample:
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][1234]=edit'; return false;" title="Edit user">
<span title="" class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-open"> </span>
</a>
Where fe_users is table name and 1234 is record uid.
alt_doc.php?returnUrl='+T3_THIS_LOCATION part handles returning to the place from which edit was started, so it will be your module again including all GET params selected by admin before editing.
For creating new user
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][6789]=new'; return false;" title="New record">
<span class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-new"> </span>
</a>
In this case 6789 is a PID (uid of the page where the user should be created...
You can even set some default values when creating records from your own module using params in your new link:
&defVals[table_name][field_name]=value
sample
<a href="#" onclick="window.location.href='alt_doc.php?returnUrl='+T3_THIS_LOCATION+'&edit[fe_users][6789]=new&defVals[fe_users][tx_extbase_type]=Tx_MyExt_People&defVals[fe_users][usergroup]=1'; return false;" title="New record">
<span class="t3-icon t3-icon-actions t3-icon-actions-document t3-icon-document-new"> </span>
</a>

Questions about grails form

Assuming that i have the following data in my params
params:[input:[1, 2, 3]]
And i have the following form in my Grails app
<div class="block1">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input1" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
<div class="block2">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input2" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
<div class="block3">
<label class="control-label">
<g:message code="input.label" default="Input"/>
</label>
<div class="controls">
<g:textField id="input3" name="input" value="${input}" readonly="${actionName != 'show' ? false : true}"/>
</div>
</div>
The form design above is correct, because in my form design, there will be several inputs of the same name (but each will be saved to the database under different primary keys) and it can be increases and decreases according to user selection.
Few questions using the above
How do i make it so that the value for input1 is params.input[0], input2 is params.input[1] and input3 is params.input[2] in the view? I can pass the model from controller without problem, but i couldn't distribute the value properly to each input on the form.
Is there any way to change the value ${input} dynamically? As in if i want to change the value to ${input[0]} or ${input[1]}
Can i automatically set the amount of block appended into the form using the g:each tag? Say like if from controller i want to set the rendering block amount to 3, so can i use the g:each tag to render the block 3 times in the form?
Thanks
The links are examples of how to use ajax/jquery to get values from a remote call and replace html element (divId) within a page - this divId could be the entire
<input type="text" name="input" value="newvalue"/>
upon triggering some form of call as above to get the new value.. in regards to
g:textField
yes it works like all other grails tags in the end they are transformed back to the correct HTML terminology...
The actual variable value is dynamic if you defined
<input name="existingvariable" value="${something}" ...
where something was a parameter from the given controller - and then you updated the call so
://YOURHOST:8080/yourapp/controller?existingvariable=newvalue
and refreshed or clicked this link which is what ajax would be doing for you doing a new call to either another controller to generate new values or same and passing new value to it and then grabbing data and pushing it back onto the divId ... (all in the background)
Groovy loading into divs
Grails - Select menu not rendering
I want my selects dropdowns to auto populate with Ajax in Grails website
The above are all related to using ajax to populate / update existing form elements
If you wish to update a live form with a new live value (non existant in DB) take a look at modaldynamix plugin. //github.com/vahidhedayati/modaldynamix

Does wicket lose hold of the HTML components after a rearrangement through JavaScript?

I have a repeating component in wicked which needs to be added and deleted as per the user requirement. The maximum number of component is predefined. So I am adding the components at start up and hiding and showing based on need. I am required to change the arrangement of the components in the HTML markup when there is any deletion of the component. I use JavaScript for this. I want to know if wicket would lose hold of the components if I do this.
<div wicket:id="borrowerTabs" id="borrowerTabs">
<span wicket:id="borrowerTab1" id="borrowerTab1" ></span>
<span wicket:id="borrowerTab2" id="borrowerTab2" ></span>
<span wicket:id="borrowerTab3" id="borrowerTab3" ></span>
<span wicket:id="borrowerTab4" id="borrowerTab4" ></span>
<button wicket:id="addBorrower" id="addBorrower" type="button"></button>
<button wicket:id="deleteBorrower" id="deleteBorrower" onclick="updateUIForDeleteBorrower()" type="button"></button>
</div>
If delete the borrowerTab3, contents inside borrowerTab4 will be replacing the contents inside borrowerTab3 and the model objects too will be swapped though I do not do a target.add(borrowerTab3). Now while form submission, I am not getting the values of the fields inside borrowerTab3.
I'm not sure if it helps but try component.setVisible(false) in your java code to hide it.