react admin datagrid exempt column from being forward to another view - datagrid

I used react admin's data grid to show my data from api and put functionField with Delete mui on it. I would like to exempt one column like to toggle DeleteButton to render modal but in datagrid I always forwarded to another view, here's my sample component
<List
actions={<ListActions />}
bulkActionButtons={false}
{...props}
sort={{
field: 'name',
order: 'DESC'
}}
empty={true}
>
<Datagrid rowClick="edit" >
<TextField label="Account No." source="account_number" emptyText="-" />
<TextField label="Account ID" source="accountId" emptyText="-" />
<TextField label="Balance" source="balance" emptyText="-" />
<FunctionField label="Action" render={ (rec: any) => <Delete onClick={() => handleDelete(rec)} /> } />
</Datagrid>
</List>
but each time I click the delete button it redirect to edit view thanks

Because you specified <Datagrid rowClick="edit">, any click on a row redirects the user to the corresponding edit view. If that's not what you want, you have two options:
remove the rowClick="edit" bit, and add an <EditButton> on every row instead.
in your click event handler, cancel event propagation to avoid that it's handled by DatagridRow after you handle it.
<Delete onClick={(event) => {
handleDelete(rec);
event.stopPropagation();
}} />

Related

How to Change Date Picker height of material ui

I am using mui date picker and i want to customize it but css is not working on it i tried inline style as well as external styling by giving className but it dosent work
I want to change its height
<DatePicker
sx={{height:'35px'}} //its not working!!
label="Due Date"
className="DatePicker"
renderInput={(params) => <TextField {...params} />}
value={selectedDate}
onChange={(newValue) => setSelectedDate(newValue)}
/>
You have to apply the style by using the sx property in the <TextField> component and target the element with class .MuiInputBase-input.
Below is the code you need and here is the codesandbox to play with.
<DateTimePicker
label="Due Date"
className="DatePicker"
renderInput={(params) => (
<TextField
sx={{
"& .MuiInputBase-input": {
height: "80px" // Set your height here.
}
}}
{...params}
/>
)}
value={selectedDate}
onChange={(newValue) => setSelectedDate(newValue)}
/>
use an other type of date picker instead. for example StaticDatePicker for large height data picker
<StaticDatePicker
value={selectedDate}
onChange={(newValue) => {
setSelectedDate(newValue);
}}
renderInput={(params) => <TextField {...params} />}
/>

How to achieve same like Segemented button with toggle button(sugg) ,change to next onclicked

As learnt from previous question of mine(how to change segmented button to next on clicked) , I used a Segmented button to do so as:
My expected results were:
when Next is pressed INDICATOR2 should be active and on second press INDICATOR3 should be active.
when on INDICATOR2 if Previous is pressed both INDICATOR2 and INDICATOR1(which is current one) should be active.
As I am using segmented button here, the 2) can't be achieved ,and also was suggested using a toggle button would do instead a segmented button.
so I tried as,
<HBox id="toggleButton1">
<ToggleButton text="BUTTON1" enabled="true" pressed="true" press="onPress">
</ToggleButton>
<ToggleButton text="BUTTON2" enabled="true" pressed="false" press="onPress">
</ToggleButton>
<ToggleButton text="BUTTON3" enabled="true" pressed="false" press="onPress">
</ToggleButton>
</HBox>
<Button text="Previous" press="onPressPrevious" enabled="true"> </Button>
<Button text="Next" press="onPressNext" enabled="true"> </Button>
For this ,
How can I write JS code such that :
when Next is pressed BUTTON2 should be active and on second press BUTTON3 should be active.
when on BUTTON2 if Previous is pressed both BUTTON2 and BUTTON1(which is current one) should be active.
How can I set these Toggle Buttons width set to whole page(tried my luck display: block; width=100% in CSS but couldn't work)
I have no knowledge on JS at least to give a try , any help so that I would go through it and learn so, TIA
Here is a sample of using the three ToggleButtons as one SegmentedButton. I am caching the list of buttons in a local variable, since there is only one group of buttons. You could adapt it to support multiple such groups if needed, by either adding more local variables, or by getting the relevant list of buttons each time.
If next is pressed, it jumps to the next button. If previous is pressed, it enables all previous buttons. If a toggle button is pressed, it disables all others, much like a SegmentedButton.
As for the size, you need to set a few flexbox related properties. fitContainer on the HBox so it stretches 100% and growFactor=1 on the toggle buttons so they actually use all that space. Even then, it seems the buttons themselves don't like stretching much, so I set an additional CSS style to force them.
sap.ui.define("myController", [
"sap/ui/core/mvc/Controller"
], function(Controller) {
"use strict";
var toggleButtons1;
return Controller.extend("myController", {
onInit: function() {
toggleButtons1 = this.byId("toggleButtons1").getItems();
},
onPressNext: function(e) {
for (var i = 0; i < toggleButtons1.length - 1; ++i) {
if (toggleButtons1[i].getPressed()) {
toggleButtons1[i].setPressed(false);
toggleButtons1[i + 1].setPressed(true);
break;
}
}
},
onPressPrevious: function() {
for (var i = toggleButtons1.length - 1; i > 0; --i) {
if (toggleButtons1[i].getPressed()) {
toggleButtons1[i - 1].setPressed(true);
}
}
},
onPress: function(e) {
var btn = e.getSource();
if(!btn.getPressed()) {
btn.setPressed(true);
return;
}
for (var i = 0; i < toggleButtons1.length; ++i) {
if (toggleButtons1[i] != btn) {
toggleButtons1[i].setPressed(false);
}
}
},
onPress1: function(e) {
this.onPress(e);
alert("Do something here!");
}
});
});
sap.ui.require(["sap/ui/core/mvc/XMLView"], function(XMLView) {
XMLView.create({
definition: $('#myView').html()
}).then(function(oView) {
oView.placeAt('content');
});
});
.fullWidthButtons button {
width: 100%;
}
<html>
<head>
<meta charset="utf-8">
<script id='sap-ui-bootstrap' src='https://sapui5.hana.ondemand.com/resources/sap-ui-core.js' data-sap-ui-theme='sap_fiori_3' data-sap-ui-libs='sap.m'></script>
<script id="myView" type="sapui5/xmlview">
<mvc:View xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m" controllerName="myController">
<HBox id="toggleButtons1" fitContainer="true" class="fullWidthButtons">
<ToggleButton text="BUTTON1" enabled="true" pressed="true" press=".onPress1">
<layoutData>
<FlexItemData growFactor="1" />
</layoutData>
</ToggleButton>
<ToggleButton text="BUTTON2" enabled="true" pressed="false" press=".onPress">
<layoutData>
<FlexItemData growFactor="1" />
</layoutData>
</ToggleButton>
<ToggleButton text="BUTTON3" enabled="true" pressed="false" press=".onPress">
<layoutData>
<FlexItemData growFactor="1" />
</layoutData>
</ToggleButton>
</HBox>
<Button text="Previous" press="onPressPrevious" enabled="true" />
<Button text="Next" press="onPressNext" enabled="true" />
</mvc:View>
</script>
</head>
<body class='sapUiBody'>
<div id='content'></div>
</body>
</html>

Update grid using NotifyChange

In my code, I have a textbox in which you can insert text and a button to 'publish' that text. Beneath there is a grid, in which all the previously published posts appear. The issue is that, using the #NotifyChange doesn't work, or I dont know how it works well enough to make it update the grid. Here is the .zul:
<!--Skipping code-->
<center style="padding:15px;" border="none">
<window>
<window title="Make post" border="normal">
<textbox id="publish" placeholder="Make a post"
height="40px" width="67%" multiline="true">
<attribute name="onChanging">
<![CDATA[
String value = event.value;
publSize.setValue("" + value.length() + "/300");
]]>
</attribute>
</textbox>
<space width="1%"/>
<textbox id="publSize" height="40px" width="6%" style="text-align:center" disabled="true" placeholder="0/300"/>
<space width="1%"/>
<button id="publicaBttn" label="Publicar" height="40px" width="25%" onClick="#command('addNewPost', p=publish)"/>
</window>
<separator bar="false"/>
<grid id="postGrid" height="550px" model="#init(vm.posts)" emptyMessage="Nothing in Posts.">
<template name="model">
<row>
<window border="normal">
<caption id="userName" label="#load(each.username)"/>
<textbox id="infoPost" readonly="true" value="#load(each.info)" multiline="true" rows="4" width="100%" mold="rounded"/>
<separator bar="true"/>
<hlayout>
<div>
<button label="Like" onClick="#command('addLike', index=each.index)"/>
</div>
<div hflex="true">
<textbox id="likeTB" disabled="true" width="3%" style="text-align:center" value="#load(each.likes)"/>
</div>
<div style="padding-right">
</div>
</hlayout>
</window>
</row></template></grid></window></center><!--...--></borderlayout></zk>
Here is the java controller:
#Command("addNewPost")
#NotifyChange("hConn")
public void addPost(#BindingParam("p") Textbox tbx) {
String text = tbx.getValue();
if (text == "") {
Messagebox.show("There must be text in a post.", null, 0, Messagebox.ERROR);
}
if (text.length() > 300) {
Messagebox.show("Posts must be under 300 characters.", null, 0, Messagebox.ERROR);
} else {
hConn.addPost(usuario,text);
}
BindUtils.postNotifyChange(null,null,this,"postGrid");
tbx.setValue("");
}
#Command("addLike")
#NotifyChange("hConn")
public void addLike(#BindingParam("index") String index) {
hConn.addLike(Integer.parseInt(index));
BindUtils.postNotifyChange(null,null,this,"postGrid");
}
When I either add a like or make i new post, the grid doesnt update to show the new like or the new post added. How can i solve this?
#init method is called when the view model is initialised. If you want updates you need to change model="#init(vm.posts)" to model="#load(vm.posts)". (I assume getPosts() in your view model returns hConn.
Some other observations:
You could use a custom constraint for your textbox. Something like (untested):
<textbox placeholder="Make a post" height="40px" width="67%" multiline="true" constraint="#load(vm.max300Constraint)" />
and in your view model:
public Constraint getMax300Constraint() {
return new Constaint() {
public void validate(Component comp, Object value) throws WrongValueException {
// check if text is greater than 300 characters
}
}
}
Another option is as follows:
<textbox placeholder="Make a post" height="40px" width="67%" multiline="true" onChanging="#command('checkLength', text=event.value)" />
and in your view model:
#Command
public void checkLength(#BindingParam("text") String text) {
// check text length
}
Both of these options also mean you can avoid putting the textbox component in your view model thereby embracing the values of MVVM.

Content element inside Toolbar component doesn't work

I'm trying to build a table with button on table's header. I'm guiding from here.
This is my code:
<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc"
xmlns="sap.m"
xmlns:l="sap.ui.layout"
xmlns:f="sap.ui.layout.form"
xmlns:t="sap.ui.table"
height="100%"
controllerName="xxxxx"
xmlns:html="http://www.w3.org/1999/xhtml">
<Page title="CONFIGURACIÓN DE LA CUENTA" navButtonPress="onCancel" showNavButton="true">
<content>
<f:SimpleForm id="form_requerimiento_datos_generales" minWidth="1024"
maxContainerCols="2" editable="true" layout="ResponsiveGridLayout"
labelSpanL="4" labelSpanM="4"
emptySpanL="0" emptySpanM="0" columnsL="2" columnsM="2"
validateFieldGroup="onValidateFieldGroup">
<f:content>
<core:Title text="Suscripciones"/>
<t:Table
rows="{/Subscriptions?$filter=UserSystem eq '1'}"
selectionMode="None"
visibleRowCount="7">
<t:toolbar>
<content>
<Title id="title" text="Listado de Suscripciones" />
<ToolbarSpacer/>
<Button
icon="sap-icon://add"
tooltip="Agregar Suscripciones"
press="addSuscription"/>
</content>
</t:toolbar>
<t:columns>
<!--columns-->
</t:columns>
</t:Table>
</f:content>
</f:SimpleForm>
</content>
</Page>
</core:View>
I have following error message:
Uncaught Error: failed to load 'sap/m/content.js' from https://sapui5.netweaver.ondemand.com/resources/sap/m/content.js: 0 - NetworkError: Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'https://sapui5.netweaver.ondemand.com/resources/sap/m/content.js'.
I don't know why I get this error. I think that It's in this part of code:
<t:toolbar>
<content>
<Title id="title" text="Listado de Suscripciones" />
<ToolbarSpacer/>
<Button
icon="sap-icon://add"
tooltip="Agregar Suscripciones"
press="addSuscription"/>
</content>
</t:toolbar>
I don't know why content label is not accepted inside toolbar label (In example this works). When I take off content label of my page. I don't get error messages.
I would like to know what doing for to solve my problem.
Thanks for help me!
UPDATE 1
I solved already my problem but Now I have another problem. I have a problem with CSS of table header (This is overlapped with table body):
The label <t:toolbar> is the aggregation name and it expects a toolbar inside it.
So, ideally <t:toolbar> is followed by a sap.m.Toolbar control.
As to why it is throwing: sap/m/content error is because, it is expecting a control after the <t:toolbar>. Also, since your default namespace is sap.m so it looks for control ( in this case you have specified content) in the default namespace.There is no such control as sap.m.content. Thus, an error.
If you will check your guiding source, you will see they have an <m:Toolbar> after <toolbar> aggregation
Here is the updated code:
<t:toolbar>
<Toolbar>
<content>
<Title id="title" text="Listado de Suscripciones" />
<ToolbarSpacer/>
<Button
icon="sap-icon://add"
tooltip="Agregar Suscripciones"
press="addSuscription"/>
</content>
</Toolbar>
</t:toolbar>

ZK: enable button in listcell only for the selected item of a listbox

In the next listbox I load elements with template:
<listbox model="#load(vm.resAccepted)" selectedItem="#bind(vm.selResAccepted)">
<template name="model">
<listitem>
<listcell label="#load(each.eventName)" />
<listcell label="#load(each.userName)" />
<listcell>
<button image="/img/button_mail.png"/>
</listcell>
</listitem>
</template>
</listbox>
My goal is to enable the button of the listitem ONLY for the row the user selects.
To do this, I try
<button disabled="#load(vm.selResAccepted.id=each.id?'false':'true')" />
checking if the unique field id is the same of the selected element, but it fails.
Any help will be appreciated.
You can use eq for equals comparison:
<button disabled="#load(vm.selResAccepted.id eq each.id?'false':'true')" />
or maybe even better: disabled when selected item is not the current item
<button disabled="#load(vm.selResAccepted ne each)" />
here ne is not equal

Resources