I am relatively new in react. I was exploring ANTD react UI and wanted to implement dropdown select with filter option.I found below sample code snippet in ANTD official site .
import { Select } from 'antd';
const { Option } = Select;
const children = [];
for (let i = 10; i < 36; i++) {
children.push(<Option key={i.toString(36) + i}>{i.toString(36) + i}</Option>);
}
function handleChange(value: any) {
console.log(`selected ${value}`);
}
ReactDOM.render(
<Select mode="tags" style={{ width: '100%' }} onChange={handleChange} tokenSeparators={[',']}>
{children}
</Select>,
mountNode,
);
But when i tried the same I was getting error, looks like some issue with ANTD component itself .
Property 'value' is missing in type '{ children: string; key: string; }' but required in type 'OptionProps'.ts(2741)
index.d.ts(9, 5): 'value' is declared here.
Each antd Option component requires a unique value prop. Change your for loop to:
const children = [];
for (let i = 10; i < 36; i++) {
children.push(
<Option value={i.toString(36) + i} key={i.toString(36) + i}>
{i.toString(36) + i}
</Option>);
}
Related
https://ant.design/components/transfer/
Hey all! I was just wondering is it possible to implement two separate functions on the transfer buttons. For example, I want to run add function when the user clicks transfer to the right and I want to add remove function when the user clicks transfer button to the left.
From the documentation all I could see was both the buttons just trigger onChange function and I dont want that.
The API of Transfer component uses only one function to change the data, but you can call different functions inside onChange depending on the direction:
import React, { useState } from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Transfer } from "antd";
const mockData = [];
for (let i = 0; i < 20; i++) {
mockData.push({
key: i.toString(),
title: `content${i + 1}`,
description: `description of content${i + 1}`
});
}
const initialTargetKeys = mockData
.filter((item) => +item.key > 10)
.map((item) => item.key);
const App = () => {
const [targetKeys, setTargetKeys] = useState(initialTargetKeys);
const [selectedKeys, setSelectedKeys] = useState([]);
const handleAdd = (nextTargetKeys, moveKeys) => {
console.log("add");
setTargetKeys(nextTargetKeys);
};
const handleDelete = (nextTargetKeys, moveKeys) => {
console.log("delete");
setTargetKeys(nextTargetKeys);
};
const onChange = (nextTargetKeys, direction, moveKeys) => {
if (direction === "left") {
handleDelete(nextTargetKeys, moveKeys);
} else {
handleAdd(nextTargetKeys, moveKeys);
}
};
const onSelectChange = (sourceSelectedKeys, targetSelectedKeys) => {
setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
};
return (
<Transfer
dataSource={mockData}
titles={["Source", "Target"]}
targetKeys={targetKeys}
selectedKeys={selectedKeys}
onChange={onChange}
onSelectChange={onSelectChange}
render={(item) => item.title}
/>
);
};
ReactDOM.render(<App />, document.getElementById("container"));
I'm fiddling around with vue for the first time and having troubles with getting v-bind:style="styleObject" getting to work properly. It works when styleObject only has one key/value-pair in it, but nothing comes when I have more than 1 key/value-pair.
When running console.log() the values comes out as they should.
My vue code:
<script>
import Vue from 'vue';
import ImageObject from './SkyCropImage.class';
export default Vue.component('sky-crop', {
props: {
src: String,
focalpoint: String,
mode: String,
round: String,
type: {
type: String,
default: 'img',
},
},
data() {
return {
image: new ImageObject(this.src),
srcString: '',
styleObject: { },
};
},
methods: {
anchorString(image) {
if (this.$el.firstChild.localName !== 'img') {
this.styleObject.backgroundPosition = `${image.anchor.x} ${image.anchor.y}`;
} else {
const pointX = (image.anchor.x.replace('%', '') * 1) / 100;
const pointY = (image.anchor.y.replace('%', '') * 1) / 100;
const differenceX = image.parent.width - image.calculatedInfo.width;
const differenceY = image.parent.height - image.calculatedInfo.height;
const anchorX = Math.min(0, differenceX * pointX);
const anchorY = Math.min(0, differenceY * pointY);
this.styleObject.transform = `translate(${anchorX}px, ${anchorY}px)`;
}
},
concatSrc(string) {
this.srcString = string;
if (this.type !== 'img') {
this.styleObject.backgroundImage = `url(${string})`;
}
},
},
created() {
this.image.mode = this.mode;
this.image.round = this.round;
this.image.anchor = {
x: this.focalpoint.split(',')[0],
y: this.focalpoint.split(',')[1],
};
},
mounted() {
this.image.setParentInfo(this.$el);
this.image.runCropJob();
this.anchorString(this.image);
this.concatSrc(this.image.outputUrl);
},
});
My template:
<div class="skyCrop-parent">
<img
class="skyCrop-element"
alt=""
v-if="type === 'img'"
v-bind:src="srcString"
v-bind:style="styleObject" />
// img result: <img alt="" src="https://source.unsplash.com/Ixp4YhCKZkI/700x394" class="skyCrop-element" style="transform: translate(-50px, 0px);">
<div
class="skyCrop-element"
v-bind:style="styleObject"
v-else>
</div>
//div result: <div class="skyCrop-element"></div>
</div>
How the component is called:
<sky-crop
src="https://source.unsplash.com/Ixp4YhCKZkI/1600x900"
focalpoint="50%,50%"
mode="width"
round="175"
type="div">
</sky-crop>
<sky-crop
src="https://source.unsplash.com/Ixp4YhCKZkI/1600x900"
focalpoint="50%,50%"
mode="width"
round="175">
</sky-crop>
The bug lies in the way Vue handles reactivity.
Since I tried to add key/value pair to styleObject like this:
this.styleObject.backgroundPosition = `${image.anchor.x} ${image.anchor.y}`;
Vue could not detect the change since the keys i tried to reference was not declare beforehand. The solution could be defining all future could be keys, which would work just fine. However using vm.$set() would be better since it handles creating the key and initiates the reactivity at the same time. In short this line (and the others which did the same):
this.styleObject.backgroundPosition = `${image.anchor.x} ${image.anchor.y}`;
Became this:
this.$set(this.styleObject, 'background-position', `${image.anchor.x} ${image.anchor.y}`);
Vue documentation about the reason for the change:
https://v2.vuejs.org/v2/guide/reactivity.html
options.dataUrl = urlObj.href;
$.mobile.changePage( $page, options );
dataUrl contains the complete url with parameters
http://example.com/#sales?p=page
but the above code only updates the url with hash only, after the new page loads... the url changes to
http://example.com/#sales
and does not apply ?p=page.
Here is the complete function, check the last few lines....
function getSPList( urlObj, options ){
var pageName = urlObj.hash.replace( /.*p=/, "" ),
pageSelector = urlObj.hash.replace( /\?.*$/, "" );
$.ajax({
url:"getSPList.php",
dataType: 'json',
data: {p: pageName},
success:function(result){
if ( result ) {
var $page = $( pageSelector ),
$header = $page.children( ":jqmData(role=header)" ),
$content = $page.children( ":jqmData(role=content)" ),
markup = "<ul data-role='listview' data-filter='true' data-filter-placeholder='Search Salesperson...'>";
for ( var i = 0; i < result.sp.length; i++ ) {
markup += "<li><a href='#addClient?p="+ result.sp[i].id +"' data-transition='slide'>" + result.sp[i].name + "</a></li>";
}
markup += "</ul>";
$content.html( markup );
$page.page();
$content.find( ":jqmData(role=listview)" ).listview();
options.dataUrl = urlObj.href;
options.changeHash = true;
$.mobile.changePage( $page, options );
}
}
});
return
}
I have experienced the same problem and here is what I've found as of version 1.3.2:
Inside $.mobile.changePage(toPage, options) options.dataUrl is passed through path.convertUrlToDataUrl() before being stored and used.
Inside path.convertUrlToDataUrl() everything before and including the '#' as well as everything after and including the '?' is stripped.
Further down inside of $.mobile.changePage() before the url is passed to $.mobile.navigate() I see this:
// rebuilding the hash here since we loose it earlier on
// TODO preserve the originally passed in path
if( !path.isPath( url ) && url.indexOf( "#" ) < 0 ) {
url = "#" + url;
}
So it seems to be a bug in jQm. For my app I'm adding this inside the bottom of the previously mentioned if statement:
var query_index = (settings.dataUrl || '').indexOf('?');
if (query_index > -1) {
url += settings.dataUrl.substring(query_index);
}
This solves the initial problem but I'm unsure about potential negative side effects or if there is a better workaround out there.
i have some dynamic data that gets appended to a list and any links in that data doesnt seem to work.
i am using jquery 1.8.3 and on() should account for the live method, i think
setInterval(function () {
getNot();
}, 2000);
function getNot() {
var data = {
t1: 'test1',
t2: 'test2',
t3: 'test3'
};
var size = 0,
li = '';
$.each(data, function (k, v) {
li += '<li>' +
'<a href="#" class="add" data-listid="' + k + '">' +
'<h2>load data - ' + k + '</h2>' +
'</a>' +
'</li>';
size++;
});
var but = $('#not'),
ul = $('#not_ul');
but.find('span').text(size + ' Notifications');
ul.html(li);
ul.listview().listview("refresh");
}
// this doesn't seem to work
$('.add').on("click", function () {
var listId = $(this).data('listid');
console.log(listId);
return false;
});
see full example here
any ideas on this issue?
$('.add').on("click", function () {
You need to pass a selector to make on generate a delegate event:
$('#{containerId}').on("click", '.add', function () {
var listId = $(this).data('listid');
console.log(listId);
return false;
});
containerId should be the closest static element to the dynamic created .adds elements.
I want to display jquery mobile alternate button's with different color. The code which I am using now is only able to change the button theme to 'e' but I want 'theme b'. What can be the problem? Below is the code.
$(document).delegate('[data-role="page"]', 'pagecreate', function(e) {
var db = openDatabase("Database", "1.0", "PhoneGap Demo", 200000);
db.transaction(function(tx) {
tx.executeSql("SELECT id FROM DEMO", [],
function(tx, results) {
var len = results.rows.length,
i;
//If no result Found
for (i = 0; i < len; i++) {
var test = results.rows.item(i).id % 2; //to get the alternate row's
if (test == 0) {
var id = "color" + results.rows.item(i).id;
$("#" + id).attr('data-content-theme', 'e').removeClass('ui-body-d').addClass('ui-body-e').trigger('create'); // Change to theme e
}
}
});
});
});
I am changing the button theme as per the id of dynamically populated buttons.
If you could post some HTML code it would help a lot.
You could try the following to see whether it solves the issue:
$("#" + id).attr('data-content-theme', 'b').removeClass('ui-body-a ui-body-b ui-body-c ui-body-d ui-body-e').addClass('ui-body-b').trigger('create');