How do you create an event when the user clicks on any part of the calendar? and then store it in the database as a new event?
I know you have to use: select: function(start, end, allDay) to get the "start" and "end" times. But after I get this data how do I pass it to the database?
Thanks!
You may use an ajax request to store the new event in your DB.
There is a demo on the projects homepage, which can easily be adapted.
Via jQuery for example like this :
select: function(start, end, allDay) {
var title = prompt('Event Title:');
if (title) {
calendar.fullCalendar('renderEvent',
{
title: title,
start: start,
end: end,
allDay: allDay
},
true // make the event "stick"
);
/**
* ajax call to store event in DB
*/
jQuery.post(
"event/new" // your url
, { // re-use event's data
title: title,
start: start,
end: end,
allDay: allDay
}
);
}
calendar.fullCalendar('unselect');
}
If you need to react on a specific click, you can also try this, but you have to grep the event end or duration by yourself.
dayClick: function(date, allDay, jsEvent, view) {
var title = prompt('Event Title:');
/**
* again : ajax call to store event in DB
*/
jQuery.post(
"event/new" // your url
, { // re-use event's data
title: title,
start: date
allDay: allDay
}
);
}
here i am sharing what ever i do.
i create a popup and get apartment number and pin number from user
and then through ajax i create a new event by requesting a custom insert_data.php file
here is the code for fullcalendar.php
selectable: true,
selectHelper: true,
select: function(start, end, allDay) {
//alert(start);
var title = $("#dialog").dialog();
//$(".popup").show();
//$(".title").focus();
var start = start; //Date.parse(start) / 1000;
var end = end; //Date.parse(end) / 1000;
var allDay = allDay;
//alert(allDay);
$("#save_frm").click(function(){
var pin_number = $("#pin_number").val();
var apartment_number =$("#apartment_number").val();
//alert(start);
//alert(end);
//alert(allDay);
$.ajax({
type: "POST",
url: "<?php echo WP_PLUGIN_URL; ?>/wp-fullcalendar/insert_data.php",
data: { apartment_number: apartment_number, pin_number: pin_number, start: start, end: end, allDay: allDay }
}).done(function( msg ) {
alert( "Data Saved: " + msg );
$("#dialog").dialog("close");
window.location.reload(true);
calendar.fullCalendar('unselect');
calendar.fullCalendar('refetchEvents');
});
});//select function end here
// calendar.fullCalendar('unselect');
},
//and then ajax request goes to insert_data.php bellow code should be place seperate file
require("../../../wp-load.php"); //connection with database
require("../../../wp-config.php");
//print_r(explode(" ",$_POST['end']));
$start = explode(" ",$_POST['start']);
//coding for extracting date
$start_date=$start[3].'-';
//$start_date.=$start[1].'-';
if($start[1]=='Jan')
{
$start_date.='01';
}
else if($start[1]=='Feb')
{
$start_date.='02';
}
else if($start[1]=='Mar')
{
$start_date.='03';
}
else if($start[1]=='Apr')
{
$start_date.='04';
}
else if($start[1]=='May')
{
$start_date.='05';
}
else if($start[1]=='Jun')
{
$start_date.='06';
}
else if($start[1]=='Jul')
{
$start_date.='07';
}
else if($start[1]=='Aug')
{
$start_date.='08';
}
else if($start[1]=='Sep')
{
$start_date.='09';
}
else if($start[1]=='Oct')
{
$start_date.='10';
}
else if($start[1]=='Nov')
{
$start_date.='11';
}
else if($start[1]=='Dec')
{
$start_date.='12';
}
$start_date.='-'.$start[2];
//coding for extracting date end here
$start_time = $start[4];
$end = explode(" ",$_POST['end']);
$end_time = $end[4];
global $wpdb;
//$table_name = $wpdb->prefix . "em_events";
//$wpdb->insert( $table_name, array( 'album' => $_POST['album'], 'artist' => $_POST['artist'] ) );
// Create post object
$apartment_number = $_POST['apartment_number'];
$pin_number = $_POST['pin_number'];
$post_date = $start_date.' ' .$start_time;
$post = array( 'ID' => ''
, 'post_author' => '1'
, 'post_date' => ''
, 'post_date_gmt' => ''
, 'post_content' => $apartment_number
, 'post_tittle' => $apartment_number
, 'post_excerpt' => $apartment_number
, 'post_status' => 'publish'
, 'comment_status' => 'closed'
, 'ping_status' => 'closed'
, 'post_password' => $pin_number
, 'post_name' => $apartment_number
, 'to_ping' => ''
, 'pinged' => ''
, 'post_modified' => ''
, 'post_modified_gmt' => ''
, 'post_content_filtered'=> '0'
, 'post_parent' => '0'
, 'guid' => '1'
, 'menu_order' => '0'
, 'post_type' => 'event'
, 'post_mime_type' => $post_date
, 'comment_count' => '0'
);
// Insert the post into the database
$post_id=wp_insert_post( $post, $wp_error );
if($wpdb->insert( 'wp_em_events', array(
'post_id' => $post_id
, 'event_slug' => $_POST['apartment_number']
, 'event_owner' => 1
, 'event_status' => 1
, 'event_name' => $_POST['apartment_number']
, 'event_start_time' => $start_time
, 'event_end_time' => $end_time
, 'event_all_day' => 0
, 'event_start_date' => $start_date
, 'event_end_date' => $start_date
, 'post_content' => $_POST['apartment_number']
, 'event_rsvp' => 0
, 'event_rsvp_date' => $end_date
, 'event_rsvp_time' => '00:00:00'
, 'event_spaces' => 0
, 'event_private' => 0
, 'location_id' => 0
//, 'recurrence_id' => 1223
, 'event_category_id' => 1
, 'event_attributes' => 'a:0:{}'
, 'event_date_created' => $start_date." ".$start_time
, 'event_date_modified' => $start_date." ".$start_time
, 'recurrence' => 0
//, 'recurrence_interval' => 12
//, 'recurrence_freq' => 12
//, 'recurrence_byday' => 1231
//, 'recurrence_byweekno' => 4564
, 'recurrence_days' => 0
//, 'blog_id' => 456465
, 'group_id' => 0
) )){
echo "query execute";
}else{
echo "query not execute";
}
The select callback has changed since. For FullCalender v5 use this...
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('calendar');
var calendar = new FullCalendar.Calendar(calendarEl, {
selectable: true,
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,timeGridDay'
},
dateClick: function(info) {
alert('clicked ' + info.dateStr);
},
select: function(info) {
alert('selected ' + info.startStr + ' to ' + info.endStr);
}
});
calendar.render();
});
Source: https://fullcalendar.io/docs/select-callback
Related
I'm having issues with a route in Zend Framework 2. For instance, in module.config.php I have it set up as follows:
'user' => array(
'type' => 'Segment',
'options' => array(
'route' => 'user[/:action][/:store_id]',
'defaults' => array(
'controller' => 'Application\Controller\User',
'action' => 'index',
),
),
),
Now, I have a function in JavaScript that calls the route part [/:store_id] when a image is clicked on.
function viewStore(id) {
if (typeof id !== undefined) {
$.getJSON('/user/store/' + id, function(data) {
document.getElementById('view-store-modal').style.display = 'block';
$.each(data, function(i) {
$('#main-store-name').html(data[i].store_name);
$("#main-store-image").prop('src', data[i].store_image);
$("#main-store-image").addClass("w3-padding").addClass("w3-round");
$('#main-store-image').attr('style', 'width: 400px; height: 200px; display: block');
$('#main-store-description').html("Store Description: " + data[i].store_description);
$('#main-store-category').html("Store Category: " + data[i].store_category);
if (data[i].number_of_items === null) {
$('#main-store-items').html("No items exist for this store yet, go add some!");
} else {
$('#main-store-items').html("Number Of Items: " + data[i].number_of_items);
}
});
});
}
}
Here is the controller code:
public function storeAction()
{
$layout = $this->layout();
$layout->setTerminal(true);
$view_model = new ViewModel();
$view_model->setTerminal(true);
$id = $this->params()->fromRoute('store_id');
if ($id !== null) {
try {
echo json_encode($this->getUserService()->getStoreFromId((int)$id));
} catch (\Exception $e) {
echo json_encode(array('failure' => $e->getMessage()));
}
}
return $view_model;
}
And this is the method that retrieves the rows:
public function getStoreFromId(int $store_id) : array
{
if ($store_id != 0 || $store_id !== null) {
$query = $this->sql->getAdapter()->getDriver()->getConnection()->execute("SELECT COUNT(i.store_id) AS number_of_items,
stores.store_name, stores.store_description, stores.store_category, stores.store_image FROM items AS i
INNER JOIN stores ON stores.store_id = i.store_id WHERE stores.store_id = " . $store_id);
if ($query->count() > 0) {
$row = [];
foreach ($query as $value) {
$row[] = $value;
}
return $row;
} else {
$select = $this->select->columns(array('store_id', 'store_name', 'store_description', 'store_category', 'store_image'))
->from('stores')
->where(array('store_id' => $store_id));
$query = $this->sql->getAdapter()->query(
$this->sql->buildSqlString($select),
Adapter::QUERY_MODE_EXECUTE
);
if ($query->count() > 0) {
$row = [];
foreach ($query as $value) {
$row[] = $value;
}
return $row;
} else {
throw new \Exception("Could not locate store.");
}
}
} else {
throw new \Exception("Invalid store id given.");
}
}
When I call it, it is like this:
<img src="<?php echo $this->basePath() . $store['store_image']; ?>" alt="Your Store" style="width: 100%;" onclick="viewStore(<?php echo $store['store_id']; ?>);">
Now, that does show all the store ids but when I click on any id but the first image, I am getting this response (shown in screenshots)
https://imgur.com/a/4XFbKFI
I'm not sure why any of the ids that are not 23 do not load. Right now, all are listed from the stores table but only the id 23 actually works.
Any help would be appreciated.
Thanks!
The issue was with the query. I changed it to this:
SELECT stores.store_id,
(SELECT count(b.store_id) FROM items b WHERE b.store_id = " . $store_id . " and stores.store_id = b.store_id) AS number_of_items, stores.store_name, stores.store_description, stores.store_category, stores.store_image FROM stores
WHERE stores.store_id = " . $store_id
and it worked just fine.
I have a textInput in _form.php. Then, I change it become select2. But after I change it, the validation is not working. What's the problem? How can I make a validation in select2 so that it cannot be blank?
This is the code:
_form.php
<?php
$formatJs = <<< 'JS'
var formatPenerima = function (penerima) {
if (penerima.loading) {
return penerima.text;
}
var markup =
'<div class="row">' +
'<div class="col-sm-4">' +
'<b style="margin-left:5px">' + penerima.text + '</b>' +
'</div>' +
'<div class="col-sm-3"><i class="fa fa-phone"></i> ' + penerima.telepon + '</div>' +
'<div class="col-sm-4"><i class="fa fa-envelope"></i> ' + penerima.mail + '</div>' +
'</div>';
return '<div style="overflow:hidden;">' + markup + '</div>';
};
var formatPenerimaSelection = function (penerima) {
return penerima.id || penerima.text;
}
JS;
// Register the formatting script
$this->registerJs($formatJs, \yii\web\View::POS_HEAD);
// Script to parse the results into the format expected by Select2
$resultsJs = <<< JS
function (data, params) {
params.page = params.page || 1;
return {
results: data.results, // check here
/*pagination: {
more: (params.page * 30) < data.total_count
}*/
};
}
JS;
$url = Url::to(['/paket/jsonlist']);
// Render your widget
// Get data from dummy data
echo $form->field($model, 'no_induk')->widget(Select2::className(), [
'name' => 'kv-repo-template',
'value' => '',
'initValueText' => '',
'options' => ['placeholder' => 'Cari pemilik ...', 'id' => 'pengambil'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'ajax' => [
'url' => $url,
'dataType' => 'json',
'delay' => 250,
'data' => new JsExpression('function(params) { return {q:params.term, page: params.page}; }'),
'processResults' => new JsExpression($resultsJs),
'cache' => true
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('formatPenerima'),
'templateSelection' => new JsExpression('formatPenerimaSelection'),
],
])->label('Pemilik');
?>
and this is my model rules:
public function rules()
{
return [
[['no_induk', 'nama', 'no_telepon', 'email', 'kategori_paket', 'nama_pengirim'/*, 'tanggal_sampai'*/],
'required', 'message' => '{attribute} tidak boleh kosong.'],
[['id_satpam_pengentry'], 'required', 'message' => 'Nama satpam tidak boleh kosong.'],
[['kategori_paket', 'status', 'id_satpam_pengentry', 'id_satpam_penyetuju'], 'integer'],
[['tanggal_sampai', 'tanggal_pengambilan'], 'safe'],
[['no_induk', 'email'], 'string', 'max' => 255],
[['nama', 'nama_pengirim', 'nama_pengambil'], 'string', 'max' => 128],
[['no_telepon'], 'string', 'max' => 64]
];
}
you can set "required = true" in the "options" array like this
'options' => ['placeholder' => 'Cari pemilik ...', 'class' => 'form-control', 'required' => true],
you have to put
class => "form-control" in your options and remove id, so validation will work
echo $form->field($model, 'no_induk')->widget(Select2::className(), [
'name' => 'kv-repo-template',
'value' => '',
'initValueText' => '',
'options' => ['placeholder' => 'Cari pemilik ...', 'class' => 'form-control'],
'pluginOptions' => [
'allowClear' => true,
'minimumInputLength' => 1,
'ajax' => [
'url' => $url,
'dataType' => 'json',
'delay' => 250,
'data' => new JsExpression('function(params) { return {q:params.term, page: params.page}; }'),
'processResults' => new JsExpression($resultsJs),
'cache' => true
],
'escapeMarkup' => new JsExpression('function (markup) { return markup; }'),
'templateResult' => new JsExpression('formatPenerima'),
'templateSelection' => new JsExpression('formatPenerimaSelection'),
],
])->label('Pemilik');
This is my controller.
public function actions()
{
return [
'auth' => [
'class' => 'yii\authclient\AuthAction',
'successCallback' => [$this, 'oAuthSuccess'],
],
];
}
public function oAuthSuccess($client) {
$name = explode(" ",$userAttributes['name']);
$existing_customer = Customer::find()
->where(['email' => $userAttributes['email']])
->orWhere(['id_facebook' => $userAttributes['id']])
->one();
if(empty($existing_customer)){
$customer = new Customer();
$customer->firstname = $name[0];
$customer->lastname = $name[1];
$customer->id_default_group = 3;
$customer->username = $userAttributes['id'].'#facebook.com';
$customer->id_facebook = $userAttributes['id'];
$customer->email = $userAttributes['email'];
$password = rand(0000, 9999);
$auth_key = Yii::$app->getSecurity()->generateRandomString();
$customer->auth_key = $auth_key;
$hash = Yii::$app->getSecurity()->generatePasswordHash($password);
$customer->password_hash = $hash;
$customer->activation_code = $password;
$customer->active =1;
if ($customer->save(false)) {
$customergroup = new CustomerGroup();
$customergroup->id_customer = $customer->id_customer;
$customergroup->id_group = $customer->id_default_group;
$customergroup->save(false);
Yii::$app->response->redirect(['advanced','email' => $customer->email]);
}
}
This is my main.php file.
'authClientCollection' => [
'class' => 'yii\authclient\Collection',
'clients' => [
'facebook' => [
'class' => 'yii\authclient\clients\Facebook',
'authUrl' => 'https://www.facebook.com/dialog/oauth?display=popup',
'clientId' => '',
'clientSecret' => '',
'scope' => [
'email',
'user_birthday',
'user_location',
'user_hometown',
],
],
],
],
Actually I am doing registration in 2 process.
After user click on facebook button it returns to my second step in popup, But i need it in my site. How is it possible?
change your auth successCallBack in action function with the action you desire..
below a sample where successCallback check if the user is a guest if true call the action authenticate otherwise the action connect
/** #inheritdoc */
public function actions()
{
return [
'auth' => [
'class' => AuthAction::className(),
'successCallback' => \Yii::$app->user->isGuest
? [$this, 'authenticate']
: [$this, 'connect'],
]
];
}
After the facebook login you return in your code inside the oAuthSuccess function .. i think the popup you are looking for is inside this function and is called from this redirect. if you want somethings others change the bootom part of this function..
Yii::$app->response->redirect(['advanced','email' => $customer->email]);
I am using default Yii2 library for auto-complete. How can I make it, so it is reading values from DB while user is typing?
This is code I have so far, but query is done when the page is created:
echo AutoComplete::widget([
'name' => 'tradeName',
'model' => TradeNames::find()->select('name')->all(),
'options' => [
'class' => 'form-control'
],
'clientOptions' => [
'source' => array_column(TradeNames::find()->select('name')->asArray()->all(), 'name'),
},
],
]);
I followed this advice
jqueryui.com/autocomplete/#multiple and have written next code
<div id="autocomplete" class="ui-widget">
<?= \yii\jui\AutoComplete::widget([
'attribute' => 'attribute',
'name' => 'tradeName',
'clientOptions' => [
'source' => \Yii::$container->get('JsExpression',['function(request, response) {
response( $.ui.autocomplete.filter( window.dataAsArray, extractLast( request.term ) ) );
}']),
'select' => \Yii::$container->get('JsExpression',['function(event, ui) {
var terms = split( this.value );
terms.pop();
terms.push( ui.item.value );
terms.push( "" );
this.value = terms.join( ", " );
return false;
}']),
'focus' => \Yii::$container->get('JsExpression',['function() {
return false;
}']),
]
]) ?>
</div>
<script>
window.dataAsArray = ['item1', 'item2', 'item3'];
function split( val ) {
return val.split( /,\s*/ );
}
function extractLast( term ) {
return split( term ).pop();
}
$(document).ready( function() {
$('#autocomplete').on('keydown', function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB && $( this ).autocomplete( "instance" ).menu.active ) {
event.preventDefault();
}
});
});
</script>
maybe it help to someone
try this
use yii\jui\AutoComplete;
use yii\web\JsExpression;
<?php
$data = TradeNames::find()
->select(['name as value', 'name as label','id as id'])
->asArray()
->all();
echo 'Trade Names' .'<br>';
echo AutoComplete::widget([
'name' => 'tradeName',
'id' => 'trade_name',
'clientOptions' => [
'source' => $data,
// 'minLength'=>'3',
'autoFill'=>true,
'select' => new JsExpression("function( event, ui ) {
$('#memberssearch-family_name_id').val(ui.item.id);//#memberssearch-family_name_id is the id of hiddenInput.
}")],
]);
?>
<?= Html::activeHiddenInput($model, 'tradeName')?>
I am trying to add a description to my form element. I am expecting to get my description in p tags.
<?php
namespace CsnCms\Form;
use Zend\Form\Form;
class ArticleForm extends Form
{
public function __construct($name = null)
{
parent::__construct('article');
$this->setAttribute('method', 'post');
$this->add(array(
'name' => 'currency',
'attributes' => array(
'type' => 'text',
'placeholder' =>'Currency',
),
'options' => array(
'label' => ' ',
'description' => 'Currency code: ie. USD',
),
));
}
}
unfortunately I am only getting this as an output
<label><span> </span><input name="currency" type="text" placeholder="Currency" value=""></label>
any advice?
Maybe this will work
$form = $this->form;
$element = $form->get("currency");
echo $this->formInput($element);
echo $element->getOption("description"); // <-------
?>
zf2 form elements don't have native description option u need to add it manually :
$this->add(array(
'name' => 'catMachineName',
'type' => 'Zend\Form\Element\Text',
'options' => array(
'label' => 'Category Machine Name',
'description' => 'Machine name can only contain English Alphabets and Numbers and _ and no space and no number at the beginning'
),
));
and render it in view like with something like this:
echo $form->get('catMachineName')->getOption('description);
Thanks I wrote my own view helper. I also added a class="error" in the error tags.
Thanks for the help guys.
<?php
namespace User\View\Helper;
use Zend\View\Helper\AbstractHelper;
use Zend\Form\View\Helper\FormRow;
use Zend\Form\ElementInterface;
class FormRowWithDescription extends FormRow
{
/**
* Utility form helper that renders a label (if it exists), an element and errors
*
* #param ElementInterface $element
* #throws \Zend\Form\Exception\DomainException
* #return string
*/
public function render(ElementInterface $element)
{ $escapeHtmlHelper = $this->getEscapeHtmlHelper();
$labelHelper = $this->getLabelHelper();
$elementHelper = $this->getElementHelper();
$elementErrorsHelper = $this->getElementErrorsHelper();
$label = $element->getLabel();
$inputErrorClass = $this->getInputErrorClass();
if (isset($label) && '' !== $label) {
// Translate the label
if (null !== ($translator = $this->getTranslator())) {
$label = $translator->translate(
$label, $this->getTranslatorTextDomain()
);
}
}
// Does this element have errors ?
if (count($element->getMessages()) > 0 && !empty($inputErrorClass)) {
$classAttributes = ($element->hasAttribute('class') ? $element->getAttribute('class') . ' ' : '');
$classAttributes = $classAttributes . $inputErrorClass;
$element->setAttribute('class', $classAttributes);
}
if ($this->partial) {
$vars = array(
'element' => $element,
'label' => $label,
'labelAttributes' => $this->labelAttributes,
'labelPosition' => $this->labelPosition,
'renderErrors' => $this->renderErrors,
);
return $this->view->render($this->partial, $vars);
}
if ($this->renderErrors) {
$elementErrorsHelper
->setMessageOpenFormat('<ul%s><li class="error">')
->setMessageSeparatorString('</li><li class="error">');
$elementErrors = $elementErrorsHelper->render($element);
}
$elementString = $elementHelper->render($element);
$description = $element->getOption('description');
$elementString.="<p class='description'>".$description."</p>";
if (isset($label) && '' !== $label) {
$label = $escapeHtmlHelper($label);
$labelAttributes = $element->getLabelAttributes();
if (empty($labelAttributes)) {
$labelAttributes = $this->labelAttributes;
}
// Multicheckbox elements have to be handled differently as the HTML standard does not allow nested
// labels. The semantic way is to group them inside a fieldset
$type = $element->getAttribute('type');
if ($type === 'multi_checkbox' || $type === 'radio') {
$markup = sprintf(
'<fieldset><legend>%s</legend>%s</fieldset>',
$label,
$elementString);
} else {
if ($element->hasAttribute('id')) {
$labelOpen = '';
$labelClose = '';
$label = $labelHelper($element);
} else {
$labelOpen = $labelHelper->openTag($labelAttributes);
$labelClose = $labelHelper->closeTag();
}
if ($label !== '' && !$element->hasAttribute('id')) {
$label = '<span>' . $label . '</span>';
}
// Button element is a special case, because label is always rendered inside it
if ($element instanceof Button) {
$labelOpen = $labelClose = $label = '';
}
switch ($this->labelPosition) {
case self::LABEL_PREPEND:
$markup = $labelOpen . $label . $elementString . $labelClose;
break;
case self::LABEL_APPEND:
default:
$markup = $labelOpen . $elementString . $label . $labelClose;
break;
}
}
if ($this->renderErrors) {
$markup .= $elementErrors;
}
} else {
if ($this->renderErrors) {
$markup = $elementString . $elementErrors;
} else {
$markup = $elementString;
}
}
return $markup;
}
}