React-Quill: Open a custom popup before firing custom toolbar button handler - react-quill

I am using react-quill in my react application. I have the editor all set up and ready to use. I have added a custom-button in the toolbar. That custom-button basically allows to the user to insert "button" in the editor area. There is a popup component which asks user to enter button-name, button-text-color, button-background-color and button-link. Based on these parameters, ditto' button is added in the editor.
The popup component is toggled using state:
this.state = {
openPopup: false
}
const CustomButton = () => <>CTA</>
const CustomToolbar = () => (
<div id="toolbar">
<select className="ql-header" defaultValue={""} onChange={e => e.persist()}>
<option value="1" />
<option value="2" />
<option selected />
</select>
<button className="ql-bold" />
<button className="ql-italic" />
<button class="ql-script" value="sub"></button>
<button class="ql-script" value="super"></button>
<select className="ql-color">
<option value="red" />
<option value="green" />
<option value="blue" />
<option value="orange" />
<option value="violet" />
<option value="#d0d1d2" />
<option selected />
</select>
<button className="ql-insertCta">
<CustomButton />
</button>
</div>
);
this.modules = {
toolbar: {
container: "#toolbar",
handlers: {
insertCta: function () {
const cursorPosition = this.quill.getSelection().index
this.quill.insertEmbed(cursorPosition, 'span', 'user')
this.quill.setSelection(cursorPosition + 1)
}
},
},
clipboard: {
matchVisual: false,
}
};
const BlockEmbed = Quill.import('blots/block/embed');
let ctaTool = this.generateButton()
class CtaBlot extends BlockEmbed {
static create(value) {
let node = super.create(value);
node.innerHTML = ctaTool;
return node;
}
}
CtaBlot.blotName = 'span';
CtaBlot.tagName = 'span';
CtaBlot.className = 'cta-button'
Quill.register(CtaBlot);
<ReactQuill
theme={"snow"}
modules={this.modules}
formats={this.formats}
value={this.state.textEditorData}
onChange={this.onEditorChange}
placeholder={"Write page content here..."}
>
</ReactQuill>
insertCta function works as expected. How do i open the popop and then onClick of save button in the popup, the "insertCta" function is fired? Currently the "insertCta" function works if fired directly. I want the user to customise the button appearance from the popup.
Popup:
popup to configure cta
Editor:
editor with custom button in toolbar
CTA Button:
editor when cta button is added
Any help is greatly appreciated!

Related

How to sort / filter / search data and display in modal in Laravel Vuejs

Scenario 1
I am using v-for loop to print categories on button, now when I click on button it should show me the data related to that category. It is working fine when i use dropdown select category and click search and it displays all the related data.
But how to do it on button click event.
=====
Fetching categories in Button using v-for directives
<form #submit.prevent="product_info_form">
<div class="row mb-4">
<div class="col-3 px-2" v-for="(category, index) in categories" v-bind:value="category.slack" v-bind:key="index">
<button type="submit" class="btn btn-primary btn-lg btn-block py-4 margin-bottom" v-on:click="displaynumbers" v-bind:value="category.slack">{{ category.label }}</button>
</div>
<select name="category" v-model="category" class="form-control custom-select custom-select-lg">
<option value="">Filter by Category..</option>
<option v-for="(category, index) in categories" v-bind:value="category.slack" v-bind:key="index">
{{ category.label }}
</option>
</select>
</div>
</form>
In method I have written following code :
displaynumbers: function(e)
{
var buttonValue = e.target.value;
var formData = new FormData();
formData.append("access_token", window.settings.access_token);
//formData.append("barcode", this.barcode);
//formData.append("product_title", this.product_title);
if(buttonValue != '')
{
alert(buttonValue);
formData.append("product_category", this.buttonValue);
}
else
{
alert('Null vlaue passed');
}
axios.post('/api/get_product', formData).then((response) => {
this.product_processing = false;
console.log(response.data.data);
this.product_list = response.data.data;
if(this.barcode !='' && this.product_list.length == 1){
this.add_to_cart(this.product_list[0]);
this.barcode = '';
}
})
.catch((error) => {
console.log(error);
});
},

Using react-bootstrap in redux form

I am trying to integrate react-bootstrap Dropdown component in redux form. This is my code
import React from 'react'
import {Input,Form,FormGroup,FormControl,ControlLabel,Button,ButtonToolbar,Panel,Checkbox,Radio} from 'react-bootstrap'
import { reduxForm,Field,reset } from 'redux-form'
const FieldInput = ({ input, meta, type, placeholder, min, max }) => {
return (
<FormControl
type={type} onChange={input.onChange} />
)
}
class dropDown extends React.Component {
render() {
return (<FormControl componentClass="select" {...this.props} {...this.input} />)
}
}
let Gri = props => {
const { handleSubmit,pristine,submitting} = props
return (
<form onSubmit={handleSubmit}>
<div>
<FormGroup controlId="formInlineName">
<ControlLabel>User Name:</ControlLabel>
<Field name="firstname" component={FieldInput} type="text"/>
</FormGroup>
</div>
<div>
<FormGroup controlId="formControlsSelect">
<ControlLabel>Category:</ControlLabel>
<Field name="category_id" component={dropDown}>
<option value="1">Health</option>
<option value="2">Municipality Roads</option>
<option value="3">Women and Child Development</option>
</Field>
</FormGroup>
</div>
<Button bsStyle="success" type="submit" disabled={submitting}>SUBMIT</Button>
</form>
)
}
const onSubmit = values => {
console.log(values)
}
Gri= reduxForm({
form: 'gri',
onSubmit,
})(Gri)
export default Gri
In the output the dropdown list is shown but the value is not returned when I click submit. Please help me finding the solution

Independent "Submit" button for tabbed form in Create

I already made 2 types of create page:
Create single record.
Import multiple records from xlsx file.
Now I want to implement 2 independent buttons:
Save
Import
meaning that when I click on button 1, only button 1 works.
Here is my code:
<Create {...this.props}>
<TabbedForm toolbar="">
<FormTab label="Single record">
<ReferenceInput label="Centre" source="centre" reference="centre" sort={{ field: 'name', order: 'ASC' }} allowEmpty>
<SelectInput optionText="name" />
</ReferenceInput>
<TextInput source="fullname" />
<TextInput source="serial " />
<TextInput source="birthday" />
<TextInput source="join_date" />
<TextInput source="remark" />
<SaveButton label="Save" redirect="show" submitOnEnter={true} />
</FormTab>
<FormTab label="Import from xlsx">
<ReferenceInput label="Centre" source="centre_import" reference="centre" sort={{ field: 'name', order: 'ASC' }} allowEmpty>
<SelectInput optionText="name" />
</ReferenceInput>
<label id="customLabel">
<input id="upload" ref={(input) => { this.textInput = input; }} type="file" hidden
onClick={(event)=> {
event.target.value = null;
}}
onChange={
(event) => {
this.fileName.textContent = event.target.files[0].name;
}
}
/>
<FlatButton primary label="Select file" icon={<ActionFile />} onClick={() => {
this.textInput.click();
}}/>
<span id="fileName" ref={(span) => { this.fileName = span; }}></span>
</label>
<SaveButton label="Import" redirect={false} submitOnEnter={true} />
</FormTab>
</TabbedForm>
</Create>
The easiest way would be to keep a single button here. You may add a text inside the importation tab explaining that clicking on save will import the file.
However, you still have to deal with the redirection. To do so, you'll have to implement a custom SaveButton:
Copy the code of the default SaveButton into a SaveOrImportButton file.
Update its mapStateToProps function and use redux-form getFormValues selector to inspect the form values and determine whether its an importation.
Use this knowledge to customize the button:
You may update the label to Import if the user selected a file. The label will update immediately after the file field gets dirty.
You can change the redirect value at L22.
Use this button inside a Toolbar component and pass this component to the toolbar prop of the Create component.

dispose multiple kendo-ui dropdownlists

I have the following JSFiddle example. How do I dispose of a KendoUI DropDownList?
http://jsfiddle.net/bryanb/bWRTm/1/
I have tried the following without luck:
supplier: <input id="suppliers1" class="suppliers" value="2" />
<br />
supplier: <input id="suppliers2" class="suppliers" value="2" />
<br />
<button id="dispose">Dispose</button>
js:
function comboboxDispose() {
$(".suppliers").each(function () {
var combobox = $(this).data("kendoComboBox"),
popup = combobox.popup,
element = popup.wrapper[0] ? popup.wrapper : popup.element;
//remove popup element;
element.remove();
//unwrap element
combobox.element.show().insertBefore(combobox.wrapper);
combobox.wrapper.remove();
combobox.element.removeData("kendoComboBox");
});
}
I figured this out. My selector was selecting the wrong elements after my kendoui combobox was initialized. Here is the fix:
function comboboxDispose() {
$("input[class='suppliers']").each(function () {
var combobox = $(this).data("kendoComboBox"),
popup = combobox.popup,
element = popup.wrapper[0] ? popup.wrapper : popup.element;
//remove popup element;
element.remove();
//unwrap element
combobox.element.show().insertBefore(combobox.wrapper);
combobox.wrapper.remove();
combobox.element.removeData("kendoComboBox");
});
}
Working Example:
http://jsfiddle.net/bryanb/bWRTm/2/

issue with ajax event

i am using an ajax event which is triggered when i hit the submit button to add data to the database but since when i orignally created this page they were all in seprate files for testing purposes so now when i have put all the code together i have notice that 4 submit buttons i was using to refresh the page and then change the data being seen by filtering it are triggering the ajax query i have placed the code bellow.. i am quite stumped in what is the only way to go about this...
<script type="text/javascript" src="js/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
$(function()
{
$("input[type='checkbox']").on('click', function() {
var $this = $(this);
var isChecked = $this.prop('checked');
var checkVal = isChecked ? $this.attr('id') : $this.attr("value");
var process= $this.attr("value");
var userid = $this.attr('name');
$.ajax({
type: "GET",
url: 'request.php',
data: {
'uname': checkVal,
'id': userid
},
success: function(data) {
if(data == 1){//Success
alert('Sucess');
}
if(data == 0){//Failure
alert('Data was NOT saved in db!');
}
}
});
});
$('form').bind('submit', function(){ // it is triggering this peice of code when the submit buttons are clicked ???
$.ajax({
type: 'POST',
url: "requestadd.php",
data: $("form").serialize(),
success: function(data) {
if(data == 1){//Success
alert('Sucess');
}
if(data == 0){//Failure
alert('Data was NOT saved in db!');
}
}
});
return false;
});
$("#claim").change(function(){
$("#area").find(".field").remove();
//or
$('#area').remove('.field');
if( $(this).val()=="Insurance")
{
$("#area").append("<input class='field' name='cost' type='text' placeholder='Cost' />");
}
});
});
</script>
</head>
<body>
<div id="add">
<form name="form1aa" method="post" id="form1a" >
<div id="area">
<input type=text name="cases" placeholder="Cases ID">
<select id="claim" name="claim">
<option value="">Select a Claim</option>
<option value="Insurance">Insurance</option>
<option value="Warranty">Warranty</option>
</select>
</div>
<select name="type" onChange=" fill_damage (document.form1aa.type.selectedIndex); ">
<option value="">Select One</option>
<option value="Hardware">Hardware</option>
<option value="Software">Software</option>
</select>
<select name="damage">
</select>
<br />
<input type=text name="comment" placeholder="Comments Box">
<input type="submit" value="Submit" name="Submit">
</form>
</div>
<?
$sql="SELECT * FROM $tbl_name ORDER BY cases ASC";
if(isset($_POST['tpc'])){
$sql="select * from $tbl_name WHERE class LIKE '1%' ORDER BY cases ASC";
}
if(isset($_POST['drc'])){
$sql="select * from $tbl_name WHERE class LIKE 'D%' ORDER BY cases ASC";
}
if(isset($_POST['bsc'])){
$sql="select * from $tbl_name WHERE class LIKE 'B%' ORDER BY cases ASC";
}
$result=mysql_query($sql);
?>
<!-- Filter p1 (Start of) !-->
<form action="ajax-with-php.php" target="_self">
<input type="submit" name="all" value="All" /> // the issue is mainly occuring here when i click any of thesse meant to refesh the page and change the query with the if statements but is trigger the other code i commented
<input type="submit" name="tpc" value="TPC" />
<input type="submit" name="drc" value="DRC" />
<input type="submit" name="bsc" value="BSC" />
</form>
$('form').bind('submit', function(){ ...
will bind to all forms. Change it to
$('form#form1a').bind('submit', function(){ ...
and it will only bind to the first form, not the second.
$('form').bind('submit', function(event){
event.preventDefault();
$.ajax({...
Try making the changes above 1) adding the event argument to your callback 2) executing the .preventDefault() method. When using AJAX with the submit event this is neccessary to stop the page from reloading and interrupting your async request.
There may be more issues than that, but hopefully that will get you on the right track.

Resources