diff --git a/app/assets/javascripts/property_hire/property-field-forms.js b/app/assets/javascripts/property_hire/property-field-forms.js
new file mode 100644
index 0000000..2efd0f0
--- /dev/null
+++ b/app/assets/javascripts/property_hire/property-field-forms.js
@@ -0,0 +1,496 @@
+// Retrieve the initial data
+function temporary() {
+ attributesArray.length = 0;
+ $('.attributes').each(function() {
+ var attributesData = {},
+ $selectType = $('.dataType').data().type;
+
+ // Capture "attributes-body" within the input[type = "text"] val
+ $(this).find('.attributes-body').find('input[type="text"]').each(function(i) {
+ var $type = $(this).data().type;
+ attributesData[$type] = $(this).val();
+ });
+
+ // Capture "attributes-body" within the input[type = "radio"] checked
+ $(this).find('.attributes-body').find('input[type="radio"]').each(function(i) {
+ var $type = $(this).data().type;
+ attributesData[$type] = $(this).prop("checked");
+ });
+
+ // Capture "attributes-body" within the dataType selected
+ $(this).find('.attributes-body').find('.dataType').children("option:selected").each(function () {
+ attributesData[$selectType] = {};
+ attributesData[$selectType].index = $(this).index();
+ attributesData[$selectType].name = $(this).attr('ref');
+ if($(this).attr('ref') == 'typeB' || $(this).attr('ref') == 'typeE' || $(this).attr('ref') == 'typeF') {
+ attributesData[$selectType].option = [];
+ }
+ });
+
+ // Capture "field-type" within the input[type = "text"] val
+ $(this).find('.field-type').find('input[type="text"]').each(function(i) {
+ var $type = $(this).data().type;
+ if(!$type.match('option_lang')) {
+ attributesData[$selectType][$type] = $(this).val();
+ }
+ });
+
+ $(this).find('.field-type .add-target').find('.input-append').each(function() {
+ var append = []
+ $(this).children('input[type="text"]').each(function() {
+ var val = $(this).val();
+ append.push(val);
+ });
+ attributesData[$selectType].option.push(append);
+ })
+
+ // Capture "field-type" within the input[type = "checkbox"] checked
+ $(this).find('.field-type').find('input[type="checkbox"]').each(function() {
+ var $type = $(this).data().type;
+ attributesData[$selectType][$type] = $(this).prop("checked");
+ });
+
+ // Capture "field-type" within the input[type = "radio"] checked
+ $(this).find('.field-type').find('input[type="radio"]').each(function() {
+ var $type = $(this).data().type;
+ attributesData[$selectType][$type] = $(this).prop("checked");
+ });
+
+ // Capture "field-type" within the dataType selected
+ $(this).find('.field-type').find('select').children("option:selected").each(function () {
+ attributesData[$selectType].dateFormat = $(this).index();
+ });
+
+ attributesArray.push(attributesData);
+ });
+};
+
+// Determine the Append input length
+function inputAppendLength() {
+ $('.add-target').each(function(i) {
+ if($(this).children('.input-append:not(:hidden)').length == 1 || $(this).children('.input-append').length == 1) {
+ $(this).children('.input-append').each(function() {
+ if($(this).children('div').hasClass('tab-content')) {
+ var btnLength = $(this).children('.btn').length;
+ $(this).find('.btn').eq(btnLength-2).addClass('last');
+ $(this).find('.remove-input').addClass('hide');
+ } else {
+ var mediumLength = $(this).children('.input-medium').length;
+ $(this).children('.input-medium').eq(mediumLength-1).addClass('last');
+ $(this).children('.remove-input').addClass('hide');
+ }
+ });
+ } else {
+ $(this).children('.input-append').each(function() {
+ if($(this).children('div').hasClass('tab-content')) {
+ $(this).find('.btn').removeClass('last');
+ $(this).find('.remove-input').removeClass('hide');
+ } else {
+ $(this).children('.input-medium').removeClass('last');
+ $(this).children('.remove-input').removeClass('hide');
+ }
+ });
+ }
+ });
+};
+
+// Role Attribute Template Data
+function setData(l, type, ol) {
+ var fields = $('#info').length ? "info[p_hire_fields]" : $('#sub_property').length ? "sub_property[p_hire_fields]" : "property[p_hire_fields]",
+ data = {
+ _add_more: ["add_more_" +l, fields+"["+l+"]["+type+"][add_more]"],
+ _calendar: ["calendar_" +l, fields+"["+l+"]["+type+"][calendar]"],
+ _cross_lang: ["cross_lang_" +l, fields+"["+l+"]["+type+"][cross_lang]"],
+ _disabled: ["disabled_" +l, fields+"["+l+"][disabled]"],
+ _format: ["format_" +l, fields+"["+l+"]["+type+"][format]"],
+ _initial: ["initial_" +l, fields+"["+l+"]["+type+"][initial]"],
+ _is_range: ["is_range_" +l, fields+"["+l+"]["+type+"][is_range]"],
+ _key: ["key_" +l, fields+"["+l+"][key]"],
+ _markup: fields+"["+l+"][markup]",
+ _option_list: ["option_list_"+l+"_"+ol, fields+"["+l+"]["+type+"][option_list]["+ol+"]", "option_list_"+ol],
+ _placeholder: ["placeholder_" +l, fields+"["+l+"]["+type+"][placeholder]"],
+ _title_translations: ["title_translations_" +l, fields+"["+l+"][title_translations]"],
+ _to_delete: ["to_delete_" +l, fields+"["+l+"][to_delete]"],
+ _to_require: ["to_require_" +l, fields+"["+l+"][to_require]"],
+ };
+ return data;
+}
+
+// Get Default Address Form
+function getAddressForm(trigger, element, decide) {
+ if(decide) {
+ addressVal.length = addressArray.length = 0;
+ var addressAllVal = [];
+ var inputNameArray = [];
+ trigger.closest('.input-append').find('.tab-pane').each(function() {
+ var adderssText = $(this).children('input[type="text"]').val(),
+ addersshidden = '',
+ addressData = {},
+ inputName = [];
+ $(this).children('input:not(:first)').each(function(j) {
+ var name = $(this).attr('name'),
+ val = $(this).val();
+ addersshidden += val;
+ addressData[name] = val;
+ inputName.push(name);
+ });
+ addressArray.push(addressData);
+ addressAllVal.push(adderssText);
+ inputNameArray.push(inputName);
+ if(adderssText != addersshidden) {
+ addressVal.push(false);
+ } else {
+ addressVal.push(true);
+ }
+ });
+ element.find('.tab-pane').each(function(i) {
+ $(this).find('textarea, input[type="text"]').each(function(j) {
+ $(this).attr('name',inputNameArray[i][j]);
+ });
+ if(addressVal[i]) {
+ $(this).find('textarea, input[type="text"]').each(function(j) {
+ $(this).val(addressArray[i][$(this).attr('name')]);
+ });
+ } else {
+ $(this).find('textarea').val(addressAllVal[i]);
+ $(this).find('input[type="text"]').each(function(j) {
+ $(this).val('');
+ });
+ }
+ });
+ };
+ element.off('show');
+};
+
+// Return Address Form
+function returnAddressForm(element, decide) {
+ if(decide) {
+ addressArray.length = 0;
+ element.find('.tab-pane').each(function(i) {
+ var addressData = {};
+ $(this).find('textarea, input[type="text"]').each(function(j) {
+ var name = $(this).attr('name'),
+ val = $(this).val();
+ addressData[name] = val;
+ });
+ addressArray.push(addressData);
+ });
+ $.map(addressInputId, function(n, i) {
+ var v = '';
+ $('#'+n).find('input[type="hidden"]').each(function() {
+ $(this).val(addressArray[i][$(this).attr('name')]);
+ v += addressArray[i][$(this).attr('name')]
+ });
+ $('#'+n).find('input[type="text"]').each(function() {
+ $(this).val(v);
+ });
+ });
+ };
+ returnDecide = false;
+};
+
+$(function() {
+ appendIndex = null;
+ if($('#user-forms').length) {
+ addressVal = [];
+ addressArray = [];
+ addressInputId = [];
+ propertyType = null;
+ returnDecide = false;
+ $('.attributes').each(function() {
+ if($(this).find('.toggle-check').attr('value') == "true") {
+ $(this).addClass('disabled').children('.attributes-body').hide();
+ }
+ });
+ $('.returnDecide').on(clickEvent, function() {
+ returnDecide = true;
+ })
+ $('#address-field').on('hidden', function () {
+ $('.btn[data-toggle="modal"]').removeClass('active').blur();
+ $(this).find('.nav-tabs > li').removeClass('active').eq(0).addClass('active');
+ $(this).find('.tab-content > .tab-pane').removeClass('active in').eq(0).addClass('active in');
+ $(this).on('show', getAddressForm(null, $(this), false));
+ returnAddressForm($(this), returnDecide)
+ });
+ $('.control-group').delegate('.btn[data-toggle="modal"]', 'click', function() {
+ var $trigger = $(this);
+ addressInputId.length = 0;
+ $(this).closest('.input-append').find('.tab-pane').each(function() {
+ addressInputId.push($(this).attr('id'));
+ });
+ $('#address-field').on('show', getAddressForm($trigger, $('#address-field'), true));
+ });
+ $('#user-forms').delegate('.togglebox, .delete, .trigger, .remove-input', clickEvent, function(event) {
+ if($(this).hasClass('togglebox')) {
+ var property_staus = [];
+ if($(this).hasClass('disable')) {
+ $(this).find('.toggle-check')
+ .attr('value', 'false')
+ .closest('.attributes')
+ .removeClass('disabled')
+ .children('.attributes-body')
+ .fadeIn(300);
+ } else {
+ $(this).find('.toggle-check')
+ .attr('value', 'true')
+ .closest('.attributes')
+ .addClass('disabled')
+ .children('.attributes-body')
+ .fadeOut(300)
+ .find('.check')
+ .attr("checked",false)
+ .attr("value",property_staus);
+ }
+ $(this).toggleClass('disable');
+ };
+ if($(this).hasClass('remove-input')) {
+ $(this).closest('.input-append').fadeOut(300, function() {
+ $(this).remove();
+ inputAppendLength();
+ });
+ };
+ if($(this).hasClass('trigger')) {
+ appendIndex = $(this).closest('.controls').find('.input-append').length;
+ nameNumber = $(this).closest('.controls').find('.input-append:eq(0)').find('input').eq(0).attr('name');
+ nameNumber = nameNumber.match(/[^[\D\]]+(?=])/g)[0];
+ propertyType = $(this).data('properties')
+ if($(this).hasClass('textInput')) {
+ $("#template-text").tmpl().appendTo($(this).closest('.controls').find('.add-target'));
+ } else if ($(this).hasClass('textLengInput')) {
+ $("#template-text-language").tmpl().appendTo($(this).closest('.controls').find('.add-target'));
+ } else if ($(this).hasClass('address')) {
+ $("#template-address").tmpl().appendTo($(this).closest('.controls').find('.add-target'));
+ }
+ inputAppendLength();
+ };
+ event.preventDefault();
+ });
+ inputAppendLength();
+ } else {
+ attributesArray = [];
+ attributesHeaderLength = null;
+ templateType = null;
+ attributeIndex = null;
+ if($('.add-target').length) {
+ inputAppendLength();
+ }
+ if(!$('.attributes').length) {
+ $('#attributes-area').addClass('clickHere');
+ } else {
+ temporary();
+ };
+
+ $('.add-attributes').on(clickEvent, function() {
+ if($('#attributes-area').hasClass('clickHere')) {
+ $('#attributes-area').removeClass('clickHere');
+ };
+ attributesHeaderLength = $('.attributes:not(:hidden)').length+1;
+ attributesLength = $('#attributes-area .attributes').length;
+ if(templateType == null){
+ templateType = "typeA";
+ }
+ $("#template-attributes").tmpl(setData(attributesLength, templateType, appendIndex)).appendTo( "#attributes-area" );
+ $('.toggle-check').togglebox();
+ });
+
+
+
+ $('.attributes.default').each(function(i) {
+ $(this).children('.field-type').not('.default').hide();
+ $(this).find('input[type="text"]').on('keyup', function() {
+ $(this).trigger("checking");
+ });
+ $(this).find('input[type="radio"], input[type="checkbox"], select').change(function() {
+ $(this).trigger("checking");
+ });
+ $(this).delegate('input[type="text"], input[type="radio"], input[type="checkbox"], select', 'checking', function(e) {
+ var e = e.target.type,
+ $data = $(this).data().type;
+ switch(e) {
+ case 'text':
+ var val = $(this).val();
+ if(!$(this).closest('.field-type').length) {
+ $data = attributesArray[i][$data];
+ } else if(!$(this).closest('.add-target').length) {
+ $data = attributesArray[i].select[$data];
+ } else {
+ appendIndex = $(this).parent('.input-append').index()
+ optionIndex = $(this).index()
+ $data = attributesArray[i].select.option[appendIndex][optionIndex];
+ }
+ if(val != $data) {
+ $(this).closest('.attributes').find('.reply').removeClass('hide');
+ }
+ break;
+ case 'radio':
+ var checked = $(this).prop("checked");
+ $data = attributesArray[i][$data];
+ if(checked != $data) {
+ $(this).closest('.attributes').find('.reply').removeClass('hide');
+ }
+ break;
+ case 'checkbox':
+ var checked = $(this).prop("checked");
+ $data = attributesArray[i].select[$data];
+ if(checked != $data) {
+ $(this).closest('.attributes').find('.reply').removeClass('hide');
+ }
+ break;
+ case 'select-one':
+ var ref,
+ $data = attributesArray[i].select.name;
+ $(this).children("option:selected").each(function() {
+ ref = $(this).attr('ref');
+ });
+ if(ref != $data) {
+ $(this).closest('.attributes').find('.reply').removeClass('hide');
+ }
+ break;
+ };
+ });
+ $(this).delegate('.reply', clickEvent, function() {
+ var $bodyText = $(this).parent('.attributes-header').siblings('.attributes-body').find('input[type="text"]'),
+ $bodyRadio = $(this).parent('.attributes-header').siblings('.attributes-body').find('input[type="radio"]'),
+ $bodySelected = $(this).parent('.attributes-header').siblings('.attributes-body').find('.dataType').children("option"),
+ $fieldTypeO = $(this).parent('.attributes-header').siblings('.field-type.default'),
+ $fieldTypeN = $(this).parent('.attributes-header').siblings('.field-type').not('.default');
+ $bodyText.each(function() {
+ var $type = $(this).data().type;
+ $(this).val(attributesArray[i][$type]);
+ });
+ $bodyRadio.each(function() {
+ var $type = $(this).data().type;
+ $(this).prop("checked", attributesArray[i][$type])
+ });
+ $fieldTypeO.find('input[type="text"]').each(function() {
+ var $type = $(this).data().type;
+ if(!$type.match('option_lang')) {
+ $(this).val(attributesArray[i].select[$type]);
+ }
+ });
+ $fieldTypeO.find('.add-target').find('.input-append').each(function(k) {
+ $(this).children('input[type="text"]').each(function(j) {
+ $(this).val(attributesArray[i].select.option[k][j]);
+ // var val = $(this).val();
+ // append.push(val);
+ });
+ })
+ $fieldTypeO.find('input[type="checkbox"], input[type="radio"]').each(function() {
+ var $type = $(this).data().type;
+ $(this).prop("checked", attributesArray[i].select[$type]);
+ });
+ $fieldTypeO.find('select').children("option").eq(attributesArray[i].select.dateFormat).prop('selected',true);
+ $bodySelected.eq(attributesArray[i].select.index).prop('selected',true);
+ $fieldTypeO.show();
+ $fieldTypeN.empty().hide();
+ $(this).addClass('hide')
+ return false
+ })
+ });
+ $('#attributes-area').delegate('.togglebox, .delete, .trigger, .remove-input', clickEvent, function(event) {
+ if($(this).hasClass('togglebox')) {
+ if($(this).hasClass('disable')) {
+ $(this).find('.toggle-check')
+ .attr('value', 'false')
+ .closest('.attributes')
+ .removeClass('disabled')
+ .find('input, select')
+ .removeAttr('disabled')
+ .end('.attributes')
+ .find('.btn-group .btn')
+ .removeClass('disabled')
+ .end().find('.attribute_field_disabled').attr('value', 'false');
+ if($(this).closest('.attributes').find('.dataType').children("option:selected").attr('ref')) {
+ $(this).closest('.attributes').find('.field-type').addClass('in').find('.control-group').delay(150).fadeIn(300);
+ }
+ } else {
+ $(this).find('.toggle-check')
+ .attr('value', 'true')
+ .closest('.attributes')
+ .addClass('disabled')
+ .find('.attributes-body input, .attributes-body select')
+ .attr({'disabled': 'disabled'})
+ .end('.attributes')
+ .find('.btn-group .btn')
+ .addClass('disabled')
+ .end().find('.attribute_field_disabled').attr('value', 'true')
+ .end().find('.field-type .control-group').fadeOut(300, function() {
+ $(this).parent('.field-type').removeClass('in');
+ });
+ }
+ $(this).toggleClass('disable');
+ };
+ if($(this).hasClass('delete')) {
+ $(this).closest('.attributes').fadeOut(300, function() {
+ $('.attributes:not(:hidden)').each(function(i) {
+ $(this).find('.attributes-header h4 span').text(i+1);
+ });
+ attributesHeaderLength = $('.attributes:not(:hidden)').length+1;
+ if(!$('.attributes:not(:hidden)').length) {
+ $('#attributes-area').addClass('clickHere');
+ };
+ }).find('.attribute_field_to_delete').attr('value', 'true');;
+ };
+ if($(this).hasClass('trigger')) {
+ // appendIndex = $(this).closest('.controls').find('.input-append').length;
+ appendIndex = $(this).closest('.controls').find('.input-append:last-child').children('input:first-child').attr('name');
+ // appendIndex = appendIndex.split("][");
+ // appendIndex = parseInt(appendIndex[appendIndex.length-2])+1;
+ appendIndex = parseInt(appendIndex.match(/[^[\D\]]+(?=])/g)[1])+1;
+ attributeIndex = $(this).closest('.attributes').index();
+ templateType = $(this).closest('.attributes').find('.dataType').children("option:selected").attr('ref');
+ $("#template-input-append").tmpl(setData(attributeIndex, templateType, appendIndex)).appendTo($(this).closest('.controls').find('.add-target'));
+ inputAppendLength();
+ };
+ if($(this).hasClass('remove-input')) {
+ $(this).parent('.input-append').fadeOut(300, function() {
+ $(this).remove()
+ inputAppendLength();
+ });
+
+ }
+ event.preventDefault();
+ });
+ $('#attributes-area').delegate('.dataType', 'change', function() {
+ $(this).children("option:selected").each(function () {
+ var target = $(this).closest('.attributes').find('.field-type').not('.default');
+ attributeIndex = $(this).closest('.attributes').index();
+ appendIndex = 0
+ // $(this).closest('.attributes').find('.add-target').find('.input-append').length;
+ if($(this).closest('.attributes').hasClass('default')){
+ var i = $(this).closest('.attributes').index()
+ if($(this).attr('ref') == attributesArray[i].select.name) {
+ $(this).closest('.attributes').find('.field-type.default').show()
+ target.empty().hide();
+ } else {
+ $(this).closest('.attributes').find('.field-type.default').hide()
+ if($(this).attr('ref')) {
+ templateType = $(this).attr('ref');
+ target.removeAttr('class').addClass('field-type fade in ' + templateType).empty();
+ $("#template-type").tmpl(setData(attributeIndex, templateType, appendIndex)).appendTo(target);
+ if(templateType == 'typeB' || templateType == 'typeE' || templateType == 'typeF') {
+ inputAppendLength();
+ }
+ } else {
+ target.removeAttr('class').addClass('field-type fade')
+ target.empty();
+ };
+ target.show();
+ }
+ } else {
+ if($(this).attr('ref')) {
+ templateType = $(this).attr('ref');
+ target.removeAttr('class').addClass('field-type fade in ' + templateType).empty();
+ $("#template-type").tmpl(setData(attributeIndex, templateType, appendIndex)).appendTo(target);
+ if(templateType == 'typeB' || templateType == 'typeE' || templateType == 'typeF') {
+ inputAppendLength();
+ }
+ } else {
+ target.removeAttr('class').addClass('field-type fade')
+ target.empty();
+ };
+ }
+ });
+ });
+ }
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/property_hire_calendar_frontend.js b/app/assets/javascripts/property_hire_calendar_frontend.js
index 750f25a..a48237e 100644
--- a/app/assets/javascripts/property_hire_calendar_frontend.js
+++ b/app/assets/javascripts/property_hire_calendar_frontend.js
@@ -65,6 +65,7 @@ window.datetime_format = is_chinese ? 'y M d h:m b' : 'd M, y h:m b';
window.date_format = is_chinese ? 'y M d' : 'd M, y';
window.time_format = "h:m b";
window.date_time_str_format = 'y/MM/d H:m';
+window.std_date_format = 'y-MM-d';
window.short_day = (is_chinese ? "d (w)" : "w d")
window.short_date = (is_chinese ? "M d (w)" : "w d, M")
window.getDateString = function(date, format,is_chinese) {
@@ -173,9 +174,19 @@ var Calendar = function(dom,property_id,currentView){
if(calEvent.jsEvent && !e){
e = {"originalEvent": calEvent.jsEvent}
}
- c.dialog.dismiss();
- c.dialog.inflate(calEvent);
- c.dialog.show({"x":e.originalEvent.clientX,"y":e.originalEvent.clientY});
+ var el = $(calEvent.el);
+ if(el.hasClass("reserve_btn")){
+ window.calEvent = calEvent;
+ var start_time = calEvent.event.start;
+ var date_str = window.getDateString(start_time,std_date_format);
+ var allow_times = calEvent.event._def.extendedProps.allow_times;
+ console.log(date_str)
+ window.pick_hire_date(date_str,allow_times);
+ }else{
+ c.dialog.dismiss();
+ c.dialog.inflate(calEvent);
+ c.dialog.show({"x":e.originalEvent.clientX,"y":e.originalEvent.clientY});
+ }
},
dateClick: function(ev) {
var calendar = this;
@@ -335,10 +346,15 @@ var EventDialog = function(calendar,event){
this.show = function(pos){
- event_quick_view.css({width: '',height: ''});
+ event_quick_view.css({display: 'inline-block',width: '',height: '', position: "fixed", "z-index": "10000"});
+ var offset;
+ var padding = 20;
if(pos){
+ offset = {"left":pos.x,"top":pos.y};
var pos = getPosition(pos);
- event_quick_view.css({"left":pos.x+"px","top":pos.y+"px"});
+ event_quick_view.offset(offset);
+ }else{
+ offset = {"left": padding, "top": padding};
}
event_quick_view.html(template).appendTo("body").show();
event_quick_view.find(".event-close-btn").one("click",function(){_t.dismiss();});
@@ -346,13 +362,12 @@ var EventDialog = function(calendar,event){
event_quick_view.find("a.edit").one("click",function(){calendar.editEvent(_this_event.edit_url,_this_event.allDay);return false;});
var window_width = $(window).width(),
window_height = $(window).height();
- var offset = event_quick_view.offset();
var dialog_width = event_quick_view.width(),
dialog_height = event_quick_view.height();
var new_offset = Object.assign({},offset);
var need_redisplay = false;
var new_width = null, new_height = null;
- var padding = 20;
+ var padding_top = padding + 40;
if(offset.left + dialog_width > window_width){
new_offset.left = window_width - dialog_width - padding;
need_redisplay = true;
@@ -366,9 +381,9 @@ var EventDialog = function(calendar,event){
new_offset.top = window_height - dialog_height - padding;
need_redisplay = true;
}
- if(new_offset.top < padding){
- new_height = dialog_height - (padding - new_offset.top);
- new_offset.top = padding;
+ if(new_offset.top < padding_top){
+ new_height = dialog_height - (padding_top - new_offset.top);
+ new_offset.top = padding_top;
need_redisplay = true;
}
if(need_redisplay){
diff --git a/app/assets/stylesheets/admin/card.scss b/app/assets/stylesheets/admin/card.scss
new file mode 100644
index 0000000..6b7183b
--- /dev/null
+++ b/app/assets/stylesheets/admin/card.scss
@@ -0,0 +1,140 @@
+.card {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ min-width: 0;
+ word-wrap: break-word;
+ background-color: #fff;
+ background-clip: border-box;
+ border: 1px solid rgba(0,0,0,.125);
+ border-radius: .25rem;
+}
+
+.card hr {
+ margin-right: 0;
+ margin-left: 0;
+}
+
+.card-header {
+ padding: .75rem 1.25rem;
+ margin-bottom: 0;
+ background-color: rgba(0,0,0,.03);
+ border-bottom: 1px solid rgba(0,0,0,.125);
+}
+
+.card-header:first-child {
+ border-radius: calc(.25rem - 1px) calc(.25rem - 1px) 0 0;
+}
+
+.card-body {
+ align-items: normal;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 1 auto;
+ flex: 1 1 auto;
+ padding: 1.25rem;
+}
+
+.card-title {
+ margin-bottom: .75rem;
+}
+
+.card-header + .list-group .list-group-item:first-child {
+ border-top: 0;
+}
+
+.card-text:last-child {
+ margin-bottom: 0;
+}
+
+.card-footer {
+ padding: .75rem 1.25rem;
+ background-color: rgba(0,0,0,.03);
+ border-top: 1px solid rgba(0,0,0,.125);
+}
+
+.card-footer:last-child {
+ border-radius: 0 0 calc(.25rem - 1px) calc(.25rem - 1px);
+}
+
+.card-group {
+ display: flex;
+ flex-direction: column;
+ // The child selector allows nested `.card` within `.card-group`
+ // to display properly.
+ > .card {
+ margin-bottom: 0.9375em;
+ }
+
+ @media screen and (min-width: 576px) {
+ flex-flow: row wrap;
+ // The child selector allows nested `.card` within `.card-group`
+ // to display properly.
+ > .card {
+ flex: 1 0 0%;
+ margin-bottom: 0;
+
+ + .card {
+ margin-left: 0;
+ border-left: 0;
+ }
+
+ &:first-child {
+ border-right-radius: 0;
+
+ .card-img-top,
+ .card-header {
+ border-top-right-radius: 0;
+ }
+
+ .card-img-bottom,
+ .card-footer {
+ border-bottom-right-radius: 0;
+ }
+ }
+
+ &:last-child {
+ border-left-radius: 0;
+
+ .card-img-top,
+ .card-header {
+ border-top-left-radius: 0;
+ }
+
+ .card-img-bottom,
+ .card-footer {
+ border-bottom-left-radius: 0;
+ }
+ }
+
+ &:only-child {
+ border-radius: .25rem;
+
+ .card-img-top,
+ .card-header {
+ border-top-radius: .25rem;
+ }
+
+ .card-img-bottom,
+ .card-footer {
+ border-radius: .25rem;
+ }
+ }
+
+ &:not(:first-child):not(:last-child):not(:only-child) {
+ border-radius: 0;
+
+ .card-img-top,
+ .card-img-bottom,
+ .card-header,
+ .card-footer {
+ border-radius: 0;
+ }
+ }
+ }
+ }
+}
diff --git a/app/assets/stylesheets/admin/properties.css b/app/assets/stylesheets/admin/properties.css
new file mode 100644
index 0000000..f08ea35
--- /dev/null
+++ b/app/assets/stylesheets/admin/properties.css
@@ -0,0 +1,79 @@
+ /*reset*/
+h1, h2, h3, h4, h5, p{
+ margin: 0;
+ padding: 0;
+}
+br{
+ display: block;
+ margin: 0 0 5px;
+}
+ol, ul{
+ margin: 0;
+ padding: 0;
+}
+li{
+ list-style: none;
+}
+body > img {
+ display: none;
+}
+
+img{
+ border: none;
+ padding: 0;
+ margin: 0;
+}
+
+a {
+ outline: none;
+ text-decoration: none !important;
+}
+
+table, tr, td{
+ padding: 0;
+ border-spacing: 0;
+}
+
+/*reset end *//* CSS Document */
+
+#property_order_table{
+ border-collapse: unset !important;
+ position: relative;
+ width: 593px;
+ margin: 40px auto;
+}
+
+#property_order_table th{
+ background-color: #454545;
+ color: #fff;
+}
+.position-text{
+ position: relative;
+ width: 85px;
+}
+
+#property_order_table .editable-input{
+ position: relative;
+ width: 25px;
+ margin-bottom: 0;
+ padding: 0px 0px 0px 5px;
+}
+
+.position-text-div{
+ height: 22px;
+}
+
+.order-edit-notification{
+ background-color: #ffffd5;
+ z-index: 10;
+ display: none;
+ height: 25px;
+ left: 40%;
+ position: fixed;
+ text-align: center;
+ margin-top: 5px;
+ top: 85px;
+ width: 400px;
+ font-size: 13px;
+}
+
diff --git a/app/assets/stylesheets/property_hire_calendar.scss b/app/assets/stylesheets/property_hire_calendar.scss
index a4c85bf..6beb81c 100644
--- a/app/assets/stylesheets/property_hire_calendar.scss
+++ b/app/assets/stylesheets/property_hire_calendar.scss
@@ -6,6 +6,9 @@
background: var(--fc-highlight-color, rgba(188, 232, 241, 0.3));
}
}
+a.reserve_btn{
+ cursor: pointer;
+}
/* orbit calendar */
#orbit_calendar {
transition: all 0.3s ease;
diff --git a/app/controllers/admin/property_hires_controller.rb b/app/controllers/admin/property_hires_controller.rb
index f984d5f..02d428d 100644
--- a/app/controllers/admin/property_hires_controller.rb
+++ b/app/controllers/admin/property_hires_controller.rb
@@ -12,7 +12,20 @@ class Admin::PropertyHiresController < OrbitAdminController
@properties = search_data(@properties,[:title]).page(params[:page]).per(10)
end
-
+ def order
+ @properties = Property.all.sort_order
+ end
+ def updateorder
+ ids_with_order = params[:order]
+ ids_with_order.each_with_index do |id,idx|
+ property = Property.find(id) rescue nil
+ if !property.nil?
+ property.order_position = idx
+ property.save
+ end
+ end
+ render :json => {"success" => true}.to_json
+ end
def my_bookings
@table_fields = ["property_hire.title","property_hire.hiring_person_name", "property_hire.reason_for_hire", "property_hire.hiring_person_number", "property_hire.period", "property_hire.passed", :actions]
@bookings = PHire.where(:hiring_person_id => current_user.member_profile.id.to_s).desc(:created_at).page(params[:page]).per(10)
@@ -61,14 +74,27 @@ class Admin::PropertyHiresController < OrbitAdminController
def update
property = Property.where(:uid => params[:id].split("-").last).first rescue nil
redirect_to admin_property_hires_path and return if property.nil?
- property.update_attributes(property_params)
- email = Array(MemberProfile.find(property.owners)).collect{|v| v.email} rescue []
- email = User.all.select{|v| v.is_admin? && v.user_name != 'rulingcom'}.collect{|v| v.member_profile.email} if email.length == 0
- Admin::PropertyHiresHelper::HireMethod.send_mail('edit',email,property.id,nil,nil,current_user.id)
- if params[:page]
- redirect_to admin_property_hires_path(:page => params[:page],:locale => params[:locale])
+ @property_params = property_params
+ if @property_params[:p_hire_fields]
+ @property_params[:p_hire_fields].each do |a|
+ @field_name = 'property'
+ field_status = a.last[:id].present?
+ @attribute_field = PHireField.add_p_hire_field(property, a.last, a.last[:id], field_status)
+ @attribute = property
+ end
+ flash.now[:notice] = "Updated Fields"
+ property.p_hire_fields.each{|t| t.destroy if t["to_delete"] == true}
+ redirect_to admin_property_hires_path(:locale => params[:locale]) and return
else
- redirect_to admin_property_hires_path(:locale => params[:locale])
+ property.update_attributes(@property_params)
+ email = Array(MemberProfile.find(property.owners)).collect{|v| v.email} rescue []
+ email = User.all.select{|v| v.is_admin? && v.user_name != 'rulingcom'}.collect{|v| v.member_profile.email} if email.length == 0
+ Admin::PropertyHiresHelper::HireMethod.send_mail('edit',email,property.id,nil,nil,current_user.id)
+ if params[:page]
+ redirect_to admin_property_hires_path(:page => params[:page],:locale => params[:locale])
+ else
+ redirect_to admin_property_hires_path(:locale => params[:locale])
+ end
end
end
@@ -175,7 +201,13 @@ class Admin::PropertyHiresController < OrbitAdminController
end
end
end
-
+ def custom_fields
+ @field_name = 'property'
+ uid = params[:id].split("-").last
+ @attribute = Property.find_by(:uid=>uid)
+ @attribute_type = 'property'
+ @class = 'properties'
+ end
private
def settings_params
@@ -190,6 +222,9 @@ class Admin::PropertyHiresController < OrbitAdminController
end
def property_params
prop = params.require(:property).permit!
+ if prop[:weekdays].nil?
+ prop[:weekdays] = []
+ end
prop.delete(:property_location) if prop[:property_location] == "other"
notes_selector = prop["notes_selector"]
notes_selector = {} if notes_selector.nil?
diff --git a/app/controllers/property_hires_controller.rb b/app/controllers/property_hires_controller.rb
index 9a31955..994e2ef 100644
--- a/app/controllers/property_hires_controller.rb
+++ b/app/controllers/property_hires_controller.rb
@@ -1,26 +1,34 @@
class PropertyHiresController < ApplicationController
include Admin::PropertyHiresHelper
def index
- properties = Property.filter_by_categories.filter_by_tags.desc(:created_at)
+ properties = Property.filter_by_categories.filter_by_tags.sort_order
data = properties.collect do |property|
actions = []
+ url_to_show = OrbitHelper.url_to_show(property.to_param)
if property.can_be_hired
+ hire_url = url_to_show + "?method=hire"
+ puts url_to_show
actions << {
"text" => t("property_hire.hire"),
"btn-class" => "btn-primary",
- "link" => OrbitHelper.url_to_show(property.to_param) + "?method=hire"
- }
- actions << {
- "text" => t("property_hire.view_calendar"),
- "btn-class" => "btn-info",
- "link" => OrbitHelper.url_to_show(property.to_param) + "?method=view_calendar"
+ "link" => hire_url
}
+ unless property.disable_view_calendar_page
+ actions << {
+ "text" => t("property_hire.view_calendar"),
+ "btn-class" => "btn-info",
+ "link" => url_to_show + "?method=view_calendar"
+ }
+ end
+ if property.disable_content_page
+ url_to_show = hire_url
+ end
end
{
"title" => property.title,
"image" => (property.image.url.blank? ? '" style="display: none;' : property.image.url),
"image-thumb" => (property.image.thumb.url.blank? ? '" style="display: none;' : property.image.thumb.url),
- "url_to_show" => OrbitHelper.url_to_show(property.to_param),
+ "url_to_show" => url_to_show,
"location" => property.get_location_name,
"actions" => actions
}
@@ -159,9 +167,25 @@ class PropertyHiresController < ApplicationController
def make_booking
booking_p = booking_params
- data = check_for_availability(booking_p[:start_time],booking_p[:end_time],booking_p[:property_id], booking_p[:recurring_interval], booking_p[:recurring_end_date])
+ time_setting_id = booking_p[:time]
+ start_time = booking_p[:start_time]
+ end_time = booking_p[:end_time]
+ time_setting = nil
+ if time_setting_id.present?
+ start_time = booking_p[:date]
+ end_time = start_time
+ time_setting = PropertyDaySetting.find(time_setting_id)
+ end
+ data = check_for_availability(start_time,end_time,booking_p[:property_id], booking_p[:recurring_interval], booking_p[:recurring_end_date], time_setting_id)
property = Property.find(booking_p[:property_id]) rescue nil
if data["success"] == true
+ if time_setting_id.present?
+ booking_p[:start_time] = booking_p[:date] + " " + time_setting.start_time
+ booking_p[:end_time] = booking_p[:date] + " " + time_setting.end_time
+ booking_p[:property_day_setting_id] = booking_p[:time]
+ booking_p.delete(:time)
+ booking_p.delete(:date)
+ end
hire = PHire.new(booking_p)
hire.passed = true if PropertyHireSetting.auto_approve_enabled?
hire.save
@@ -197,7 +221,8 @@ class PropertyHiresController < ApplicationController
end
def check_availability
- data = check_for_availability params[:stime], params[:etime], params[:property_id], params[:interval], params[:recurring_end_date]
+ time_setting_id = params[:time_setting_id]
+ data = check_for_availability params[:stime], params[:etime], params[:property_id], params[:interval], params[:recurring_end_date], time_setting_id
render :json => data.to_json
end
@@ -210,7 +235,23 @@ class PropertyHiresController < ApplicationController
edt = Time.at(params[:end].to_i)
events = PHire.monthly_event(sdt,edt,params[:property_id])
re = PHire.recurring_event(sdt,edt,params[:property_id])
+ events = events.map{|e| e.as_json}
allevents = events.inject(re, :<<)
+ @need_check_events = allevents.map{|e| [Date.parse(e[:start].split("T")[0]),e[:s_id]]}
+ if property.set_availability
+ all_day_settings = property.property_day_settings.asc(:key).group_by(&:day).map{|d,settings| [d,settings.map{|s| [s.start_time,s.end_time,s.id.to_s,s.title,s.reservation_limit]}]}.to_h
+ if all_day_settings.count != 0
+ time_now = Time.now
+ get_start_time = [sdt,time_now].max
+ get_end_time = edt
+ if property.set_unavailibility
+ if property.can_hire_before_months != 0
+ get_end_time = [time_now + (property.can_hire_before_months).send("month"),edt].min
+ end
+ allevents += generate_all_reserve_buttons(get_start_time,get_end_time,all_day_settings)
+ end
+ end
+ end
end
end
respond_to do |format|
@@ -218,12 +259,124 @@ class PropertyHiresController < ApplicationController
format.json { render json: allevents.to_json }
end
end
-
+ def reserve_calendar_event(date,title,allow_times)
+ {:title=>title, :start=>date.to_s, :end => (date + 1.day).to_s, :allDay => true, :color => "#3788d8",:allow_times=>allow_times,:classNames=>["reserve_btn"]}
+ end
+ def generate_all_reserve_buttons(startt,endt,all_day_settings)
+ @display_title = I18n.t("property_hire.reserve")
+ @allevents = []
+ start_wday = startt.wday
+ end_flag = false
+ start_date = startt.to_date
+ @start_date = start_date
+ end_date = endt.to_date
+ @end_date = end_date
+ @first_check_time = startt.strftime("%H:%M")
+ @all_day_settings = all_day_settings
+ @startt = startt
+ @endt = endt
+ print all_day_settings
+ puts nil
+ def generate_events(start_wday,end_wday,type=0)
+ if type == 0
+ (start_wday..end_wday).each do |wday|
+ wday_str = wday.to_s
+ is_start_day = (start_wday == wday)
+ if @all_day_settings.has_key?(wday_str)
+ check_time = nil
+ check_time = @first_check_time if is_start_day
+ i = @need_check_events.index{|e| e[0] > @start_date}
+ if i.nil?
+ i = -1
+ elsif i != -1
+ i -= 1
+ end
+ check_events = []
+ if i != -1
+ check_events = @need_check_events[0..i]
+ end
+ @need_check_events = @need_check_events[(i+1)..-1]
+ settings = @all_day_settings[wday_str]
+ if check_events.count != 0
+ settings = settings.select do |s|
+ flag = true
+ if check_time
+ if check_time > s[1]
+ flag = false
+ end
+ end
+ if flag
+ if s[3] == 0 #reservation_limit == 0 => no limit
+ true
+ else
+ @need_check_events.select{|e| e[1] == s[2] }.count <= s[3]
+ end
+ else
+ false
+ end
+ end
+ end
+ if settings.count != 0
+ @allevents << reserve_calendar_event(@start_date,@display_title,settings)
+ end
+ end
+ @start_date += 1.day
+ if @start_date > @end_date
+ end_flag = true
+ break
+ end
+ end
+ else
+ @all_day_settings.each do |wday_str,settings|
+ tmp_date = @start_date + wday_str.to_i.send("day")
+ check_time = "00:00"
+ i = @need_check_events.index{|e| e[0] > tmp_date}
+ if i.nil?
+ i = -1
+ elsif i != -1
+ i -= 1
+ end
+ check_events = []
+ if i != -1
+ check_events = @need_check_events[0..i]
+ end
+ @need_check_events = @need_check_events[(i+1)..-1]
+ if check_events.count != 0
+ settings = settings.select do |s|
+ @need_check_events.select{|e| e[1] == s[2] }.count == 0
+ end
+ end
+ if settings.count != 0
+ @allevents << reserve_calendar_event(tmp_date,@display_title,settings)
+ end
+ end
+ @start_date += 7.day
+ end
+ end
+ all_days = (end_date-start_date).to_i
+ end_wday = 6
+ end_date_wday = end_date.wday
+ only_first_week = false
+ if (start_wday + all_days <= 6)
+ end_wday = end_date_wday
+ only_first_week = true
+ end
+ generate_events(start_wday,end_wday)
+ unless only_first_week
+ all_days = all_days - (end_wday - start_wday)
+ while all_days > 6 do
+ generate_events(0,6)
+ all_days -= 7
+ end
+ generate_events(0,all_days)
+ end
+ @allevents
+ end
private
def booking_params
p_hire_params = params.require(:p_hire).permit!
- property = Property.find(params[:property_id]) rescue Property.last
+ property = Property.find(params[:p_hire][:property_id]) rescue Property.last
if(property.enable_notes_selector rescue false)
note_texts = ""
property.notes_selector.each do |index,sub_hash|
@@ -231,7 +384,7 @@ class PropertyHiresController < ApplicationController
name = sub_hash["name"].values.select{|v| v.present?}.first.to_s if name.blank?
values = sub_hash["value"][I18n.locale.to_s]
values = sub_hash["value"].values.select{|v| v.present?}.first.to_s if values.blank?
- value_text = p_hire_params["notes_selector"][index.to_s].to_a.map{|i| values[i.to_i]}.join(",")
+ value_text = p_hire_params["notes_selector"][index.to_s].to_a.map{|i| values[i.to_i]}.join(",") rescue ""
value_text = I18n.t("property_hire.none") if value_text.blank?
note_texts += (name + ":"+value_text)
note_texts += "
".html_safe
diff --git a/app/helpers/admin/p_hire_field_helper.rb b/app/helpers/admin/p_hire_field_helper.rb
new file mode 100644
index 0000000..fbf99f0
--- /dev/null
+++ b/app/helpers/admin/p_hire_field_helper.rb
@@ -0,0 +1,555 @@
+module Admin::PHireFieldHelper
+
+ include ActionView::Helpers::FormTagHelper
+ include ActionView::Helpers::FormOptionsHelper
+ include ActionView::Helpers::DateHelper
+ include ActionView::Helpers::TagHelper
+ include ActionView::Helpers::RenderingHelper
+ include ActionView::Context
+ include OrbitBasis::RenderAnywhere
+
+ include OrbitFormHelper
+
+ def block_helper(member,index,disable = false,attribute_type=nil,p_hire=nil, to_require=true, col=2)
+ unless self.disabled
+ @col = col
+ @index = index
+ @require = to_require
+ @markup_options = markup_options.merge(:disabled=>disable, :required => to_require)
+ @member = member
+ @attribute_value = @member.get_value_from_field_id(id,p_hire)
+ @attribute_type = attribute_type
+ @new_attribute = @attribute_value.nil?
+ @attribute_value = @attribute_value || p_hire.p_hire_field_values.build(p_hire_field_id: id)
+ @prefiled_value = @attribute_value.value rescue nil
+ return instance_eval("render_#{markup}") rescue ""
+ end
+ end
+
+ def lang_tab(str,lang)
+ content_tag(:div,str,:class=>"tab-pane fade",:id=>(get_field_name_base+"tab_#{lang}"))
+ end
+ def render_hint_text
+ control_group_wrapper do |key,value|
+ if !@prefiled_value.nil?
+ value = can_muti_lang_input? ? @prefiled_value[key] : @prefiled_value
+ else
+ value = nil
+ end
+ key = can_muti_lang_input? ? "#{key}" : I18n.locale
+ place_holder= typeF["placeholder"][key] rescue ''
+ name1 = ""
+ text_area_tag(name1, place_holder,@markup_options.merge(:class=>'input-medium form-control',:readonly=>"",:rows=>"4"))
+ end
+ end
+ def render_address
+ control_group_wrapper do |key,value|
+ value = (can_muti_lang_input? ? @prefiled_value[key] : @prefiled_value) rescue nil
+ key_field = can_muti_lang_input? ? "[#{key}]" : ""
+ place_holder= @panel_setting["placeholder"][key] rescue ''
+ # result = text_area_tag(get_field_name_base + key_field, value,@markup_options.merge({:placeholder=>place_holder,:for=>key}))
+ result = text_field_tag(get_field_name_base + key_field, value,@markup_options.merge({:placeholder=>place_holder,:for=>key}))
+
+ add_ext= @attribute_value.address_key[key] rescue {}
+
+ result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][county]",add_ext["county"],:class=>"county_#{key}", :id=>nil)
+ result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][street_address]",add_ext["street_address"],:class=>"street_address_#{key}", :id=>nil)
+ result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][city]",add_ext["city"],:class=>"city_#{key}", :id=>nil)
+ result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][zip]",add_ext["zip"],:class=>"zip_#{key}", :id=>nil)
+ result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][country]",add_ext["country"],:class=>"country_#{key}", :id=>nil)
+ result << hidden_field_tag(get_basic_field_name_base+"[address_key][#{key}][indicator]",add_ext["indicator"],:class=>"indicator_#{key}", :id=>nil)
+ end
+ end
+
+ def render_checkbox
+ @prefiled_value ||=[]
+ control_group_wrapper do
+ a = self.typeE[:option_list].collect do |key,value|
+ label_tag("#{get_basic_field_name_org}_#{self.id}_#{key}",check_box_tag(get_field_name_base+"[#{key}]", true , (@prefiled_value.include?(key) ? true : false), { :id=>"#{get_basic_field_name_org}_#{self.id}_#{key}"})+value[I18n.locale.to_s],@markup_options.merge(:class=>"checkbox inline"))
+ end.join.html_safe rescue ""
+ end
+ end
+
+ def render_date
+ d = DateTime.now()
+
+ if date_is_range?
+ # fill_from = @attribute_value.get_date(:from) rescue nil
+ # fill_to = @attribute_value.get_date(:to) rescue nil
+ control_group_wrapper do
+
+ case self.typeC['format']
+ when 'format1'
+ fill_from = (@prefiled_value && @prefiled_value["from"] ) ? @prefiled_value["from"] : d.strftime("%Y/%m/%d %H:%M")
+ fill_to = (@prefiled_value && @prefiled_value["to"] ) ? @prefiled_value["to"] : d.strftime("%Y/%m/%d %H:%M")
+ buf = datetime_picker(get_field_name_base+'[from]', fill_from, 'yyyy/MM/dd hh:mm', true)
+ buf << ' ~ '
+ buf << datetime_picker(get_field_name_base+'[to]', fill_to, 'yyyy/MM/dd hh:mm', true)
+ when 'format2'
+ fill_from = (@prefiled_value && @prefiled_value["from"] ) ? @prefiled_value["from"] : d.strftime("%Y/%m/%d")
+ fill_to = (@prefiled_value && @prefiled_value["to"] ) ? @prefiled_value["to"] : d.strftime("%Y/%m/%d")
+ buf = datetime_picker(get_field_name_base+'[from]', fill_from, 'yyyy/MM/dd')
+ buf << ' ~ '
+ buf << datetime_picker(get_field_name_base+'[to]', fill_to, 'yyyy/MM/dd')
+ when 'format3'
+ fill_from = (@prefiled_value && @prefiled_value["from"] ) ? @prefiled_value["from"] : d.strftime("%Y/%m")
+ fill_to = (@prefiled_value && @prefiled_value["to"] ) ? @prefiled_value["to"] : d.strftime("%Y/%m/")
+ buf = datetime_picker(get_field_name_base+'[from]', fill_from, 'yyyy/MM')
+ buf << ' ~ '
+ buf << datetime_picker(get_field_name_base+'[to]', fill_to, 'yyyy/MM')
+ when 'format4'
+ fill_from = (@prefiled_value && @prefiled_value["from"] ) ? @prefiled_value["from"] : d.strftime("%Y")
+ fill_to = (@prefiled_value && @prefiled_value["to"] ) ? @prefiled_value["to"] : d.strftime("%Y")
+ buf = datetime_picker(get_field_name_base+'[from]', fill_from, 'yyyy')
+ buf << ' ~ '
+ buf << datetime_picker(get_field_name_base+'[to]', fill_to, 'yyyy')
+ end
+
+ # buf = date_select(get_field_name_base+'[from]',nil,@markup_options.merge(:default=>fill_from),:class=>"input-small")
+ # buf << ' ~ '
+ # buf << date_select(get_field_name_base+'[to]',nil,@markup_options.merge(:default=>fill_to),:class=>"input-small")
+ buf
+ end
+ else
+ # @prefiled_value = @attribute_value.get_date
+ # @prefiled_value = @attribute_value.get_date
+
+ case self.typeC['format']
+ when 'format1'
+ tmp = datetime_picker(get_field_name_base, (@prefiled_value ? @prefiled_value : d.strftime("%Y/%m/%d %H:%M")), 'yyyy/MM/dd hh:mm', true)
+ when 'format2'
+ tmp = datetime_picker(get_field_name_base, (@prefiled_value ? @prefiled_value : d.strftime("%Y/%m/%d")), 'yyyy/MM/dd')
+ when 'format3'
+ tmp = datetime_picker(get_field_name_base, (@prefiled_value ? @prefiled_value : d.strftime("%Y/%m")), 'yyyy/MM')
+ when 'format4'
+ tmp = datetime_picker(get_field_name_base, (@prefiled_value ? @prefiled_value : d.strftime("%Y")), 'yyyy')
+ end
+
+ control_group_wrapper{tmp}
+ # control_group_wrapper{date_select(get_field_name_base,nil,@markup_options.merge(:default=>@prefiled_value),:class=>"input-small")}
+
+ end
+ end
+
+ def property_datetime_picker(object_name, value, format, time=false)
+ content_tag :div, :class => "input-append datetimepick", "data-date-format"=>format, "data-picktime"=>"#{time}" do
+ concat text_field_tag(object_name, value, :placeholder=>format)
+ concat (content_tag :span, :class => 'add-on clearDate' do
+ content_tag :i, nil, :class => 'icons-cross-3'
+ end)
+ concat (content_tag :span, :class => 'add-on iconbtn' do
+ content_tag :i, nil, 'data-time-icon' => 'icons-clock', 'data-date-icon' => 'icons-calendar', :class=>"icons-calendar"
+ end)
+ end
+ end
+
+ def render_date_durnation #Need re-write low priority
+
+ end
+
+ def render_radio_button
+ @prefiled_value ||=[]
+ control_group_wrapper do
+ self.typeE[:option_list].collect do |key,value|
+ label_tag("#{get_basic_field_name_org}_#{self.id}_#{key}",radio_button_tag(get_field_name_base, key , (@prefiled_value.include?(key) ? true : false), {:required=>@require,:id=>"#{get_basic_field_name_org}_#{self.id}_#{key}"})+value[I18n.locale.to_s],@markup_options.merge(:class=>"radio inline"))
+ end.join.html_safe
+ end
+ end
+ def render_property_preferred_session
+ @prefiled_value ||=[]
+ @prefiled_value = Array(@prefiled_value)
+ control_group_wrapper do
+ @member.summary_chioices.map.with_index do |value,key|
+ key = key.to_s
+ label_tag("#{get_basic_field_name_org}_#{self.id}_#{key}",radio_button_tag(get_field_name_base, key , ((@prefiled_value.include?(key) || @prefiled_value.include?(key.to_i)) ? true : false), {:required=>@require,:id=>"#{get_basic_field_name_org}_#{self.id}_#{key}"})+value,@markup_options.merge(:class=>"radio inline"))
+ end.join.html_safe
+ end if @member.enable_summary_choice
+ end
+ def render_select
+ prompt = @panel_setting["initial"][I18n.locale.to_s] rescue nil
+ @markup_options.merge!(:prompt => prompt) unless prompt.nil?
+ control_group_wrapper{select_tag( get_field_name_base,options_for_select(self.typeB["option_list"].collect{|p| [p[1][I18n.locale.to_s],p[0]]},@prefiled_value),@markup_options)} rescue ""
+ end
+
+ def render_text_area
+ control_group_wrapper do |key,value|
+ if !@prefiled_value.nil?
+ value = can_muti_lang_input? ? @prefiled_value[key] : @prefiled_value
+ else
+ value = nil
+ end
+ key = can_muti_lang_input? ? "#{key}" : I18n.locale
+ place_holder= typeD["placeholder"][key] rescue ''
+ name1 = can_muti_lang_input? ? (get_field_name_base + "[#{key}]") : get_field_name_base
+ text_area_tag(name1, value,@markup_options.merge(:placeholder=>place_holder,:class=>'ckeditor input-medium form-control'))
+ end
+ end
+
+ def render_text_field
+ a = control_group_wrapper do |key,value|
+ add_more_blank = can_add_more ? "[]" : ""
+ key_field = can_muti_lang_input? ? "#{key}" : I18n.locale
+ place_holder= typeA["placeholder"][key_field] rescue ''
+ name1 = can_muti_lang_input? ? ([get_field_name_base,add_more_blank,"[#{key_field}]"].join) : ([get_field_name_base,add_more_blank].join)
+ text_field_tag(name1, value,@markup_options.merge(:placeholder=>place_holder,:class=>'input-medium form-control'))
+ end
+ end
+
+ def date_is_range?
+ is_range = "false"
+ data = get_data
+ if !data.nil?
+ is_range = data['is_range'] if data.has_key? "is_range"
+ end
+ is_range == "true"
+ end
+
+protected
+
+ def valid_locales
+ site = Site.first
+ [I18n.locale]+(site.valid_locales-[I18n.locale])
+ end
+
+ def lang_panel_tabbable_wrapper(add_more_params,&block)
+ add_more_counter = ''
+
+ if self.markup=='text_area' #or self.markup=='address'
+ tmp1 = valid_locales.collect do |key|
+ if !@prefiled_value.nil?
+ value = @prefiled_value[key] || @prefiled_value[key.to_s] rescue nil
+ else
+ value = nil
+ end
+ # div_class_ary = ["tab-pane" ,"fade","#{get_pairing_tab_class({})}_#{key}"]
+ div_class_ary = ["tab-pane" ,"fade"]
+ if @show_set_field && @markup=='text_area'
+ div_id = "ckeditor_#{get_pairing_tab_class({})}_#{key}"
+ else
+ div_id = "#{get_pairing_tab_class({})}_#{key}"
+ end
+ if can_add_more
+ add_more_value = add_more_params[0][:value]
+ add_more_counter = add_more_params[0][:counter]
+ value = add_more_value[key] rescue nil
+ div_class_ary << "add_more_item_#{add_more_counter}"
+ end
+
+ div_class = div_class_ary.join(" ")
+ div_class << (key == I18n.locale ? " active in" : '')
+ content_tag(:div,yield(key,value), :id=>div_id,:class=>div_class)
+ end# of VALID_LOCALES.collect for tabed input
+ tmp2 = content_tag(:div,:class => 'btn-group', :data=>{:toggle=>"buttons-radio"}) do
+ buff2 = valid_locales.each.collect do |key|
+ # link_entry = self.add_more ? "#{add_more_tab(:tab_btn,loop_counter,key)}" : "#tab"+id.to_s+"_#{key}"
+ if @show_set_field && @markup=='text_area'
+ link_entry_ary = ["#ckeditor_#{get_pairing_tab_class({})}","_#{key}"]
+ else
+ link_entry_ary = ["##{get_pairing_tab_class({})}","_#{key}"]
+ end
+ link_entry_ary << ".add_more_item_#{add_more_counter}" if can_add_more
+ link_entry = link_entry_ary.join
+ link_to(I18n.t(key),link_entry,:data=>{:toggle=>"tab"},:class=>"btn #{(key == I18n.locale ? "active" : nil)}",:for=>key)
+ end # of VALID_LOCALES.collect for tabs
+
+ buff2 << link_to((content_tag :i,'',:class=>'icon-edit'),"##{get_pairing_tab_class({})}_m_window", :role=>"button",:class=>'btn',:data=>{:toggle=>"modal"}) if self.markup == 'address'
+ buff2 << link_to((content_tag :i,'',:class=>'icon-trash'),"#",:class=>"btn remove-input") if self.add_more
+ buff2.join.html_safe
+ end # of content ul
+ tmp = content_tag :div,:class=> "tab-content textarea-lang" do
+ tmp2 << tmp1.join('').html_safe
+ end
+ else
+
+ # tmp = content_tag :div,:class=> (add_more || self.markup=='address') ? "input-append" : "tab-content" do
+ tmp1 =
+ content_tag :div,:class=> "tab-content" do
+
+ buff = valid_locales.collect do |key|
+ value = @prefiled_value[key] || @prefiled_value[key.to_s] rescue nil
+ # div_class_ary = ["tab-pane" ,"fade","#{get_pairing_tab_class({})}_#{key}"]
+ div_class_ary = ["tab-pane" ,"fade"]
+
+ div_id = "#{get_pairing_tab_class({})}_#{key}"
+
+
+ if can_add_more
+ add_more_value = add_more_params[0][:value]
+ add_more_counter = add_more_params[0][:counter]
+ value = add_more_value[key] rescue nil
+ div_class_ary << "add_more_item_#{add_more_counter}"
+ end
+
+ div_class = div_class_ary.join(" ")
+ div_class << (key == I18n.locale ? " active in" : '')
+ content_tag(:div,yield(key,value), :id=>div_id,:class=>div_class)
+ end# of VALID_LOCALES.collect for tabed input
+
+ buff.join('').html_safe
+
+ end
+
+ tmp2 = content_tag(:div,:class => 'btn-group', :data=>{:toggle=>"buttons-radio"}) do
+ buff2 = valid_locales.each.collect do |key|
+ # link_entry = self.add_more ? "#{add_more_tab(:tab_btn,loop_counter,key)}" : "#tab"+id.to_s+"_#{key}"
+ link_entry_ary = ["##{get_pairing_tab_class({})}","_#{key}"]
+ link_entry_ary << ".add_more_item_#{add_more_counter}" if can_add_more
+ link_entry = link_entry_ary.join
+ link_to(I18n.t(key),link_entry,:data=>{:toggle=>"tab"},:class=>"btn #{(key == I18n.locale ? "active" : nil)}",:for=>key)
+ end # of VALID_LOCALES.collect for tabs
+
+ buff2 << link_to((content_tag :i,'',:class=>'icon-edit'),"#address-field", :role=>"button",:class=>'btn',:data=>{:toggle=>"modal"}) if self.markup == 'address'
+ buff2 << link_to((content_tag :i,'',:class=>'icon-trash'),"#",:class=>"btn remove-input") if self.add_more
+ buff2.join.html_safe
+ end # of content ul
+
+
+
+ tmp = content_tag :div,:class=> "input-append" do
+ tmp1 << tmp2
+ end
+
+ end
+
+ end
+
+
+ def controls_wrapper(*add_more_params,&block)
+ result = Array.new
+ add_more_counter = ""
+
+ if can_add_more
+ add_more_counter = add_more_params[0][:counter]
+ add_more_value = add_more_params[0][:value]
+ end
+
+
+
+ if can_muti_lang_input?
+ result << lang_panel_tabbable_wrapper(add_more_params,&block)
+ result << gen_modal_dialog if self.markup == "address"
+ # result << add_more_unt if can_add_more
+ else #cross lang field
+ case can_add_more
+ when true
+ value = add_more_params[0][:value]
+ result << content_tag(:div,:class=>"input-append"){yield(nil,value) + link_to((content_tag :i,'',:class=>'icon-trash'),"#",:class=>"btn remove-input") }
+ # result << add_more_unt
+ else
+ value = @prefiled_value
+ result << yield(nil,value)
+ end
+
+
+ end
+ if self.markup == "address"
+ result
+ else
+ result[0]
+ end
+
+ end # of def controls_wrapper(&block)
+
+ def control_group_wrapper(&block)
+ div_class = can_muti_lang_input? ? "col-sm-#{12-@col} controls" : "col-sm-#{12-@col} controls"
+ # div_class = can_muti_lang_input? ? "control-group language-swich" : "control-group"
+ result = ""
+
+ case self.markup
+
+ when "text_field"
+
+ if can_add_more
+
+ multipleInputs =
+ content_tag(:div,:class=>"add-target") do
+ @attribute_value.add_more_counter.times.collect do |t|
+ controls_wrapper(:value=>(@prefiled_value[t] rescue nil),:counter=>t,&block)
+ end.join('').html_safe # of add_more fields
+ end
+
+
+ temp = content_tag(:div, multipleInputs + add_more_unt, :class=>'add-input')
+
+ result = form_label + content_tag(:div,temp,:class=>div_class)
+
+ # result = label + multipleInputs + add_more_unt
+ # result = label + 一堆的輸入框(要用 multipleInput editMore 包起來) + add_more btn + hidden_fields
+ else
+ result = form_label + content_tag(:div,controls_wrapper(&block),:class=>div_class)
+ end
+
+ when "address"
+
+ # address = content_tag :div,:class=>"multipleInput editMore" do
+ address = content_tag :div,:class=>"col-sm-#{12-@col}" do
+ form_label + content_tag(:div, controls_wrapper(&block), :class=>'add-input')
+ end # of div multipleInput editMore
+
+ result = address
+
+ else
+ result = form_label + content_tag(:div,controls_wrapper(&block),:class=>div_class)
+ end
+ result = result + end_block
+ result.html_safe
+
+ end
+
+
+ def add_more_unt
+ temp_field_name = get_basic_field_name_base + '[temp]'
+ add_more = content_tag :p,:class=> 'add-btn' do
+ content = link_to (content_tag :i,I18n.t(:add),:class=>"icon-plus"),"#","data-roles"=>"role_a",:class=>"trigger #{can_muti_lang_input? ? 'textLengInput' : 'textInput' } btn btn-small btn-primary"
+ content << hidden_field_tag("#{temp_field_name}[count]",@attribute_value.add_more_counter ,:class=>"list_count", :id=>nil)
+ content << hidden_field_tag("#{temp_field_name}[count]",get_basic_field_name_base,:class=>"field_name", :id=>nil)
+ content
+ end # of div
+ # add_more = content_tag :div,:class=> 'controls' do
+ # content_tag :span,:class=> 'help-block' do
+ # content = link_to (content_tag :i,I18n.t(:add),:class=>"icon-plus-sign"),"#",:class=>'addinput'
+ # content << hidden_field_tag("#{temp_field_name}[count]",@attribute_value.add_more_counter ,:class=>"list_count")
+ # content << hidden_field_tag("#{temp_field_name}[count]",get_basic_field_name_base,:class=>"field_name")
+ # content
+ # end # of span
+ # end # of div
+ end
+
+ def end_block
+ if @new_attribute
+ hidden_field_tag(get_basic_field_name_base+"[#{get_basic_field_name}_id]",id,:for=>"field_#{@index}", :id=>nil)
+ else
+ hidden_field_tag(get_basic_field_name_base+"[id]",@attribute_value.id,:for=>"field_#{@index}", :id=>nil)
+ end
+ end
+
+ def add_more_tab(mode,counter,key)
+ case mode
+ when :input_field
+ get_pairing_tab_class(:suffix=>['','tab'+counter.to_s,key].join('-'))
+ when :tab_btn
+ ".#{get_pairing_tab_class(:suffix=>['','tab'+counter.to_s,key].join('-'))}"
+ end
+ end
+
+ def get_pairing_tab_class(opts)
+ prefix = opts[:prefix]
+ suffix = opts[:suffix]
+ str = get_basic_field_name_base.gsub("[","_").gsub("]",'')
+ str = prefix.nil? ? str : prefix+ str
+ suffix.nil? ? str : str + suffix
+ end
+
+ def get_basic_field_name_org
+ "p_hire_field_values"
+ end
+
+ def get_basic_field_name
+ "p_hire_field"
+ end
+
+ def get_basic_field_name_base
+ "#{get_basic_field_name_org}[#{@index}]"
+ end
+
+ def get_field_name_base
+ get_basic_field_name_base + "[value]"
+ end
+
+ def form_label
+ if self.markup == "text_area"
+ plc = typeD["placeholder"][I18n.locale].to_s.blank? ? '' : "(#{typeD["placeholder"][I18n.locale]})"
+ ""+
+ label_tag(key,(!@require.blank? ? '*'+title : title),:class=>"col-sm-#{@col} control-label muted",:style =>'display: contents;')+
+ tag(:br)+"#{plc}"
+ else
+ label_tag(key,(!@require.blank? ? '*'+title : title),:class=>"col-sm-#{@col} control-label muted")
+ end
+ end
+
+ def can_muti_lang_input?
+ if self.markup == "address"
+ return true
+ else
+ $property_list[:markups][markup]["muti_lang_input_supprt"] and !(get_data["cross_lang"] == "true")
+ end
+ end
+
+ def can_add_more
+ if self.markup == "address"
+ return false
+ else
+ add_more
+ end
+ end
+
+ def gen_modal_dialog
+ render_anywhere("shared/attribute_field/address_modal_dialog",{
+ :field_name=>title,
+ :html_id=>"address-field",
+ :btn_class => "#{get_pairing_tab_class({})}",
+ :field_name_basic => get_basic_field_name_base
+ }
+ )
+ end
+ def show_set_field(field_sets,key_field,key_index,field,markup='text_field')
+ @show_set_field = true
+ def self.can_muti_lang_input?
+ true
+ end
+ def self.can_add_more
+ false
+ end
+ @markup = markup
+ def self.markup
+ @markup
+ end
+ def self.add_more
+ false
+ end
+ @new_attribute = false
+ @key_index = key_index
+ def self.key
+ @key_index
+ end
+ def self.form_label
+ ''
+ end
+ def self.end_block
+ unless @attribute_value.new_record?
+ hidden_field_tag("property[#{@key_field}][#{@key_index}]"+"[id]",
+ @attribute_value.id,:for=>"field_#{@key_index}", :id=>nil)
+ else
+ ""
+ end
+ end
+ @key_field = key_field
+ @field = field
+ def self.get_basic_field_name_base
+ "property[#{@key_field}][#{@key_index}][#{@field}]"
+ end
+ def self.get_field_name_base
+ "property[#{@key_field}][#{@key_index}][#{@field}]"
+ end
+ @attribute_value = field_sets
+ @prefiled_value = field_sets[field]
+ a = control_group_wrapper do |key,value|
+ add_more_blank = ""
+ if markup=='text_field'
+ if key_field == 'property_email_sets'
+ inside = text_field_tag([get_field_name_base,"[#{key}]"].join,value,:class=>'input-medium form-control')
+ else
+ inside = text_field_tag([get_field_name_base,"[#{key}]"].join,value)
+ end
+ else
+ inside = cktext_area("property[#{@key_field}][#{@key_index}][#{@field}]","#{key}",value:value)
+ end
+ inside
+ end
+ @key_field = nil
+ @key_index = nil
+ @field = nil
+ @show_set_field = nil
+ return a.html_safe
+ end
+end
\ No newline at end of file
diff --git a/app/helpers/admin/p_hire_field_values_helper.rb b/app/helpers/admin/p_hire_field_values_helper.rb
new file mode 100644
index 0000000..a3fdbdc
--- /dev/null
+++ b/app/helpers/admin/p_hire_field_values_helper.rb
@@ -0,0 +1,113 @@
+module Admin::PHireFieldValuesHelper
+ def show_property_type_panel(attribute_field,type)
+ markup = attribute_field.markup
+ $property_list[:markups][markup]["panel"] == type ? type : [type,'hide'].join(" ")
+ end
+ def show_west_calender(from_to=nil)
+ case from_to
+ when :to
+ date = get_date(:to)
+ when :from
+ date = get_date(:from)
+ when nil
+ date = get_date
+ end
+
+ # case self.member_profile_field["typeC"]["format"]
+ # when 'format1' # Y/M/D h:m
+ # date.strftime("%Y/%m/%d %H:%M")
+ # when 'format2' # Y/M/D
+ # date.strftime("%Y/%m/%d")
+ # when 'format3' # Y/M
+ # date.strftime("%Y/%m")
+ # when 'format4' # Y
+ # date.strftime("%Y")
+ # end # of case west cal format
+ end
+
+ def show_minguo_calendar(from_to=nil)
+ get_minguo
+
+ case from_to
+ when :to
+ date = get_date(:to)
+ when :from
+ date = get_date(:from)
+ when nil
+ date = get_date
+ end
+
+ @date = date.split('/')
+ date_year = @date[0].to_i
+
+ year_str = ""
+ unless date_year == 1912
+ m_year = (date_year - 1912).abs.to_s + I18n.t("date.minguo_calendar.year")
+ year_str = minguo_format_year(m_year)
+ end
+ get_minguo_year(from_to) + minguo_m_y_d_time(from_to)
+ end
+
+ def get_minguo_year(from_to=nil)
+ case from_to
+ when :to
+ date = get_date(:to)
+ when :from
+ date = get_date(:from)
+ when nil
+ date = get_date
+ end
+
+ @date = date.split('/')
+ date_year = @date[0].to_i
+
+ m_year = (date_year - 1911).abs
+ year_end = I18n.t("date.minguo_calendar.year")
+ case
+ when date_year <1912
+ I18n.t("date.minguo_calendar.before") + (m_year+1).to_s + year_end
+ when date_year ==1912
+ I18n.t("date.minguo_calendar.first_year")
+ when date_year >1912
+ I18n.t("date.minguo_calendar.after")+ (m_year).to_s + year_end
+ end # of case tw_calendar year
+ end
+
+ def minguo_m_y_d_time(from_to=nil)
+ case from_to
+ when :to
+ date = get_date(:to)
+ when :from
+ date = get_date(:from)
+ when nil
+ date = get_date
+ end
+ @date = date.split('/')
+
+ case self.p_hire_field["typeC"]["format"]
+ when 'format1' # Y/M/D h:m
+ "/#{@date[1]}/#{@date[2]}"
+ when 'format2' # Y/M/D
+ "/#{@date[1]}/#{@date[2]}"
+ when 'format3' # Y/M
+
+ "/#{@date[1]}#{I18n.t("date.minguo_calendar.month")}"\
+ when 'format4' # Y
+ ''
+ end # of case
+ end
+
+ def get_date_by_format(from_to = nil)
+ case I18n.locale
+ when :zh_tw
+ case
+ when self.p_hire_field["typeC"]["calendar"] == "west_calendar"
+ show_west_calender(from_to)
+ when self.p_hire_field["typeC"]["calendar"] == "tw_calendar"
+ show_minguo_calendar(from_to)
+ end #case self.p_hire_field["typeC"]["calendar"]
+ when :en
+ show_west_calender(from_to)
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/helpers/admin/property_hires_helper.rb b/app/helpers/admin/property_hires_helper.rb
index 78d05a1..83f5c35 100644
--- a/app/helpers/admin/property_hires_helper.rb
+++ b/app/helpers/admin/property_hires_helper.rb
@@ -1,6 +1,7 @@
module Admin::PropertyHiresHelper
-
- def check_for_availability(stime, etime, pid, interval=nil, recurring_end_date=nil)
+ data = File.open(File.join(File.dirname(__FILE__), '../../../config', 'list.yml')).read
+ $property_list = YAML::load(ERB.new(data).result(binding)).symbolize_keys
+ def check_for_availability(stime, etime, pid, interval=nil, recurring_end_date=nil, time_setting_id=nil)
property = Property.find(pid)
return {"success" => false, "msg" => I18n.t("property_hire.values_are_not_ok",:default=>"Values are not ok.")} if property.nil? || stime.blank? || etime.blank?
timezone = (params[:timezone] rescue nil)
@@ -39,9 +40,9 @@ module Admin::PropertyHiresHelper
return {"success" => false, "msg" => I18n.t("property_hire.starting_time_cannot_be_greater_than_ending_time")}
end
end
- available_flag = property.is_available_for_hire?(stime, etime, interval, recurring_end_date)
+ available_flag = property.is_available_for_hire?(stime, etime, interval, recurring_end_date, time_setting_id)
if available_flag
- if property.not_yet_hired?(stime, etime, interval, recurring_end_date,params[:phire_id])
+ if property.not_yet_hired?(stime, etime, interval, recurring_end_date,params[:phire_id], time_setting_id)
data = {"success" => true}
else
I18n.with_locale(params[:locale]) do
@@ -62,6 +63,25 @@ module Admin::PropertyHiresHelper
end
return data
end
+ def render_custom_text_field(f,field_name,type)
+ text = "
+ <%= hidden_field_tag 'property_carousel_image_count', f.object.property_carousel_images.count %> + <%= t(:add) %> +
<%= t('property_hire.field_name') %> | +<%= t('property_hire.name') %> | +<%= t('property_hire.placeholder') %> | +<%= t('property_hire.disable') %> | +<%= t('property_hire.required') %> | + + + <% fields_name.each do |field_name| %> +
---|---|---|---|---|
+ <%= t("property_hire.#{field_name}") %> + | ++ <%= render_custom_text_field(f,field_name,"name") %> + | ++ <%= render_custom_text_field(f,field_name,"placeholder") %> + | ++ + <%= check_box_tag("#{f.object_name}[#{field_name}][enable]", "0" , (f.object.send(field_name)["enable"] == "0" rescue false)) %> + | ++ + <%= check_box_tag("#{f.object_name}[#{field_name}][required]", "true" , (f.object.send(field_name)["required"] == "true" rescue false)) %> + | +
+ <%= hidden_field_tag 'property_link_field_count', f.object.property_links.count %> + <%= t(:add) %> +
++ <%= hidden_field_tag 'property_file_field_count', f.object.property_files.count %> + <%= t(:add) %> +
+ ++ | <%= t("property_hire.position") %> | +<%= t("property_hire.title") %> | +
---|---|---|
+ |
+ <%= (i + 1).to_s %>
+ |
+
+ <%= property.title %>
+ |
+